void CSE_Abstract::Spawn_Write (NET_Packet &tNetPacket, BOOL bLocal) { // generic tNetPacket.w_begin (M_SPAWN); tNetPacket.w_stringZ (s_name ); tNetPacket.w_stringZ (s_name_replace ? s_name_replace : ""); tNetPacket.w_u8 (0); tNetPacket.w_u8 (s_RP ); tNetPacket.w_vec3 (o_Position ); tNetPacket.w_vec3 (o_Angle ); tNetPacket.w_u16 (RespawnTime ); tNetPacket.w_u16 (ID ); tNetPacket.w_u16 (ID_Parent ); tNetPacket.w_u16 (ID_Phantom ); s_flags.set (M_SPAWN_VERSION,TRUE); if (bLocal) tNetPacket.w_u16 (u16(s_flags.flags|M_SPAWN_OBJECT_LOCAL) ); else tNetPacket.w_u16 (u16(s_flags.flags&~(M_SPAWN_OBJECT_LOCAL|M_SPAWN_OBJECT_ASPLAYER))); tNetPacket.w_u16 (SPAWN_VERSION); tNetPacket.w_u16 (m_gameType.m_GameType.get()); tNetPacket.w_u16 (script_server_object_version()); //client object custom data serialization SAVE u16 client_data_size = (u16)client_data.size(); //не может быть больше 256 байт tNetPacket.w_u16 (client_data_size); // Msg ("SERVER:saving:save:%d bytes:%d:%s",client_data_size,ID,s_name_replace ? s_name_replace : ""); if (client_data_size > 0) { tNetPacket.w (&*client_data.begin(),client_data_size); } tNetPacket.w_u16 (m_tSpawnID); // tNetPacket.w_float (m_spawn_probability); // tNetPacket.w_u32 (m_spawn_flags.get()); // tNetPacket.w_stringZ (m_spawn_control); // tNetPacket.w_u32 (m_max_spawn_count); // tNetPacket.w_u64 (m_min_spawn_interval); // tNetPacket.w_u64 (m_max_spawn_interval); #ifdef XRSE_FACTORY_EXPORTS CScriptValueContainer::assign(); #endif // write specific data u32 position = tNetPacket.w_tell(); tNetPacket.w_u16 (0); STATE_Write (tNetPacket); u16 size = u16(tNetPacket.w_tell() - position); //#ifdef XRSE_FACTORY_EXPORTS R_ASSERT3 ((m_tClassID == CLSID_SPECTATOR) || (size > sizeof(size)), "object isn't successfully saved, get your backup :(",name_replace()); //#endif tNetPacket.w_seek (position,&size,sizeof(u16)); }
u32 xrServer::OnMessage (NET_Packet& P, ClientID sender) // Non-Zero means broadcasting with "flags" as returned { if (g_pGameLevel && Level().IsDemoSave()) Level().Demo_StoreServerData(P.B.data, P.B.count); u16 type; P.r_begin (type); csPlayers.Enter (); VERIFY (verify_entities()); xrClientData* CL = ID_to_client(sender); switch (type) { case M_UPDATE: { Process_update (P,sender); // No broadcast VERIFY (verify_entities()); }break; case M_SPAWN: { // R_ASSERT(CL->flags.bLocal); if (CL->flags.bLocal) Process_spawn (P,sender); VERIFY (verify_entities()); }break; case M_EVENT: { Process_event (P,sender); VERIFY (verify_entities()); }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); OnMessage (tmpP, sender); }; }break; case M_CL_UPDATE: { xrClientData* CL = ID_to_client (sender); if (!CL) break; CL->net_Ready = TRUE; if (!CL->net_PassUpdates) break; //------------------------------------------------------------------- u32 ClientPing = CL->stats.getPing(); P.w_seek(P.r_tell()+2, &ClientPing, 4); //------------------------------------------------------------------- if (SV_Client) SendTo (SV_Client->ID, P, net_flags(TRUE, TRUE)); VERIFY (verify_entities()); }break; case M_MOVE_PLAYERS_RESPOND: { xrClientData* CL = ID_to_client (sender); if (!CL) break; CL->net_Ready = TRUE; CL->net_PassUpdates = TRUE; }break; //------------------------------------------------------------------- case M_CL_PING_CHALLENGE: { P.r_u32(); u32 id = sender.value(); P.w_seek( P.r_tell(), &(id), 4); if (SV_Client) SendTo (SV_Client->ID, P, net_flags(FALSE)); }break; case M_CL_PING_CHALLENGE_RESPOND: { P.r_u32(); u32 id = P.r_u32(); ClientID clientID; clientID.set(id); u32 clLastPing = P.r_u32(); xrClientData* pCL = ID_to_client(clientID); pCL->ps->Rping = u16(clLastPing); SendTo (clientID, P, net_flags(FALSE)); }break; //------------------------------------------------------------------- case M_CL_INPUT: { xrClientData* CL = ID_to_client (sender); if (CL) CL->net_Ready = TRUE; if (SV_Client) SendTo (SV_Client->ID, P, net_flags(TRUE, TRUE)); VERIFY (verify_entities()); }break; case M_GAMEMESSAGE: { ClientID clientID;clientID.setBroadcast(); SendBroadcast (clientID,P,net_flags(TRUE,TRUE)); VERIFY (verify_entities()); }break; case M_CLIENTREADY: { xrClientData* CL = ID_to_client(sender); if (CL) { CL->net_Ready = TRUE; CL->ps->DeathTime = Device.dwTimeGlobal; game->OnPlayerConnectFinished(sender); }; game->signal_Syncronize (); VERIFY (verify_entities()); }break; case M_SWITCH_DISTANCE: { game->switch_distance (P,sender); VERIFY (verify_entities()); }break; case M_CHANGE_LEVEL: { if (game->change_level(P,sender)){ ClientID clientID;clientID.setBroadcast(); SendBroadcast (clientID,P,net_flags(TRUE,TRUE)); } VERIFY (verify_entities()); }break; case M_SAVE_GAME: { game->save_game (P,sender); VERIFY (verify_entities()); }break; case M_LOAD_GAME: { game->load_game (P,sender); ClientID clientID;clientID.setBroadcast(); SendBroadcast (clientID,P,net_flags(TRUE,TRUE)); VERIFY (verify_entities()); }break; case M_RELOAD_GAME: { ClientID clientID;clientID.setBroadcast(); SendBroadcast (clientID,P,net_flags(TRUE,TRUE)); VERIFY (verify_entities()); }break; case M_SAVE_PACKET: { Process_save (P,sender); VERIFY (verify_entities()); }break; case M_CLIENT_REQUEST_CONNECTION_DATA: { xrClientData* CL = ID_to_client (sender); OnCL_Connected (CL); }break; case M_CHAT_MESSAGE: { xrClientData *l_pC = ID_to_client(sender); OnChatMessage (&P, l_pC); }break; case M_CHANGE_LEVEL_GAME: { ClientID CID; CID.set (0xffffffff); SendBroadcast (CID,P,net_flags(TRUE,TRUE)); }break; case M_CL_AUTH: { game->AddDelayedEvent (P,GAME_EVENT_PLAYER_AUTH, 0, sender); }break; case M_PAUSE_GAME: { ClientID clientID;clientID.setBroadcast(); SendBroadcast (clientID,P,net_flags(TRUE,TRUE)); }break; case M_STATISTIC_UPDATE: { ClientID clientID;clientID.setBroadcast(); if (SV_Client) SendBroadcast (SV_Client->ID,P,net_flags(TRUE,TRUE)); else SendBroadcast (clientID,P,net_flags(TRUE,TRUE)); }break; case M_STATISTIC_UPDATE_RESPOND: { if (SV_Client) SendTo (SV_Client->ID, P, net_flags(TRUE, TRUE)); }break; case M_PLAYER_FIRE: { if (game) game->OnPlayerFire(sender, P); }break; } VERIFY (verify_entities()); csPlayers.Leave (); return IPureServer::OnMessage(P, sender); }