From 50a1e2b2fe3c207c7227df4941f2f66990db0c2c Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 4 Aug 2008 18:24:36 +0000 Subject: network protocol version 5, netserver per-client updates, zone change protocol --- src/core/netconnection.cc | 109 +++++++++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 30 deletions(-) (limited to 'src/core/netconnection.cc') diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index db8e3a2..3b302dd 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -451,7 +451,7 @@ void NetConnection::parse_incoming_message(const std::string & message) } else if (command == "die") { unsigned int id; if (msgstream >> id) { - //con_debug << "Received die entity id " << id << std::endl; + con_debug << "Received die entity id " << id << std::endl; Entity *e = Entity::find(id); if (localcontrol() == e) localplayer()->set_control(0); @@ -460,47 +460,96 @@ void NetConnection::parse_incoming_message(const std::string & message) } } else if (command == "ent") { - unsigned int type; - if (msgstream >> type) { - //con_debug << "Received create entity type " << type << std::endl; - switch (type) - { - case Entity::Default: - game()->update_entity_clientstate(new Entity(msgstream)); - break; - case Entity::Dynamic: - game()->update_entity_clientstate(new EntityDynamic(msgstream)); - break; - case Entity::Controlable: - game()->update_entity_clientstate(new EntityControlable(msgstream)); - break; - case Entity::Globe: - game()->update_entity_clientstate(new EntityGlobe(msgstream)); - break; - default: - con_warn << "Create for unknown entity type " << type << std::endl; - break; + + 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.compare("zone") == 0) { + unsigned int id; std::string label; if (msgstream >> id) { - con_debug << "Received create zone " << id << std::endl; - Zone * zone = Zone::find(id); + if (id) { + con_debug << "Received zone " << id << std::endl; + Zone * zone = Zone::find(id); - // create the zone if necessary - if (!zone) { - zone = new Zone(msgstream); - Zone::add(zone, id); - } else { - zone->receive_server_update(msgstream); + // create the zone if necessary + if (!zone) { + zone = new Zone(msgstream); + Zone::add(zone, id); + } else { + zone->receive_server_update(msgstream); + } } + + // control is set to 0 on zone change and is put back by pif + connection()->localplayer()->set_control(0); } } else if (command == "pif") { - //con_debug << "Received update player info" << std::endl; + 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; + + if ((entity->zone() == oldzone)) { + delete entity; + Entity::registry().erase(it++); + } else { + ++it; + } + } + oldzone->content().clear(); + } } else if (command == "sup") { if (connection_state == Connected) -- cgit v1.2.3