void game_cl_GameState::TranslateGameMessage (u32 msg, NET_Packet& P) { CStringTable st; string512 Text; char Color_Main[] = "%c[255,192,192,192]"; LPSTR Color_Teams[3] = {"%c[255,255,240,190]", "%c[255,64,255,64]", "%c[255,64,64,255]"}; switch (msg) { case GAME_EVENT_PLAYER_CONNECTED: { #ifdef BATTLEYE if ( g_pGameLevel && Level().battleye_system.GetTestClient() ) { bool res_battleye = Level().battleye_system.LoadClient(); VERIFY( res_battleye ); } #endif // BATTLEYE string64 PlayerName; P.r_stringZ(PlayerName); sprintf_s(Text, "%s%s %s%s",Color_Teams[0],PlayerName,Color_Main,*st.translate("mp_connected")); CommonMessageOut(Text); //--------------------------------------- Msg("%s connected", PlayerName); }break; case GAME_EVENT_PLAYER_DISCONNECTED: { string64 PlayerName; P.r_stringZ(PlayerName); sprintf_s(Text, "%s%s %s%s",Color_Teams[0],PlayerName,Color_Main,*st.translate("mp_disconnected")); CommonMessageOut(Text); //--------------------------------------- Msg("%s disconnected", PlayerName); }break; case GAME_EVENT_PLAYER_ENTERED_GAME: { string64 PlayerName; P.r_stringZ(PlayerName); sprintf_s(Text, "%s%s %s%s",Color_Teams[0],PlayerName,Color_Main,*st.translate("mp_entered_game")); CommonMessageOut(Text); }break; default: { R_ASSERT2(0,"Unknown Game Message"); }break; }; }
void CLevel__cl_Process_CustomEventServer(NET_Packet& pack) { if (HookHandle->IsServer()) { unsigned char type = 0; pack.r_u8(type); if (type == e_so_engine_packet) { unsigned char e; pack.r_u8(e); switch (e) { case e_add_money: { LogHandle->Write("CLevel__cl_Process_CustomEventServer add money event"); ClientID cl_id; pack.r_clientID(cl_id); HookHandle->Add_money_mp(cl_id); }break; default: LogHandle->Write("CLevel__cl_Process_CustomEventServer unknown event %d",e); break; } } else if (type == e_so_script_packet) { char data[2048]; pack.r_stringZ(data); LogHandle->Write("Recieved data at server side '%s'",data); HookHandle->messanges_sv.push_back(data); } else { LogHandle->Write("ERROR: CLevel__cl_Process_CustomEventServer unknown type"); } } }
void game_cl_Deathmatch::net_import_state (NET_Packet& P) { inherited::net_import_state (P); m_s32FragLimit = P.r_s32(); m_s32TimeLimit = P.r_s32() * 60000; m_u32ForceRespawn = P.r_u32() * 1000; m_cl_dwWarmUp_Time = P.r_u32(); m_bDamageBlockIndicators = !!P.r_u8(); // Teams u16 t_count; P.r_u16 (t_count); teams.clear (); for (u16 t_it=0; t_it<t_count; ++t_it) { game_TeamState ts; P.r (&ts,sizeof(game_TeamState)); teams.push_back (ts); }; switch (Phase()) { case GAME_PHASE_PLAYER_SCORES: { P.r_stringZ(WinnerName); bool NeedSndMessage = (xr_strlen(WinnerName) != 0); if (NeedSndMessage && local_player && !xr_strcmp(WinnerName, local_player->getName())) { PlaySndMessage(ID_YOU_WON); } }break; } }
void game_PlayerState::net_Import(NET_Packet& P) { BOOL bFullUpdate = !!P.r_u8(); if (bFullUpdate) P.r_stringZ (name); P.r_u8 ( team ); P.r_s16 ( m_iRivalKills ); P.r_s16 ( m_iSelfKills ); P.r_s16 ( m_iTeamKills ); P.r_s16 ( m_iDeaths ); P.r_s32 ( money_for_round ); P.r_float_q8 ( experience_D, -1.0f, 2.0f); P.r_u8 ( rank ); P.r_u8 ( af_count ); P.r_u16 ( flags__ ); P.r_u16 ( ping ); P.r_u16 ( GameID ); P.r_s8 ( skin ); P.r_u8 ( m_bCurrentVoteAgreed ); DeathTime = P.r_u32(); };
void CInventoryItem::OnEvent (NET_Packet& P, u16 type) { switch (type) { case GE_ADDON_ATTACH: { u16 ItemID; P.r_u16 (ItemID); CInventoryItem* ItemToAttach = smart_cast<CInventoryItem*>(Level().Objects.net_Find(ItemID)); if (!ItemToAttach) break; Attach(ItemToAttach,true); }break; case GE_ADDON_DETACH: { string64 i_name; P.r_stringZ (i_name); Detach(i_name, true); }break; case GE_CHANGE_POS: { Fvector p; P.r_vec3(p); CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem(0); if (!pSyncObj) return; SPHNetState state; pSyncObj->get_State(state); state.position = p; state.previous_position = p; pSyncObj->set_State(state); }break; } }
void CALifeStorageManager::save (NET_Packet &net_packet) { prepare_objects_for_save (); shared_str game_name; net_packet.r_stringZ (game_name); save (*game_name,!!net_packet.r_u8()); }
void game_cl_TeamDeathmatch::TranslateGameMessage (u32 msg, NET_Packet& P) { CStringTable st; string512 Text; // LPSTR Color_Teams[3] = {"%c[255,255,255,255]", "%c[255,64,255,64]", "%c[255,64,64,255]"}; char Color_Main[] = "%c[255,192,192,192]"; // LPSTR TeamsNames[3] = {"Zero Team", "Team Green", "Team Blue"}; switch(msg) { case GAME_EVENT_PLAYER_JOIN_TEAM: //tdm { string64 PlayerName; P.r_stringZ (PlayerName); u16 Team; P.r_u16 (Team); sprintf_s(Text, "%s%s %s%s %s%s", "",//no color PlayerName, Color_Main, *st.translate("mp_joined"), CTeamInfo::GetTeam_color_tag(int(Team)), CTeamInfo::GetTeam_name(int(Team))); CommonMessageOut(Text); //--------------------------------------- Msg("%s %s %s", PlayerName, *st.translate("mp_joined"), CTeamInfo::GetTeam_name(int(Team))); }break; case PLAYER_CHANGE_TEAM://tdm { u16 PlayerID, OldTeam, NewTeam; P.r_u16 (PlayerID); P.r_u16 (OldTeam); P.r_u16 (NewTeam); game_PlayerState* pPlayer = GetPlayerByGameID(PlayerID); if (!pPlayer) break; sprintf_s(Text, "%s%s %s%s %s%s", CTeamInfo::GetTeam_color_tag(int(OldTeam)), pPlayer->name, Color_Main, *st.translate("mp_switched_to"), CTeamInfo::GetTeam_color_tag(int(NewTeam)), CTeamInfo::GetTeam_name(int(NewTeam))); CommonMessageOut(Text); //--------------------------------------- Msg("%s *s %s", pPlayer->name, *st.translate("mp_switched_to"), CTeamInfo::GetTeam_name(int(NewTeam))); }break; default: inherited::TranslateGameMessage(msg,P); }; }
void CSE_ALifeItemDocument::STATE_Read (NET_Packet &tNetPacket, u16 size) { inherited::STATE_Read (tNetPacket,size); if ( m_wVersion < 98 ){ u16 tmp; tNetPacket.r_u16 (tmp); m_wDoc = NULL; }else tNetPacket.r_stringZ (m_wDoc); }
void CSE_ALifeItemPDA::STATE_Read (NET_Packet &tNetPacket, u16 size) { inherited::STATE_Read (tNetPacket,size); if (m_wVersion > 58) tNetPacket.r (&m_original_owner,sizeof(m_original_owner)); if (m_wVersion > 89) if ( (m_wVersion > 89)&&(m_wVersion < 98) ) { int tmp,tmp2; tNetPacket.r (&tmp, sizeof(int)); tNetPacket.r (&tmp2, sizeof(int)); m_info_portion = NULL; m_specific_character = NULL; }else{ tNetPacket.r_stringZ (m_specific_character); tNetPacket.r_stringZ (m_info_portion); } }
u16 GetSpawnInfo(NET_Packet &P, u16 &parent_id) { u16 dummy16, id; P.r_begin(dummy16); shared_str s_name; P.r_stringZ(s_name); CSE_Abstract* E = F_entity_Create(*s_name); E->Spawn_Read(P); if (E->s_flags.is(M_SPAWN_UPDATE)) E->UPDATE_Read(P); id = E->ID; parent_id = E->ID_Parent; F_entity_Destroy(E); P.r_pos = 0; return id; }
void CInventoryItem::OnEvent (NET_Packet& P, u16 type) { switch (type) { case GE_ADDON_ATTACH: { u32 ItemID; P.r_u32 (ItemID); CInventoryItem* ItemToAttach = smart_cast<CInventoryItem*>(Level().Objects.net_Find(ItemID)); if (!ItemToAttach) break; Attach(ItemToAttach,true); CActor* pActor = smart_cast<CActor*>(object().H_Parent()); if (pActor && pActor->inventory().ActiveItem() == this) { pActor->inventory().SetPrevActiveSlot(pActor->inventory().GetActiveSlot()); pActor->inventory().Activate(NO_ACTIVE_SLOT); } }break; case GE_ADDON_DETACH: { string64 i_name; P.r_stringZ (i_name); Detach(i_name, true); CActor* pActor = smart_cast<CActor*>(object().H_Parent()); if (pActor && pActor->inventory().ActiveItem() == this) { pActor->inventory().SetPrevActiveSlot(pActor->inventory().GetActiveSlot()); pActor->inventory().Activate(NO_ACTIVE_SLOT); }; }break; case GE_CHANGE_POS: { Fvector p; P.r_vec3(p); CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem(0); if (!pSyncObj) return; SPHNetState state; pSyncObj->get_State(state); state.position = p; state.previous_position = p; pSyncObj->set_State(state); }break; } }
void CSE_SmartCover::STATE_Read (NET_Packet &tNetPacket, u16 size) { inherited1::STATE_Read (tNetPacket, size); cform_read (tNetPacket); tNetPacket.r_stringZ (m_description); m_hold_position_time = tNetPacket.r_float(); if (m_wVersion >= 120) { m_enter_min_enemy_distance = tNetPacket.r_float(); m_exit_min_enemy_distance = tNetPacket.r_float(); } if (m_wVersion >= 122) m_is_combat_cover = tNetPacket.r_u8(); if (m_wVersion >= 128) m_can_fire = tNetPacket.r_u8(); }
void CAI_Stalker::net_Import (NET_Packet& P) { R_ASSERT (Remote()); net_update N; u8 flags; P.r_float (); set_money ( P.r_u32(), false ); float health; P.r_float (health); SetfHealth (health); // fEntityHealth = health; P.r_u32 (N.dwTimeStamp); P.r_u8 (flags); P.r_vec3 (N.p_pos); P.r_float /*r_angle8*/ (N.o_model); P.r_float /*r_angle8*/ (N.o_torso.yaw); P.r_float /*r_angle8*/ (N.o_torso.pitch); P.r_float /*r_angle8*/ (N.o_torso.roll ); id_Team = P.r_u8(); id_Squad = P.r_u8(); id_Group = P.r_u8(); GameGraph::_GRAPH_ID graph_vertex_id = movement().game_dest_vertex_id(); P.r (&graph_vertex_id, sizeof(GameGraph::_GRAPH_ID)); graph_vertex_id = ai_location().game_vertex_id(); P.r (&graph_vertex_id, sizeof(GameGraph::_GRAPH_ID)); if (NET.empty() || (NET.back().dwTimeStamp<N.dwTimeStamp)) { NET.push_back (N); NET_WasInterpolating = TRUE; } P.r_float (); P.r_float (); P.r_stringZ (m_sStartDialog); setVisible (TRUE); setEnabled (TRUE); }
void CInventoryOwner::OnEvent (NET_Packet& P, u16 type) { switch (type) { case GE_INFO_TRANSFER: { u16 id; shared_str info_id; u8 add_info; P.r_u16 (id); //отправитель P.r_stringZ (info_id); //номер полученной информации P.r_u8 (add_info); //добавление или убирание информации if(add_info) OnReceiveInfo (info_id); else OnDisableInfo (info_id); } break; } }
void CLevel__cl_Process_CustomEvent(NET_Packet& pack) { if (!HookHandle->IsServer() || (HookHandle->IsServer() && !HookHandle->IsDedicated())) { unsigned char type = 0; pack.r_u8(type); if (type == e_so_engine_packet) { unsigned char e; pack.r_u8(e); switch (e) { default: LogHandle->Write("CLevel__cl_Process_CustomEvent unknown event %d",e); break; } } else if (type == e_so_script_packet) { char data[2048]; pack.r_stringZ(data); LogHandle->Write("Recieved data at client side '%s'",data); HookHandle->messanges_cl.push_back(data); } else { LogHandle->Write("ERROR: CLevel__cl_Process_CustomEvent unknown type"); } } }
void CLevel::cl_Process_Spawn(NET_Packet& P) { // Begin analysis shared_str s_name; P.r_stringZ (s_name); // Create DC (xrSE) CSE_Abstract* E = F_entity_Create (*s_name); R_ASSERT2(E, *s_name); E->Spawn_Read (P); if (E->s_flags.is(M_SPAWN_UPDATE)) E->UPDATE_Read (P); if (!E->match_configuration()) { F_entity_Destroy(E); return; } //------------------------------------------------- //. Msg ("M_SPAWN - %s[%d][%x] - %d %d", *s_name, E->ID, E,E->ID_Parent, Device.dwFrame); //------------------------------------------------- //force object to be local for server client if (OnServer()) { E->s_flags.set(M_SPAWN_OBJECT_LOCAL, TRUE); }; /* game_spawn_queue.push_back(E); if (g_bDebugEvents) ProcessGameSpawns(); /*/ g_sv_Spawn (E); F_entity_Destroy (E); //*/ };
void CGameGraphBuilder::load_graph_point (NET_Packet &net_packet) { string256 section_id; u16 id; net_packet.r_begin (id); R_ASSERT (M_SPAWN == id); net_packet.r_stringZ (section_id); // if (xr_strcmp("graph_point",section_id)) // return; CSE_Abstract *entity = F_entity_Create(section_id); if (!entity) { Msg ("Cannot create entity from section %s, skipping",section_id); return; } CSE_ALifeGraphPoint *graph_point = smart_cast<CSE_ALifeGraphPoint*>(entity); if (!graph_point) { F_entity_Destroy (entity); return; } entity->Spawn_Read (net_packet); vertex_type vertex; vertex.tLocalPoint = graph_point->o_Position; // check for duplicate graph point positions { graph_type::const_vertex_iterator I = graph().vertices().begin(); graph_type::const_vertex_iterator E = graph().vertices().end(); for ( ; I != E; ++I) { if ((*I).second->data().tLocalPoint.distance_to_sqr(vertex.tLocalPoint) < EPS_L) { Msg ("! removing graph point [%s][%f][%f][%f] because it is too close to the another graph point",entity->name_replace(),VPUSH(entity->o_Position)); return; } } } vertex.tGlobalPoint = graph_point->o_Position; vertex.tNodeID = level_graph().valid_vertex_position(vertex.tLocalPoint) ? level_graph().vertex_id(vertex.tLocalPoint) : u32(-1); if (!level_graph().valid_vertex_id(vertex.tNodeID)) { Msg ("! removing graph point [%s][%f][%f][%f] because it is outside of the AI map",entity->name_replace(),VPUSH(entity->o_Position)); return; } { graph_type::const_vertex_iterator I = graph().vertices().begin(); graph_type::const_vertex_iterator E = graph().vertices().end(); for ( ; I != E; ++I) { if ((*I).second->data().tNodeID == vertex.tNodeID) { Msg ("! removing graph point [%s][%f][%f][%f] because it has the same AI node as another graph point",entity->name_replace(),VPUSH(entity->o_Position)); return; } } } vertex.tNeighbourCount = 0; Memory.mem_copy (vertex.tVertexTypes,graph_point->m_tLocations,GameGraph::LOCATION_TYPE_COUNT*sizeof(GameGraph::_LOCATION_ID)); vertex.tLevelID = 0; vertex.tDeathPointCount = 0; vertex.dwPointOffset = 0; graph().add_vertex (vertex,graph().vertices().size()); F_entity_Destroy (entity); }
void game_sv_GameState::OnEvent (NET_Packet &tNetPacket, u16 type, u32 time, ClientID sender ) { switch (type) { case GAME_EVENT_PLAYER_CONNECTED: { ClientID ID; tNetPacket.r_clientID(ID); OnPlayerConnect(ID); }break; case GAME_EVENT_PLAYER_DISCONNECTED: { ClientID ID; tNetPacket.r_clientID(ID); string1024 PlayerName; tNetPacket.r_stringZ(PlayerName); u16 GameID = tNetPacket.r_u16(); OnPlayerDisconnect(ID, PlayerName, GameID); }break; case GAME_EVENT_PLAYER_KILLED: { }break ; case GAME_EVENT_ON_HIT: { u16 id_dest = tNetPacket.r_u16(); u16 id_src = tNetPacket.r_u16(); CSE_Abstract* e_src = get_entity_from_eid (id_src ); if(!e_src) // && !IsGameTypeSingle() added by andy because of Phantom does not have server entity { if( IsGameTypeSingle() ) break; game_PlayerState* ps = get_eid(id_src); if (!ps) break; id_src = ps->GameID; } OnHit(id_src, id_dest, tNetPacket); m_server->SendBroadcast (BroadcastCID,tNetPacket,net_flags(TRUE,TRUE)); }break; case GAME_EVENT_CREATE_CLIENT: { IClient* CL = (IClient*)m_server->ID_to_client(sender); VERIFY2(CL, "bad create client message GAME_EVENT_CREATE_CLIENT"); if ( CL == NULL ) { break; } CL->flags.bConnected = TRUE; m_server->AttachNewClient (CL); }break; case GAME_EVENT_PLAYER_AUTH: { IClient* CL = m_server->ID_to_client (sender); m_server->OnBuildVersionRespond(CL, tNetPacket); }break; case GAME_EVENT_CREATE_PLAYER_STATE: { xrClientData* CL = m_server->ID_to_client(sender); R_ASSERT2(CL, make_string("M_CREATE_PLAYER_STATE: client 0x%08x not found", sender.value() ).c_str() ); CL->ps = createPlayerState(&tNetPacket); CL->ps->m_online_time = Level().timeServer(); CL->ps->DeathTime = Device.dwTimeGlobal; if (psNET_direct_connect) //IsGameTypeSingle()) break; if (Level().IsDemoPlay()) break; if (g_dedicated_server && (CL == m_server->GetServerClient())) break; CheckNewPlayer(CL); }break; default: { string16 tmp; R_ASSERT3 (0,"Game Event not implemented!!!", itoa(type, tmp, 10)); }; }; }
void CSE_Visual::visual_read (NET_Packet &tNetPacket, u16 version) { tNetPacket.r_stringZ (visual_name); if (version>103) flags.assign (tNetPacket.r_u8()); }
void CSE_Motion::motion_read (NET_Packet &tNetPacket) { tNetPacket.r_stringZ (motion_name); }
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; } }
BOOL CSE_Abstract::Spawn_Read (NET_Packet &tNetPacket) { u16 dummy16; // generic tNetPacket.r_begin (dummy16); R_ASSERT (M_SPAWN==dummy16); tNetPacket.r_stringZ (s_name ); string256 temp; tNetPacket.r_stringZ (temp); set_name_replace (temp); tNetPacket.r_u8 (s_gameid ); tNetPacket.r_u8 (s_RP ); tNetPacket.r_vec3 (o_Position ); tNetPacket.r_vec3 (o_Angle ); tNetPacket.r_u16 (RespawnTime ); tNetPacket.r_u16 (ID ); tNetPacket.r_u16 (ID_Parent ); tNetPacket.r_u16 (ID_Phantom ); tNetPacket.r_u16 (s_flags.flags ); // dangerous!!!!!!!!! if (s_flags.is(M_SPAWN_VERSION)) tNetPacket.r_u16 (m_wVersion); if (0==m_wVersion) { tNetPacket.r_pos -= sizeof(u16); m_wVersion = 0; return FALSE; } if (m_wVersion > 69) m_script_version = tNetPacket.r_u16(); // read specific data //client object custom data serialization LOAD if (m_wVersion > 70) { u16 client_data_size = (m_wVersion > 93) ? tNetPacket.r_u16() : tNetPacket.r_u8(); //не может быть больше 256 байт if (client_data_size > 0) { // Msg ("SERVER:loading:load:%d bytes:%d:%s",client_data_size,ID,s_name_replace ? s_name_replace : ""); client_data.resize (client_data_size); tNetPacket.r (&*client_data.begin(),client_data_size); } else client_data.clear (); } else client_data.clear (); if (m_wVersion > 79) tNetPacket.r (&m_tSpawnID, sizeof(m_tSpawnID)); if (m_wVersion < 112) { if (m_wVersion > 82) tNetPacket.r_float ();//m_spawn_probability); if (m_wVersion > 83) { tNetPacket.r_u32 ();//m_spawn_flags.assign(tNetPacket.r_u32()); xr_string temp; tNetPacket.r_stringZ (temp);//tNetPacket.r_stringZ(m_spawn_control); tNetPacket.r_u32 ();//m_max_spawn_count); // this stuff we do not need even in case of uncomment tNetPacket.r_u32 ();//m_spawn_count); tNetPacket.r_u64 ();//m_last_spawn_time); } if (m_wVersion > 84) { tNetPacket.r_u64 ();//m_min_spawn_interval); tNetPacket.r_u64 ();//m_max_spawn_interval); } } u16 size; tNetPacket.r_u16 (size); // size R_ASSERT3 ((m_tClassID == CLSID_SPECTATOR) || (size > sizeof(size)),"cannot read object, which is not successfully saved :(",name_replace()); STATE_Read (tNetPacket,size); return TRUE; }
CLevelGameGraph ( LPCSTR graph_file_name, LPCSTR raw_cross_table_file_name, CGameGraph::SLevel *tLevel, LPCSTR S, u32 dwOffset, u32 dwLevelID, CInifile *Ini ) { m_tLevel = *tLevel; m_dwOffset = dwOffset; m_tpLevelPoints.clear (); FILE_NAME caFileName; // loading graph strcpy_s (caFileName,graph_file_name); m_tpGraph = new CGameGraph(caFileName); strcpy_s (caFileName,raw_cross_table_file_name); CGameLevelCrossTable *l_tpCrossTable = new CGameLevelCrossTable(caFileName); CLevelGraph *l_tpAI_Map = new CLevelGraph(S); VERIFY2 (l_tpCrossTable->header().level_guid() == l_tpAI_Map->header().guid(), "cross table doesn't correspond to the AI-map, rebuild graph!"); VERIFY2 (l_tpCrossTable->header().game_guid() == m_tpGraph->header().guid(), "cross table doesn't correspond to the graph, rebuild graph!"); VERIFY2 (m_tpGraph->header().level(GameGraph::_LEVEL_ID(0)).guid() == l_tpAI_Map->header().guid(), "cross table doesn't correspond to the AI-map, rebuild graph!"); VERIFY (l_tpAI_Map->header().vertex_count() == l_tpCrossTable->header().level_vertex_count()); VERIFY (m_tpGraph->header().vertex_count() == l_tpCrossTable->header().game_vertex_count()); tLevel->m_guid = l_tpAI_Map->header().guid(); { for (GameGraph::_GRAPH_ID i=0, n = m_tpGraph->header().vertex_count(); i<n; ++i) if ((!l_tpAI_Map->valid_vertex_id(m_tpGraph->vertex(i)->level_vertex_id()) || (l_tpCrossTable->vertex(m_tpGraph->vertex(i)->level_vertex_id()).game_vertex_id() != i) || !l_tpAI_Map->inside(m_tpGraph->vertex(i)->level_vertex_id(),m_tpGraph->vertex(i)->level_point()))) { Msg ("! Graph doesn't correspond to the cross table"); R_ASSERT2 (false,"Graph doesn't correspond to the cross table"); } } m_tpVertices.resize (m_tpGraph->header().vertex_count()); GRAPH_VERTEX_IT B = m_tpVertices.begin(); GRAPH_VERTEX_IT I = B; GRAPH_VERTEX_IT E = m_tpVertices.end(); for ( ; I != E; I++) { (*I).tLocalPoint = m_tpGraph->vertex(int(I - B))->level_point(); (*I).tGlobalPoint.add (m_tpGraph->vertex(int(I - B))->game_point(),m_tLevel.offset()); (*I).tLevelID = dwLevelID; (*I).tNodeID = m_tpGraph->vertex(int(I - B))->level_vertex_id(); Memory.mem_copy ((*I).tVertexTypes,m_tpGraph->vertex(int(I - B))->vertex_type(),GameGraph::LOCATION_TYPE_COUNT*sizeof(GameGraph::_LOCATION_ID)); (*I).tNeighbourCount = m_tpGraph->vertex(int(I - B))->edge_count(); CGameGraph::const_iterator b,i,e; m_tpGraph->begin (int(I - B),i,e); (*I).tpaEdges = (CGameGraph::CEdge*)xr_malloc((*I).tNeighbourCount*sizeof(CGameGraph::CEdge)); b = i; for ( ; i != e; ++i) { GameGraph::CEdge &edge = (*I).tpaEdges[i - b]; edge = *i; VERIFY ((edge.vertex_id() + dwOffset) < (u32(1) << (8*sizeof(GameGraph::_GRAPH_ID)))); edge.m_vertex_id = (GameGraph::_GRAPH_ID)(edge.m_vertex_id + dwOffset); } (*I).dwPointOffset = 0; vfGenerateDeathPoints (int(I - B),l_tpCrossTable,l_tpAI_Map,(*I).tDeathPointCount); } xr_delete (l_tpCrossTable); xr_delete (l_tpAI_Map); // updating cross-table { strcpy_s (caFileName,raw_cross_table_file_name); CGameLevelCrossTable *tpCrossTable = new CGameLevelCrossTable(caFileName); xr_vector<CGameLevelCrossTable::CCell> tCrossTableUpdate; tCrossTableUpdate.resize(tpCrossTable->header().level_vertex_count()); for (int i=0; i<(int)tpCrossTable->header().level_vertex_count(); i++) { tCrossTableUpdate[i] = tpCrossTable->vertex(i); VERIFY (u32(tCrossTableUpdate[i].tGraphIndex) < tpCrossTable->header().game_vertex_count()); tCrossTableUpdate[i].tGraphIndex = tCrossTableUpdate[i].tGraphIndex + (GameGraph::_GRAPH_ID)dwOffset; } CGameLevelCrossTable::CHeader tCrossTableHeader; tCrossTableHeader.dwVersion = XRAI_CURRENT_VERSION; tCrossTableHeader.dwNodeCount = tpCrossTable->m_tCrossTableHeader.dwNodeCount; tCrossTableHeader.dwGraphPointCount = tpCrossTable->m_tCrossTableHeader.dwGraphPointCount; tCrossTableHeader.m_level_guid = tpCrossTable->m_tCrossTableHeader.m_level_guid; tCrossTableHeader.m_game_guid = tGraphHeader.m_guid; xr_delete (tpCrossTable); m_cross_table.w(&tCrossTableHeader,sizeof(tCrossTableHeader)); for (int i=0; i<(int)tCrossTableHeader.dwNodeCount; i++) m_cross_table.w(&(tCrossTableUpdate[i]),sizeof(tCrossTableUpdate[i])); } // fill vertex map { string_path fName; strconcat (sizeof(fName),fName,S,"level.spawn"); IReader *F = FS.r_open(fName); u32 id; IReader *O = F->open_chunk_iterator(id); for (int i=0; O; O = F->open_chunk_iterator(id,O)) { NET_Packet P; P.B.count = O->length(); O->r (P.B.data,P.B.count); u16 ID; P.r_begin (ID); R_ASSERT (M_SPAWN==ID); P.r_stringZ (fName); CSE_Abstract *E = F_entity_Create(fName); R_ASSERT3 (E,"Can't create entity.",fName); // E->Spawn_Read (P); CSE_ALifeGraphPoint *tpGraphPoint = smart_cast<CSE_ALifeGraphPoint*>(E); if (tpGraphPoint) { E->Spawn_Read (P); Fvector tVector; tVector = tpGraphPoint->o_Position; GameGraph::_GRAPH_ID tGraphID = GameGraph::_GRAPH_ID(-1); float fMinDistance = 1000000.f; { GRAPH_VERTEX_IT B = m_tpVertices.begin(); GRAPH_VERTEX_IT I = B; GRAPH_VERTEX_IT E = m_tpVertices.end(); for ( ; I != E; I++) { float fDistance = (*I).tLocalPoint.distance_to(tVector); if (fDistance < fMinDistance) { fMinDistance = fDistance; tGraphID = GameGraph::_GRAPH_ID(I - B); if (fMinDistance < EPS_L) break; } } } if (fMinDistance < EPS_L) { SConnectionVertex T; LPSTR S; S = xr_strdup(tpGraphPoint->name_replace()); T.caConnectName = xr_strdup(*tpGraphPoint->m_caConnectionPointName); T.dwLevelID = dwfGetIDByLevelName(Ini,*tpGraphPoint->m_caConnectionLevelName); // T.tGraphID = (GameGraph::_GRAPH_ID)i; // T.tOldGraphID = tGraphID; T.tOldGraphID = (GameGraph::_GRAPH_ID)i; T.tGraphID = tGraphID; bool ok = true; VERTEX_MAP::const_iterator II = m_tVertexMap.begin(); VERTEX_MAP::const_iterator EE = m_tVertexMap.end(); for ( ; II != EE; ++II) if (T.tOldGraphID == (*II).second.tOldGraphID) { ok = false; Msg ("Graph point %s is removed,because it has the same position as some another graph point",E->name_replace()); break; } if (ok) { m_tVertexMap.insert (mk_pair(S,T)); i++; } } } F_entity_Destroy (E); } if (i != m_tpGraph->header().vertex_count()) Msg ("Graph for the level %s doesn't correspond to the graph points from Level Editor! (%d : %d)",*m_tLevel.name(),i,m_tpGraph->header().vertex_count()); VERTEX_MAP::const_iterator I = m_tVertexMap.begin(); VERTEX_MAP::const_iterator E = m_tVertexMap.end(); for ( ; I != E; ++I) { R_ASSERT3 (!xr_strlen((*I).second.caConnectName) || ((*I).second.tGraphID < m_tpVertices.size()),"Rebuild graph for the level",*m_tLevel.name()); } // VERIFY3 (i == m_tpGraph->header().vertex_count(), "Rebuild graph for the level ",m_tLevel.name()); O->close (); FS.r_close (F); } };
void CLevel::ClientReceive() { Demo_StartFrame(); Demo_Update(); m_dwRPC = 0; m_dwRPS = 0; for (NET_Packet* P = net_msg_Retreive(); P; P=net_msg_Retreive()) { //----------------------------------------------------- m_dwRPC++; m_dwRPS += P->B.count; //----------------------------------------------------- u16 m_type; u16 ID; P->r_begin (m_type); switch (m_type) { case M_MAP_SYNC: { shared_str map_name; P->r_stringZ(map_name); shared_str _name = net_Hosts.size() ? net_Hosts.front().dpSessionName:""; if(_name.size() && _name!=map_name && OnClient()) { Msg("!!! map sync failed. current is[%s] server is[%s]",m_name.c_str(), map_name.c_str()); Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",m_caServerOptions.size() ? size_t( xr_strdup(*m_caServerOptions)) : 0, m_caClientOptions.size() ? size_t(xr_strdup(*m_caClientOptions)) : 0); } }break; case M_SPAWN: { if (!m_bGameConfigStarted || !bReady) { Msg ("Unconventional M_SPAWN received : cgf[%s] | bReady[%s]", (m_bGameConfigStarted) ? "true" : "false", (bReady) ? "true" : "false"); break; } /*/ cl_Process_Spawn(*P); /*/ game_events->insert (*P); if (g_bDebugEvents) ProcessGameEvents(); //*/ } break; case M_EVENT: game_events->insert (*P); if (g_bDebugEvents) ProcessGameEvents(); break; case M_EVENT_PACK: NET_Packet tmpP; while (!P->r_eof()) { tmpP.B.count = P->r_u8(); P->r(&tmpP.B.data, tmpP.B.count); tmpP.timeReceive = P->timeReceive; game_events->insert (tmpP); if (g_bDebugEvents) ProcessGameEvents(); }; break; case M_UPDATE: { game->net_import_update (*P); //------------------------------------------- if (OnServer()) break; //------------------------------------------- }; // ни в коем случае нельзя здесь ставить break, т.к. в случае если все объекты не влазят в пакет M_UPDATE, // они досылаются через M_UPDATE_OBJECTS case M_UPDATE_OBJECTS: { Objects.net_Import (P); if (OnClient()) UpdateDeltaUpd(timeServer()); IClientStatistic pStat = Level().GetStatistic(); u32 dTime = 0; if ((Level().timeServer() + pStat.getPing()) < P->timeReceive) { dTime = pStat.getPing(); } else dTime = Level().timeServer() - P->timeReceive + pStat.getPing(); u32 NumSteps = ph_world->CalcNumSteps(dTime); SetNumCrSteps(NumSteps); }break; // case M_UPDATE_OBJECTS: // { // Objects.net_Import (P); // }break; //----------- for E3 ----------------------------- case M_CL_UPDATE: { if (OnClient()) break; P->r_u16 (ID); u32 Ping = P->r_u32(); CGameObject* O = smart_cast<CGameObject*>(Objects.net_Find (ID)); if (0 == O) break; O->net_Import(*P); //--------------------------------------------------- UpdateDeltaUpd(timeServer()); if (pObjects4CrPr.empty() && pActors4CrPr.empty()) break; if (O->CLS_ID != CLSID_OBJECT_ACTOR) break; u32 dTime = 0; if ((Level().timeServer() + Ping) < P->timeReceive) { #ifdef DEBUG // Msg("! TimeServer[%d] < TimeReceive[%d]", Level().timeServer(), P->timeReceive); #endif dTime = Ping; } else dTime = Level().timeServer() - P->timeReceive + Ping; u32 NumSteps = ph_world->CalcNumSteps(dTime); SetNumCrSteps(NumSteps); O->CrPr_SetActivationStep(u32(ph_world->m_steps_num) - NumSteps); AddActor_To_Actors4CrPr(O); }break; case M_MOVE_PLAYERS: { u8 Count = P->r_u8(); for (u8 i=0; i<Count; i++) { u16 ID = P->r_u16(); Fvector NewPos, NewDir; P->r_vec3(NewPos); P->r_vec3(NewDir); CActor* OActor = smart_cast<CActor*>(Objects.net_Find (ID)); if (0 == OActor) break; OActor->MoveActor(NewPos, NewDir); }; NET_Packet PRespond; PRespond.w_begin(M_MOVE_PLAYERS_RESPOND); Send(PRespond, net_flags(TRUE, TRUE)); }break; //------------------------------------------------ case M_CL_INPUT: { P->r_u16 (ID); CObject* O = Objects.net_Find (ID); if (0 == O) break; O->net_ImportInput(*P); }break; //--------------------------------------------------- case M_SV_CONFIG_NEW_CLIENT: InitializeClientGame(*P); break; case M_SV_CONFIG_GAME: game->net_import_state (*P); break; case M_SV_CONFIG_FINISHED: game_configured = TRUE; Msg("- Game configuring : Finished "); break; case M_MIGRATE_DEACTIVATE: // TO: Changing server, just deactivate { P->r_u16 (ID); CObject* O = Objects.net_Find (ID); if (0 == O) break; O->net_MigrateInactive (*P); if (bDebug) Log("! MIGRATE_DEACTIVATE",*O->cName()); } break; case M_MIGRATE_ACTIVATE: // TO: Changing server, full state { P->r_u16 (ID); CObject* O = Objects.net_Find (ID); if (0 == O) break; O->net_MigrateActive (*P); if (bDebug) Log("! MIGRATE_ACTIVATE",*O->cName()); } break; case M_CHAT: { char buffer[256]; P->r_stringZ(buffer); Msg ("- %s",buffer); } break; case M_GAMEMESSAGE: { if (!game) break; Game().OnGameMessage(*P); }break; case M_RELOAD_GAME: case M_LOAD_GAME: case M_CHANGE_LEVEL: { if(m_type==M_LOAD_GAME) { string256 saved_name; P->r_stringZ (saved_name); if(xr_strlen(saved_name) && ai().get_alife()) { CSavedGameWrapper wrapper(saved_name); if (wrapper.level_id() == ai().level_graph().level_id()) { Engine.Event.Defer ("Game:QuickLoad", size_t(xr_strdup(saved_name)), 0); break; } } } Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",size_t(xr_strdup(*m_caServerOptions)),size_t(xr_strdup(*m_caClientOptions))); }break; case M_SAVE_GAME: { ClientSave (); }break; case M_GAMESPY_CDKEY_VALIDATION_CHALLENGE: { OnGameSpyChallenge(P); }break; case M_AUTH_CHALLENGE: { OnBuildVersionChallenge(); }break; case M_CLIENT_CONNECT_RESULT: { OnConnectResult(P); }break; case M_CHAT_MESSAGE: { if (!game) break; Game().OnChatMessage(P); }break; case M_CLIENT_WARN: { if (!game) break; Game().OnWarnMessage(P); }break; case M_REMOTE_CONTROL_AUTH: case M_REMOTE_CONTROL_CMD: { Game().OnRadminMessage(m_type, P); }break; case M_CHANGE_LEVEL_GAME: { Msg("- M_CHANGE_LEVEL_GAME Received"); if (OnClient()) { Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",m_caServerOptions.size() ? size_t( xr_strdup(*m_caServerOptions)) : 0,m_caClientOptions.size() ? size_t(xr_strdup(*m_caClientOptions)) : 0); } else { const char* m_SO = m_caServerOptions.c_str(); // const char* m_CO = m_caClientOptions.c_str(); m_SO = strchr(m_SO, '/'); if (m_SO) m_SO++; m_SO = strchr(m_SO, '/'); string128 LevelName = ""; string128 GameType = ""; P->r_stringZ(LevelName); P->r_stringZ(GameType); string4096 NewServerOptions = ""; sprintf_s(NewServerOptions, "%s/%s", LevelName, GameType); if (m_SO) strcat(NewServerOptions, m_SO); m_caServerOptions = NewServerOptions; Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",size_t(xr_strdup(*m_caServerOptions)),size_t(xr_strdup(*m_caClientOptions))); }; }break; case M_CHANGE_SELF_NAME: { net_OnChangeSelfName(P); }break; case M_BULLET_CHECK_RESPOND: { if (!game) break; if (GameID() != GAME_SINGLE) Game().m_WeaponUsageStatistic->On_Check_Respond(P); }break; case M_STATISTIC_UPDATE: { if (!game) break; if (GameID() != GAME_SINGLE) Game().m_WeaponUsageStatistic->OnUpdateRequest(P); }break; case M_STATISTIC_UPDATE_RESPOND: { if (!game) break; if (GameID() != GAME_SINGLE) Game().m_WeaponUsageStatistic->OnUpdateRespond(P); }break; case M_BATTLEYE: { #ifdef BATTLEYE battleye_system.ReadPacketClient( P ); #endif // BATTLEYE }break; } net_msg_Release(); } // if (!g_bDebugEvents) ProcessGameSpawns(); }
void game_cl_Deathmatch::OnVoteStart(NET_Packet& P) { CStringTable st; inherited::OnVoteStart(P); string1024 Command = ""; string64 Player = ""; P.r_stringZ(Command); P.r_stringZ(Player); m_dwVoteEndTime = Level().timeServer() + P.r_u32(); if(m_game_ui) { string4096 CmdName = ""; string1024 NewCmd; xr_strcpy(NewCmd, Command); string1024 CmdParams[MAX_VOTE_PARAMS] = {"", "", "", "", ""}; sscanf (Command,"%s %s %s %s %s %s", CmdName, CmdParams[0], CmdParams[1], CmdParams[2], CmdParams[3], CmdParams[4]); if (!xr_strcmp(CmdName, "restart")) { xr_sprintf(NewCmd, "%s", *st.translate("mp_restart") ); } else if (!xr_strcmp(CmdName, "restart_fast")) { xr_sprintf(NewCmd, "%s", *st.translate("mp_restart_fast") ); } else if (!xr_strcmp(CmdName, "kick")) { xr_sprintf(NewCmd, "%s %s", *st.translate("mp_kick"), CmdParams[0] ); for (int i=1; i<MAX_VOTE_PARAMS; i++) { if (xr_strlen(CmdParams[i])) { xr_strcat(NewCmd, " "); xr_strcat(NewCmd, CmdParams[i]); } } } else if (!xr_strcmp(CmdName, "ban")) { xr_sprintf(NewCmd, "%s %s", *st.translate("mp_ban"), CmdParams[0] ); for (int i=1; i<MAX_VOTE_PARAMS; i++) { if (xr_strlen(CmdParams[i])) { xr_strcat(NewCmd, " "); xr_strcat(NewCmd, CmdParams[i]); } } } else if (!xr_strcmp(CmdName, "changemap")) { xr_sprintf(NewCmd, "%s %s", *st.translate("mp_change_map"), *st.translate(CmdParams[0]) ); } else if (!xr_strcmp(CmdName, "changeweather")) { xr_sprintf(NewCmd, "%s %s", *st.translate("mp_change_weather"), *st.translate(CmdParams[0]) ); } string1024 VoteStr; xr_sprintf(VoteStr, *st.translate("mp_voting_started"), NewCmd, Player); m_game_ui->SetVoteMessage(VoteStr); m_game_ui->SetVoteTimeResultMsg(""); if (!m_pVoteRespondWindow) m_pVoteRespondWindow = xr_new<CUIVote>(); m_pVoteRespondWindow->SetVoting(VoteStr); }; };