Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/gameconnection.cc41
-rw-r--r--src/core/gameserver.cc132
-rw-r--r--src/core/gameserver.h3
-rw-r--r--src/core/net.h3
-rw-r--r--src/core/netclient.h2
-rw-r--r--src/core/netconnection.cc30
-rw-r--r--src/core/netconnection.h5
-rw-r--r--src/core/netserver.cc39
-rw-r--r--src/core/player.cc1
-rw-r--r--src/core/player.h8
-rw-r--r--src/game/game.cc2
11 files changed, 231 insertions, 35 deletions
diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc
index 4d2a745..daf47e1 100644
--- a/src/core/gameconnection.cc
+++ b/src/core/gameconnection.cc
@@ -47,6 +47,12 @@ GameConnection::GameConnection(std::string const &connectionstr)
return;
}
+ // send connect request
+ std::stringstream netmsgstream("");
+ netmsgstream << "connect " << PROTOCOLVERSION << "\n";
+ connection_network->send(netmsgstream.str());
+ connection_network->transmit();
+
connection_frametime = 0;
connection_running = true;
}
@@ -112,26 +118,23 @@ void GameConnection::frame(float seconds)
}
}
- if ((connection_network->state() == NetConnection::Connected) && localcontrol() && localcontrol()->dirty()) {
- std::ostringstream netmsg;
- netmsg << "cup " << localcontrol()->id() << " ";
- localcontrol()->serialize_client_update(netmsg);
- netmsg << "\n";
-
- connection_network->send(netmsg.str());
- localcontrol()->entity_dirty = false;
- //con_debug << netmsg.str();
- }
-
- if (localplayer()->dirty()) {
- localplayer()->update_info();
+ if (connection_network->state() == NetConnection::Connected) {
+
+ if(localcontrol() && localcontrol()->dirty()) {
+ std::ostringstream netmsg;
+ netmsg << "cup " << localcontrol()->id() << " ";
+ localcontrol()->serialize_client_update(netmsg);
+ netmsg << "\n";
+
+ connection_network->send(netmsg.str());
+ localcontrol()->entity_dirty = false;
+ //con_debug << netmsg.str();
+ }
- std::ostringstream osstream;
- osstream << "pif ";
- localplayer()->serialize_client_update(osstream);
- osstream << '\n';
- connection_network->send(osstream.str());
- localplayer()->player_dirty = false;
+ if (localplayer()->dirty()) {
+ connection_network->send_playerinfo();
+
+ }
}
connection_network->transmit();
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index 2027098..4172d4f 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -17,6 +17,15 @@
namespace core
{
+Player *console_find_player(std::string const & target)
+{
+ Player *targetplayer = server()->find_player(target);
+ if (!targetplayer) {
+ con_print << "^BPlayer " + target + "^B not found.";
+ }
+ return targetplayer;
+}
+
void func_who(std::string const &args)
{
server()->list_players();
@@ -27,6 +36,70 @@ void func_time(std::string const &args)
server()->showtime();
}
+void func_mute(std::string const &args)
+{
+ Player *targetplayer = 0;
+ if (!(targetplayer = console_find_player(args)))
+ return;
+
+ if (targetplayer->mute()) {
+ con_print << "^BPlayer " + targetplayer->name() + "^B has already been muted.";
+ return;
+ }
+
+ targetplayer->player_mute = true;
+ server()->broadcast("^B" + targetplayer->name() + "^B has been muted.", targetplayer);
+ server()->send(targetplayer, "^BYou have been muted.");
+}
+
+void func_unmute(std::string const &args)
+{
+ Player *targetplayer = 0;
+ if (!(targetplayer = console_find_player(args)))
+ return;
+
+ if (!targetplayer->mute()) {
+ con_print << "^BPlayer " + targetplayer->name() + "^B has not been muted.";
+ return;
+ }
+
+ targetplayer->player_mute = false;
+ server()->broadcast("^B" +targetplayer->name() + "^B has been unmuted.", targetplayer);
+ server()->send(targetplayer, "^BYou have been unmuted.");
+}
+
+void func_kick(std::string const &args)
+{
+ std::stringstream str(args);
+ std::string name;
+
+ if (str >> name) {
+ Player *targetplayer = 0;
+ if (!(targetplayer = console_find_player(name)))
+ return;
+ std::string reason;
+ if (args.size() > name.size()+1)
+ reason.assign(args.substr(name.size()+1));
+ else
+ reason.assign("forcefully removed.");
+
+ server()->kick(targetplayer, reason);
+ }
+}
+
+void func_grant_rcon(std::string const &args)
+{
+ Player *targetplayer = 0;
+ if (!(targetplayer = console_find_player(args)))
+ return;}
+
+void func_revoke_rcon(std::string const &args)
+{
+ Player *targetplayer = 0;
+ if (!(targetplayer = console_find_player(args)))
+ return;
+}
+
GameServer *GameServer::server_instance = 0;
GameServer::GameServer() : GameInterface()
@@ -69,8 +142,30 @@ GameServer::GameServer() : GameInterface()
server_network = 0;
}
- Func::add("time", func_time, Func::Shared);
- Func::add("who", func_who, Func::Shared);
+ Func *func = 0;
+
+ /* -- admin functions -- */
+ func = Func::add("mute", func_mute);
+ func->set_info("[player] mute a player");
+
+ func = Func::add("unmute", func_unmute);
+ func->set_info("[player] unmute a player");
+
+ func = Func::add("kick", func_kick);
+ func->set_info("[player] [reason] kick a player from the server");
+/*
+ func = Func::add("grant_rcon", func_grant_rcon);
+ func->set_info("[player] grant a player rcon rights");
+
+ func = Func::add("revoke_rcon", func_grant_rcon);
+ func->set_info("[player] revoke a player's rcon rights");
+*/
+ /* -- player functions --*/
+ func = Func::add("time", func_time, Func::Shared);
+ func->set_info("get the server uptime and current localtime");
+
+ func = Func::add("who", func_who, Func::Shared);
+ func->set_info("get a list of connected players");
if (!Cvar::sv_dedicated->value()) {
player_connect(localplayer());
@@ -100,6 +195,12 @@ GameServer::~GameServer()
delete server_module;
}
+ Func::remove("mute");
+ Func::remove("unmute");
+
+/* Func::remove("grant_rcon");
+ Func::remove("revoke_rcon");
+*/
Func::remove("time");
Func::remove("who");
@@ -174,6 +275,11 @@ void GameServer::say(Player *player, std::string const &message)
if (!message.size())
return;
+ if (player->mute()) {
+ send(player, "^BYou have been muted.");
+ return;
+ }
+
std::string notification("^B");
notification.append(player->name());
notification.append("^F:^B ");
@@ -192,6 +298,28 @@ void GameServer::say(Player *player, std::string const &message)
}
}
+void GameServer::kick(Player *player, std::string const &reason)
+{
+ // FIXME kicked by
+ if (!server_network) {
+ con_print << "Not running a networked server." << std::endl;
+ return;
+ }
+
+ NetClient *client = server_network->find_client(player);
+ if (client) {
+ broadcast("^B" + player->name() + "^B has been kicked: " + reason, player);
+ send(player, "^WYou have been kicked: " + reason);
+
+ client->send("disconnect\n");
+ client->transmit(server_network->fd());
+
+ client->abort();
+ } else {
+ con_print << "Network client not found." << std::endl;
+ }
+}
+
void GameServer::broadcast(std::string const & message, Player *ignore_player)
{
// send to application
diff --git a/src/core/gameserver.h b/src/core/gameserver.h
index 7a2f4a6..172fb94 100644
--- a/src/core/gameserver.h
+++ b/src/core/gameserver.h
@@ -52,6 +52,9 @@ public:
/// a player sends a chat message to the public channel
void say(Player *player, std::string const &args);
+ /// kick a player from the server
+ void kick(Player *player, std::string const &reason);
+
/// broadcast a message to all players
void broadcast(std::string const & message, Player *ignore_player = 0);
diff --git a/src/core/net.h b/src/core/net.h
index 3c49467..2ca81fe 100644
--- a/src/core/net.h
+++ b/src/core/net.h
@@ -10,6 +10,9 @@
namespace core
{
+/// network protocol version
+const unsigned int PROTOCOLVERSION = 1;
+
/// maximum lenght of a (compressed) network message block
const unsigned int FRAMESIZE = 1152;
const unsigned int BLOCKSIZE = 8192;
diff --git a/src/core/netclient.h b/src/core/netclient.h
index 7176260..39c425f 100644
--- a/src/core/netclient.h
+++ b/src/core/netclient.h
@@ -65,7 +65,7 @@ public:
void abort();
- enum State {Connecting=0, Connected=1};
+ enum State {Connecting=0, Pending=1, Connected=2};
inline State state() const { return client_state; }
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index 4c916a1..bee0843 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -89,6 +89,7 @@ void NetConnection::connect(std::string const &to_host, int to_port)
connection_timeout = application()->time();
connection_keepalive = application()->time();
+ connection_state = Pending;
game()->localplayer()->player_dirty = true;
@@ -278,6 +279,18 @@ void NetConnection::send(std::string const &msg)
sendq.append(msg);
}
+void NetConnection::send_playerinfo()
+{
+ localplayer()->update_info();
+
+ std::ostringstream osstream;
+ osstream << "pif ";
+ localplayer()->serialize_client_update(osstream);
+ osstream << '\n';
+ send(osstream.str());
+ localplayer()->player_dirty = false;
+}
+
void NetConnection::transmit()
{
@@ -363,9 +376,11 @@ void NetConnection::parse_incoming_message(const std::string & message)
}
}
} else if (command == "connect") {
-
- connection_state = Connected;
- con_print << "^BConnected." << std::endl;
+ if (connection_state == Pending) {
+ send_playerinfo();
+ connection_state = Connected;
+ con_print << "^BConnected." << std::endl;
+ }
return;
} else if (command == "disconnect") {
@@ -391,6 +406,7 @@ void NetConnection::parse_incoming_message(const std::string & message)
if (e)
Entity::remove(id);
}
+
} else if (command == "ent") {
unsigned int type;
if (msgstream >> type) {
@@ -414,6 +430,10 @@ void NetConnection::parse_incoming_message(const std::string & message)
break;
}
}
+ } else if (command == "pif") {
+ //con_debug << "Received update player info" << std::endl;
+ connection()->localplayer()->recieve_server_update(msgstream);
+
} else if (command == "sup") {
if (connection_state == Connected)
{
@@ -428,11 +448,7 @@ void NetConnection::parse_incoming_message(const std::string & message)
}
}
- } else if (command == "pif") {
- //con_debug << "Received update player info" << std::endl;
- connection()->localplayer()->recieve_server_update(msgstream);
}
-
}
}
diff --git a/src/core/netconnection.h b/src/core/netconnection.h
index ddc70f0..a2e9f2f 100644
--- a/src/core/netconnection.h
+++ b/src/core/netconnection.h
@@ -52,6 +52,9 @@ public:
/// buffer outgoing data
void send(std::string const &msg);
+ /// sennd a player info message
+ void send_playerinfo();
+
/// send bufered outgoing data
void transmit();
@@ -71,7 +74,7 @@ public:
inline bool connected() const { return ((connection_fd != -1) && !connection_error); }
- enum State {Connecting=0, Connected=1};
+ enum State {Connecting=0, Pending=1, Connected=2};
inline State state() const { return connection_state; }
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index 2859006..fe6e45b 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -300,10 +300,14 @@ void NetServer::client_initialize(NetClient *client) {
netmsg << "\n";
client->send(netmsg.str());
}
+
+ // send connect completed
netmsg.str("connect\n");
client->send(netmsg.str());
-
client->transmit(fd());
+
+ // set client state to pending
+ client->client_state = NetClient::Pending;
}
void NetServer::send(NetClient * client, std::string const & message)
@@ -361,15 +365,42 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
return;
}
+ // connection request
+ // connect is the first command expected from the client
+ if (command == "connect") {
+ if (client->state() != NetClient::Connecting)
+ return;
+
+ unsigned int protover;
+ if (msgstream >> protover) {
+ if (protover != PROTOCOLVERSION) {
+ std::stringstream netmsgstream("");
+ netmsgstream << "Protocol version mismatch: ";
+ netmsgstream << "client " << protover << " server " << PROTOCOLVERSION << "!\n";
+
+ con_print << client->host() << ":" << client->port() << " " << netmsgstream.str() << std::endl;
+ server()->send(client->player(), netmsgstream.str());
+ } else {
+ client_initialize(client);
+ }
+ } else {
+ std::string message("Unknown client protocol version!");
+ con_print << client->host() << ":" << client->port() << " " << message << std::endl;
+ server()->send(client->player(), message);
+ client->abort();
+ }
+ return;
+ }
+
// pif - update player information
- // pif is the first command expected from the client
+ // client connection is completed on the first pif
if (command == "pif") {
std::string oldname(client->player()->name());
client->player()->recieve_client_update(msgstream);
- if (client->state() == NetClient::Connecting) {
+ if (client->state() == NetClient::Pending) {
+
client->client_state = NetClient::Connected;
- client_initialize(client);
server()->player_connect(client->player());
} else if ((client->state() == NetClient::Connected) && (client->player()->name() != oldname)) {
diff --git a/src/core/player.cc b/src/core/player.cc
index 97b6944..4ad2c3a 100644
--- a/src/core/player.cc
+++ b/src/core/player.cc
@@ -29,6 +29,7 @@ void Player::clear()
player_name.clear();
player_dirty = false;
player_rcon = false;
+ player_mute = false;
clear_assets();
}
diff --git a/src/core/player.h b/src/core/player.h
index b8dd100..fa13b22 100644
--- a/src/core/player.h
+++ b/src/core/player.h
@@ -47,6 +47,9 @@ public:
/// player base color
inline math::Color const & color() const { return player_color; }
+ /// player has been muted by admin or console
+ inline bool mute() const { return player_mute; }
+
/*----- mutators -------------------------------------------------- */
/// serialize player info to a stream
@@ -96,10 +99,15 @@ public:
/// player color
math::Color player_color;
+ /// player is muted by admin
+ bool player_mute;
+
/// the entity the Player is currently controling
EntityControlable *player_control;
std::list<EntityControlable*> assets;
+
+
};
}
diff --git a/src/game/game.cc b/src/game/game.cc
index 6d85f0f..8054773 100644
--- a/src/game/game.cc
+++ b/src/game/game.cc
@@ -117,7 +117,7 @@ void func_hail(core::Player *player, std::string const &args)
core::Player *targetplayer = core::server()->find_player(target);
if (!targetplayer) {
- core::server()->send(player, "Player " + target + "^N not found.");
+ core::server()->send(player, "^BPlayer " + target + "^B not found.");
return;
}