diff options
Diffstat (limited to 'src/core/netconnection.cc')
-rw-r--r-- | src/core/netconnection.cc | 245 |
1 files changed, 154 insertions, 91 deletions
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index 1318467..0a816b8 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -356,7 +356,7 @@ void NetConnection::send_playerinfo() } // send a "cup" client update message to the server -void NetConnection::send_clientupdate(Entity *entity) +void NetConnection::send_client_update(Entity *entity) { // cup <id> <entity data> std::ostringstream msg; @@ -366,6 +366,15 @@ void NetConnection::send_clientupdate(Entity *entity) this->send_raw(msg.str()); } +// send a "req" entity request +void NetConnection::send_entity_request(Entity *entity) +{ + // req <id> + std::ostringstream msg; + msg << "req " << entity->id() << '\n'; + this->send_raw(msg.str()); +} + // send a "cmd" command line message to the server void NetConnection::send_command(std::string const &cmdline) { @@ -440,12 +449,12 @@ void NetConnection::send_info_request(Info *info) * msg rcon <text> * msg snd <soundname> * die <id> - * ent <id> + * ent <id> <typeid> * frame - * sup <id> + * sup <id> <typeid> * pif <id> * pid <id> - * inf <id> + * inf <id> <typelabel> <label> * zone */ void NetConnection::parse_incoming_message(const std::string & message) @@ -455,7 +464,126 @@ void NetConnection::parse_incoming_message(const std::string & message) std::string command; msgstream >> command; - if (command == "msg") { + if (command.compare("sup") == 0) { + + // entity server update: sup <id> <typeid> + if (connection_state == Connected) { + unsigned int type; + unsigned int id; + + if ((msgstream >> id) && (msgstream >> type)) { + if (!id) { + return; + } + + Entity *entity = Entity::find(id); + if (entity) { + // validate entity type + if (entity->type() != type) { + // type mismatch, delete the entity + if (localcontrol() == entity) + localplayer()->set_control(0); + + Entity::erase(id); + entity = 0; + } + } + + if (!entity) { + switch (type) { + case Entity::Default: + entity = new Entity(msgstream); + break; + case Entity::Dynamic: + entity = new EntityDynamic(msgstream); + break; + case Entity::Controlable: + entity = new EntityControlable(msgstream); + break; + case Entity::Globe: + entity = new EntityGlobe(msgstream); + break; + default: + con_warn << "Received update for unknown entity type " << type << "!" << std::endl; + return; + break; + } + + Entity::add(entity, id); + send_entity_request(entity); + } + + // receive update + entity->receive_server_update(msgstream); + } + } + + } else if (command.compare("ent") == 0) { + // entity create message + unsigned int type = 0; + unsigned int id = 0; + + if ((msgstream >> id) && (msgstream >> type)) { + + if (!id) { + con_warn << "Received create for NULL entity!" << std::endl; + return; + } + //con_debug << "Received create entity id " << id << " type " << type << std::endl; + + Entity *entity = Entity::find(id); + + if (entity) { + // validate entity type + if (entity->type() != type) { + // type mismatch, delete the entity + if (localcontrol() == entity) + localplayer()->set_control(0); + Entity::erase(id); + entity = 0; + } + } + + if (!entity) { + switch (type) { + case Entity::Default: + entity = new Entity(msgstream); + break; + case Entity::Dynamic: + entity = new EntityDynamic(msgstream); + break; + case Entity::Controlable: + entity = new EntityControlable(msgstream); + break; + case Entity::Globe: + entity = new EntityGlobe(msgstream); + break; + default: + con_warn << "Received create for unknown entity type " << type << "!" << std::endl; + return; + break; + } + Entity::add(entity, id); + } + + entity->receive_server_create(msgstream); + } + + } else if (command.compare("die") == 0) { + + unsigned int id; + if (msgstream >> id) { + //con_debug << "Received die entity id " << id << std::endl; + Entity *e = Entity::find(id); + if (localcontrol() == e) + localplayer()->set_control(0); + if (e) + Entity::erase(id); + } + + } else if (command.compare("msg") == 0) { + + // text message: msg <level> std::string level; if (msgstream >> level) { if (level == "info") { @@ -482,7 +610,9 @@ void NetConnection::parse_incoming_message(const std::string & message) } } } - } else if (command == "connect") { + + } else if (command.compare("connect") == 0) { + if (connection_state == Pending) { send_playerinfo(); connection_state = Connected; @@ -490,80 +620,30 @@ void NetConnection::parse_incoming_message(const std::string & message) } return; - } else if (command == "disconnect") { + } else if (command.compare("disconnect") == 0) { con_error << "Server disconnected!" << std::endl; abort(); - } else if (command == "ping") { + } else if (command.compare("ping") == 0) { + unsigned long timestamp; if ((msgstream >> timestamp)) { send_ping_reply(timestamp); } - } else if (command == "frame") { + } else if (command.compare("frame") == 0) { + unsigned long timestamp; if ((msgstream >> timestamp)) { send_ping_reply(timestamp); connection_timestamp = timestamp; } - - } else if (command == "die") { - unsigned int id; - if (msgstream >> id) { - //con_debug << "Received die entity id " << id << std::endl; - Entity *e = Entity::find(id); - if (localcontrol() == e) - localplayer()->set_control(0); - if (e) - Entity::erase(id); - } - - } else if (command == "ent") { - - unsigned int type = 0; - unsigned int id = 0; - - if ((msgstream >> id) && (msgstream >> type)) { - - if (!id) { - con_warn << "Received create for NULL entity!" << std::endl; - return; - } - //con_debug << "Received create entity id " << id << " type " << type << std::endl; - - Entity *entity = Entity::find(id); - - if (!entity) { - switch (type) { - case Entity::Default: - entity = new Entity(msgstream); - break; - case Entity::Dynamic: - entity = new EntityDynamic(msgstream); - break; - case Entity::Controlable: - entity = new EntityControlable(msgstream); - break; - case Entity::Globe: - entity = new EntityGlobe(msgstream); - break; - default: - con_warn << "Received create for unknown entity type " << type << "!" << std::endl; - return; - break; - } - - Entity::add(entity, id); - } - - entity->receive_server_create(msgstream); - //game()->update_entity_clientstate(entity); - } - - } else if (command == "menu") { + + } else if (command.compare("menu") == 0) { unsigned int id = 0; + if (msgstream >> id) { if (!id) { con_warn << "Received menu for NULL entity!" << std::endl; @@ -614,7 +694,7 @@ void NetConnection::parse_incoming_message(const std::string & message) connection()->localplayer()->set_control(0); } - } else if (command == "pif") { + } else if (command.compare("pif") == 0) { //con_debug << "Received update player info" << std::endl; int player_id; @@ -671,7 +751,7 @@ void NetConnection::parse_incoming_message(const std::string & message) player->set_dirty(false); } - } else if (command == "pid") { + } else if (command.compare("pid") == 0) { con_debug << "Received player disconnect info" << std::endl; int player_id; @@ -694,8 +774,9 @@ void NetConnection::parse_incoming_message(const std::string & message) return; } } + + } else if (command.compare("inf") == 0) { - } else if (command == "inf") { // incoming info record unsigned int id = 0; std::string typelabelstr; @@ -708,25 +789,25 @@ void NetConnection::parse_incoming_message(const std::string & message) con_warn << "Received invalid info record message!" << std::endl; return; } - + // read type label n.clear(); while ((msgstream.get(c)) && (c != '"')); while ((msgstream.get(c)) && (c != '"')) n +=c; - - typelabelstr.assign(n); + + typelabelstr.assign(n); if (!typelabelstr.size()) { con_warn << "Received invalid info record message!" << std::endl; return; } - + // read info label n.clear(); while ((msgstream.get(c)) && (c != '"')); while ((msgstream.get(c)) && (c != '"')) n +=c; - + infolabelstr.assign(n); if (!infolabelstr.size()) { con_warn << "Received invalid info record message for type '" << typelabelstr << "'!" << std::endl; @@ -742,7 +823,7 @@ void NetConnection::parse_incoming_message(const std::string & message) // find the Info instance Info *info = Info::find(id); if (!info) { - info = Info::find(infotype, infolabelstr); + info = Info::find(infotype, infolabelstr); } // create one if necessary @@ -756,24 +837,6 @@ void NetConnection::parse_incoming_message(const std::string & message) info->receive_server_update(msgstream); info->clear_timestamp(); - - } else if (command == "sup") { - - if (connection_state == Connected) { - unsigned int id; - if (msgstream >> id) { - //con_debug << "Received update entity id " << id << std::endl; - Entity *entity = Entity::find(id); - if (!entity) { - // FIXME request entity from the server - con_warn << "Update for unknown entity " << id << "!" << std::endl; - } else { - // FIXME check of the received update matches the actual entity - entity->receive_server_update(msgstream); - } - } - } - } } |