diff options
author | Stijn Buys <ingar@osirion.org> | 2014-12-07 23:27:31 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2014-12-07 23:27:31 +0000 |
commit | 493e4317e19725e2de2d51753e5c1906bf9c64ba (patch) | |
tree | c46831d6d661a79b5da6580d4472d39a615fedea /src/core | |
parent | 941c64546ca22b87a9153d36e9e3fe59c18abafe (diff) |
Implemented messageboxes and the ability for the game module to send them to remote clients,
send a messagebox if the player's ship is destroyed, this fixes having to press the respawn button twice.
added messageboxes on network connection failures.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/application.cc | 22 | ||||
-rw-r--r-- | src/core/application.h | 6 | ||||
-rw-r--r-- | src/core/gameserver.cc | 19 | ||||
-rw-r--r-- | src/core/gameserver.h | 3 | ||||
-rw-r--r-- | src/core/netconnection.cc | 54 | ||||
-rw-r--r-- | src/core/netserver.cc | 42 | ||||
-rw-r--r-- | src/core/netserver.h | 7 | ||||
-rw-r--r-- | src/core/player.cc | 13 | ||||
-rw-r--r-- | src/core/player.h | 5 |
9 files changed, 158 insertions, 13 deletions
diff --git a/src/core/application.cc b/src/core/application.cc index 14bb9f3..b181178 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -469,10 +469,30 @@ void Application::notify_message(const core::Message::Channel channel, const std } } +void Application::messagebox(const char *text, const char *label1, const char *command1, const char *label2, const char *command2) +{ + std::string str_text(text ? text : "" ); + + std::string str_label1(label1 ? label1 : "" ); + std::string str_command1(command1 ? command1 : "" ); + + std::string str_label2(label2 ? label2 : "" ); + std::string str_command2(command2 ? command2 : "" ); + + notify_messagebox(str_text, str_label1, str_command1, str_label2, str_command2); +} + + +void Application::notify_messagebox(const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2) +{ + // the default implementation does nothing + // used by the client to show messageboxes +} + void Application::notify_loader(const std::string &message) { // the default implementation does nothing. - // used by the client to udpate the loader screen + // used by the client to update the loader screen } void Application::notify_zonechange() diff --git a/src/core/application.h b/src/core/application.h index 3f99187..da722db 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -82,6 +82,12 @@ public: /// loading message notification virtual void notify_loader(const std::string &message); + + /// messagebox notifications + virtual void notify_messagebox(const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2); + + /// messagebox notifications + void messagebox(const char *text, const char *label1 = 0, const char *command1 = 0, const char *label2 = 0, const char *command2 = 0); /// connect notification virtual void notify_connect(); diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 544f660..37c486c 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -472,6 +472,25 @@ void GameServer::broadcast_sound(const std::string name, Player *ignore_player) } } +// server sends a messagebox to a single player +void GameServer::messagebox(Player *player, const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2) +{ + if (!text.size()) { + return; + } + + NetClient *client = player->client(); + + if (client) { + // this player is a network client, send message over network + server_network->send_messagebox(client, text, label1, command1, label2, command2); + + } else if (player == localplayer()) { + // local player, send message to the local application + application()->notify_messagebox(text, label1, command1, label2, command2); + } +} + // execute a command for a remote player void GameServer::exec(Player *player, std::string const & cmdline) { diff --git a/src/core/gameserver.h b/src/core/gameserver.h index 4f25a9b..3e9c50a 100644 --- a/src/core/gameserver.h +++ b/src/core/gameserver.h @@ -80,7 +80,8 @@ public: /// broadcast a sound to all players void broadcast_sound(std::string const sound, Player *ignore_player = 0); - + /// send a messagebox to a single player + void messagebox(Player *player, const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2); /// a player sends a command to the game server void exec(Player *player, std::string const &cmdline); diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index 4892792..ee3e754 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -56,8 +56,13 @@ void NetConnection::connect(std::string const &to_host, int to_port) struct hostent *serverhostent; serverhostent = gethostbyname(to_host.c_str()); if (!serverhostent) { - con_warn << "Could not resolve '" << to_host.c_str() << "'" << std::endl; + std::ostringstream str; + str << "Could not resolve hostname'" << to_host.c_str() << "'"; + con_error << str.str() << std::endl; + abort(); + + application()->messagebox(str.str().c_str()); return; } @@ -76,8 +81,13 @@ void NetConnection::connect(std::string const &to_host, int to_port) server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)serverhostent->h_addr))); memset(server_addr.sin_zero, '\0', sizeof server_addr.sin_zero); if (server_addr.sin_addr.s_addr == INADDR_NONE) { - con_error << "Network invalid address " << to_host << "!" << std::endl; + std::ostringstream str; + str << "Invalid address for '" << to_host << "'"; + con_error << str.str() << std::endl; + abort(); + + application()->messagebox(str.str().c_str()); return; } @@ -156,12 +166,14 @@ void NetConnection::receive() if (bytes_received == 0) { con_print << "^BDisconnected." << std::endl; - abort(); + abort(); + application()->messagebox("Disconnected from server."); return; } else if (bytes_received < 0) { con_error << "Network receive() error!" << std::endl; //perror("recv"); abort(); + application()->messagebox("Disconnected from server."); return; } @@ -249,8 +261,9 @@ void NetConnection::frame() int nb = select(fd() + 1, &readset, NULL, NULL, &timeout); if (nb == 0) { if (connection_timeout + NETTIMEOUT < core::application()->time()) { - con_error << "Connection timeout!\n"; + con_error << "Connection timeout exceeded!\n"; abort(); + application()->messagebox("Connection timeout exceeded!"); } return; } @@ -649,6 +662,39 @@ void NetConnection::parse_incoming_message(const std::string & message) } } + } else if (command.compare("box") == 0) { + + // box "text" "label1" "cmd1" "label2" "cmd2" + char c; + + // read text + std::string text; + while ((msgstream.get(c)) && (c != '"')); + while ((msgstream.get(c)) && (c != '"')) + text += c; + + std::string label1; + while ((msgstream.get(c)) && (c != '"')); + while ((msgstream.get(c)) && (c != '"')) + label1 += c; + + std::string command1; + while ((msgstream.get(c)) && (c != '"')); + while ((msgstream.get(c)) && (c != '"')) + command1 += c; + + std::string label2; + while ((msgstream.get(c)) && (c != '"')); + while ((msgstream.get(c)) && (c != '"')) + label2 += c; + + std::string command2; + while ((msgstream.get(c)) && (c != '"')); + while ((msgstream.get(c)) && (c != '"')) + command2 += c; + + application()->notify_messagebox(text, label1, command1, label2, command2); + } else if (command.compare("connect") == 0) { if (connection_state == Pending) { diff --git a/src/core/netserver.cc b/src/core/netserver.cc index cbb2dc7..1b49aee 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -487,20 +487,23 @@ void NetServer::frame(unsigned long timestamp) * The following messages can be send to a client * * frame <timestamp> <previous timestamp> - * ent <id> <entity create data> + * ent <id> <entity data> * die <id> <entity data> * inf <id> * inv <id> * ping <timestamp> - * sup <entity update data> + * rep <reputation data> + * sup <entity data> * * msg <channel> <text> * supported message channels are "info" "public" "rcon" and "snd" * "snd" is a special channel to transmit sound events + * box <text> <label1> <command1> <label2> <command2> + * send a messagebox * zone <id> <zone create/update data> */ -// send a message on a specified channel to a single client +// send a text message on a specified channel to a single client void NetServer::send_message(NetClient *client, const Message::Channel channel, const std::string & message) { if (!message.size()) @@ -538,15 +541,44 @@ void NetServer::send_message(NetClient *client, const Message::Channel channel, break; } + std::string str_message(message); + aux::strip_quotes(str_message); + std::string msg("msg "); msg.append(msg_channel); msg += ' '; - msg.append(message); + msg.append(str_message); msg += '\n'; client->send_raw(msg); } +// send a messagebox to a single client +void NetServer::send_messagebox(NetClient *client, const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2) +{ + std::string str_text(text); + aux::strip_quotes(str_text); + + std::string str_label1(label1); + aux::strip_quotes(str_label1); + std::string str_command1(command1); + aux::strip_quotes(str_command1); + + std::string str_label2(label2); + aux::strip_quotes(str_label2); + std::string str_command2(command2); + aux::strip_quotes(str_command2); + + std::ostringstream msg(""); + msg << "box "; + msg << "\"" << str_text << '\"' << ' '; + msg << "\"" << str_label1 << '\"' << ' '; + msg << "\"" << str_command1 << '\"' << ' '; + msg << "\"" << str_label2 << '\"' << ' '; + msg << "\"" << str_command2 << '\"' << '\n'; + + client->send_raw(msg.str()); +} // disconnect a client void NetServer::send_disconnect(NetClient *client) @@ -745,7 +777,6 @@ void NetServer::send_inventory_update(NetClient *client, Entity *entity, const u * info <id> * req <id> * inv <id> - * */ void NetServer::parse_incoming_message(NetClient *client, const std::string & message) { @@ -779,6 +810,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me con_print << client->host() << ":" << client->port() << " " << netmsgstream.str() << std::endl; send_message(client, Message::Info, netmsgstream.str()); + send_messagebox(client, netmsgstream.str(), "", "", "", ""); send_disconnect(client); } else { diff --git a/src/core/netserver.h b/src/core/netserver.h index 7277866..95ada0d 100644 --- a/src/core/netserver.h +++ b/src/core/netserver.h @@ -18,7 +18,9 @@ namespace core { -/// network server +/** + * Handles server-side network messages + * */ class NetServer { public: @@ -72,6 +74,9 @@ public: /// send a message on a specified channel void send_message(NetClient *client, const Message::Channel channel, const std::string & message); + + /// send a messagebox to a single client + void send_messagebox(NetClient *client, const std::string & text, const std::string &label1, const std::string command1, const std::string &label2, const std::string command2); protected: diff --git a/src/core/player.cc b/src/core/player.cc index 14767bd..7511e06 100644 --- a/src/core/player.cc +++ b/src/core/player.cc @@ -95,6 +95,19 @@ void Player::print() const << std::setfill('0') << std::setw(2) << time_wasted_seconds << std::endl; } +void Player::messagebox(const char *text, const char *label1, const char *command1, const char *label2, const char *command2) +{ + std::string str_text(text ? text : "" ); + + std::string str_label1(label1 ? label1 : "" ); + std::string str_command1(command1 ? command1 : "" ); + + std::string str_label2(label2 ? label2 : "" ); + std::string str_command2(command2 ? command2 : "" ); + + server()->messagebox(this, str_text, str_label1, str_command1, str_label2, str_command2); +} + void Player::message(Message::Channel channel, const std::string text) { server()->message(this, channel, text); diff --git a/src/core/player.h b/src/core/player.h index a9eb4b0..e68a219 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -200,7 +200,10 @@ public: } - /*----- server-side mesage functions ------------------------------ */ + /*----- server-side message functions ----------------------------- */ + + /// send a messagebox to the player + void messagebox(const char *text, const char *label1 = 0, const char *command1 = 0, const char *label2 = 0, const char *command2 = 0); /// send a message to the player on one of the message channels void message(core::Message::Channel channel, const std::string text); |