void CGameObject::net_Save (NET_Packet &net_packet) { u32 position; net_packet.w_chunk_open16 (position); save (net_packet); // Script Binder Save --------------------------------------- #ifdef DEBUG if (psAI_Flags.test(aiSerialize)) { Msg(">> **** Save script object [%s] *****", *cName()); Msg(">> Before save :: packet position = [%u]", net_packet.w_tell()); } #endif CScriptBinder::save (net_packet); #ifdef DEBUG if (psAI_Flags.test(aiSerialize)) { Msg(">> After save :: packet position = [%u]", net_packet.w_tell()); } #endif // ---------------------------------------------------------- net_packet.w_chunk_close16 (position); }
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)); }
bool operator()(HitData & hit) { if (hit.Completed) { if (NET_PacketSizeLimit - packet_to_write->w_tell() < HitData::net_packet_size) return false; hit.net_save(packet_to_write, vtable, btable); ++complete_hits_count; return true; } return false; }
void xrServer::Update () { NET_Packet Packet; u32 position; csPlayers.Enter (); VERIFY (verify_entities()); // game update game->ProcessDelayedEvent(); game->Update (); // spawn queue u32 svT = Device.TimerAsync(); while (!(q_respawn.empty() || (svT<q_respawn.begin()->timestamp))) { // get svs_respawn R = *q_respawn.begin(); q_respawn.erase (q_respawn.begin()); // CSE_Abstract* E = ID_to_entity(R.phantom); E->Spawn_Write (Packet,FALSE); u16 ID; Packet.r_begin (ID); R_ASSERT(M_SPAWN==ID); ClientID clientID; clientID.set(0xffff); Process_spawn (Packet,clientID); } // for (u32 client=0; client<net_Players.size(); ++client) { // Initialize process and check for available bandwidth xrClientData* Client = (xrClientData*) net_Players [client]; if (!Client->net_Ready) continue; if (!HasBandwidth(Client) #ifdef DEBUG && !g_sv_SendUpdate #endif ) continue; // Send relevant entities to client // CSE_Abstract* Base = Client->owner; u16 PacketType = M_UPDATE; Packet.w_begin (PacketType); // GameUpdate ++(Client->game_replicate_id); u32 g_it = (Client->game_replicate_id % client_Count()); // u32 g_id = net_Players[g_it]->ID; ClientID g_id = net_Players[g_it]->ID; game->net_Export_Update (Packet,Client->ID,g_id); // if (!Client->flags.bLocal) game->net_Export_GameTime(Packet); if (!Client->flags.bLocal || client_Count() == 1) { #ifdef DEBUG if (g_Dump_Update_Write) Msg("---- UPDATE_Write to %s --- ", *(Client->Name)); #endif // Entities NET_Packet tmpPacket; xrS_entities::iterator I=entities.begin(),E=entities.end(); for (; I!=E; ++I) { CSE_Abstract& Test = *(I->second); if (0==Test.owner) continue; // Phantom(?) if (!Test.net_Ready) continue; if (Test.owner == Client && Client->flags.bLocal) continue; // Can't be relevant if (Test.s_flags.is(M_SPAWN_OBJECT_PHANTOM)) continue; // Surely: phantom tmpPacket.B.count = 0; // write specific data { tmpPacket.w_u16 (Test.ID ); tmpPacket.w_chunk_open8 (position ); Test.UPDATE_Write (tmpPacket ); #ifdef DEBUG if (g_Dump_Update_Write) Msg("* %s : %d", Test.name(), u32(tmpPacket.w_tell()-position)-sizeof(u8)); #endif tmpPacket.w_chunk_close8 (position ); if (Packet.B.count + tmpPacket.B.count < NET_PacketSizeLimit) { Packet.w(tmpPacket.B.data, tmpPacket.B.count); } else { if (Packet.B.count > 2) { // if (!Client->flags.bLocal) // Msg ("- Server Update[%d] to Client : %d", PacketType, Packet.B.count); SendTo (Client->ID,Packet,net_flags(FALSE,TRUE)); } PacketType = M_UPDATE_OBJECTS; Packet.w_begin(PacketType); } } } #ifdef DEBUG if (g_Dump_Update_Write) Msg("----------------------- "); #endif }; if (Packet.B.count > 2) { // if (!Client->flags.bLocal) // Msg ("- Server Update[%d] to Client : %d", PacketType, Packet.B.count); SendTo (Client->ID,Packet,net_flags(FALSE,TRUE)); } } #ifdef DEBUG g_sv_SendUpdate = 0; #endif if (game->sv_force_sync) Perform_game_export(); VERIFY (verify_entities()); //----------------------------------------------------- //Remove any of long time disconnected players for (u32 DI = 0; DI<net_Players_disconnected.size(); DI++) { IClient* CL = net_Players_disconnected[DI]; if (CL->dwTime_LastUpdate+g_sv_Client_Reconnect_Time*60000<Device.dwTimeGlobal) client_Destroy(CL); } //----------------------------------------------------- csPlayers.Leave (); }