Exemple #1
0
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;
	};

}
Exemple #2
0
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");
		}
	}
}
Exemple #3
0
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;
	}
}
Exemple #4
0
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);
	
	}
}
Exemple #10
0
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;
}
Exemple #11
0
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();
}
Exemple #13
0
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;
	}
}
Exemple #15
0
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);
}
Exemple #18
0
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;
}
Exemple #23
0
								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);
	};
};