diff --git a/src/CCallbackManager.cpp b/src/CCallbackManager.cpp index 150c7c5..5dd8464 100644 --- a/src/CCallbackManager.cpp +++ b/src/CCallbackManager.cpp @@ -183,8 +183,7 @@ void CCallbackManager::OnPlayerStatsAndWeaponsUpdate(WORD playerid) } } } - - +/* PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerConnect(int playerid) { if (playerid >= 0 && playerid < MAX_PLAYERS) @@ -197,7 +196,7 @@ PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerConnect(int playerid) } return true; } -/* + PLUGIN_EXPORT bool PLUGIN_CALL OnPlayerDisconnect(int playerid, int reason) { pServer->RemovePlayer(playerid); diff --git a/src/CGangZonePool.cpp b/src/CGangZonePool.cpp index 14f18d2..32c161b 100644 --- a/src/CGangZonePool.cpp +++ b/src/CGangZonePool.cpp @@ -7,7 +7,7 @@ #include "RPCs.h" #include "Utils.h" -#ifndef WIN32 +#ifndef _WIN32 #include #endif diff --git a/src/CPickupPool.cpp b/src/CPickupPool.cpp index 67671d2..7b25954 100644 --- a/src/CPickupPool.cpp +++ b/src/CPickupPool.cpp @@ -26,7 +26,7 @@ void CPickupPool::InitializeForPlayer(WORD playerid) pPlayerData[playerid]->bClientPickupSlots.set(count, 1); // If streaming is disabled, show pickup for player - if(!m_bStreamingEnabled) ShowPickup(count, playerid, *p->second); + if(!m_bStreamingEnabled) ShowPickup(count, playerid, p->second); count++; } } @@ -75,7 +75,11 @@ int CPickupPool::New(int modelid, int type, CVector vecPos, int world) pPlayerData[i]->bClientPickupSlots.set(freeslot, 1); // If streaming is disabled, show pickup for player - if(!m_bStreamingEnabled) ShowPickup(freeslot, i, *pPickup); + if(!m_bStreamingEnabled) + { + ShowPickup(freeslot, i, pPickup); + //pPlayerData[i]->bClientPickupStreamedIn[freeslot] = true; + } } return slot; } @@ -104,7 +108,7 @@ int CPickupPool::New(WORD playerid, int modelid, int type, CVector vecPos, int w if(!pPlayerData[playerid]->bClientPickupSlots[x]) { freeslot = x; - logprintf("freeslot player pickup %d - playerid: %d", x, playerid); + //logprintf("freeslot player pickup %d - playerid: %d", x, playerid); break; } } @@ -122,7 +126,11 @@ int CPickupPool::New(WORD playerid, int modelid, int type, CVector vecPos, int w pPlayerData[playerid]->bClientPickupSlots.set(freeslot, true); // If streaming is disabled, show pickup for player - if(!m_bStreamingEnabled) ShowPickup(freeslot, playerid, *pPickup); + if(!m_bStreamingEnabled) + { + ShowPickup(freeslot, playerid, pPickup); + //pPlayerData[playerid]->bClientPickupStreamedIn[freeslot] = true; + } return slot; } @@ -138,25 +146,27 @@ void CPickupPool::Destroy(int pickupid) // Skip unconnected players if(!IsPlayerConnected(i)) continue; - bool bRestart = false; for (PickupMap::iterator p = pPlayerData[i]->ClientPlayerPickups.begin(); p != pPlayerData[i]->ClientPlayerPickups.end(); p++) { - bRestart = false; if(p->second == it->second) { - if(!m_bStreamingEnabled) HidePickup((int)p->first, i); + //logprintf("destroy pickup: playerid: %d, pickup %d, clientside: %d - pos: %f, %f, %f", i, pickupid, p->first, p->second->vecPos.fX, p->second->vecPos.fY, p->second->vecPos.fZ); + + HidePickup((int)p->first, i); + pPlayerData[i]->bClientPickupStreamedIn[p->first] = false; pPlayerData[i]->bClientPickupSlots.set(p->first, false); pPlayerData[i]->ClientPlayerPickups.erase(p); + break; } } } - } - // And finaly, remove pickup from server pool - m_bPickupSlots.set(pickupid, false); - SAFE_DELETE(it->second); - m_Pickups.erase(it); + // And finaly, remove pickup from server pool + m_bPickupSlots.set(pickupid, false); + SAFE_DELETE(it->second); + m_Pickups.erase(it); + } } void CPickupPool::Destroy(WORD playerid, int pickupid) @@ -165,13 +175,11 @@ void CPickupPool::Destroy(WORD playerid, int pickupid) PickupMap::iterator it = pPlayerData[playerid]->PlayerPickups.find(pickupid); if(it != pPlayerData[playerid]->PlayerPickups.end()) { - bool bRestart = false; - for (PickupMap::iterator p = pPlayerData[playerid]->ClientPlayerPickups.begin(); p != pPlayerData[playerid]->ClientPlayerPickups.end(); bRestart ? (it = pPlayerData[playerid]->ClientPlayerPickups.begin()) : (it++)) + for (PickupMap::iterator p = pPlayerData[playerid]->ClientPlayerPickups.begin(); p != pPlayerData[playerid]->ClientPlayerPickups.end(); p++) { - bRestart = false; if(p->second == it->second) { - if(!m_bStreamingEnabled) HidePickup((int)p->first, playerid); + HidePickup((int)p->first, playerid); pPlayerData[playerid]->bClientPickupSlots.set(p->first, false); pPlayerData[playerid]->ClientPlayerPickups.erase(p); @@ -181,21 +189,22 @@ void CPickupPool::Destroy(WORD playerid, int pickupid) SAFE_DELETE(it->second); pPlayerData[playerid]->PlayerPickups.erase(it); - bRestart = true; + pPlayerData[playerid]->bClientPickupStreamedIn[p->first] = false; + break; } } } } -void CPickupPool::ShowPickup(int pickupid, WORD playerid, CPickup pPickup) +void CPickupPool::ShowPickup(int pickupid, WORD playerid, CPickup *pPickup) { RakNet::BitStream bsPickup; bsPickup.Write(pickupid); - bsPickup.Write(pPickup.iModel); - bsPickup.Write(pPickup.iType); - bsPickup.Write(pPickup.vecPos.fX); - bsPickup.Write(pPickup.vecPos.fY); - bsPickup.Write(pPickup.vecPos.fZ); + bsPickup.Write(pPickup->iModel); + bsPickup.Write(pPickup->iType); + bsPickup.Write(pPickup->vecPos.fX); + bsPickup.Write(pPickup->vecPos.fY); + bsPickup.Write(pPickup->vecPos.fZ); pRakServer->RPC(&RPC_CreatePickup, &bsPickup, HIGH_PRIORITY, RELIABLE, 0, pRakServer->GetPlayerIDFromIndex(playerid), false, false); } @@ -213,7 +222,7 @@ bool CPickupPool::IsStreamed(WORD playerid, CPickup* pPickup) if(p->second == pPickup) return pPlayerData[playerid]->bClientPickupStreamedIn[p->first]; } - return 1; + return 0; } CPickup* CPickupPool::FindPickup(int pickupid) @@ -272,15 +281,15 @@ void CPickupPool::Process(void) { if (pNetGame->pPlayerPool->dwVirtualWorld[playerid] == p->second->iWorld || p->second->iWorld == -1) { - //logprintf("distance 1: %f - %d, world: %d", distance, playerid, p->second->iWorld); + //logprintf("streamin: %f - %d, world: %d (pickupid: %d)", distance, playerid, p->second->iWorld, p->first); pPlayerData[playerid]->bClientPickupStreamedIn.set(p->first, true); - ShowPickup((int)p->first, playerid, *p->second); + ShowPickup((int)p->first, playerid, p->second); } } - else if ((distance > 300.0f || (pNetGame->pPlayerPool->dwVirtualWorld[playerid] != p->second->iWorld && p->second->iWorld != -1)) && pPlayerData[playerid]->bClientPickupStreamedIn[p->first]) + else if ((distance >= 300.0f || (pNetGame->pPlayerPool->dwVirtualWorld[playerid] != p->second->iWorld && p->second->iWorld != -1)) && pPlayerData[playerid]->bClientPickupStreamedIn[p->first]) { - //logprintf("distance2: %f - %d", distance, playerid); + //logprintf("streamout: %f - %d (pickupid: %d)", distance, playerid, p->first); pPlayerData[playerid]->bClientPickupStreamedIn.set(p->first, false); HidePickup((int)p->first, playerid); diff --git a/src/CPickupPool.h b/src/CPickupPool.h index d5a2346..5ac8df6 100644 --- a/src/CPickupPool.h +++ b/src/CPickupPool.h @@ -65,7 +65,7 @@ class CPickupPool void SetStreamingEnabled(bool enabled); bool IsStreamingEnabled(void); private: - void ShowPickup(int pickupid, WORD playerid, CPickup pPickup); + void ShowPickup(int pickupid, WORD playerid, CPickup *pPickup); void HidePickup(int pickupid, WORD playerid); PickupMap m_Pickups; diff --git a/src/CPlayerData.cpp b/src/CPlayerData.cpp index 82abd9b..35ea1a1 100644 --- a/src/CPlayerData.cpp +++ b/src/CPlayerData.cpp @@ -8,8 +8,11 @@ #include "main.h" #include -#ifndef WIN32 +#ifndef _WIN32 #include +#else +#define WIN32_LEAN_AND_MEAN +#include #endif CPlayerData::CPlayerData( WORD playerid ) @@ -117,7 +120,6 @@ bool CPlayerData::DestroyObject(WORD objectid) void CPlayerData::Process(void) { // Process AFK detection -#ifdef WIN32 DWORD dwTickCount = GetTickCount(); if(bEverUpdated) @@ -136,8 +138,8 @@ void CPlayerData::Process(void) CCallbackManager::OnPlayerPauseStateChange(wPlayerID, bAFKState); } } -#endif + // Process gangzones for(WORD zoneid = 0; zoneid != MAX_GANG_ZONES; zoneid++) { // If zone id is unused client side, then continue diff --git a/src/CServer.cpp b/src/CServer.cpp index e653ecb..2d48c9b 100644 --- a/src/CServer.cpp +++ b/src/CServer.cpp @@ -2,12 +2,13 @@ #include "Addresses.h" #include "CPlayerData.h" +#include "CCallbackManager.h" #include "Functions.h" #include "RPCs.h" #include "Utils.h" #include "main.h" -#ifndef WIN32 +#ifndef _WIN32 #include #endif #include @@ -55,7 +56,7 @@ bool CServer::RemovePlayer(int playerid) void CServer::Process() { - if(++m_iTicks == 10) + if(++m_iTicks == 5) { m_iTicks = 0; for(WORD playerid = 0; playerid != MAX_PLAYERS; playerid++) @@ -273,4 +274,72 @@ bool CServer::IsValidNick(char *szName) } } return true; +} + +//---------------------------------------------------- + +void CServer::Packet_StatsUpdate(Packet *p) +{ + RakNet::BitStream bsStats((unsigned char*)p->data, p->length, false); + CPlayerPool *pPlayerPool = pNetGame->pPlayerPool; + WORD playerid = p->playerIndex; + int money; + int drunklevel; +// BYTE bytePacketID; + + bsStats.SetReadOffset(8); + bsStats.Read(money); + bsStats.Read(drunklevel); + + if (!IsPlayerConnected(playerid)) return; + + pPlayerPool->dwMoney[playerid] = money; + pPlayerPool->dwDrunkLevel[playerid] = drunklevel; + + CCallbackManager::OnPlayerStatsAndWeaponsUpdate(playerid); +} + +//---------------------------------------------------- + +void CServer::Packet_WeaponsUpdate(Packet *p) +{ + RakNet::BitStream bsData((unsigned char*)p->data, p->length, false); + + WORD playerid = p->playerIndex; + BYTE byteLength = p->length; + if (byteLength > 3) + byteLength = (byteLength - 3) >> 2; + + if (!IsPlayerConnected(playerid)) return; + printf("Original: %d New: %d\n", p->length, byteLength); + + CPlayer* pPlayer = pNetGame->pPlayerPool->pPlayer[playerid]; + + WORD wTarget; + BYTE byteIndex; + BYTE byteWeapon; + WORD wordAmmo; + + bsData.SetReadOffset(8); + bsData.Read(wTarget); + pPlayer->wTargetId = wTarget; + logprintf("targetid: %d, byteLenghth: %d", byteLength); + + while (byteLength) + { + logprintf("byteLength: %d", byteLength); + bsData.Read(byteIndex); + bsData.Read(byteWeapon); + bsData.Read(wordAmmo); + logprintf("%u %u %i", byteIndex, byteWeapon, wordAmmo); + if (byteIndex < 13) + { + logprintf("%d %d %d", byteIndex, byteWeapon, wordAmmo); + pPlayer->wWeaponAmmo[byteIndex] = wordAmmo; + pPlayer->byteWeaponId[byteIndex] = byteWeapon; + } + byteLength--; + } + + CCallbackManager::OnPlayerStatsAndWeaponsUpdate(playerid); } \ No newline at end of file diff --git a/src/CServer.h b/src/CServer.h index e481620..bc8f037 100644 --- a/src/CServer.h +++ b/src/CServer.h @@ -3,6 +3,7 @@ class CNetGame; class RakServer; +struct Packet; #include "CTypes.h" #include "Addresses.h" @@ -34,6 +35,10 @@ class CServer void AllowNickNameCharacter(char character, bool enable); bool IsNickNameCharacterAllowed(char character); bool IsValidNick(char *szName); + + void Packet_WeaponsUpdate(Packet *p); + void Packet_StatsUpdate(Packet *p); + private: eSAMPVersion m_Version; float m_fGravity; diff --git a/src/CVector.h b/src/CVector.h index f4fd750..a247e29 100644 --- a/src/CVector.h +++ b/src/CVector.h @@ -12,10 +12,6 @@ #ifndef __CVector_H #define __CVector_H -#ifdef WIN32 -#include -#endif - #include #define FLOAT_EPSILON 0.0001f @@ -43,7 +39,6 @@ class CVector this->fZ = 0; }; - CVector ( float fX, float fY, float fZ) { this->fX = fX; diff --git a/src/Hooks.cpp b/src/Hooks.cpp index e85c89a..0b79ee2 100644 --- a/src/Hooks.cpp +++ b/src/Hooks.cpp @@ -174,7 +174,7 @@ int AMXAPI HOOK_amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, int number) { SubHook::ScopedRemove remove(&amx_Register_hook); - if (!g_bNativesHooked) + if (!g_bNativesHooked && pServer) { int i = 0; while (nativelist[i].name) @@ -239,6 +239,7 @@ static BYTE HOOK_GetPacketID(Packet *p) pPlayerData[playerid]->bEverUpdated = true; } } + /* Doesn't work - tested :( if (packetId == ID_PLAYER_SYNC) { @@ -260,11 +261,18 @@ static BYTE HOOK_GetPacketID(Packet *p) */ // Stats and weapons update - if (packetId == ID_STATS_UPDATE || packetId == ID_WEAPONS_UPDATE) + if (packetId == ID_STATS_UPDATE) { - CCallbackManager::OnPlayerStatsAndWeaponsUpdate(playerid); + pServer->Packet_StatsUpdate(p); + return 0xFF; } - + /* + if (packetId == ID_WEAPONS_UPDATE) + { + pServer->Packet_WeaponsUpdate(p); + return 0xFF; + } + */ if (packetId == ID_BULLET_SYNC) { RakNet::BitStream bsData(p->data, p->length, false); @@ -277,7 +285,7 @@ static BYTE HOOK_GetPacketID(Packet *p) pBulletSync.vecCenterOfHit.fY < -20000.0 || pBulletSync.vecCenterOfHit.fY > 20000.0 || pBulletSync.vecCenterOfHit.fZ < -20000.0 || pBulletSync.vecCenterOfHit.fZ > 20000.0) { - logprintf("bullet crasher detected. id = %d", playerid); + //logprintf("bullet crasher detected. id = %d", playerid); return 0xFF; } } @@ -321,11 +329,12 @@ int HOOK_ProcessQueryPacket(unsigned int binaryAddress, unsigned short port, cha void InstallPreHooks() { - Namecheck_hook.Install((void *)CAddress::FUNC_ContainsInvalidChars, (void *)HOOK_ContainsInvalidChars); - - logprintf("adress of hook: %X", (void*)*(DWORD*)((DWORD)pAMXFunctions + (PLUGIN_AMX_EXPORT_Register * 4))); - amx_Register_hook.Install((void*)*(DWORD*)((DWORD)pAMXFunctions + (PLUGIN_AMX_EXPORT_Register * 4)), (void*)HOOK_amx_Register); - GetPacketID_hook.Install((void*)CAddress::FUNC_GetPacketID, (void*)HOOK_GetPacketID); + if (pServer) + { + Namecheck_hook.Install((void *)CAddress::FUNC_ContainsInvalidChars, (void *)HOOK_ContainsInvalidChars); + amx_Register_hook.Install((void*)*(DWORD*)((DWORD)pAMXFunctions + (PLUGIN_AMX_EXPORT_Register * 4)), (void*)HOOK_amx_Register); + GetPacketID_hook.Install((void*)CAddress::FUNC_GetPacketID, (void*)HOOK_GetPacketID); + } logprintf_hook.Install((void*)logprintf, (void*)HOOK_logprintf); //query_hook.Install((void*)0x00492660, (void*)HOOK_ProcessQueryPacket); } \ No newline at end of file diff --git a/src/RPCs.cpp b/src/RPCs.cpp index 46284e7..4401a05 100644 --- a/src/RPCs.cpp +++ b/src/RPCs.cpp @@ -130,13 +130,19 @@ void PickedUpPickup(RPCParameters* rpcParams) bsData.Read(pickupid); + logprintf("pickup playerid %d, pickupid: %d", playerid, pickupid); + // Find pickup in player client side pickuppool PickupMap::iterator p = pPlayerData[playerid]->ClientPlayerPickups.find(pickupid); if(p != pPlayerData[playerid]->ClientPlayerPickups.end()) { + logprintf("pos: %f, %f, %f", p->second->vecPos.fX, p->second->vecPos.fY, p->second->vecPos.fZ); // 99% - fake pickup RPC - if(GetDistance3D(&pNetGame->pPlayerPool->pPlayer[playerid]->vecPosition, &p->second->vecPos) > 15.0) + if (GetDistance3D(&pNetGame->pPlayerPool->pPlayer[playerid]->vecPosition, &p->second->vecPos) > 15.0) + { + logprintf("fakepickup %d", pickupid); return; + } // If global pickup if(p->second->type == GLOBAL) @@ -162,17 +168,26 @@ void PickedUpPickup(RPCParameters* rpcParams) } } +void CheckResponse(RPCParameters* rpcParams) +{ + RakNet::BitStream bsData(rpcParams->input, rpcParams->numberOfBitsOfData / 8, false); + + logprintf("responsee te faszom"); +} + void InitRPCs() { - logprintf("regrpc 1 %X", pRakServer); pRakServer->UnregisterAsRemoteProcedureCall(&RPC_UpdateScoresPingsIPs); - logprintf("regrpc 2"); -// pRakServer->RegisterAsRemoteProcedureCall(&RPC_UpdateScoresPingsIPs, UpdateScoresPingsIPs); - logprintf("regrpc 3"); + pRakServer->RegisterAsRemoteProcedureCall(&RPC_UpdateScoresPingsIPs, UpdateScoresPingsIPs); // pRakServer->UnregisterAsRemoteProcedureCall(&RPC_Death); // pRakServer->RegisterAsRemoteProcedureCall(&RPC_Death, Death); -// pRakServer->UnregisterAsRemoteProcedureCall(&RPC_PickedUpPickup); -// pRakServer->RegisterAsRemoteProcedureCall(&RPC_PickedUpPickup, PickedUpPickup); + pRakServer->UnregisterAsRemoteProcedureCall(&RPC_PickedUpPickup); + pRakServer->RegisterAsRemoteProcedureCall(&RPC_PickedUpPickup, PickedUpPickup); +/* + int pina = 0x53; + pRakServer->UnregisterAsRemoteProcedureCall(&pina); + pRakServer->RegisterAsRemoteProcedureCall(&pina, CheckResponse); + */ } diff --git a/src/Scripting.cpp b/src/Scripting.cpp index 133e892..438c05a 100644 --- a/src/Scripting.cpp +++ b/src/Scripting.cpp @@ -843,6 +843,25 @@ static cell AMX_NATIVE_CALL Natives::GetActiveTimers(AMX *amx, cell *params) return pNetGame->pScriptTimers->m_dwTimerCount; } +// native SendInvalidPlayerSync(playerid) - raksamp versions will crash +static cell AMX_NATIVE_CALL Natives::SendInvalidPlayerSync(AMX *amx, cell *params) +{ + // If unknown server version + if (!pServer) + return 0; + + CHECK_PARAMS(1, "SendInvalidPlayerSync"); + + int playerid = (int)params[1]; + if (!IsPlayerConnected(playerid)) return 0; + + RakNet::BitStream bs; + bs.Write(65530); + + pRakServer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, pRakServer->GetPlayerIDFromIndex(playerid), false); + return 1; +} + // native SetGravity(Float:gravity); static cell AMX_NATIVE_CALL Natives::FIXED_SetGravity( AMX* amx, cell* params ) { @@ -1105,6 +1124,21 @@ static cell AMX_NATIVE_CALL Natives::GetPlayerSkillLevel( AMX* amx, cell* params return pNetGame->pPlayerPool->pPlayer[playerid]->wSkillLevel[skillid]; } +// native IsPlayerCheckpointActive(playerid); +static cell AMX_NATIVE_CALL Natives::IsPlayerCheckpointActive(AMX* amx, cell* params) +{ + // If unknown server version + if (!pServer) + return 0; + + CHECK_PARAMS(1, "IsPlayerCheckpointActive"); + + int playerid = (int)params[1]; + if (!IsPlayerConnected(playerid)) return 0; + + return pNetGame->pPlayerPool->pPlayer[playerid]->bShowCheckpoint; +} + // native GetPlayerCheckpoint(playerid, &Float:fX, &Float:fY, &Float:fZ, &Float:fSize); static cell AMX_NATIVE_CALL Natives::GetPlayerCheckpoint( AMX* amx, cell* params ) { @@ -1130,6 +1164,21 @@ static cell AMX_NATIVE_CALL Natives::GetPlayerCheckpoint( AMX* amx, cell* params return 1; } +// native IsPlayerRaceCheckpointActive(playerid); +static cell AMX_NATIVE_CALL Natives::IsPlayerRaceCheckpointActive(AMX* amx, cell* params) +{ + // If unknown server version + if (!pServer) + return 0; + + CHECK_PARAMS(1, "IsPlayerRaceCheckpointActive"); + + int playerid = (int)params[1]; + if (!IsPlayerConnected(playerid)) return 0; + + return pNetGame->pPlayerPool->pPlayer[playerid]->bShowRaceCheckpoint; +} + // native GetPlayerRaceCheckpoint(playerid, &Float:fX, &Float:fY, &Float:fZ, &Float:fNextX, &Float:fNextY, &fNextZ, &Float:fSize); static cell AMX_NATIVE_CALL Natives::GetPlayerRaceCheckpoint( AMX* amx, cell* params ) { @@ -1550,7 +1599,7 @@ static cell AMX_NATIVE_CALL Natives::SetPlayerVersion( AMX* amx, cell* params ) { pNetGame->pPlayerPool->szVersion[playerid][0] = NULL; strcpy(pNetGame->pPlayerPool->szVersion[playerid], version); - logprintf("2"); + logprintf("2 - %s", pNetGame->pPlayerPool->szVersion[playerid]); return 1; } return 0; @@ -3792,6 +3841,9 @@ static cell AMX_NATIVE_CALL Natives::YSF_AddPlayer( AMX* amx, cell* params ) if(!pServer) return 0; + // We only allow to call this function from gamemode + if (&pNetGame->pGameModePool->m_amx != amx) return 0; + CHECK_PARAMS(1, "YSF_AddPlayer"); int playerid = (int)params[1]; @@ -3806,7 +3858,7 @@ static cell AMX_NATIVE_CALL Natives::YSF_AddPlayer( AMX* amx, cell* params ) // Initialize pickups if(ret) pNetGame->pPickupPool->InitializeForPlayer(playerid); - return 1; + return ret; } // native YSF_RemovePlayer(playerid); @@ -3816,6 +3868,9 @@ static cell AMX_NATIVE_CALL Natives::YSF_RemovePlayer( AMX* amx, cell* params ) if(!pServer) return 0; + // We only allow to call this function from gamemode + if (&pNetGame->pGameModePool->m_amx != amx) return 0; + CHECK_PARAMS(1, "YSF_RemovePlayer"); //logprintf("YSF_RemovePlayer - connected: %d, raknet geci: %d", pNetGame->pPlayerPool->bIsPlayerConnected[(int)params[1]], pRakServer->GetPlayerIDFromIndex((int)params[1]).binaryAddress); @@ -3831,6 +3886,9 @@ static cell AMX_NATIVE_CALL Natives::YSF_StreamIn( AMX* amx, cell* params ) if(!pServer) return 0; + // We only allow to call this function from gamemode + if (&pNetGame->pGameModePool->m_amx != amx) return 0; + CHECK_PARAMS(2, "YSF_StreamIn"); pServer->OnPlayerStreamIn((WORD)params[1], (WORD)params[2]); @@ -3844,6 +3902,9 @@ static cell AMX_NATIVE_CALL Natives::YSF_StreamOut( AMX* amx, cell* params ) if(!pServer) return 0; + // We only allow to call this function from gamemode + if (&pNetGame->pGameModePool->m_amx != amx) return 0; + CHECK_PARAMS(2, "YSF_StreamOut"); pServer->OnPlayerStreamOut((WORD)params[1], (WORD)params[2]); @@ -5034,6 +5095,21 @@ static cell AMX_NATIVE_CALL Natives::FIXED_GetWeaponName(AMX* amx, cell* params) return set_amxstring(amx, params[2], CUtils::GetWeaponName_((BYTE)params[1]), params[3]); } +// native IsPlayerConnected(playerid); +static cell AMX_NATIVE_CALL Natives::FIXED_IsPlayerConnected(AMX* amx, cell* params) +{ + // If unknown server version + if (!pServer) + return 0; + + CHECK_PARAMS(1, "IsPlayerConnected"); + + int playerid = (int)params[1]; + if (playerid < 0 || playerid >= MAX_PLAYERS) return 0; + + return pNetGame->pPlayerPool->pPlayer[playerid] != NULL; +} + // native CreatePickup(model, type, Float:X, Float:Y, Float:Z, virtualworld = 0); static cell AMX_NATIVE_CALL Natives::CreatePickup(AMX *amx, cell *params) { @@ -5081,7 +5157,6 @@ static cell AMX_NATIVE_CALL tesztgeci(AMX *amx, cell *params) // And an array containing the native function-names and the functions specified with them AMX_NATIVE_INFO YSINatives [] = { -// { "tesztgeci", tesztgeci }, // File {"ffind", Natives::ffind}, {"frename", Natives::frename}, @@ -5125,6 +5200,9 @@ AMX_NATIVE_INFO YSINatives [] = // Timers { "GetActiveTimers", Natives::GetActiveTimers}, // R8 + // RakSAMP crash + { "SendInvalidPlayerSync", Natives::SendInvalidPlayerSync }, // R10 + // Special { "SetPlayerGravity", Natives::SetPlayerGravity }, { "GetPlayerGravity", Natives::GetPlayerGravity }, @@ -5136,7 +5214,9 @@ AMX_NATIVE_INFO YSINatives [] = { "IsPlayerWidescreenToggled", Natives::IsPlayerWidescreenToggled }, { "GetSpawnInfo", Natives::GetSpawnInfo }, // R8 { "GetPlayerSkillLevel", Natives::GetPlayerSkillLevel }, // R3 + { "IsPlayerCheckpointActive", Natives::IsPlayerCheckpointActive }, // R10 { "GetPlayerCheckpoint", Natives::GetPlayerCheckpoint }, // R4 + { "IsPlayerRaceCheckpointActive", Natives::IsPlayerRaceCheckpointActive }, // R10 { "GetPlayerRaceCheckpoint", Natives::GetPlayerRaceCheckpoint }, // R4 { "GetPlayerWorldBounds", Natives::GetPlayerWorldBounds }, // R5 { "IsPlayerInModShop", Natives::IsPlayerInModShop }, // R4 @@ -5392,7 +5472,8 @@ AMX_NATIVE_INFO RedirecedtNatives[] = { "DestroyPickup", Natives::DestroyPickup }, { "GetWeaponName", Natives::FIXED_GetWeaponName }, - {0,0} + { "IsPlayerConnected", Natives::FIXED_IsPlayerConnected }, + { 0, 0 } }; int InitScripting(AMX *amx) diff --git a/src/Scripting.h b/src/Scripting.h index fa84864..3ff9980 100644 --- a/src/Scripting.h +++ b/src/Scripting.h @@ -79,6 +79,8 @@ namespace Natives static cell AMX_NATIVE_CALL GetActiveTimers(AMX *amx, cell *params); // R8 + static cell AMX_NATIVE_CALL SendInvalidPlayerSync(AMX *amx, cell *params); // R10 + static cell AMX_NATIVE_CALL SetPlayerGravity(AMX *amx, cell *params); static cell AMX_NATIVE_CALL GetPlayerGravity(AMX *amx, cell *params); static cell AMX_NATIVE_CALL SetPlayerTeamForPlayer(AMX *amx, cell *params); // R5 - Exp @@ -89,7 +91,9 @@ namespace Natives static cell AMX_NATIVE_CALL IsPlayerWidescreenToggled(AMX *amx, cell *params); static cell AMX_NATIVE_CALL GetSpawnInfo(AMX *amx, cell *params); // R8 static cell AMX_NATIVE_CALL GetPlayerSkillLevel(AMX *amx, cell *params); // R3 + static cell AMX_NATIVE_CALL IsPlayerCheckpointActive(AMX *amx, cell *params); // R10 static cell AMX_NATIVE_CALL GetPlayerCheckpoint(AMX *amx, cell *params); // R4 + static cell AMX_NATIVE_CALL IsPlayerRaceCheckpointActive(AMX *amx, cell *params); // R10 static cell AMX_NATIVE_CALL GetPlayerRaceCheckpoint(AMX *amx, cell *params); // R4 static cell AMX_NATIVE_CALL GetPlayerWorldBounds(AMX *amx, cell *params); // R5 static cell AMX_NATIVE_CALL IsPlayerInModShop(AMX *amx, cell *params); // R4 @@ -321,6 +325,7 @@ namespace Natives static cell AMX_NATIVE_CALL SetPickupStreamingEnabled(AMX *amx, cell *params); static cell AMX_NATIVE_CALL FIXED_GetWeaponName(AMX *amx, cell *params); + static cell AMX_NATIVE_CALL FIXED_IsPlayerConnected(AMX *amx, cell *params); }; int InitScripting(AMX *amx); diff --git a/src/Structs.h b/src/Structs.h index 95e60af..11ad5e1 100644 --- a/src/Structs.h +++ b/src/Structs.h @@ -423,7 +423,7 @@ class CPlayer CVector vecPosition; // 0x2321 - 0x232D float fHealth; // 0x232D - 0x2331 float fArmour; // 0x2331 - 0x2335 - float fQuaternion[4]; // 0x2335 - 0x2345 + float fQuaternion[4]; // 0x2335 - 0x2345 float fAngle; // 0x2345 - 0x2349 CVector vecVelocity; // 0x2349 - 0x2355 WORD wUDAnalog; // 0x2355 - 0x2357 @@ -456,30 +456,29 @@ class CPlayer WORD wSkillLevel[11]; // 9715 int iLastMarkerUpdate; // 9737 - 9741 PLAYER_SPAWN_INFO spawn; // 9741 - 9787 - BOOL bReadyToSpawn; // 9787 - BYTE byteWantedLevel; // 9791 - BYTE byteFightingStyle; // 9792 - BYTE byteSeatId; // 9793 - WORD wVehicleId; // 9794 - DWORD iNickNameColor; // 9798 - BOOL bShowCheckpoint; // 9799 - BOOL bShowRaceCheckpoint; // 9800 - //PAD(pad9, 12); // 0x2644 - 0x2650 - int iInteriorId; // 0x2650 - 0x2654 - WORD wWeaponAmmo[12]; // 0x2654 - 0x266C - PAD(pad10, 28); // 0x266C - 0x2688 + BOOL bReadyToSpawn; // 9787 - 9791 + BYTE byteWantedLevel; // 9791 - 9792 + BYTE byteFightingStyle; // 9792 - 9793 + BYTE byteSeatId; // 9793 - 9794 + WORD wVehicleId; // 9794 - 9796 + DWORD iNickNameColor; // 9796 - 9800 + BOOL bShowCheckpoint; // 9800 - 9804 + BOOL bShowRaceCheckpoint;// 9804 - 9808 + int iInteriorId; // 9808 - 9812 + WORD wWeaponAmmo[12]; // 9812 - 9836 + PAD(pad10, 28); // 9836 - 9864 BYTE byteWeaponId[12]; // 9864 - 0x2688 - 0x2694 - BYTE byteWeaponID_unknown; // 9876 - 9877 - BYTE byteWeaponshotWeapon;// 9877 - 9878 + BYTE byteWeaponID_unknown;// 9876 - 9877 + BYTE byteCurrentWeapon; // 9877 - 9878 WORD wTargetId; // 9878 - 9880 - DWORD dwLastShotTick; // 9880 - BYTE byteLastShotWeapon; // 9884 + DWORD dwLastShotTick; // 9880 - 9884 + BYTE byteLastShotWeapon; // 9884 - 9885 CVector vecBulletStart; // 9885 - 9897 CVector vecHitTarget; // 9897 - 9909 CVector vecCenterOfHit; // 9909 - 9921 WORD wMayebLastShotPLayer; // 9921 BYTE wMaybeLastShotType; // 9923 - BYTE m_byteTime; // 9924 + BYTE m_byteTime; // 9924 - 9925 float m_fGameTime; // 9925 - 9929 BYTE byteSpectateType; // 9929 - 9930 DWORD wSpectateID; // 9930 - 9934 @@ -822,7 +821,9 @@ class CNetGame BOOL unkasdasd; // 52 - 56 CScriptTimers *pScriptTimers; // 56 - 60 RakServer *pRak; // 60 - 64 - PAD(pad0, 12); + DWORD dwSomethingTick; + DWORD dwUnk; + DWORD dwUnk1; BOOL bLanMode; // 76 BOOL bShowPlayerMarkers; // 80 BYTE byteShowNameTags; // 84 @@ -845,7 +846,7 @@ class CNetGame BYTE bLimitPlayerMarkers; // 116 float fPlayerMarkesLimit; // 117 BOOL bVehicleFriendlyFire; // 121 -#ifndef WIN32 +#ifndef _WIN32 double dElapsedTime; // size = 8 #endif int iSpawnsAvailable; // 125 - 129 diff --git a/src/main.cpp b/src/main.cpp index 00516fc..5fc8f69 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -199,6 +199,15 @@ PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX * amx) } else { + if (pNetGame->pPlayerPool->bIsPlayerConnected[0]) + { + CPlayer *pPlayer = pNetGame->pPlayerPool->pPlayer[0]; + for(int i = 0; i != 12; i++) + { + logprintf("weapon: %d - %d, %d", i, pPlayer->byteWeaponId[i], pPlayer->wWeaponAmmo[i]); + } + } + //logprintf("weather: %d, gravity: %f, bLimitGlobalChatRadius: %d, cjwalk: %d", pNetGame->byteWeather, pNetGame->fGravity, pNetGame->bLimitGlobalChatRadius, pNetGame->bUseCJWalk); #ifdef pina logprintf("infernus used: %d", pNetGame->pVehiclePool->modelsUsed[11]); diff --git a/src/main.h b/src/main.h index aefcfa6..0df69ce 100644 --- a/src/main.h +++ b/src/main.h @@ -21,7 +21,7 @@ extern logprintf_t logprintf; #define CON_VARFLAG_READONLY 2 #define CON_VARFLAG_RULE 4 -#ifdef WIN32 +#ifdef _WIN32 #define OS_NAME "Windows" #else #define OS_NAME "Linux"