bool xrServer::Process_event_reject (NET_Packet& P, const ClientID sender, const u32 time, const u16 id_parent, const u16 id_entity, bool send_message) { // Parse message CSE_Abstract* e_parent = game->get_entity_from_eid (id_parent); CSE_Abstract* e_entity = game->get_entity_from_eid (id_entity); #ifdef DEBUG Msg("sv reject. id_parent %s id_entity %s [%d]",ent_name_safe(id_parent).c_str(),ent_name_safe(id_entity).c_str(), Device.dwFrame); #endif R_ASSERT (e_parent && e_entity); game->OnDetach (id_parent,id_entity); if (0xffff == e_entity->ID_Parent) { Msg ("~ ERROR: can't detach independant object. entity[%s:%d], parent[%s:%d], section[%s]", e_entity->name_replace(),id_entity,e_parent->name_replace(),id_parent, *e_entity->s_name); if (game_lua()) Msg("~ %s", get_lua_traceback(game_lua(), 2)); return (false); } // Rebuild parentness R_ASSERT3 (e_entity->ID_Parent == id_parent, e_entity->name_replace(), e_parent->name_replace()); e_entity->ID_Parent = 0xffff; xr_vector<u16>& C = e_parent->children; xr_vector<u16>::iterator c = std::find (C.begin(),C.end(),id_entity); R_ASSERT3 (C.end()!=c,e_entity->name_replace(),e_parent->name_replace()); C.erase (c); // Signal to everyone (including sender) if (send_message) { DWORD MODE = net_flags(TRUE,TRUE, FALSE, TRUE); SendBroadcast (BroadcastCID,P,MODE); } return (true); }
void xrServer::Process_event_destroy (NET_Packet& P, ClientID sender, u32 time, u16 ID, NET_Packet* pEPack) { u32 MODE = net_flags(TRUE,TRUE); // Parse message u16 id_dest = ID; #ifdef DEBUG if( dbg_net_Draw_Flags.test( dbg_destroy ) ) Msg ("sv destroy object %s [%d]", ent_name_safe(id_dest).c_str(), Device.dwFrame); #endif CSE_Abstract* e_dest = game->get_entity_from_eid (id_dest); // кто должен быть уничтожен if (!e_dest) { #ifndef MASTER_GOLD Msg ("! SV:ge_destroy: [%d] not found on server",id_dest); #endif // #ifndef MASTER_GOLD return; }; R_ASSERT (e_dest); xrClientData *c_dest = e_dest->owner; // клиент, чей юнит R_ASSERT (c_dest); xrClientData *c_from = ID_to_client(sender); // клиент, кто прислал R_ASSERT (c_dest == c_from); // assure client ownership of event u16 parent_id = e_dest->ID_Parent; #ifdef MP_LOGGING Msg("- SV: Process destroy: parent [%d] item [%d][%s]", parent_id, id_dest, e_dest->name()); #endif //#ifdef MP_LOGGING //--------------------------------------------- NET_Packet P2, *pEventPack = pEPack; P2.w_begin (M_EVENT_PACK); //--------------------------------------------- // check if we have children if (!e_dest->children.empty()) { if (!pEventPack) pEventPack = &P2; while (!e_dest->children.empty()) Process_event_destroy (P,sender,time,*e_dest->children.begin(), pEventPack); }; if (0xffff == parent_id && NULL == pEventPack) { SendBroadcast (BroadcastCID,P,MODE); } else { NET_Packet tmpP; if (0xffff != parent_id && Process_event_reject(P,sender,time,parent_id,ID,false)) { game->u_EventGen(tmpP, GE_OWNERSHIP_REJECT, parent_id); tmpP.w_u16(id_dest); tmpP.w_u8(1); if (!pEventPack) pEventPack = &P2; pEventPack->w_u8(u8(tmpP.B.count)); pEventPack->w(&tmpP.B.data, tmpP.B.count); }; game->u_EventGen(tmpP, GE_DESTROY, id_dest); pEventPack->w_u8(u8(tmpP.B.count)); pEventPack->w(&tmpP.B.data, tmpP.B.count); }; if (NULL == pEPack && NULL != pEventPack) { SendBroadcast (BroadcastCID, *pEventPack, MODE); } // Everything OK, so perform entity-destroy if (e_dest->m_bALifeControl && ai().get_alife()) { game_sv_Single *_game = smart_cast<game_sv_Single*>(game); VERIFY (_game); if (ai().alife().objects().object(id_dest,true)) _game->alife().release (e_dest,false); } if (game) game->OnDestroyObject (e_dest->ID); entity_Destroy (e_dest); }