예제 #1
0
void CAI_Trader::OnEvent		(NET_Packet& P, u16 type)
{
	inherited::OnEvent			(P,type);
	CInventoryOwner::OnEvent	(P,type);

	u16 id;
	CObject* Obj;

	switch (type) {
		case GE_TRADE_BUY:
		case GE_OWNERSHIP_TAKE:
			P.r_u16		(id);
			Obj = Level().Objects.net_Find	(id);
			if(inventory().CanTakeItem(smart_cast<CInventoryItem*>(Obj))){
				Obj->H_SetParent(this);
				inventory().Take(smart_cast<CGameObject*>(Obj), false, false);
			}else
			{
				NET_Packet				P;
				u_EventGen				(P,GE_OWNERSHIP_REJECT,ID());
				P.w_u16					(u16(Obj->ID()));
				u_EventSend				(P);
			}
			break;
		case GE_TRADE_SELL:
		case GE_OWNERSHIP_REJECT:
			P.r_u16		(id);
			Obj = Level().Objects.net_Find	(id);
			if(inventory().Drop(smart_cast<CGameObject*>(Obj))) 
				Obj->H_SetParent(0,!P.r_eof() && P.r_u8());
			break;
		case GE_TRANSFER_AMMO:
			break;
	}
}
예제 #2
0
void xrServer::Process_save(NET_Packet& P, ClientID sender)
{
    xrClientData* CL		= ID_to_client(sender);
    if (CL)	CL->net_Ready	= TRUE;

    R_ASSERT(CL->flags.bLocal);
    // while has information
    while (!P.r_eof())
    {
        // find entity
        u16				ID;
        u16				size;

        P.r_u16			(ID);
        P.r_u16			(size);
        s32				_pos_start	= P.r_tell	();
        CSE_Abstract	*E	= ID_to_entity(ID);

        if (E) {
            E->net_Ready = TRUE;
            E->load		(P);
        }
        else
            P.r_advance	(size);
        s32				_pos_end	= P.r_tell	();
        s32				_size		= size;
        if				(_size != (_pos_end-_pos_start))	{
            Msg			("! load/save mismatch, object: '%s'",E?E->name_replace():"unknown");
            s32			_rollback	= _pos_start+_size;
            P.r_seek	(_rollback);
        }
    }
}
예제 #3
0
void CInventoryBox::OnEvent(NET_Packet& P, u16 type)
{
	inherited::OnEvent	(P, type);

	switch (type)
	{
	case GE_OWNERSHIP_TAKE:
		{
			u16 id;
            P.r_u16(id);
			CObject* itm = Level().Objects.net_Find(id);  VERIFY(itm);
			m_items.push_back	(id);
			itm->H_SetParent	(this);
			itm->setVisible		(FALSE);
			itm->setEnabled		(FALSE);
		}break;
	case GE_OWNERSHIP_REJECT:
		{
			u16 id;
            P.r_u16(id);
			CObject* itm = Level().Objects.net_Find(id);  VERIFY(itm);
			xr_vector<u16>::iterator it;
			it = std::find(m_items.begin(),m_items.end(),id); VERIFY(it!=m_items.end());
			m_items.erase		(it);
			itm->H_SetParent	(NULL,!P.r_eof() && P.r_u8());

			if( m_in_use )
			{
				CGameObject* GO		= smart_cast<CGameObject*>(itm);
				Actor()->callback(GameObject::eInvBoxItemTake)( this->lua_game_object(), GO->lua_game_object() );
			}
		}break;
	};
}
예제 #4
0
void xrServer::Process_update(NET_Packet& P, ClientID sender)
{
    xrClientData* CL		= ID_to_client(sender);
    if (!CL)
    {
        return;
    }
//	if (CL)	CL->net_Ready	= TRUE;

#ifdef DEBUG
    if (g_Dump_Update_Read) Msg("---- UPDATE_Read --- ");
#endif						// Entities

    R_ASSERT(CL->flags.bLocal);
    // while has information
    while (!P.r_eof())
    {
        // find entity
        u16				ID;
        u8				size;

        P.r_u16			(ID);
        P.r_u8			(size);
        u32	_pos		= P.r_tell();
        CSE_Abstract	*E	= ID_to_entity(ID);

        if (E) {
            //Msg				("sv_import: %d '%s'",E->ID,E->name_replace());
            E->net_Ready	= TRUE;
            E->UPDATE_Read	(P);
#ifdef DEBUG
            if (g_Dump_Update_Read) Msg("* %s : %d - %d", E->name(), size, P.r_tell() - _pos);
#endif

            if ((P.r_tell()-_pos) != size)	{
                string16	tmp;
                CLSID2TEXT	(E->m_tClassID,tmp);
                Debug.fatal	(DEBUG_INFO,"Beer from the creator of '%s'",tmp);
            }
        }
        else
            P.r_advance	(size);
    }
#ifdef DEBUG
    if (g_Dump_Update_Read) Msg("-------------------- ");
#endif						// Entities

}
예제 #5
0
void CCar::OnEvent(NET_Packet& P, u16 type)
{
	inherited::OnEvent		(P,type);
	CExplosive::OnEvent		(P,type);

	//обработка сообщений, нужных для работы с багажником машины
	u16 id;
	switch (type)
	{
	case GE_OWNERSHIP_TAKE:
		{
			P.r_u16		(id);
			CObject* O	= Level().Objects.net_Find	(id);
			if( GetInventory()->CanTakeItem(smart_cast<CInventoryItem*>(O)) ) 
			{
				O->H_SetParent(this);
				GetInventory()->Take(smart_cast<CGameObject*>(O), false, false);
			}
			else 
			{
				if (!O || !O->H_Parent() || (this != O->H_Parent())) return;
				NET_Packet P;
				u_EventGen(P,GE_OWNERSHIP_REJECT,ID());
				P.w_u16(u16(O->ID()));
				u_EventSend(P);
			}
		}break;
	case GE_OWNERSHIP_REJECT:
		{
			P.r_u16		(id);
			CObject* O	= Level().Objects.net_Find	(id);

			bool just_before_destroy		= !P.r_eof() && P.r_u8();
			O->SetTmpPreDestroy				(just_before_destroy);
			GetInventory()->DropItem(smart_cast<CGameObject*>(O), just_before_destroy, just_before_destroy);
			//if(GetInventory()->DropItem(smart_cast<CGameObject*>(O), just_before_destroy)) 
			//{
			//	O->H_SetParent(0, just_before_destroy);
			//}
			//moved to DropItem
		}break;
	}

}
예제 #6
0
void xrServer::Process_update(NET_Packet& P, ClientID sender)
{
	xrClientData* CL		= ID_to_client(sender);
	R_ASSERT2				(CL,"Process_update client not found");

	if (g_Dump_Update_Read) Msg("---- UPDATE_Read --- ");

	R_ASSERT(CL->flags.bLocal);
	// while has information
	while (!P.r_eof())
	{
		// find entity
		u16				ID;
		u8				size;

		P.r_u16			(ID);
		P.r_u8			(size);
		u32	_pos		= P.r_tell();
		CSE_Abstract	*E	= ID_to_entity(ID);
		
		if (E) {
			//Msg				("sv_import: %d '%s'",E->ID,E->name_replace());
			E->net_Ready	= TRUE;
			E->UPDATE_Read	(P);

			u32 cp = P.r_tell();
			if (g_Dump_Update_Read) Msg("* %s : %d - %d", E->name(), size, cp - _pos);

			if ((cp - _pos) != size)	{
				string16	tmp;
				CLSID2TEXT	(E->m_tClassID,tmp);
				Msg("* size = %d, start read = %d, end read = %d", size, _pos, cp);
				Debug.fatal	(DEBUG_INFO,"Beer from the creator of '%s', version of object = %d", tmp, E->m_wVersion);				
			}
		}
		else
			P.r_advance	(size);
	}
	if (g_Dump_Update_Read) Msg("-------------------- ");

}
예제 #7
0
void CMPPlayersBag::OnEvent(NET_Packet& P, u16 type) 
{
	CInventoryItemObject::OnEvent		(P,type);
	u16						id;
	switch (type) {
		case GE_OWNERSHIP_TAKE : 
			{
				P.r_u16(id);
				CObject* O = Level().Objects.net_Find(id);
				O->H_SetParent(this);
				O->Position().set(Position());
			}break;
		case GE_OWNERSHIP_REJECT : 
			{
				P.r_u16			(id);
				CObject* O = Level().Objects.net_Find(id);
				O->H_SetParent(0,!P.r_eof() && P.r_u8());
			}break;

	}
}
예제 #8
0
void message_filter::check_new_data	(NET_Packet & packet)
{
	u32			tmp_old_pos = packet.r_tell();
	
	msg_type_subtype_t	packet_mtype;
	packet_mtype.import	(packet);


	if (packet_mtype.msg_type == M_EVENT_PACK)
	{
		NET_Packet tmp_packet;
		while (!packet.r_eof())
		{
			tmp_packet.B.count = packet.r_u8();
			packet.r	(tmp_packet.B.data, tmp_packet.B.count);
			packet_mtype.import(tmp_packet);
			
			R_ASSERT2(packet_mtype.msg_type != M_EVENT_PACK, "M_EVENT_PACK in M_EVENT_PACK");
			dbg_print_msg	(tmp_packet, packet_mtype);

			filters_map_t::iterator tmp_iter = m_filters.find(packet_mtype);
			if (tmp_iter != m_filters.end())
			{
				tmp_iter->second(packet_mtype.msg_type,
					packet_mtype.msg_subtype,
					tmp_packet);
			}
		}
	} else {
		dbg_print_msg			(packet, packet_mtype);
		filters_map_t::iterator tmp_iter = m_filters.find(packet_mtype);
		if (tmp_iter != m_filters.end())
		{
			tmp_iter->second(packet_mtype.msg_type,
				packet_mtype.msg_subtype,
				packet);
		}
	}
	packet.r_seek	(tmp_old_pos);
}
void CSE_ALifeInventoryItem::UPDATE_Read	(NET_Packet &tNetPacket)
{
	tNetPacket.r_u8					(m_u8NumItems);
	if (!m_u8NumItems) {
		//Msg("* Object [%d] has no sync items", this->cast_abstract()->ID);
		return;
	}

	mask_num_items					num_items;
	num_items.common				= m_u8NumItems;
	m_u8NumItems					= num_items.num_items;

	R_ASSERT2						(
		m_u8NumItems < (u8(1) << 5),
		make_string("%d",m_u8NumItems)
		);
	
	/*if (check(num_items.mask,animated))
	{
		tNetPacket.r_float(m_blend_timeCurrent);
		anim_use=true;
	}
	else
	{
	anim_use=false;
	}*/

	{
		tNetPacket.r_vec3				(State.force);
		tNetPacket.r_vec3				(State.torque);

		tNetPacket.r_vec3				(State.position);
		base()->o_Position.set			(State.position); //this is very important because many functions use this o_Position..

		tNetPacket.r_float			(State.quaternion.x);
		tNetPacket.r_float			(State.quaternion.y);
		tNetPacket.r_float			(State.quaternion.z);
		tNetPacket.r_float			(State.quaternion.w);	

		State.enabled					= check(num_items.mask,inventory_item_state_enabled);

		if (!check(num_items.mask,inventory_item_angular_null)) {
			tNetPacket.r_float		(State.angular_vel.x);
			tNetPacket.r_float		(State.angular_vel.y);
			tNetPacket.r_float		(State.angular_vel.z);
		}
		else
			State.angular_vel.set		(0.f,0.f,0.f);

		if (!check(num_items.mask,inventory_item_linear_null)) {
			tNetPacket.r_float		(State.linear_vel.x);
			tNetPacket.r_float		(State.linear_vel.y);
			tNetPacket.r_float		(State.linear_vel.z);
		}
		else
			State.linear_vel.set		(0.f,0.f,0.f);

		/*if (check(num_items.mask,animated))
		{
			anim_use=true;
		}*/
	}
	prev_freezed = freezed;
	if (tNetPacket.r_eof())		// in case spawn + update 
	{
		freezed = false;
		return;
	}
	if (tNetPacket.r_u8())
	{
		freezed = false;
	}
	else {
		if (!freezed)
#ifdef XRGAME_EXPORTS
			m_freeze_time	= Device.dwTimeGlobal;
#else
			m_freeze_time	= 0;
#endif
		freezed = true;
	}
};
예제 #10
0
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();
}
예제 #11
0
void CActor::OnEvent		(NET_Packet& P, u16 type)
{
	inherited::OnEvent			(P,type);
	CInventoryOwner::OnEvent	(P,type);

	u16 id;
	switch (type)
	{
	case GE_TRADE_BUY:
	case GE_OWNERSHIP_TAKE:
		{
			P.r_u16		(id);
			CObject* O	= Level().Objects.net_Find	(id);
			if (!O)
			{
				Msg("! Error: No object to take/buy [%d]", id);
				break;
			}

			CGameObject* _GO = smart_cast<CGameObject*>(O);
			
			CFoodItem* pFood = smart_cast<CFoodItem*>(O);
			if(pFood)
#if defined(INV_NEW_SLOTS_SYSTEM)
			if (pFood->m_eItemPlace != eItemPlaceSlot)
#endif
				pFood->m_eItemPlace = eItemPlaceRuck;

			if( inventory().CanTakeItem(smart_cast<CInventoryItem*>(_GO)) )
			{
				O->H_SetParent(smart_cast<CObject*>(this));

				inventory().Take(_GO, false, true);

				CUIGameSP* pGameSP = NULL;
				CUI* ui = HUD().GetUI();
				if( ui&&ui->UIGame() )
				{
					pGameSP = smart_cast<CUIGameSP*>(HUD().GetUI()->UIGame());
					if (Level().CurrentViewEntity() == this)
							HUD().GetUI()->UIGame()->ReInitShownUI();
				};
				
				//добавить отсоединенный аддон в инвентарь
				if(pGameSP)
				{
					if(pGameSP->MainInputReceiver() == pGameSP->InventoryMenu)
					{
						pGameSP->InventoryMenu->AddItemToBag(smart_cast<CInventoryItem*>(O));
					}
				}
				
				SelectBestWeapon(O);
			} 
			else 
			{
				NET_Packet P;
				u_EventGen(P,GE_OWNERSHIP_REJECT,ID());
				P.w_u16(u16(O->ID()));
				u_EventSend(P);
			}
		}
		break;
	case GE_TRADE_SELL:
	case GE_OWNERSHIP_REJECT:
		{
			P.r_u16		(id);
			CObject* O	= Level().Objects.net_Find	(id);
			if (!O)
			{
				Msg("! Error: No object to reject/sell [%d]", id);
				break;
			}
			bool just_before_destroy	= !P.r_eof() && P.r_u8();
			O->SetTmpPreDestroy				(just_before_destroy);
			if (inventory().DropItem(smart_cast<CGameObject*>(O)) && !O->getDestroy()) 
			{
				O->H_SetParent(0,just_before_destroy);
//.				feel_touch_deny(O,2000);
				Level().m_feel_deny.feel_touch_deny(O, 1000);

			}

			SelectBestWeapon(O);

			if (Level().CurrentViewEntity() == this && HUD().GetUI() && HUD().GetUI()->UIGame())
				HUD().GetUI()->UIGame()->ReInitShownUI();
		}
		break;
	case GE_INV_ACTION:
		{
			s32 cmd;
			P.r_s32		(cmd);
			u32 flags;
			P.r_u32		(flags);
			s32 ZoomRndSeed = P.r_s32();
			s32 ShotRndSeed = P.r_s32();
									
			if (flags & CMD_START)
			{
				if (cmd == kWPN_ZOOM)
					SetZoomRndSeed(ZoomRndSeed);
				if (cmd == kWPN_FIRE)
					SetShotRndSeed(ShotRndSeed);
				IR_OnKeyboardPress(cmd);
			}
			else
				IR_OnKeyboardRelease(cmd);
		}
		break;
	case GEG_PLAYER_ITEM2SLOT:
	case GEG_PLAYER_ITEM2BELT:
	case GEG_PLAYER_ITEM2RUCK:
	case GEG_PLAYER_ITEM_EAT:
	case GEG_PLAYER_ACTIVATEARTEFACT:
		{
			P.r_u16		(id);
			CObject* O	= Level().Objects.net_Find	(id);
			if(!O)		break;
			if (O->getDestroy()) 
			{
#ifdef DEBUG
				Msg("! something to destroyed object - %s[%d]0x%X", *O->cName(), id, smart_cast<CInventoryItem*>(O));
#endif
				break;
			}
			switch (type)
			{
			case GEG_PLAYER_ITEM2SLOT:	 
				inventory().Slot(smart_cast<CInventoryItem*>(O)); 
				break;
			case GEG_PLAYER_ITEM2BELT:	 
				inventory().Belt(smart_cast<CInventoryItem*>(O)); 
				break;
			case GEG_PLAYER_ITEM2RUCK:	 
				inventory().Ruck(smart_cast<CInventoryItem*>(O)); 
				break;
			case GEG_PLAYER_ITEM_EAT:	 
				inventory().Eat(smart_cast<CInventoryItem*>(O)); 
				break;
			case GEG_PLAYER_ACTIVATEARTEFACT:
				{
					CArtefact* pArtefact		= smart_cast<CArtefact*>(O);
					pArtefact->ActivateArtefact	();
				}break;
			}
		}break;
	case GEG_PLAYER_ACTIVATE_SLOT:
		{
			u32							slot_id;
			P.r_u32						(slot_id);

			inventory().Activate		(slot_id);
								  
		}break;

	case GEG_PLAYER_WEAPON_HIDE_STATE:
		{
			u32 State		= P.r_u32();
			BOOL	Set		= !!P.r_u8();
			inventory().SetSlotsBlocked	((u16)State, !!Set);
		}break;
	case GE_MOVE_ACTOR:
		{
			Fvector NewPos, NewRot;
			P.r_vec3(NewPos);
			P.r_vec3(NewRot);
			
			MoveActor(NewPos, NewRot);
		}break;
	case GE_ACTOR_MAX_POWER:
		{
			conditions().MaxPower();
			conditions().ClearWounds();
			ClearBloodWounds();
		}break;
	case GEG_PLAYER_ATTACH_HOLDER:
		{
			u32 id = P.r_u32();
			CObject* O	= Level().Objects.net_Find	(id);
			if (!O){
				Msg("! Error: No object to attach holder [%d]", id);
				break;
			}
			VERIFY(m_holder==NULL);
			CHolderCustom*	holder = smart_cast<CHolderCustom*>(O);
			if(!holder->Engaged())	use_Holder		(holder);

		}break;
	case GEG_PLAYER_DETACH_HOLDER:
		{
			if			(!m_holder)	break;
			u32 id			= P.r_u32();
			CGameObject*	GO	= smart_cast<CGameObject*>(m_holder);
			VERIFY			(id==GO->ID());
			use_Holder		(NULL);
		}break;
	case GEG_PLAYER_PLAY_HEADSHOT_PARTICLE:
		{
			OnPlayHeadShotParticle(P);
		}break;
	case GE_ACTOR_JUMPING:
		{
			/*
			Fvector dir;
			P.r_dir(dir);
			float jump = P.r_float();
			NET_SavedAccel = dir;
			extern float NET_Jump;
			NET_Jump = jump;
			m_bInInterpolation = false;
			mstate_real |= mcJump;
			*/
		}break;
	}
}
예제 #12
0
void CActor::OnEvent(NET_Packet& P, u16 type)
{
	inherited::OnEvent			(P,type);
	CInventoryOwner::OnEvent	(P,type);

	u16 id;
	switch (type)
	{
	case GE_TRADE_BUY:
	case GE_OWNERSHIP_TAKE:
		{
			P.r_u16					(id);
			CObject* Obj			= Level().Objects.net_Find	(id);

//			R_ASSERT2( Obj, make_string("GE_OWNERSHIP_TAKE: Object not found. object_id = [%d]", id).c_str() );
			VERIFY2  ( Obj, make_string("GE_OWNERSHIP_TAKE: Object not found. object_id = [%d]", id).c_str() );
			if ( !Obj ) {
				Msg                 ( "! GE_OWNERSHIP_TAKE: Object not found. object_id = [%d]", id );
				break;
			}
		
			CGameObject* _GO		= smart_cast<CGameObject*>(Obj);
			if (!IsGameTypeSingle() && !g_Alive())
			{
				Msg("! WARNING: dead player [%d][%s] can't take items [%d][%s]",
					ID(), Name(), _GO->ID(), _GO->cNameSect().c_str());
				break;
			}
			
			if( inventory().CanTakeItem(smart_cast<CInventoryItem*>(_GO)) )
			{
				Obj->H_SetParent		(smart_cast<CObject*>(this));
				
#ifdef MP_LOGGING
				string64 act;
				xr_strcpy( act, (type == GE_TRADE_BUY)? "buys" : "takes" );
				Msg("--- Actor [%d][%s]  %s  [%d][%s]", ID(), Name(), act, _GO->ID(), _GO->cNameSect().c_str());
#endif // MP_LOGGING
				
				inventory().Take	(_GO, false, true);
			
				SelectBestWeapon(Obj);
			}
			else
			{
				if (IsGameTypeSingle())
				{
					NET_Packet		P;
					u_EventGen		(P,GE_OWNERSHIP_REJECT,ID());
					P.w_u16			(u16(Obj->ID()));
					u_EventSend		(P);
				} else
				{
					Msg("! ERROR: Actor [%d][%s]  tries to drop on take [%d][%s]", ID(), Name(), _GO->ID(), _GO->cNameSect().c_str());
				}
			}
		}
		break;
	case GE_TRADE_SELL:
	case GE_OWNERSHIP_REJECT:
		{
			P.r_u16							(id);
			CObject* Obj					= Level().Objects.net_Find	(id);

//			R_ASSERT2( Obj, make_string("GE_OWNERSHIP_REJECT: Object not found, id = %d", id).c_str() );
			VERIFY2  ( Obj, make_string("GE_OWNERSHIP_REJECT: Object not found, id = %d", id).c_str() );
			if ( !Obj ) {
				Msg                 ( "! GE_OWNERSHIP_REJECT: Object not found, id = %d", id );
				break;
			}

			bool just_before_destroy		= !P.r_eof() && P.r_u8();
			bool dont_create_shell			= (type==GE_TRADE_SELL) || just_before_destroy;
			Obj->SetTmpPreDestroy			(just_before_destroy);
			
			CGameObject * GO = smart_cast<CGameObject*>(Obj);
			
#ifdef MP_LOGGING
			string64 act;
			xr_strcpy( act, (type == GE_TRADE_SELL)? "sells" : "rejects" );
			Msg("--- Actor [%d][%s]  %s  [%d][%s]", ID(), Name(), act, GO->ID(), GO->cNameSect().c_str());
#endif // MP_LOGGING
			
			VERIFY( GO->H_Parent() );
			if ( !GO->H_Parent() )
			{
				Msg("! ERROR: Actor [%d][%s] tries to reject item [%d][%s] that has no parent", 
					ID(), Name(), GO->ID(), GO->cNameSect().c_str());
				break;
			}
			
			VERIFY2( GO->H_Parent()->ID() == ID(), 
				make_string("actor [%d][%s] tries to drop not own object [%d][%s]",
					ID(), Name(), GO->ID(), GO->cNameSect().c_str() ).c_str() );

			if ( GO->H_Parent()->ID() != ID() )
			{
				CActor* real_parent = smart_cast<CActor*>(GO->H_Parent());
				Msg("! ERROR: Actor [%d][%s] tries to drop not own item [%d][%s], his parent is [%d][%s]",
					ID(), Name(), GO->ID(), GO->cNameSect().c_str(), real_parent->ID(), real_parent->Name());
				break;
			}

			if (!Obj->getDestroy() && inventory().DropItem(GO, just_before_destroy, dont_create_shell)) 
			{
				//O->H_SetParent(0,just_before_destroy);//moved to DropItem
				//feel_touch_deny(O,2000);
				Level().m_feel_deny.feel_touch_deny(Obj, 1000);

				// [12.11.07] Alexander Maniluk: extended GE_OWNERSHIP_REJECT packet for drop item to selected position
				Fvector dropPosition;
				if (!P.r_eof())
				{
					P.r_vec3(dropPosition);
					GO->MoveTo(dropPosition);
					//Other variant :)
					/*NET_Packet MovePacket;
					MovePacket.w_begin(M_MOVE_ARTEFACTS);
					MovePacket.w_u8(1);
					MovePacket.w_u16(id);
					MovePacket.w_vec3(dropPosition);
					u_EventSend(MovePacket);*/
				}
			}

			if (!just_before_destroy)
				SelectBestWeapon(Obj);

		}
		break;
	case GE_INV_ACTION:
		{
			u16 cmd;
			P.r_u16		(cmd);
			u32 flags;
			P.r_u32		(flags);
			s32 ZoomRndSeed = P.r_s32();
			s32 ShotRndSeed = P.r_s32();
			if (!IsGameTypeSingle() && !g_Alive())
			{
//				Msg("! WARNING: dead player tries to rize inventory action");
				break;
			}
									
			if (flags & CMD_START)
			{
				if (cmd == kWPN_ZOOM)
					SetZoomRndSeed(ZoomRndSeed);
				if (cmd == kWPN_FIRE)
					SetShotRndSeed(ShotRndSeed);
				IR_OnKeyboardPress(cmd);
			}
			else
				IR_OnKeyboardRelease(cmd);
		}
		break;
	case GEG_PLAYER_ITEM2SLOT:
	case GEG_PLAYER_ITEM2BELT:
	case GEG_PLAYER_ITEM2RUCK:
	case GEG_PLAYER_ITEM_EAT:
	case GEG_PLAYER_ACTIVATEARTEFACT:
{
			P.r_u16		(id);
			CObject* Obj	= Level().Objects.net_Find	(id);

//			R_ASSERT2( Obj, make_string("GEG_PLAYER_ITEM_EAT(use): Object not found. object_id = [%d]", id).c_str() );
			VERIFY2  ( Obj, make_string("GEG_PLAYER_ITEM_EAT(use): Object not found. object_id = [%d]", id).c_str() );
			if ( !Obj ) {
//				Msg                 ( "! GEG_PLAYER_ITEM_EAT(use): Object not found. object_id = [%d]", id );
				break;
			}

//			R_ASSERT2( !Obj->getDestroy(), make_string("GEG_PLAYER_ITEM_EAT(use): Object is destroying. object_id = [%d]", id).c_str() );
			VERIFY2  ( !Obj->getDestroy(), make_string("GEG_PLAYER_ITEM_EAT(use): Object is destroying. object_id = [%d]", id).c_str() );
			if ( Obj->getDestroy() ) {
//				Msg                                ( "! GEG_PLAYER_ITEM_EAT(use): Object is destroying. object_id = [%d]", id );
				break;
			}

			if (!IsGameTypeSingle() && !g_Alive())
			{
				Msg("! WARNING: dead player [%d][%s] can't use items [%d][%s]",
					ID(), Name(), Obj->ID(), Obj->cNameSect().c_str());
				break;
			}

			if ( type == GEG_PLAYER_ACTIVATEARTEFACT )
			{
				CArtefact* pArtefact = smart_cast<CArtefact*>(Obj);
	//			R_ASSERT2( pArtefact, make_string("GEG_PLAYER_ACTIVATEARTEFACT: Artefact not found. artefact_id = [%d]", id).c_str() );
				VERIFY2  ( pArtefact, make_string("GEG_PLAYER_ACTIVATEARTEFACT: Artefact not found. artefact_id = [%d]", id).c_str() );
				if ( !pArtefact ) {
					Msg                       ( "! GEG_PLAYER_ACTIVATEARTEFACT: Artefact not found. artefact_id = [%d]", id );
					break;//1
				}
				
				pArtefact->ActivateArtefact	();
				break;//1
			}
			
			PIItem iitem = smart_cast<CInventoryItem*>(Obj);
			R_ASSERT( iitem );

			switch (type)
			{
			case GEG_PLAYER_ITEM2SLOT:
			{
				u16 slot_id = P.r_u16();
				inventory().Slot(slot_id, iitem ); 
			}break;//2
			case GEG_PLAYER_ITEM2BELT:	 
				inventory().Belt( iitem ); 
				break;//2
			case GEG_PLAYER_ITEM2RUCK:	 
				inventory().Ruck( iitem ); 
				break;//2
			case GEG_PLAYER_ITEM_EAT:	 
				inventory().Eat( iitem ); 
				break;//2
			}//switch

		}break;//1
	case GEG_PLAYER_ACTIVATE_SLOT:
		{
			u16							slot_id;
			P.r_u16						(slot_id);

			inventory().Activate		(slot_id);
								  
		}break;

	case GEG_PLAYER_DISABLE_SPRINT:
		{
			s8 cmd				= P.r_s8();
			m_block_sprint_counter = m_block_sprint_counter+cmd;
			Msg("m_block_sprint_counter=%d",m_block_sprint_counter);
			if(m_block_sprint_counter>0)
			{
				mstate_wishful	&=~mcSprint;
			}
		}break;

	case GEG_PLAYER_WEAPON_HIDE_STATE:
		{
			u16 State		= P.r_u16();
			BOOL	Set		= !!P.r_u8();
			inventory().SetSlotsBlocked	(State, !!Set);
		}break;
	case GE_MOVE_ACTOR:
		{
			Fvector NewPos, NewRot;
			P.r_vec3(NewPos);
			P.r_vec3(NewRot);
			
			MoveActor(NewPos, NewRot);
		}break;
	case GE_ACTOR_MAX_POWER:
		{
			conditions().MaxPower();
			conditions().ClearWounds();
			ClearBloodWounds();
		}break;
	case GE_ACTOR_MAX_HEALTH:
		{
			SetfHealth(GetMaxHealth());
		}break;
	case GEG_PLAYER_ATTACH_HOLDER:
		{
			u16 id = P.r_u16();
			CObject* O	= Level().Objects.net_Find	(id);
			if (!O){
				Msg("! Error: No object to attach holder [%d]", id);
				break;
			}
			VERIFY(m_holder==NULL);
			CHolderCustom*	holder = smart_cast<CHolderCustom*>(O);
			if(!holder->Engaged())	use_Holder		(holder);

		}break;
	case GEG_PLAYER_DETACH_HOLDER:
		{
			if			(!m_holder)	break;
			u16 id			= P.r_u16();
			CGameObject*	GO	= smart_cast<CGameObject*>(m_holder);
			VERIFY			(id==GO->ID());
			use_Holder		(NULL);
		}break;
	case GEG_PLAYER_PLAY_HEADSHOT_PARTICLE:
		{
			OnPlayHeadShotParticle(P);
		}break;
	case GE_ACTOR_JUMPING:
		{
			/*
			Fvector dir;
			P.r_dir(dir);
			float jump = P.r_float();
			NET_SavedAccel = dir;
			extern float NET_Jump;
			NET_Jump = jump;
			m_bInInterpolation = false;
			mstate_real |= mcJump;
			*/
		}break;
	}
}
예제 #13
0
void CAI_Stalker::OnEvent		(NET_Packet& P, u16 type)
{
	inherited::OnEvent			(P,type);
	CInventoryOwner::OnEvent	(P,type);

	switch (type)
	{
		case GE_TRADE_BUY :
		case GE_OWNERSHIP_TAKE : {

			u16			id;
			P.r_u16		(id);
			CObject		*O = Level().Objects.net_Find	(id);

			R_ASSERT	(O);

#ifndef SILENCE
			Msg("Trying to take - %s (%d)", *O->cName(),O->ID());
#endif
			CGameObject	*_O = smart_cast<CGameObject*>(O);
			if (inventory().CanTakeItem(smart_cast<CInventoryItem*>(_O))) { //GetScriptControl()
				O->H_SetParent(this);
				inventory().Take(_O,true, false);
				if (!inventory().ActiveItem() && GetScriptControl() && smart_cast<CShootingObject*>(O))
					CObjectHandler::set_goal	(eObjectActionIdle,_O);

				on_after_take			(_O);
#ifndef SILENCE
				Msg("TAKE - %s (%d)", *O->cName(),O->ID());
#endif
			}
			else {
//				DropItemSendMessage(O);
				NET_Packet				P;
				u_EventGen				(P,GE_OWNERSHIP_REJECT,ID());
				P.w_u16					(u16(O->ID()));
				u_EventSend				(P);

#ifndef SILENCE
				Msg("TAKE - can't take! - Dropping for valid server information %s (%d)", *O->cName(),O->ID());
#endif
			}
			break;
		}
		case GE_TRADE_SELL :
		case GE_OWNERSHIP_REJECT : {
			u16 id;
			P.r_u16		(id);
			CObject		*O = Level().Objects.net_Find(id);

#pragma todo("Dima to Oles : how can this happen?")
			if (!O)
				break;

			bool just_before_destroy	= !P.r_eof() && P.r_u8();
			O->SetTmpPreDestroy				(just_before_destroy);

			if (inventory().DropItem(smart_cast<CGameObject*>(O)) && !O->getDestroy()) {
				O->H_SetParent	(0, just_before_destroy);
				feel_touch_deny	(O,2000);
			}

			break;
		}
	}
}
예제 #14
0
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);
}