diff options
author | Stijn Buys <ingar@osirion.org> | 2010-09-22 21:32:34 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2010-09-22 21:32:34 +0000 |
commit | a6f9773c358dd7d091ff64cbda504ab8d8066dd3 (patch) | |
tree | 226e23c4656957e908623ccda9d3d1c50240a0b4 /src/core/netserver.cc | |
parent | bbb43d1c15f2858573f5abb595aa62f8224e4d76 (diff) |
full trading support for networked games
Diffstat (limited to 'src/core/netserver.cc')
-rw-r--r-- | src/core/netserver.cc | 97 |
1 files changed, 92 insertions, 5 deletions
diff --git a/src/core/netserver.cc b/src/core/netserver.cc index 2d83728..8d3e762 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -15,8 +15,6 @@ #include <netinet/in.h> #include <arpa/inet.h> -#else -#include <windows.h> #endif #include <iostream> @@ -295,6 +293,10 @@ void NetServer::client_initialize(NetClient *client) client->player()->send(welcome); client->transmit(); + // send info types + send_infotypes(client); + client->transmit(); + // send zones for (Zone::Registry::iterator it = Zone::registry().begin(); it != Zone::registry().end(); it++) { send_zone_update(client, (*it).second); @@ -377,6 +379,19 @@ void NetServer::client_frame(NetClient *client, unsigned long timestamp) } } + // send inventory update for control + // FIXME this should be done for all player assets + if (client->player()->control() && client->player()->control()->inventory() && client->player()->control()->inventory()->dirty()) { + //con_debug << "SERVER Sending inventory for entity " << client->player()->control()->id() << " server timestamp " << game()->timestamp() << std::endl; + send_inventory_update(client, client->player()->control(), client->player()->control()->inventory()->timestamp()); + } + + // send inventory updates for view + if (client->player()->view() && client->player()->view()->inventory() && client->player()->view()->inventory()->dirty()) { + //con_debug << "SERVER Sending inventory for entity " << client->player()->view()->id() << " server timestamp " << game()->timestamp() << std::endl; + send_inventory_update(client, client->player()->view(), client->player()->view()->inventory()->timestamp()); + } + // send updates for other players for (GameInterface::Players::iterator it = server()->players().begin(); it != server()->players().end(); it++) { if (((*it)->id() != client->player()->id()) && ((*it)->dirty())) { @@ -429,6 +444,8 @@ void NetServer::frame(unsigned long timestamp) * frame <timestamp> <previous timestamp> * ent <id> <entity create data> * die <id> <entity data> + * inf <id> + * inv <id> * ping <timestamp> * sup <entity update data> * @@ -571,6 +588,49 @@ void NetServer::send_info_update(NetClient *client, Info *info) client->send_raw(msg.str()); } +// send "inf" info types +void NetServer::send_infotypes(NetClient *client) +{ + std::ostringstream msg; + msg << "inf 0 " << InfoType::registry().size(); + + for (InfoType::Registry::const_iterator it = InfoType::registry().begin(); it != InfoType::registry().end(); it++) { + msg << " \"" << (*it)->label() << "\""; + } + msg << '\n'; + client->send_raw(msg.str()); +} + +// send a "inv" inventory update +void NetServer::send_inventory_update(NetClient *client, Entity *entity, const unsigned long timestamp) +{ + if (!entity || !entity->inventory()) + return; + + std::ostringstream msg; + msg << "inv " << entity->id() << " " << game()->timestamp() << " "; + + size_t nbitems = 0; + + std::ostringstream itemstr; + for (Inventory::Items::const_iterator it = entity->inventory()->items().begin(); it != entity->inventory()->items().end(); it++) { + const Item *item = (*it); + if (item->timestamp() >= timestamp) { + itemstr << item->info()->id() << " "; + item->serialize_server_update(itemstr); + nbitems++; + } + } + + msg << nbitems; + + if (nbitems) { + msg << " " << itemstr.str(); + } + msg << '\n'; + client->send_raw(msg.str()); +} + // parse incoming client messages /** @@ -584,8 +644,9 @@ void NetServer::send_info_update(NetClient *client, Info *info) * ping * say <text> * priv <player> <text> - * info <id> <typelabel> <label> + * info <id> * req <id> + * inv <id> * */ void NetServer::parse_incoming_message(NetClient *client, const std::string & message) @@ -641,8 +702,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me std::string oldname(client->player()->name()); client->player()->receive_client_update(msgstream); - if (client->state() == NetClient::Pending) { - + if (client->state() == NetClient::Pending) { client->client_state = NetClient::Connected; server()->player_connect(client->player()); @@ -740,6 +800,33 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me } } return; + + } else if (command.compare("inv") == 0) { + + // request information record + unsigned int id; + unsigned long client_timestamp; + + if (!(msgstream >> id >> client_timestamp)) { + con_warn << "^B" << client->player()->name() << "^W invalid inventory request" << std::endl; + return; + } + + Entity *entity = Entity::find (id); + if (!entity) { + con_warn << "^B" << client->player()->name() << "^W invalid request for non-existing entity " << id << std::endl; + return; + } + if (!entity->inventory()) { + con_warn << "^B" << client->player()->name() << "^W invalid request for entity " << id << " without inventory" << std::endl; + return; + } + + //con_debug << "SERVER Sending inventory for entity " << id << " client timestamp " << client_timestamp << std::endl; + + send_inventory_update(client, entity, client_timestamp); + + client->transmit(); } else if (command.compare("rcon") == 0) { if ((message.size() > command.size() + 1) && Cvar::sv_password->str().size()) { |