From 9ff5cf6184b9c5183c1f55cfa6c0d08586eb02c9 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Thu, 10 Feb 2011 18:07:24 +0000 Subject: Added a local chat channel. The say command defaults to zone chat, global messages can be send with the shout command. Removed NonSolid flag fro race objects, have race use the local chat channel. Updated to network protocol version 22. Updated developer documentation. --- src/client/client.cc | 8 +++---- src/core/application.cc | 16 ++++++++++++- src/core/application.h | 1 + src/core/gameconnection.cc | 8 +++++++ src/core/gameconnection.h | 5 +++- src/core/gameserver.cc | 57 +++++++++++++++++++++++++++++++++++++++++++--- src/core/gameserver.h | 8 ++++++- src/core/message.h | 9 +++++++- src/core/net.h | 2 +- src/core/netclient.cc | 4 ++-- src/core/netconnection.cc | 19 ++++++++++++++-- src/core/netconnection.h | 5 +++- src/core/netserver.cc | 36 +++++++++++++++++++---------- src/game/base/racetrack.cc | 39 ++++++++++++++++++++++--------- src/game/base/racetrack.h | 1 + src/render/gl.cc | 8 +++---- src/render/gl.h | 33 +++++++++++++++++++++------ 17 files changed, 208 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/client/client.cc b/src/client/client.cc index 97cfc91..5b72146 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -365,10 +365,7 @@ void Client::notify_message(const core::Message::Channel channel, const std::str case core::Message::Info: // Info message break; - - case core::Message::Local: // Chat message in the local zone - break; - + case core::Message::RCon: // RCon message break; @@ -376,6 +373,9 @@ void Client::notify_message(const core::Message::Channel channel, const std::str audio::play("com/chat"); break; + case core::Message::Local: // Local chat message + break; + case core::Message::Private: // Private chat message audio::play("com/priv"); break; diff --git a/src/core/application.cc b/src/core/application.cc index c731833..ec7e89c 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -202,8 +202,11 @@ void Application::init(int count, char **arguments) func = Func::add("disconnect", Application::func_disconnect); func->set_info("leave the current game"); + func = Func::add("shout", Application::func_shout); + func->set_info("shout [text] shout something on the global chat"); + func = Func::add("say", Application::func_say); - func->set_info("say [text] say something on the public chat"); + func->set_info("say [text] say something on the local chat"); func = Func::add("msg", Application::func_msg); func->set_info("msg [player] [text] send a private message to another player"); @@ -518,6 +521,17 @@ void Application::func_disconnect(std::string const &args) Application::instance()->disconnect(); } +void Application::func_shout(std::string const &args) +{ + if (connection()) { + connection()->shout(args); + } else if (server()) { + server()->shout(localplayer(), args); + } else { + con_print << "Not connected." << std::endl; + } +} + void Application::func_say(std::string const &args) { if (connection()) { diff --git a/src/core/application.h b/src/core/application.h index fbaba9d..37b70c2 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -127,6 +127,7 @@ private: static void func_quit(std::string const &args); static void func_connect(std::string const &args); static void func_disconnect(std::string const &args); + static void func_shout(std::string const &args); static void func_say(std::string const &args); static void func_msg(std::string const &args); static void func_load(std::string const &args); diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index dee506a..ebd5a49 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -162,6 +162,14 @@ void GameConnection::say(std::string const &args) connection_network->send_say(args); } +void GameConnection::shout(std::string const &args) +{ + if (!connection_network->connected()) + return; + + connection_network->send_shout(args); +} + void GameConnection::private_message(std::string const &args) { if (!connection_network->connected()) diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h index fdd5daf..1cc6deb 100644 --- a/src/core/gameconnection.h +++ b/src/core/gameconnection.h @@ -31,7 +31,10 @@ public: /// forward a remote console command void rcon(std::string const &cmdline); - /// localplayer sends a chat message to the public channel + /// localplayer sends a chat message to the global chat channel + void shout(std::string const &args); + + /// localplayer sends a chat message to the local chat channel void say(std::string const &args); /// localplayer sends a private message to another player diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 1bd0dbe..d6f9029 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -255,7 +255,8 @@ Inventory *GameServer::request_inventory(Entity *entity) } -void GameServer::say(Player *player, std::string const &message) +// global chat message +void GameServer::shout(Player *player, std::string const &message) { if (!message.size()) return; @@ -265,14 +266,39 @@ void GameServer::say(Player *player, std::string const &message) return; } + // TODO strip color codes if requested std::string notification("^B"); notification.append(player->name()); - notification.append("^F:^N "); + notification.append("^B: "); notification.append(message); broadcast(Message::Public, notification); } +// local chat message +void GameServer::say(Player *player, std::string const &message) +{ + if (!message.size()) + return; + + if(!player->zone()) + return; + + if (player->mute()) { + player->send("^WYou have been muted"); + return; + } + + // TODO strip color codes if requested + std::string notification("^B"); + notification.append(player->name()); + notification.append("^B:^N "); + notification.append(message); + + broadcast(player->zone(), notification); +} + +// player-to-player chat messages void GameServer::private_message(Player *player, std::string const &args) { if (!args.size()) @@ -346,6 +372,29 @@ void GameServer::broadcast(const Message::Channel channel, const std::string tex } } +// broadcast a message to all players in a particular zone +void GameServer::broadcast(Zone *zone, std::string const text, Player *ignore_player) +{ + if (!text.size()) + return; + + for (Players::iterator it = players().begin(); it != players().end(); it++) { + Player *player = (*it); + if ((player->zone() == zone) && (player != ignore_player)) { + Player *player = (*it); + player->message(Message::Local, text); + } + } + + // console is not in the player list + if (Cvar::sv_dedicated->value()) { + std::string notification(zone->label()); + notification += ' '; + notification.append(text); + localplayer()->message(Message::Local, notification); + } +} + // broadcast a sound event to all players void GameServer::broadcast_sound(const std::string name, Player *ignore_player) { @@ -418,11 +467,13 @@ void GameServer::player_connect(Player *player) player->player_id = server_maxplayerid++; + /* std::string message("^B"); message.append(player->name()); message.append("^B connects."); broadcast(message, player); - + */ + // notify the game module server_module->player_connect(player); diff --git a/src/core/gameserver.h b/src/core/gameserver.h index f0cf88b..ab2bf92 100644 --- a/src/core/gameserver.h +++ b/src/core/gameserver.h @@ -43,7 +43,10 @@ public: /// run a game server time frame void frame(unsigned long timestamp); - /// a player sends a chat message to the public channel + /// a player sends a chat message to the global chat channel + void shout(Player *player, std::string const &args); + + /// a player sends a chat message to the local chat channel void say(Player *player, std::string const &args); /// a player sends a private message to another player @@ -54,6 +57,9 @@ public: /// broadcast an Info message to all players void broadcast(std::string const message, Player *ignore_player = 0); + + /// broadcast an Info message to all players in a particular zone + void broadcast(Zone *zone, std::string const message, Player *ignore_player = 0); /// broadcast a message to all players on a specified channel void broadcast(Message::Channel const channel, std::string const message, Player *ignore_player = 0); diff --git a/src/core/message.h b/src/core/message.h index 3c53439..bab095d 100644 --- a/src/core/message.h +++ b/src/core/message.h @@ -14,7 +14,14 @@ class Message { public: - /// indicates the type of message + /** + * @brief indicates the type of message + * Info info messages from the server to the player + * Public public global chat + * Local public local (zone) chat + * Private player to player private messages + * RCon rcon messages + */ enum Channel {Info = 0, Public = 1, Local = 2, Private = 3, RCon = 4}; }; diff --git a/src/core/net.h b/src/core/net.h index f89d0d8..4607797 100644 --- a/src/core/net.h +++ b/src/core/net.h @@ -11,7 +11,7 @@ namespace core { /// network protocol version -const unsigned int PROTOCOLVERSION = 21; +const unsigned int PROTOCOLVERSION = 22; /// maximum lenght of a (compressed) network message block const unsigned int FRAMESIZE = 1152; diff --git a/src/core/netclient.cc b/src/core/netclient.cc index 46694a6..01de8b8 100644 --- a/src/core/netclient.cc +++ b/src/core/netclient.cc @@ -34,7 +34,7 @@ NetClient::NetClient(std::string host, int port, int fd) : abort(); return; } - con_print << host << ":" << port << " connected." << std::endl; + con_print << host << ":" << port << " connected" << std::endl; client_addr.sin_family = AF_INET; client_addr.sin_port = htons(port); @@ -58,7 +58,7 @@ NetClient::NetClient(std::string host, int port, int fd) : NetClient::~NetClient() { - con_print << host() << ":" << port() << " disconnected." << std::endl; + con_print << host() << ":" << port() << " disconnected" << std::endl; delete client_player; } diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index 15e57e2..262c956 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -393,10 +393,19 @@ void NetConnection::send_rcon(std::string const &cmdline) this->send_raw(msg); } +// send a "shout" chat message message to the server +void NetConnection::send_shout(std::string const &text) +{ + std::string msg("msg public "); + msg.append(text); + msg += '\n'; + this->send_raw(msg); +} + // send a "say" chat message message to the server void NetConnection::send_say(std::string const &text) { - std::string msg("say "); + std::string msg("msg local "); msg.append(text); msg += '\n'; this->send_raw(msg); @@ -405,7 +414,7 @@ void NetConnection::send_say(std::string const &text) // send a "priv" private message to the server void NetConnection::send_private_message(std::string const &text) { - std::string msg("priv "); + std::string msg("msg private "); msg.append(text); msg += '\n'; this->send_raw(msg); @@ -604,6 +613,12 @@ void NetConnection::parse_incoming_message(const std::string & message) if (message.size() > 9) { application()->notify_message(Message::RCon, message.substr(9)); } + } else if (level == "local") { + // FIXME - separate zone and sender nickname + if (message.size() > 10) { + application()->notify_message(Message::Local, message.substr(10)); + } + } else if (level == "public") { // FIXME - separate sender nickname if (message.size() > 11) { diff --git a/src/core/netconnection.h b/src/core/netconnection.h index ffab093..dc5dc27 100644 --- a/src/core/netconnection.h +++ b/src/core/netconnection.h @@ -67,8 +67,11 @@ public: /// send an entity request void send_entity_request(Entity *entity); - /// send a chat message + /// send a local chat message void send_say(std::string const &text); + + /// send a public chat message + void send_shout(std::string const &text); /// send a private message void send_private_message(std::string const &text); diff --git a/src/core/netserver.cc b/src/core/netserver.cc index 937d91b..f58f2d4 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -41,6 +41,8 @@ namespace core NetServer::NetServer(std::string const host, unsigned int const port) { con_print << "^BInitializing network server..." << std::endl; + + con_debug << " protocol version " << PROTOCOLVERSION << std::endl; // initialize variables netserver_fd = -1; @@ -280,7 +282,7 @@ void NetServer::receive() NetClient * NetServer::client_connect(std::string const host, int const port) { - con_print << "Client " << host << ":" << port << " connected\n"; + //con_print << "Client " << host << ":" << port << " connected\n"; NetClient *client = new NetClient(host, port, fd()); if (client->error()) { @@ -651,8 +653,7 @@ void NetServer::send_inventory_update(NetClient *client, Entity *entity, const u * inf * pif * ping - * say - * priv + * msg * info * req * inv @@ -863,15 +864,26 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me } return; - } else if (command.compare("say") == 0 ) { - if (message.size() > command.size() + 1) { - server()->say(client->player(), message.substr(command.size() + 1)); - } - return; - - } else if (command.compare("priv") == 0 ) { - if (message.size() > command.size() + 1) { - server()->private_message(client->player(), message.substr(command.size() + 1)); + } else if (command.compare("msg") == 0 ) { + std::string channel; + msgstream >> channel; + + if (!channel.size()) + return; + + const size_t subpos = command.size() + channel.size() + 2; + if (message.size() <= subpos) + return; + + if (channel.compare("public") == 0) { + server()->shout(client->player(), message.substr(subpos)); + + } else if (channel.compare("local") == 0) { + server()->say(client->player(), message.substr(subpos)); + + } else if (channel.compare("private") == 0) { + + server()->say(client->player(), message.substr(subpos)); } return; } diff --git a/src/game/base/racetrack.cc b/src/game/base/racetrack.cc index 67b8327..fd5d339 100644 --- a/src/game/base/racetrack.cc +++ b/src/game/base/racetrack.cc @@ -29,7 +29,7 @@ CheckPoint::CheckPoint(RaceTrack *parent) die(); } - set_flag(core::Entity::NonSolid); + //set_flag(core::Entity::NonSolid); } CheckPoint::~CheckPoint() @@ -44,11 +44,13 @@ RaceTrack::RaceTrack() : EntityDynamic() track_player = 0; track_racestart = 0; track_checkpointtime = 0; + track_record = 0; + entity_moduletypeid = race_enttype; set_state(core::Entity::NoPower); set_flag(core::Entity::Dockable); - set_flag(core::Entity::NonSolid); + //set_flag(core::Entity::NonSolid); } RaceTrack::~RaceTrack() @@ -104,7 +106,7 @@ void RaceTrack::func_dock(core::Entity *entity) entity_timer = 5.0f; std::string message("^B" + track_player->name() + " ^Bactivated the race! Race starts in 5..."); - core::server()->broadcast(message); + core::server()->broadcast(zone(), message); track_player->set_mission_target(this); return; } @@ -140,7 +142,7 @@ void RaceTrack::frame(float seconds) if (math::distance(location(), player->control()->location()) > radius()) { std::string message("^BNo cheating!"); - core::server()->broadcast(message); + core::server()->broadcast(zone(), message); reset_race(); return; } @@ -152,14 +154,14 @@ void RaceTrack::frame(float seconds) if (entity_timer > 0) { std::stringstream msgstr; msgstr << "^B" << entity_timer << "..."; - core::server()->broadcast(msgstr.str()); + core::server()->broadcast(zone(), msgstr.str()); track_racestart = core::server()->time(); } else { for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { (*cpit)->set_state(core::Entity::NoPower); } std::string message("^BGo!"); - core::server()->broadcast(message); + core::server()->broadcast(zone(), message); track_racestart = core::server()->time(); track_checkpointtime = core::server()->time() + 15.0f; @@ -174,7 +176,7 @@ void RaceTrack::frame(float seconds) if (core::server()->time() > track_checkpointtime) { std::string message("^BToo slow, race lost!"); - core::server()->broadcast(message); + core::server()->broadcast(zone(), message); reset_race(); return; @@ -187,7 +189,7 @@ void RaceTrack::frame(float seconds) if (next_checkpoint != track_checkpoints.end()) { std::string message("^BCheckpoint!"); - core::server()->broadcast(message); + core::server()->broadcast(zone(), message); track_checkpointtime = core::server()->time() + 15.0f; (*track_checkpoint)->set_state(core::Entity::NoPower); track_checkpoint++; @@ -196,12 +198,25 @@ void RaceTrack::frame(float seconds) } else { + float player_time = core::server()->time() - track_racestart; + const bool new_record = ((track_record > 0.0f) && (player_time > 0.0f) && (player_time < track_record)); + std::stringstream msgstr; - msgstr << "^BRace completed in " << core::server()->time() - track_racestart << " seconds!"; - core::server()->broadcast(msgstr.str()); - + msgstr << "^B" << player->name() << "completed the race in " << player_time << " seconds"; + + if (new_record) { + msgstr << ", a new record!"; + } else { + msgstr << "."; + } + core::server()->broadcast(zone(), msgstr.str()); + // prize money unsigned long the_prize = (unsigned long) floorf(10000.0f / (core::server()->time() - track_racestart)); + if (track_record && new_record) { + the_prize += 1000.0f * (track_record - player_time); + } + player->add_credits(the_prize); msgstr.clear(); msgstr.str(""); @@ -209,6 +224,8 @@ void RaceTrack::frame(float seconds) player->send(msgstr.str()); player->sound("game/buy"); + if (new_record) + track_record = player_time; reset_race(); } } diff --git a/src/game/base/racetrack.h b/src/game/base/racetrack.h index da810a3..705039a 100644 --- a/src/game/base/racetrack.h +++ b/src/game/base/racetrack.h @@ -57,6 +57,7 @@ private: float track_racestart; float track_checkpointtime; CheckPoints::iterator track_checkpoint; + float track_record; }; diff --git a/src/render/gl.cc b/src/render/gl.cc index ebba733..e416943 100644 --- a/src/render/gl.cc +++ b/src/render/gl.cc @@ -14,10 +14,10 @@ using math::Vector2f; using math::Vector3f; using math::Color; -genbuffers_func genbuffers = 0; -deletebuffers_func deletebuffers = 0; -bindbuffer_func bindbuffer = 0; -bufferdata_func bufferdata = 0; +genbuffers_func genbuffers = 0; +deletebuffers_func deletebuffers = 0; +bindbuffer_func bindbuffer = 0; +bufferdata_func bufferdata = 0; std::string renderer() { diff --git a/src/render/gl.h b/src/render/gl.h index c230547..51e215c 100644 --- a/src/render/gl.h +++ b/src/render/gl.h @@ -20,35 +20,53 @@ #ifdef _WIN32 #ifndef GL_RESCALE_NORMAL -#define GL_RESCALE_NORMAL 0x803A +#define GL_RESCALE_NORMAL 0x803A #endif #ifndef GL_TEXTURE_MAX_LEVEL -#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LEVEL 0x813D #endif #ifndef GL_GENERATE_MIPMAP -#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP 0x8191 #endif #ifndef GL_REFLECTION_MAP -#define GL_REFLECTION_MAP 0x8512 +#define GL_REFLECTION_MAP 0x8512 #endif #ifndef GL_CLAMP_TO_EDGE -#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLAMP_TO_EDGE 0x812F #endif #ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER 0x8892 #endif #ifndef GL_STATIC_DRAW -#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_DRAW 0x88E4 #endif #endif // _WIN32 +/* + * @brief wrapper class for OpenGL functions + * The gl class accesses the OpenGL library functions + * through function pointers. + * This allows loading the library at runtime + * and makes static builds possible + */ +/* +class GL { + +private: + typedef void (* APIENTRY gl_genbuffers_func)(GLuint count, GLuint *id); + typedef void (* APIENTRY gl_deletebuffers_func)(GLuint count, GLuint *id); + typedef void (* APIENTRY gl_bindbuffer_func)(GLenum target, GLuint id); + typedef void (* APIENTRY gl_bufferdata_func)(GLenum target, GLsizei size, const GLvoid *data, GLenum usage); + +} +*/ /// wrapper namespace for OpenGL operations /** The gl namespace provides a wrapper to the OpenGL library functions. * All methods take floats or Vector3f and Color as parameters. @@ -83,6 +101,7 @@ void viewport(GLint x, GLint y, GLsizei width, GLsizei height); /// set the color used to clear to buffer void clearcolor(math::Color const &color); + void clearcolor(const float r, const float g, const float b, const float a); /// clear buffers to preset values -- cgit v1.2.3