Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Makefile.am3
-rw-r--r--src/core/application.cc29
-rw-r--r--src/core/application.h6
-rw-r--r--src/core/commandbuffer.cc24
-rw-r--r--src/core/core.h1
-rw-r--r--src/core/gameconnection.cc10
-rw-r--r--src/core/gameconnection.h3
-rw-r--r--src/core/gameinterface.cc44
-rw-r--r--src/core/gameinterface.h11
-rw-r--r--src/core/gameserver.cc196
-rw-r--r--src/core/gameserver.h37
-rw-r--r--src/core/message.h23
-rw-r--r--src/core/net.h2
-rw-r--r--src/core/netconnection.cc91
-rw-r--r--src/core/netconnection.h3
-rw-r--r--src/core/netserver.cc11
-rw-r--r--src/core/player.cc28
-rw-r--r--src/core/player.h9
18 files changed, 391 insertions, 140 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 802234e..8c44d13 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -12,6 +12,5 @@ libcore_la_LIBADD = $(top_builddir)/src/model/libmodel.la \
noinst_LTLIBRARIES = libcore.la
noinst_HEADERS = application.h clientstate.h commandbuffer.h core.h cvar.h \
- entity.h func.h gameconnection.h gameinterface.h gameserver.h module.h net.h \
+ entity.h func.h gameconnection.h gameinterface.h gameserver.h message.h module.h net.h \
netclient.h netconnection.h netserver.h player.h range.h stats.h timer.h
-
diff --git a/src/core/application.cc b/src/core/application.cc
index 21d5e50..6207a0d 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -70,6 +70,16 @@ void func_say(std::string const &args)
}
}
+void func_msg(std::string const &args)
+{
+ if (connection()) {
+ connection()->private_message(args);
+ } else if (server()) {
+ server()->private_message(localplayer(), args);
+ } else {
+ con_print << "Not connected." << std::endl;
+ }
+}
// --------------- signal_handler -----------------------------------
#ifndef _WIN32
@@ -222,6 +232,9 @@ void Application::init(int count, char **arguments)
func = Func::add("say",func_say);
func->set_info("say [text] say something on the public chat");
+
+ func = Func::add("msg",func_msg);
+ func->set_info("msg [player] [text] send a private message to another player");
}
void Application::shutdown()
@@ -299,6 +312,7 @@ void Application::connect(std::string const &host)
void Application::disconnect()
{
if(application_game) {
+ notify_disconnect();
delete application_game;
application_game = 0;
con_print << "^BDisconnected.\n";
@@ -446,6 +460,11 @@ void Application::load_commandline(int count, char **arguments)
cmd() << '\n';
}
+void Application::notify_message(Message::Channel const channel, std::string const message)
+{
+ con_print << message << std::endl;
+}
+
void Application::notify_sound(const char *name)
{
// the default implementation does nothing.
@@ -458,15 +477,17 @@ void Application::notify_remove_sound(size_t source)
// Dedicated servers don't need sounds
}
-void Application::notify_message(std::string const & message)
+void Application::notify_zoneclear(Zone *zone)
{
- con_print << message << std::endl;
+ // the default implementation does nothing.
+ // The client uses this to clear old zones
}
-void Application::notify_zoneclear(Zone *zone)
+void Application::notify_disconnect()
{
// the default implementation does nothing.
- // The client uses this to clear old zones
+ // The client uses this to clear game data
+
}
}
diff --git a/src/core/application.h b/src/core/application.h
index ef89e70..0dfa652 100644
--- a/src/core/application.h
+++ b/src/core/application.h
@@ -9,6 +9,7 @@
#include "sys/sys.h"
#include "core/commandbuffer.h"
+#include "core/message.h"
#include "core/netserver.h"
#include "core/netconnection.h"
#include "core/gameinterface.h"
@@ -62,7 +63,7 @@ public:
virtual void notify_sound(const char * name);
/// text notifications from the core to the application
- virtual void notify_message(std::string const & message);
+ virtual void notify_message(Message::Channel const channel, std::string const message);
/// remove sound source notification
virtual void notify_remove_sound(size_t source);
@@ -70,6 +71,9 @@ public:
/// zone clear notification
virtual void notify_zoneclear(Zone *zone);
+ /// disconnect notification
+ virtual void notify_disconnect();
+
/*----- static --------------------------------------------------- */
/// a pointer to the current application instance
diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc
index c111e17..5ed3787 100644
--- a/src/core/commandbuffer.cc
+++ b/src/core/commandbuffer.cc
@@ -64,6 +64,11 @@ void func_list_zone(std::string const &args)
}
}
+void func_list_model(std::string const &args)
+{
+ model::Model::list();
+}
+
void func_set(std::string const &args)
{
std::istringstream argstream(args);
@@ -160,6 +165,9 @@ void CommandBuffer::init()
func = Func::add("list_zone", (FuncPtr)func_list_zone);
func->set_info("list zones");
+ Func::add("list_model", (FuncPtr) func_list_model);
+ func->set_info("list models");
+
func = Func::add("set", (FuncPtr)func_set);
func->set_info("[variable] [str] set variable value");
@@ -185,6 +193,7 @@ void CommandBuffer::shutdown()
Func::remove("list_var");
Func::remove("list_func");
Func::remove("list_ent");
+ Func::remove("list_model");
Func::remove("list_zone");
Func::remove("print");
Func::remove("print_file");
@@ -205,6 +214,10 @@ void CommandBuffer::exec(std::string const &cmdline)
aux::to_lowercase(command);
//con_debug << "Executing '" << cmdline << "'\n";
+ if ((command[0] == '\\') || (command[0] == '/')) {
+ command.erase(0, 1);
+ }
+
// is it a function
Func *f = Func::find(command);
if (f) {
@@ -248,10 +261,15 @@ void CommandBuffer::exec(std::string const &cmdline)
}
// this gets forwarded to the server
- if (connection())
- connection()->forward(cmdline);
- else
+ if (connection()) {
+ if ((cmdline[0] == '\\') || (cmdline[0] == '/')) {
+ connection()->forward(cmdline.substr(1, cmdline.size()-1));
+ } else {
+ connection()->forward(cmdline);
+ }
+ } else {
con_print << "Unknown command '" << command << "^N'\n";
+ }
}
void CommandBuffer::exec()
diff --git a/src/core/core.h b/src/core/core.h
index feca5fd..80f6d54 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -18,6 +18,7 @@
#include "core/module.h"
#include "core/player.h"
#include "core/range.h"
+#include "core/stats.h"
#include "core/zone.h"
/// core contains the basic functionality of the engine
diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc
index ef998e6..114931c 100644
--- a/src/core/gameconnection.cc
+++ b/src/core/gameconnection.cc
@@ -57,6 +57,8 @@ GameConnection::GameConnection(std::string const &connectionstr)
return;
}
+ game_players.push_back(localplayer());
+
connection_running = true;
}
@@ -91,6 +93,14 @@ void GameConnection::say(std::string const &args)
connection_network->send_say(args);
}
+void GameConnection::private_message(std::string const &args)
+{
+ if (!connection_network->connected())
+ return;
+
+ connection_network->send_private_message(args);
+}
+
void GameConnection::frame(float seconds)
{
if (!running())
diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h
index d0da18e..ecf50f2 100644
--- a/src/core/gameconnection.h
+++ b/src/core/gameconnection.h
@@ -39,6 +39,9 @@ public:
/// localplayer sends a chat message to the public channel
void say(std::string const &args);
+ /// localplayer sends a private message to another player
+ void private_message(std::string const &args);
+
/*----- static ---------------------------------------------------- */
/// return the current game connection
diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index 70224b0..17623f2 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -4,9 +4,11 @@
the terms of the GNU General Public License version 2
*/
-#include <stdlib.h>
+#include <cstdlib>
#include <iostream>
+#include <iomanip>
+#include "auxiliary/functions.h"
#include "core/application.h"
#include "core/cvar.h"
#include "core/func.h"
@@ -19,13 +21,13 @@
namespace core
{
-const float MIN_DELTA = 10e-10;
-
-void func_list_model(std::string const &args)
+void func_list_players(std::string const &args)
{
- model::Model::list();
+ game()->list_players();
}
+const float MIN_DELTA = 10e-10;
+
Player GameInterface::game_localplayer;
EntityControlable *localcontrol()
@@ -52,13 +54,14 @@ GameInterface::GameInterface()
game_localplayer.player_name.assign("Player");
game_localplayer.update_info();
}
-
- Func::add("list_model", (FuncPtr) func_list_model);
+
+ Func *func = Func::add("list_players", func_list_players);
+ func->set_info("get the local list of connected players");
}
GameInterface::~GameInterface()
{
- Func::remove("list_model");
+ Func::remove("list_players");
game_localplayer.clear();
@@ -105,6 +108,16 @@ void GameInterface::clear()
// remove all models
model::Model::clear();
+ // clear player list
+ for (Players::iterator it = game_players.begin(); it != game_players.end(); it++) {
+ Player *player = (*it);
+ if (player != localplayer()) {
+ delete player;
+ }
+ }
+
+ game_players.clear();
+
game_previousframetime = 0;
game_serverframetime = 0;
game_clientframetime = 0;
@@ -220,4 +233,19 @@ float GameInterface::timeoffset() {
return t/d;
}
+void GameInterface::list_players()
+{
+ using namespace std;
+ stringstream msgstr;
+ int count = 0;
+
+ for (Players::iterator it = game_players.begin(); it != game_players.end(); it++) {
+ msgstr.str("");
+ con_print << setw(3) << (*it)->id() << aux::pad_left((*it)->name(), 24) << std::endl;
+ count++;
+ }
+
+ con_print << count << " connected " << aux::plural("player", count) << std::endl;
+}
+
}
diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h
index ef51545..69cd588 100644
--- a/src/core/gameinterface.h
+++ b/src/core/gameinterface.h
@@ -22,6 +22,9 @@ public:
/// destroy the game
virtual ~GameInterface();
+ /// type definition for the Players collection
+ typedef std::list<Player *> Players;
+
/*----- inspectors ---------------------------------------------- */
/// return the local player
@@ -41,6 +44,11 @@ public:
inline float timestep() const { return game_timestep; }
+ inline Players & players() { return game_players; }
+
+ /// show a list of connected players
+ void list_players();
+
/*----- virtual inspectors --------------------------------------- */
/// returns true if the game server can run a time frime
@@ -68,6 +76,9 @@ public:
protected:
/// the local player
static Player game_localplayer;
+
+ /// all the players
+ Players game_players;
float game_serverframetime;
float game_previousframetime;
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index 14f97bb..f251b75 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -4,17 +4,17 @@
the terms of the GNU General Public License version 2
*/
-#include <iomanip>
#include <fstream>
+#include <iomanip>
#include "auxiliary/functions.h"
-#include "sys/sys.h"
#include "core/application.h"
#include "core/cvar.h"
#include "core/func.h"
#include "core/gameserver.h"
#include "core/netserver.h"
#include "filesystem/filesystem.h"
+#include "sys/sys.h"
namespace core
{
@@ -174,8 +174,6 @@ GameServer::GameServer() : GameInterface()
func = Func::add("who", func_who, Func::Shared);
func->set_info("get a list of connected players");
- server_players.clear();
-
if (!Cvar::sv_dedicated->value()) {
player_connect(localplayer());
}
@@ -218,8 +216,6 @@ GameServer::~GameServer()
Func::remove("who");
server_instance = 0;
-
- server_players.clear();
}
void GameServer::abort()
@@ -227,21 +223,6 @@ void GameServer::abort()
server_running = false;
}
-void GameServer::list_players()
-{
- using namespace std;
- stringstream msgstr;
- int count = 0;
-
- for (Players::iterator it = server_players.begin(); it != server_players.end(); it++) {
- msgstr.str("");
- con_print << setw(3) << (*it)->id() << aux::pad_left((*it)->name(), 24) << std::endl;
- count++;
- }
-
- con_print << count << " connected " << aux::plural("player", count) << std::endl;
-}
-
void GameServer::showtime()
{
using namespace std;
@@ -265,7 +246,7 @@ Player *GameServer::find_player(std::string const search)
std::istringstream searchstr(search);
int id = 0;
if (searchstr >> id) {
- for (std::list<Player *>:: iterator it = server_players.begin(); it != server_players.end(); it++) {
+ for (std::list<Player *>:: iterator it = game_players.begin(); it != game_players.end(); it++) {
if ((*it)->id() == id) {
return (*it);
}
@@ -275,7 +256,7 @@ Player *GameServer::find_player(std::string const search)
if (search.size() <3)
return 0;
- for (std::list<Player *>:: iterator it = server_players.begin(); it != server_players.end(); it++) {
+ for (std::list<Player *>:: iterator it = game_players.begin(); it != game_players.end(); it++) {
if (aux::text_strip_lowercase((*it)->name()).find(lowercase(search)) != std::string::npos)
return (*it);
}
@@ -298,14 +279,35 @@ void GameServer::say(Player *player, std::string const &message)
notification.append("^F:^B ");
notification.append(message);
- // send to application
- application()->notify_message(notification);
- application()->notify_sound("com/chat");
-
- // broadcast to remote clients
- if (server_network) {
- server_network->broadcast_message("public", notification);
+ broadcast_message(Message::Public, notification);
+}
+
+void GameServer::private_message(Player *player, std::string const &args)
+{
+ if (!args.size())
+ return;
+
+ if (player->mute()) {
+ send(player, "^BYou have been muted.");
+ return;
+ }
+
+ std::string target;
+ std::stringstream argstr(args);
+ if (!(argstr >> target)) {
+ return;
}
+
+ core::Player *targetplayer = core::server()->find_player(target);
+ if (!targetplayer) {
+ send(player, "^BPlayer " + target + "^B not found.");
+ return;
+ }
+
+
+ std::string message(args.substr(target.size()));
+ send_message(Message::Private, player, "^FTo ^B" + targetplayer->name() + "^F:" + message);
+ send_message(Message::Private, targetplayer, "^FFrom ^B" + player->name() + "^F:" + message);
}
// FIXME kicked by
@@ -327,44 +329,114 @@ void GameServer::kick(Player *player, std::string const &reason)
}
// broadcast an "info" message to all players
-void GameServer::broadcast(std::string const & message, Player *ignore_player)
+void GameServer::broadcast(std::string const message, Player *ignore_player)
{
if (!message.size())
return;
- // send to application
- if (ignore_player != game()->localplayer())
- application()->notify_message(message);
-
- // broadcast to remote clients
- if (server_network) {
- server_network->broadcast_message("info", message, ignore_player);
- }
+ broadcast_message(Message::Info, message, ignore_player);
}
// send and "info" message to a single player
-void GameServer::send(Player *player, std::string message)
+void GameServer::send(Player *player, std::string const message)
+{
+ send_message(Message::Info, player, message);
+}
+
+// send an rcon message to a single player
+void GameServer::send_rcon(Player *player, std::string const message)
+{
+ send_message(Message::RCon, player, message);
+}
+
+void GameServer::send_message(Message::Channel const channel, Player *player, std::string const message)
{
if (!message.size())
return;
- // send to application
if (player == localplayer()) {
- application()->notify_message(message);
+ application()->notify_message(channel, message);
return;
+ } else {
+ if (server_network) {
+ std::string msg_channel;
+ switch(channel) {
+ case core::Message::Info: // Info message
+ msg_channel.assign("info");
+ break;
+
+ case core::Message::Local: // Chat message in the local zone
+ msg_channel.assign("local");
+ break;
+
+ case core::Message::Public: // Public chat message
+ msg_channel.assign("public");
+ break;
+
+ case core::Message::Private: // Private chat message
+ msg_channel.assign("private");
+ break;
+
+ case core::Message::RCon: // RCon message
+ msg_channel.assign("rcon");
+ break;
+
+ default:
+ con_warn << "message on unknown channel " << channel << "!" << std::endl;
+ return;
+ break;
+ }
+
+ NetClient *client = server_network->find_client(player);
+ if (client) {
+ server_network->send_message(client, msg_channel.c_str(), message);
+ }
+ }
}
+}
+
+// broadcast a message on a specified channel to all players
+void GameServer::broadcast_message(Message::Channel const channel, std::string const message, Player *ignore_player)
+{
+ if (!message.size())
+ return;
- // send to remote clients
+ // send to application
+ if (ignore_player != game()->localplayer())
+ application()->notify_message(channel, message);
+
+ // broadcast to remote clients
if (server_network) {
- NetClient *client = server_network->find_client(player);
- if (client) {
- server_network->send_message(client, "info", message);
+ std::string msg_channel;
+ switch(channel) {
+ case core::Message::Info: // Info message
+ msg_channel.assign("info");
+ break;
+
+ case core::Message::Local: // Chat message in the local zone
+ msg_channel.assign("local");
+ break;
+
+ case core::Message::RCon: // RCon message
+ msg_channel.assign("rcon");
+ break;
+
+ case core::Message::Public: // Public chat message
+ msg_channel.assign("public");
+ break;
+
+ default:
+ con_warn << "message on unknown channel " << channel << "!" << std::endl;
+ return;
+ break;
}
+
+ server_network->broadcast_message(msg_channel.c_str(), message);
}
}
// broadcast a sound event to all players
-void GameServer::broadcast_sound(std::string const & sound, Player *ignore_player)
+void GameServer::broadcast_sound(std::string const sound, Player *ignore_player)
{
if (!sound.size())
return;
@@ -381,7 +453,7 @@ void GameServer::broadcast_sound(std::string const & sound, Player *ignore_playe
}
// send a sound event to a single player
-void GameServer::send_sound(Player *player, std::string sound)
+void GameServer::send_sound(Player *player, std::string const sound)
{
if (!sound.size())
return;
@@ -401,24 +473,6 @@ void GameServer::send_sound(Player *player, std::string sound)
}
}
-// send an rcon message to a single player
-void GameServer::send_rcon(Player *player, std::string message)
-{
- // send to application
- if (player == localplayer()) {
- con_print << message << std::endl;
- return;
- }
-
- // send to remote clients
- if (server_network) {
- NetClient *client = server_network->find_client(player);
- if (client) {
- server_network->send_message(client, "rcon", message);
- }
- }
-}
-
// execute a command for a remote player
void GameServer::exec(Player *player, std::string const & cmdline)
{
@@ -478,7 +532,7 @@ void GameServer::player_connect(Player *player)
server_module->player_connect(player);
// manage player list
- server_players.push_back(player);
+ game_players.push_back(player);
}
void GameServer::player_disconnect(Player *player)
@@ -495,12 +549,12 @@ void GameServer::player_disconnect(Player *player)
server_module->player_disconnect(player);
// manage player list
- std::list<Player *>:: iterator it = server_players.begin();
- while (((*it)->id() != player->id()) && (it != server_players.end())) {
+ std::list<Player *>:: iterator it = game_players.begin();
+ while (((*it)->id() != player->id()) && (it != game_players.end())) {
it++;
}
- if (it != server_players.end()) {
- server_players.erase(it);
+ if (it != game_players.end()) {
+ game_players.erase(it);
}
}
diff --git a/src/core/gameserver.h b/src/core/gameserver.h
index 1f6d8cc..b25f1a0 100644
--- a/src/core/gameserver.h
+++ b/src/core/gameserver.h
@@ -8,6 +8,7 @@
#define __INCLUDED_CORE_GAMESERVER_H__
#include "core/gameinterface.h"
+#include "core/message.h"
#include "core/module.h"
#include "core/netserver.h"
@@ -21,8 +22,6 @@ namespace core
class GameServer : public GameInterface
{
public:
- typedef std::list<Player *> Players;
-
GameServer();
~GameServer();
@@ -34,9 +33,6 @@ public:
/// returns true if the game server can not run a time frime
inline bool error() { return !server_running; }
- /// show a list of connected players
- void list_players();
-
/// show the current time
void showtime();
@@ -57,23 +53,32 @@ public:
/// a player sends a chat message to the public channel
void say(Player *player, std::string const &args);
+ /// a player sends a private message to another player
+ void private_message(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);
+ /// broadcast an Info message to all players
+ void broadcast(std::string const message, Player *ignore_player = 0);
+
+ /// broadcast a message to all players on a specified channel
+ void broadcast_message(Message::Channel const channel, std::string const message, Player *ignore_player = 0);
+
+ /// send an Info message to a single player
+ void send(Player *player, std::string const message);
- /// send a message to a single player
- void send(Player *player, std::string message);
+ /// send a RCon message to a single player
+ void send_rcon(Player *player, std::string const message);
+
+ /// send a message on the specific channel to the specified Player
+ void send_message(Message::Channel const channel, Player *player, std::string const message);
/// broadcast a sound to all players
- void broadcast_sound(std::string const & sound, Player *ignore_player = 0);
+ void broadcast_sound(std::string const sound, Player *ignore_player = 0);
/// send a sound to a single player
- void send_sound(Player *player, std::string sound);
-
- /// send a rcon message to a single player
- void send_rcon(Player *player, std::string message);
+ void send_sound(Player *player, std::string const sound);
/// a player sends a command to the game server
void exec(Player *player, std::string const &cmdline);
@@ -81,8 +86,6 @@ public:
/// find the first player who's id or name matches the search string
Player *find_player(std::string const search);
- inline Players & players() { return server_players; }
-
/*----- static ---------------------------------------------------- */
/// return the current game server
@@ -104,8 +107,6 @@ private:
float server_frametime;
float server_time;
float server_previoustime;
-
- Players server_players;
};
inline GameServer *server() { return GameServer::instance(); }
diff --git a/src/core/message.h b/src/core/message.h
new file mode 100644
index 0000000..53d24be
--- /dev/null
+++ b/src/core/message.h
@@ -0,0 +1,23 @@
+/*
+ core/message.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_CORE_MESSAGE_H__
+#define __INCLUDED_CORE_MESSAGE_H__
+
+namespace core
+{
+
+class Message {
+
+public:
+ /// indicates the type of message
+ enum Channel {Info=0, Public=1, Local=2, Private=3, RCon=4 };
+};
+
+}
+
+#endif // __INCLUDED_CORE_MESSAGE_H__
+
diff --git a/src/core/net.h b/src/core/net.h
index f3f976b..4909136 100644
--- a/src/core/net.h
+++ b/src/core/net.h
@@ -11,7 +11,7 @@ namespace core
{
/// network protocol version
-const unsigned int PROTOCOLVERSION = 9;
+const unsigned int PROTOCOLVERSION = 10;
/// maximum lenght of a (compressed) network message block
const unsigned int FRAMESIZE = 1152;
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index ed1a91b..9268447 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -328,6 +328,7 @@ void NetConnection::send_raw(std::string const &msg)
* cup <id> <entity data>
* cmd <text>
* say <text>
+ * priv <text>
*/
// send a "connect" message to the server
@@ -380,6 +381,15 @@ void NetConnection::send_say(std::string const &text)
this->send_raw(msg);
}
+// send a "priv" private message to the server
+void NetConnection::send_private_message(std::string const &text)
+{
+ std::string msg("priv ");
+ msg.append(text);
+ msg += '\n';
+ this->send_raw(msg);
+}
+
// parse incoming client messages
/**
* The following incoming messages are parsed;
@@ -388,13 +398,14 @@ void NetConnection::send_say(std::string const &text)
* disconnect
* msg info <text>
* msg public <name> <text>
+ * msg private <name> <text>
* msg rcon <text>
* msg snd <soundname>
- * die
- * ent
+ * die <id>
+ * ent <id>
* frame
- * sup
- * pif
+ * sup <id>
+ * pif <id>
* zone
*/
void NetConnection::parse_incoming_message(const std::string & message)
@@ -409,19 +420,22 @@ void NetConnection::parse_incoming_message(const std::string & message)
if (msgstream >> level) {
if (level =="info") {
if (message.size() > 9) {
- application()->notify_message(message.substr(9));
+ application()->notify_message(Message::Info, message.substr(9));
}
} else if (level =="rcon") {
if (message.size() > 9) {
- con_print << message.substr(9) << std::endl;
+ application()->notify_message(Message::RCon, message.substr(9));
}
} else if (level == "public") {
// FIXME - separate sender nickname
if (message.size() > 11) {
- application()->notify_message(message.substr(11));
- application()->notify_sound("com/chat");
+ application()->notify_message(Message::Public, message.substr(11));
}
-
+ } else if (level == "private") {
+ // FIXME - separate sender nickname
+ if (message.size() > 12) {
+ application()->notify_message(Message::Private, message.substr(12));
+ }
} else if (level == "snd") {
if (message.size() > 8) {
application()->notify_sound(message.substr(8).c_str());
@@ -527,29 +541,50 @@ void NetConnection::parse_incoming_message(const std::string & message)
} else if (command == "pif") {
//con_debug << "Received update player info" << std::endl;
-
- Zone *oldzone = connection()->localplayer()->zone();
- connection()->localplayer()->receive_server_update(msgstream);
-
- //con_debug << "zone " << ( connection()->localplayer()->zone() ? connection()->localplayer()->zone()->id() : 0) << std::endl;
- if (connection()->localplayer()->zonechange() && oldzone && (oldzone != connection()->localplayer()->zone())) {
-
- // notify the applciation to clear none-core zone assets (textures etc)
- application()->notify_zoneclear(oldzone);
-
- // delete all entities in the old zone
- for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); ) {
- Entity *entity = (*it).second;
+ int player_id;
+ if (!(msgstream >> player_id)) {
+ con_warn << "Received illegal update player info for player!" << std::endl;
+ return;
+ }
- if ((entity->zone() == oldzone)) {
- delete entity;
- Entity::registry().erase(it++);
- } else {
- ++it;
+ if (!player_id) {
+ Zone *oldzone = connection()->localplayer()->zone();
+ connection()->localplayer()->receive_server_update(msgstream);
+
+ //con_debug << "zone " << ( connection()->localplayer()->zone() ? connection()->localplayer()->zone()->id() : 0) << std::endl;
+
+ if (connection()->localplayer()->zonechange() && oldzone && (oldzone != connection()->localplayer()->zone())) {
+
+ // notify the applciation to clear none-core zone assets (textures etc)
+ application()->notify_zoneclear(oldzone);
+
+ // delete all entities in the old zone
+ for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); ) {
+ Entity *entity = (*it).second;
+
+ if ((entity->zone() == oldzone)) {
+ delete entity;
+ Entity::registry().erase(it++);
+ } else {
+ ++it;
+ }
+ }
+ oldzone->content().clear();
+ }
+ } else {
+ // FIXME find player
+ Player *player = 0;
+ for (GameInterface::Players::iterator it = game()->players().begin(); it != game()->players().end() && !player; it++) {
+ if( (*it)->id() == player_id) {
+ player = (*it);
}
}
- oldzone->content().clear();
+ if (!player) {
+ player = new Player();
+ game()->players().push_back(player);
+ }
+ player->receive_server_update(msgstream);
}
} else if (command == "sup") {
diff --git a/src/core/netconnection.h b/src/core/netconnection.h
index da683f5..cb04ce2 100644
--- a/src/core/netconnection.h
+++ b/src/core/netconnection.h
@@ -62,6 +62,9 @@ public:
/// send a chat message
void send_say(std::string const &text);
+ /// send a private message
+ void send_private_message(std::string const &text);
+
/// send a command line to the remote server
void send_command(std::string const &cmdline);
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index 93d4682..e1bd41a 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -514,7 +514,7 @@ void NetServer::send_zone_update(NetClient *client, Zone *zone)
void NetServer::send_player_update(NetClient *client)
{
std::ostringstream msg;
- msg << "pif ";
+ msg << "pif 0 ";
client->player()->serialize_server_update(msg);
msg << '\n';
client->send_raw(msg.str());
@@ -531,6 +531,7 @@ void NetServer::send_player_update(NetClient *client)
* pif
* ping
* say <text>
+ * priv <player> <text>
*
*/
void NetServer::parse_incoming_message(NetClient *client, const std::string & message)
@@ -653,6 +654,14 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
}
return;
}
+
+ // priv
+ if (command == "priv") {
+ if (message.size() > command.size()+1) {
+ server()->private_message(client->player(), message.substr(command.size()+1));
+ }
+ return;
+ }
}
diff --git a/src/core/player.cc b/src/core/player.cc
index 1a610ca..26ea070 100644
--- a/src/core/player.cc
+++ b/src/core/player.cc
@@ -6,6 +6,7 @@
#include <sstream>
+#include "auxiliary/functions.h"
#include "sys/sys.h"
#include "core/player.h"
#include "core/cvar.h"
@@ -33,6 +34,7 @@ void Player::clear()
player_zonechange = false;
player_rcon = false;
player_mute = false;
+ player_mission_target = 0;
clear_assets();
player_control = 0;
@@ -56,12 +58,23 @@ void Player::set_zone(Zone *zone)
}
}
+void Player::set_mission_target(Entity *new_mission_target)
+{
+ if (new_mission_target != player_mission_target) {
+ player_mission_target = new_mission_target;
+ player_dirty = true;
+ }
+}
+
void Player::update_info()
{
Cvar *cl_name = Cvar::find("cl_name");
if (cl_name) {
- if (cl_name->str().size())
+ if (cl_name->str().size()) {
player_name = cl_name->str();
+ aux::strip_quotes(player_name);
+ (*cl_name) = player_name;
+ }
}
Cvar *cl_color = Cvar::find("cl_color");
@@ -105,8 +118,9 @@ void Player::serialize_server_update(std::ostream & os) const
{
unsigned int zo = (zone() ? zone()->id() : 0);
unsigned int co = (player_control ? player_control->id() : 0);
+ unsigned int mission = (player_mission_target ? player_mission_target->id() : 0);
- os << player_id << " " << zo << " " << co << " " << player_color << " \"" << player_name << "\"";
+ os << player_id << " " << zo << " " << co << " " << mission << " " << player_color << " \"" << player_name << "\"";
}
void Player::receive_server_update(std::istream &is)
@@ -131,6 +145,16 @@ void Player::receive_server_update(std::istream &is)
player_control = 0;
}
+ unsigned int mission = 0;
+ is >> mission;
+ if (mission) {
+ player_mission_target = Entity::find(mission);
+ if (!player_mission_target) {
+ con_warn << "mission target set to unknown entity " << co << "\n";
+ }
+ } else {
+ player_mission_target = 0;
+ }
is >> player_color;
std::string n;
diff --git a/src/core/player.h b/src/core/player.h
index 7bf533c..aa31a35 100644
--- a/src/core/player.h
+++ b/src/core/player.h
@@ -67,6 +67,9 @@ public:
/// player has been muted by admin or console
inline bool mute() const { return player_mute; }
+ /// mission target
+ inline Entity *mission_target() { return player_mission_target; }
+
/*----- mutators -------------------------------------------------- */
/// serialize player info to a stream
@@ -99,6 +102,8 @@ public:
/// update player info from client variables
void update_info();
+ void set_mission_target(Entity *new_mission_target);
+
/* -- should actually not be public --*/
/// dirty state
@@ -131,10 +136,12 @@ private:
// the entity the Player is currently controling
EntityControlable *player_control;
+ Entity *player_mission_target;
+
// the zone the player is currently in
Zone *player_zone;
-
+ float player_credits;
};
}