void game_sv_GameState::net_Export_State (NET_Packet& P, ClientID to) { // Generic P.w_clientID (to); P.w_s32 (m_type); P.w_u16 (m_phase); P.w_s32 (m_round); P.w_u32 (m_start_time); P.w_u8 (u8(g_sv_base_iVotingEnabled&0xff)); P.w_u8 (u8(net_sv_control_hit)); P.w_u8 (u8(g_bCollectStatisticData)); // Players // u32 p_count = get_players_count() - ((g_dedicated_server)? 1 : 0); xrClientData* tmp_client = static_cast<xrClientData*>( m_server->GetClientByID(to)); game_PlayerState* tmp_ps = tmp_client->ps; player_exporter tmp_functor(to, tmp_ps, &P); fastdelegate::FastDelegate1<IClient*, void> pcounter; pcounter.bind(&tmp_functor, &player_exporter::count_players); fastdelegate::FastDelegate1<IClient*, void> exporter; exporter.bind(&tmp_functor, &player_exporter::export_players); m_server->ForEachClientDo(pcounter); P.w_u16(tmp_functor.counter); m_server->ForEachClientDo(exporter); net_Export_GameTime(P); }
void game_sv_GameState::net_Export_Update(NET_Packet& P, ClientID id_to, ClientID id) { game_PlayerState* A = get_id(id); if (A) { u16 bk_flags = A->flags__; if (id==id_to) { A->setFlag(GAME_PLAYER_FLAG_LOCAL); } P.w_clientID (id); A->net_Export (P); A->flags__ = bk_flags; }; net_Export_GameTime (P); };
void xrServer::OnCL_Disconnected (IClient* CL) { //csPlayers.Enter (); // Game config (all, info includes deleted player now, excludes at the next cl-update) NET_Packet P; P.B.count = 0; P.w_clientID(CL->ID); xrClientData* xrCData = (xrClientData*)(CL); VERIFY(xrCData); if (!xrCData->ps) return; P.w_stringZ(xrCData->ps->getName()); P.w_u16(xrCData->ps->GameID); P.r_pos = 0; ClientID clientID; clientID.set(0); game->AddDelayedEvent(P,GAME_EVENT_PLAYER_DISCONNECTED, 0, clientID); // xrS_entities::iterator I=entities.begin(),E=entities.end(); if (GetClientsCount()>1 && !CL->flags.bLocal) { // Migrate entities for (; I!=E; ++I) { CSE_Abstract* entity = I->second; if (entity->owner == CL) PerformMigration (entity,(xrClientData*)CL,SelectBestClientToMigrateTo(entity,TRUE)); } } else { // Destroy entities while (!entities.empty()) { CSE_Abstract* entity = entities.begin()->second; entity_Destroy (entity); } } //csPlayers.Leave (); Server_Client_Check(CL); }
void __stdcall export_players(IClient* client) { xrClientData* tmp_client = static_cast<xrClientData*>(client); if (!tmp_client->net_Ready || (tmp_client->ps->IsSkip() && tmp_client->ID != to_client)) { return; } game_PlayerState* curr_ps = tmp_client->ps; u16 tmp_flags = curr_ps->flags__; if (to_ps == curr_ps) curr_ps->setFlag(GAME_PLAYER_FLAG_LOCAL); p_to_send->w_clientID (client->ID); curr_ps->net_Export (*p_to_send, TRUE); curr_ps->flags__ = tmp_flags; }
void xrServer::OnCL_Connected (IClient* _CL) { xrClientData* CL = (xrClientData*)_CL; CL->net_Accepted = TRUE; /// Server_Client_Check(CL); csPlayers.Enter (); Export_game_type(CL); Perform_game_export(); SendConnectionData(CL); // NET_Packet P; P.B.count = 0; P.w_clientID(CL->ID); P.r_pos = 0; ClientID clientID;clientID.set (0); game->AddDelayedEvent (P,GAME_EVENT_PLAYER_CONNECTED, 0, clientID); csPlayers.Leave (); game->ProcessDelayedEvent (); }
void xrServer::Process_event (NET_Packet& P, ClientID sender) { # ifdef SLOW_VERIFY_ENTITIES VERIFY (verify_entities()); # endif u32 timestamp; u16 type; u16 destination; u32 MODE = net_flags(TRUE,TRUE); // correct timestamp with server-unique-time (note: direct message correction) P.r_u32 (timestamp ); // read generic info P.r_u16 (type ); P.r_u16 (destination); CSE_Abstract* receiver = game->get_entity_from_eid (destination); if (receiver) { R_ASSERT(receiver->owner); receiver->OnEvent (P,type,timestamp,sender); }; switch (type) { case GE_GAME_EVENT: { u16 game_event_type; P.r_u16(game_event_type); game->AddDelayedEvent(P,game_event_type,timestamp,sender); }break; case GE_INFO_TRANSFER: case GE_WPN_STATE_CHANGE: case GE_ZONE_STATE_CHANGE: case GE_ACTOR_JUMPING: case GEG_PLAYER_PLAY_HEADSHOT_PARTICLE: case GEG_PLAYER_ATTACH_HOLDER: case GEG_PLAYER_DETACH_HOLDER: case GEG_PLAYER_ITEM2SLOT: case GEG_PLAYER_ITEM2BELT: case GEG_PLAYER_ITEM2RUCK: case GE_GRENADE_EXPLODE: { SendBroadcast (BroadcastCID,P,MODE); }break; case GEG_PLAYER_ACTIVATEARTEFACT: { Process_event_activate (P,sender,timestamp,destination,P.r_u16(), true); break; }; case GE_INV_ACTION: { xrClientData* CL = ID_to_client(sender); if (CL) CL->net_Ready = TRUE; if (SV_Client) SendTo(SV_Client->ID, P, net_flags(TRUE, TRUE)); }break; case GE_RESPAWN: { CSE_Abstract* E = receiver; if (E) { R_ASSERT (E->s_flags.is(M_SPAWN_OBJECT_PHANTOM)); svs_respawn R; R.timestamp = timestamp + E->RespawnTime*1000; R.phantom = destination; q_respawn.insert (R); } } break; case GE_TRADE_BUY: case GE_OWNERSHIP_TAKE: { Process_event_ownership (P,sender,timestamp,destination); VERIFY (verify_entities()); }break; case GE_OWNERSHIP_TAKE_MP_FORCED: { Process_event_ownership (P,sender,timestamp,destination,TRUE); VERIFY (verify_entities()); }break; case GE_TRADE_SELL: case GE_OWNERSHIP_REJECT: case GE_LAUNCH_ROCKET: { Process_event_reject (P,sender,timestamp,destination,P.r_u16()); VERIFY (verify_entities()); }break; case GE_DESTROY: { Process_event_destroy (P,sender,timestamp,destination, NULL); VERIFY (verify_entities()); } break; case GE_TRANSFER_AMMO: { u16 id_entity; P.r_u16 (id_entity); CSE_Abstract* e_parent = receiver; // кто забирает (для своих нужд) CSE_Abstract* e_entity = game->get_entity_from_eid (id_entity); // кто отдает if (!e_entity) break; if (0xffff != e_entity->ID_Parent) break; // this item already taken xrClientData* c_parent = e_parent->owner; xrClientData* c_from = ID_to_client (sender); R_ASSERT (c_from == c_parent); // assure client ownership of event // Signal to everyone (including sender) SendBroadcast (BroadcastCID,P,MODE); // Perfrom real destroy entity_Destroy (e_entity ); VERIFY (verify_entities()); } break; case GE_HIT: case GE_HIT_STATISTIC: { P.r_pos -=2; if (type == GE_HIT_STATISTIC) { P.B.count -= 4; P.w_u32(sender.value()); }; game->AddDelayedEvent(P,GAME_EVENT_ON_HIT, 0, ClientID() ); } break; case GE_ASSIGN_KILLER: { u16 id_src; P.r_u16 (id_src); CSE_Abstract *e_dest = receiver; // кто умер // this is possible when hit event is sent before destroy event if (!e_dest) break; CSE_ALifeCreatureAbstract *creature = smart_cast<CSE_ALifeCreatureAbstract*>(e_dest); if (creature) creature->set_killer_id( id_src ); // Msg ("[%d][%s] killed [%d][%s]",id_src,id_src==u16(-1) ? "UNKNOWN" : game->get_entity_from_eid(id_src)->name_replace(),id_dest,e_dest->name_replace()); break; } case GE_CHANGE_VISUAL: { CSE_Visual* visual = smart_cast<CSE_Visual*>(receiver); VERIFY(visual); string256 tmp; P.r_stringZ (tmp); visual->set_visual (tmp); }break; case GE_DIE: { // Parse message u16 id_dest = destination, id_src; P.r_u16 (id_src); xrClientData *l_pC = ID_to_client(sender); VERIFY (game && l_pC); #ifndef MASTER_GOLD if ((game->Type() != eGameIDSingle) && l_pC && l_pC->owner) { Msg ("* [%2d] killed by [%2d] - sended by [%s:%2d]", id_dest, id_src, game->get_option_s(*l_pC->name,"name","Player"), l_pC->owner->ID); } #endif // #ifndef MASTER_GOLD CSE_Abstract* e_dest = receiver; // кто умер // this is possible when hit event is sent before destroy event if (!e_dest) break; #ifndef MASTER_GOLD if (game->Type() != eGameIDSingle) Msg ("* [%2d] is [%s:%s]", id_dest, *e_dest->s_name, e_dest->name_replace()); #endif // #ifndef MASTER_GOLD CSE_Abstract* e_src = game->get_entity_from_eid (id_src ); // кто убил if (!e_src) { xrClientData* C = (xrClientData*) game->get_client(id_src); if (C) e_src = C->owner; }; VERIFY (e_src); if (!e_src) { Msg("! ERROR: SV: src killer not exist."); return; } // R_ASSERT2 (e_dest && e_src, "Killer or/and being killed are offline or not exist at all :("); #ifndef MASTER_GOLD if (game->Type() != eGameIDSingle) Msg ("* [%2d] is [%s:%s]", id_src, *e_src->s_name, e_src->name_replace()); #endif // #ifndef MASTER_GOLD game->on_death (e_dest,e_src); xrClientData* c_src = e_src->owner; // клиент, чей юнит убил if (c_src->owner->ID == id_src) { // Main unit P.w_begin (M_EVENT); P.w_u32 (timestamp); P.w_u16 (type); P.w_u16 (destination); P.w_u16 (id_src); P.w_clientID (c_src->ID); } SendBroadcast (BroadcastCID,P,MODE); ////////////////////////////////////////////////////////////////////////// // if (game->Type() == eGameIDSingle) { P.w_begin (M_EVENT); P.w_u32 (timestamp); P.w_u16 (GE_KILL_SOMEONE); P.w_u16 (id_src); P.w_u16 (destination); SendTo (c_src->ID, P, net_flags(TRUE, TRUE)); } ////////////////////////////////////////////////////////////////////////// VERIFY (verify_entities()); } break; case GE_ADDON_ATTACH: case GE_ADDON_DETACH: case GE_CHANGE_POS: { SendTo(SV_Client->ID, P, net_flags(TRUE, TRUE)); }break; case GE_INSTALL_UPGRADE: { shared_str upgrade_id; P.r_stringZ ( upgrade_id ); CSE_ALifeInventoryItem* iitem = smart_cast<CSE_ALifeInventoryItem*>( receiver ); if ( !iitem ) { break; } iitem->add_upgrade ( upgrade_id ); }break; case GEG_PLAYER_DISABLE_SPRINT: case GEG_PLAYER_WEAPON_HIDE_STATE: { SendTo (SV_Client->ID, P, net_flags(TRUE, TRUE)); # ifdef SLOW_VERIFY_ENTITIES VERIFY (verify_entities()); # endif }break; case GEG_PLAYER_ACTIVATE_SLOT: case GEG_PLAYER_ITEM_EAT: { SendTo(SV_Client->ID, P, net_flags(TRUE, TRUE)); # ifdef SLOW_VERIFY_ENTITIES VERIFY (verify_entities()); # endif }break; case GEG_PLAYER_ITEM_SELL: { game->OnPlayer_Sell_Item(sender, P); }break; case GE_TELEPORT_OBJECT: { game->teleport_object (P,destination); }break; case GE_ADD_RESTRICTION: { game->add_restriction (P,destination); }break; case GE_REMOVE_RESTRICTION: { game->remove_restriction(P,destination); }break; case GE_REMOVE_ALL_RESTRICTIONS: { game->remove_all_restrictions(P,destination); }break; case GE_MONEY: { CSE_Abstract *e_dest = receiver; CSE_ALifeTraderAbstract* pTa = smart_cast<CSE_ALifeTraderAbstract*>(e_dest); pTa->m_dwMoney = P.r_u32(); }break; case GE_FREEZE_OBJECT: break; default: R_ASSERT2 (0,"Game Event not implemented!!!"); break; } }