diff --git a/managed/src/SwiftlyS2.Core/Modules/Menus/MenuManagerAPI.cs b/managed/src/SwiftlyS2.Core/Modules/Menus/MenuManagerAPI.cs index 1e61e5006..85f95a964 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Menus/MenuManagerAPI.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Menus/MenuManagerAPI.cs @@ -145,7 +145,7 @@ private void KeyStateChange( IOnClientKeyStateChangedEvent @event ) if (menu.Configuration.PlaySound) { scrollSound.Recipients.AddRecipient(@event.PlayerId); - scrollSound.Emit(); + _ = scrollSound.Emit(); scrollSound.Recipients.RemoveRecipient(@event.PlayerId); } } @@ -156,18 +156,18 @@ private void KeyStateChange( IOnClientKeyStateChangedEvent @event ) if (menu.Configuration.PlaySound) { scrollSound.Recipients.AddRecipient(@event.PlayerId); - scrollSound.Emit(); + _ = scrollSound.Emit(); scrollSound.Recipients.RemoveRecipient(@event.PlayerId); } } else if (exitKey.HasFlag(@event.Key.ToKeyBind())) { - CloseMenuForPlayer(player, menu); + CloseMenuForPlayerInternal(player, menu, true); if (menu.Configuration.PlaySound) { exitSound.Recipients.AddRecipient(@event.PlayerId); - exitSound.Emit(); + _ = exitSound.Emit(); exitSound.Recipients.RemoveRecipient(@event.PlayerId); } } @@ -181,7 +181,7 @@ private void KeyStateChange( IOnClientKeyStateChangedEvent @event ) if (menu.Configuration.PlaySound && option.PlaySound) { useSound.Recipients.AddRecipient(@event.PlayerId); - useSound.Emit(); + _ = useSound.Emit(); useSound.Recipients.RemoveRecipient(@event.PlayerId); } } @@ -196,7 +196,7 @@ private void KeyStateChange( IOnClientKeyStateChangedEvent @event ) if (menu.Configuration.PlaySound) { scrollSound.Recipients.AddRecipient(@event.PlayerId); - scrollSound.Emit(); + _ = scrollSound.Emit(); scrollSound.Recipients.RemoveRecipient(@event.PlayerId); } } @@ -207,17 +207,17 @@ private void KeyStateChange( IOnClientKeyStateChangedEvent @event ) if (menu.Configuration.PlaySound) { scrollSound.Recipients.AddRecipient(@event.PlayerId); - scrollSound.Emit(); + _ = scrollSound.Emit(); scrollSound.Recipients.RemoveRecipient(@event.PlayerId); } } else if (KeyBind.A.HasFlag(@event.Key.ToKeyBind())) { - CloseMenuForPlayer(player, menu); + CloseMenuForPlayerInternal(player, menu, true); if (menu.Configuration.PlaySound) { exitSound.Recipients.AddRecipient(@event.PlayerId); - exitSound.Emit(); + _ = exitSound.Emit(); exitSound.Recipients.RemoveRecipient(@event.PlayerId); } } @@ -231,7 +231,7 @@ private void KeyStateChange( IOnClientKeyStateChangedEvent @event ) if (menu.Configuration.PlaySound && option.PlaySound) { useSound.Recipients.AddRecipient(@event.PlayerId); - useSound.Emit(); + _ = useSound.Emit(); useSound.Recipients.RemoveRecipient(@event.PlayerId); } } @@ -247,7 +247,7 @@ private void OnClientDisconnected( IOnClientDisconnectedEvent @event ) openMenus .Where(kvp => kvp.Key == player) .ToList() - .ForEach(kvp => CloseMenuForPlayer(player, kvp.Value)); + .ForEach(kvp => CloseMenuForPlayerInternal(player, kvp.Value, true)); } } @@ -322,7 +322,7 @@ public void OpenMenuForPlayer( IPlayer player, IMenuAPI menu ) if (menu.Parent.ParentMenu == currentMenu) { // We are transitioning from the current menu to one of its submenus. - // To show the submenu, we first need to close the current (parent) menu, see CloseMenuForPlayer. + // To show the submenu, we first need to close the current (parent) menu. // The parent menu may have an onClosed callback registered in onClosedCallbacks. // If we do not remove that callback temporarily, closing the parent menu here // would incorrectly invoke the callback even though the user is only navigating @@ -333,12 +333,12 @@ public void OpenMenuForPlayer( IPlayer player, IMenuAPI menu ) // 3. Re-register the callback so it will only be invoked later, when the // logical end of the menu flow is reached and the menu is truly closed. _ = onClosedCallbacks.TryRemove((player, currentMenu), out var callback); - CloseMenuForPlayer(player, currentMenu); + CloseMenuForPlayerInternal(player, currentMenu, false); _ = onClosedCallbacks.AddOrUpdate((player, currentMenu), callback, ( _, _ ) => callback); } else { - CloseMenuForPlayer(player, currentMenu); + CloseMenuForPlayerInternal(player, currentMenu, false); } } @@ -358,15 +358,36 @@ public void CloseMenu( IMenuAPI menu ) Core.PlayerManager .GetAllPlayers() .ToList() - .ForEach(player => CloseMenuForPlayer(player, menu)); + .ForEach(player => CloseMenuForPlayerInternal(player, menu, true)); } public void CloseMenuForPlayer( IPlayer player, IMenuAPI menu ) + { + CloseMenuForPlayerInternal(player, menu, true); + } + + public void CloseAllMenus() + { + openMenus.ToList().ForEach(kvp => + { + var currentMenu = kvp.Value; + while (currentMenu != null) + { + currentMenu.HideForPlayer(kvp.Key); + MenuClosed?.Invoke(this, new MenuManagerEventArgs { Player = kvp.Key, Menu = currentMenu }); + currentMenu = currentMenu.Parent.ParentMenu; + } + _ = openMenus.TryRemove(kvp.Key, out _); + }); + } + + private void CloseMenuForPlayerInternal( IPlayer player, IMenuAPI menu, bool reopenParent ) { if (!openMenus.TryGetValue(player, out var currentMenu) || currentMenu != menu) { return; } + if (onClosedCallbacks.TryRemove((player, menu), out var onClosed) && onClosed != null) { onClosed(player, menu); @@ -377,25 +398,10 @@ public void CloseMenuForPlayer( IPlayer player, IMenuAPI menu ) menu.HideForPlayer(player); MenuClosed?.Invoke(this, new MenuManagerEventArgs { Player = player, Menu = menu }); - if (menu.Parent.ParentMenu != null) + if (reopenParent && menu.Parent.ParentMenu != null) { OpenMenuForPlayer(player, menu.Parent.ParentMenu); } } } - - public void CloseAllMenus() - { - openMenus.ToList().ForEach(kvp => - { - var currentMenu = kvp.Value; - while (currentMenu != null) - { - currentMenu.HideForPlayer(kvp.Key); - MenuClosed?.Invoke(this, new MenuManagerEventArgs { Player = kvp.Key, Menu = currentMenu }); - currentMenu = currentMenu.Parent.ParentMenu; - } - _ = openMenus.TryRemove(kvp.Key, out _); - }); - } } \ No newline at end of file diff --git a/managed/src/SwiftlyS2.Core/Natives/GameFunctions.cs b/managed/src/SwiftlyS2.Core/Natives/GameFunctions.cs index 8332a0fab..e4e185100 100644 --- a/managed/src/SwiftlyS2.Core/Natives/GameFunctions.cs +++ b/managed/src/SwiftlyS2.Core/Natives/GameFunctions.cs @@ -2,12 +2,12 @@ using System.Text; using Spectre.Console; using SwiftlyS2.Shared.Natives; -using SwiftlyS2.Shared.SchemaDefinitions; namespace SwiftlyS2.Core.Natives; internal static class GameFunctions { + private static readonly bool IsWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows); public static unsafe delegate* unmanaged< CTakeDamageInfo*, nint, nint, nint, Vector*, Vector*, float, int, int, void*, void > pCTakeDamageInfo_Constructor; public static unsafe delegate* unmanaged< nint, Ray_t*, Vector, Vector, CTraceFilter*, CGameTrace*, void > pTraceShape; public static unsafe delegate* unmanaged< Vector, Vector, BBox_t, CTraceFilter*, CGameTrace*, void > pTracePlayerBBox; @@ -16,7 +16,8 @@ internal static class GameFunctions public static unsafe delegate* unmanaged< nint, nint, float, void > pSetOrAddAttribute; public static unsafe delegate* unmanaged< int, nint, nint > pGetWeaponCSDataFromKey; public static unsafe delegate* unmanaged< nint, uint, nint, byte, CUtlSymbolLarge, byte, int, nint, nint, void > pDispatchParticleEffect; - public static unsafe delegate* unmanaged< nint, uint, float, nint, byte, void > pTerminateRound; + public static unsafe delegate* unmanaged< nint, uint, float, nint, byte, void > pTerminateRoundLinux; + public static unsafe delegate* unmanaged< nint, float, uint, nint, byte, void > pTerminateRoundWindows; public static unsafe delegate* unmanaged< nint, Vector*, QAngle*, Vector*, void > pTeleport; public static int TeleportOffset => NativeOffsets.Fetch("CBaseEntity::Teleport"); public static int CommitSuicideOffset => NativeOffsets.Fetch("CBasePlayerPawn::CommitSuicide"); @@ -43,7 +44,14 @@ public static void Initialize() pSetOrAddAttribute = (delegate* unmanaged< nint, IntPtr, float, void >)NativeSignatures.Fetch("CAttributeList::SetOrAddAttributeValueByName"); pGetWeaponCSDataFromKey = (delegate* unmanaged< int, nint, nint >)NativeSignatures.Fetch("GetWeaponCSDataFromKey"); pDispatchParticleEffect = (delegate* unmanaged< nint, uint, nint, byte, CUtlSymbolLarge, byte, int, nint, nint, void >)NativeSignatures.Fetch("DispatchParticleEffect"); - pTerminateRound = (delegate* unmanaged< nint, uint, float, nint, byte, void >)NativeSignatures.Fetch("CGameRules::TerminateRound"); + if (IsWindows) + { + pTerminateRoundWindows = (delegate* unmanaged< nint, float, uint, nint, byte, void >)NativeSignatures.Fetch("CGameRules::TerminateRound"); + } + else + { + pTerminateRoundLinux = (delegate* unmanaged< nint, uint, float, nint, byte, void >)NativeSignatures.Fetch("CGameRules::TerminateRound"); + } pTeleport = (delegate* unmanaged< nint, Vector*, QAngle*, Vector*, void >)((void**)NativeMemoryHelpers.GetVirtualTableAddress("server", "CBaseEntity"))[TeleportOffset]; } } @@ -60,7 +68,14 @@ public static void TerminateRound( nint gameRules, uint reason, float delay ) { unsafe { - pTerminateRound(gameRules, reason, delay, 0, 0); + if (IsWindows) + { + pTerminateRoundWindows(gameRules, delay, reason, 0, 0); + } + else + { + pTerminateRoundLinux(gameRules, reason, delay, 0, 0); + } } } catch (Exception e) diff --git a/managed/src/TestPlugin/TestPlugin.cs b/managed/src/TestPlugin/TestPlugin.cs index d29722c08..a80b93994 100644 --- a/managed/src/TestPlugin/TestPlugin.cs +++ b/managed/src/TestPlugin/TestPlugin.cs @@ -36,6 +36,7 @@ using System.Collections.Concurrent; using Dia2Lib; using System.Reflection.Metadata; +using Microsoft.Diagnostics.Tracing.Parsers.MicrosoftWindowsTCPIP; namespace TestPlugin; @@ -620,6 +621,12 @@ public void GetIpCommand( ICommandContext context ) // Core.Menus.OpenMenu(player, settingsMenu); // } + [Command("ed")] + public void EndRoundCommand( ICommandContext _ ) + { + var gameRules = Core.EntitySystem.GetGameRules()!; + gameRules.TerminateRound(RoundEndReason.CTsWin, 10.0f); + } [Command("tm")] public void TestMenuCommand( ICommandContext context ) @@ -645,16 +652,42 @@ public void TestMenuCommand( ICommandContext context ) .AddOption(new ButtonMenuOption("Cancel") { CloseAfterClick = true }) .Build(); - var menu = Core.MenusAPI + var shopMenu = Core.MenusAPI .CreateBuilder() .Design.SetMenuTitle("Shop Menu") - .AddOption(new SubmenuMenuOption("Item 1", confirmMenu)) - .AddOption(new SubmenuMenuOption("Item 2", confirmMenu)) - .AddOption(new SubmenuMenuOption("Item 3", confirmMenu)) - .AddOption(new SubmenuMenuOption("Item 4", confirmMenu)) + .AddOption(new SubmenuMenuOption("Item 1", async () => + { + await Task.Delay(100); + return confirmMenu; + })) + .AddOption(new SubmenuMenuOption("Item 2", async () => + { + await Task.Delay(100); + return confirmMenu; + })) + .AddOption(new SubmenuMenuOption("Item 3", async () => + { + await Task.Delay(100); + return confirmMenu; + })) + .AddOption(new SubmenuMenuOption("Item 4", async () => + { + await Task.Delay(100); + return confirmMenu; + })) + .Build(); + + var mainMenu = Core.MenusAPI + .CreateBuilder() + .Design.SetMenuTitle("Menu") + .AddOption(new SubmenuMenuOption("Shop", async () => + { + await Task.Delay(100); + return shopMenu; + })) .Build(); - Core.MenusAPI.OpenMenu(menu, ( player, menu ) => + Core.MenusAPI.OpenMenu(mainMenu, ( player, menu ) => { Console.WriteLine($"{menu.Configuration.Title} closed for player: {player.Controller.PlayerName}"); }); diff --git a/src/server/players/manager.cpp b/src/server/players/manager.cpp index f88c4b68d..8a6f8061e 100644 --- a/src/server/players/manager.cpp +++ b/src/server/players/manager.cpp @@ -210,8 +210,14 @@ void CheckTransmitHook(void* _this, CCheckTransmitInfo** ppInfoList, int infoCou auto& pInfo = ppInfoList[i]; int playerid = pInfo->m_nPlayerSlot.Get(); if (!playermanager->IsPlayerOnline(playerid)) + { continue; + } auto player = playermanager->GetPlayer(playerid); + if (!player) + { + continue; + } auto& blockedBits = player->GetBlockedTransmittingBits(); @@ -275,12 +281,21 @@ bool ClientConnectHook(void* _this, CPlayerSlot slot, const char* pszName, uint6 static auto playermanager = g_ifaceService.FetchInterface(PLAYERMANAGER_INTERFACE_VERSION); auto playerid = slot.Get(); auto player = playermanager->RegisterPlayer(playerid); - player->Initialize(playerid); + // player->Initialize(playerid); + if (!player) + { + return false; + } + player->SetUnauthorizedSteamID(xuid); if (g_pOnClientConnectCallback) + { if (reinterpret_cast(g_pOnClientConnectCallback)(playerid) == false) + { return false; + } + } return reinterpret_cast(g_pClientConnectHook->GetOriginal())(_this, slot, pszName, xuid, pszNetworkID, unk1, pRejectReason); } @@ -291,8 +306,8 @@ void OnClientConnectedHook(void* _this, CPlayerSlot slot, const char* pszName, u auto playerid = slot.Get(); if (bFakePlayer) { - auto player = playermanager->RegisterPlayer(playerid); - player->Initialize(playerid); + playermanager->RegisterPlayer(playerid); + // player->Initialize(playerid); } else { @@ -326,10 +341,11 @@ IPlayer* CPlayerManager::RegisterPlayer(int playerid) if (g_Players[playerid] != nullptr) UnregisterPlayer(playerid); - g_Players[playerid] = new CPlayer(); - g_Players[playerid]->Initialize(playerid); + auto player = new CPlayer(); + player->Initialize(playerid); + g_Players[playerid] = player; - return g_Players[playerid]; + return player; } void CPlayerManager::UnregisterPlayer(int playerid) @@ -341,11 +357,13 @@ void CPlayerManager::UnregisterPlayer(int playerid) static auto vgui = g_ifaceService.FetchInterface(VGUI_INTERFACE_VERSION); - vgui->UnregisterForPlayer(g_Players[playerid]); - - g_Players[playerid]->Shutdown(); - delete g_Players[playerid]; + auto player = g_Players[playerid]; g_Players[playerid] = nullptr; + + vgui->UnregisterForPlayer(player); + + player->Shutdown(); + delete player; } IPlayer* CPlayerManager::GetPlayer(int playerid) diff --git a/src/server/players/player.cpp b/src/server/players/player.cpp index 80361cbfc..e3928fe87 100644 --- a/src/server/players/player.cpp +++ b/src/server/players/player.cpp @@ -18,19 +18,19 @@ #include "player.h" -#include #include +#include -#include #include +#include -#include #include +#include #include "usermessages.pb.h" #define CBaseEntity_m_iTeamNum 0x9DC483B8A5BFEFB3 -#define CBaseEntity_m_fFlags 0x9DC483B8A4A37590 +#define CBaseEntity_m_fFlags 0x9DC483B8A4A37590 #define CBasePlayerController_m_hPawn 0x3979FF6E7C628C1D #define CCSPlayerController_m_hPlayerPawn 0x28ECD7A1D6C93E7C @@ -119,7 +119,8 @@ void CPlayer::Shutdown() m_iPlayerId = -1; m_bAuthorized = false; - if (centerMessageEvent) { + if (centerMessageEvent) + { static auto eventmanager = g_ifaceService.FetchInterface(GAMEEVENTMANAGER_INTERFACE_VERSION); eventmanager->GetGameEventManager()->FreeEvent(centerMessageEvent); centerMessageEvent = nullptr; @@ -130,39 +131,55 @@ extern INetworkMessages* networkMessages; void CPlayer::SendMsg(MessageType type, const std::string& message, int duration = 5000) { - if (IsFakeClient()) return; + if (IsFakeClient()) + return; - if (type == MessageType::CenterHTML) { - if (message == "") centerMessageEndTime = 0; - else { + if (type == MessageType::CenterHTML) + { + if (message == "") + centerMessageEndTime = 0; + else + { centerMessageEndTime = GetTime() + duration; centerMessageText = message; } } - else if (type == MessageType::Console) { - if (message.size() == 0) return; + else if (type == MessageType::Console) + { + if (message.size() == 0) + return; auto msg = ClearColors(message); auto engine = g_ifaceService.FetchInterface(INTERFACEVERSION_VENGINESERVER); + if (!engine) + return; engine->ClientPrintf(CPlayerSlot(m_iPlayerId), msg.c_str()); } - else { + else + { auto msg = RemoveHtmlTags(message); - if (msg.size() > 0) { - if (msg.ends_with("\n")) msg.pop_back(); + if (msg.size() > 0) + { + if (msg.ends_with("\n")) + msg.pop_back(); msg += "\x01"; bool startsWithColor = (msg.at(0) == '['); auto schema = g_ifaceService.FetchInterface(SDKSCHEMA_INTERFACE_VERSION); + if (!schema) + return; msg = ProcessColor(message, *(int*)(schema->GetPropPtr(GetController(), CBaseEntity_m_iTeamNum))); - if (startsWithColor) msg = " " + msg; + if (startsWithColor) + msg = " " + msg; } auto gameEventSystem = g_ifaceService.FetchInterface(GAMEEVENTSYSTEM_INTERFACE_VERSION); + if (!gameEventSystem) + return; auto netmsg = networkMessages->FindNetworkMessagePartial("TextMsg"); auto pmsg = netmsg->AllocateMessage()->ToPB(); @@ -186,10 +203,15 @@ bool CPlayer::IsAuthorized() bool CPlayer::IsFakeClient() { auto schema = g_ifaceService.FetchInterface(SDKSCHEMA_INTERFACE_VERSION); - if (!GetController()) return true; + if (!schema) + return true; + + if (!GetController()) + return true; uint32_t* flagsPtr = (uint32_t*)schema->GetPropPtr(GetController(), CBaseEntity_m_fFlags); - if (flagsPtr == nullptr) return true; + if (flagsPtr == nullptr) + return true; return (*flagsPtr & Flags_t::FL_FAKECLIENT); } @@ -211,12 +233,16 @@ void CPlayer::SetUnauthorizedSteamID(uint64_t steamID) uint64_t CPlayer::GetUnauthorizedSteamID() { - if (IsFakeClient()) return 0; + if (IsFakeClient()) + return 0; auto engine = g_ifaceService.FetchInterface(INTERFACEVERSION_VENGINESERVER); + if (!engine) + return m_uUnauthorizedSteamID; auto steamid = engine->GetClientSteamID(m_iPlayerId); - if (!steamid) return m_uUnauthorizedSteamID; + if (!steamid) + return m_uUnauthorizedSteamID; return steamid->ConvertToUint64(); } @@ -224,21 +250,30 @@ uint64_t CPlayer::GetUnauthorizedSteamID() uint64_t CPlayer::GetSteamID() { auto config = g_ifaceService.FetchInterface(CONFIGURATION_INTERFACE_VERSION); + if (!config) + return 0; auto s = std::get_if(&config->GetValue("core.SteamAuth.Mode")); - if (m_bAuthorized) { - if (IsFakeClient()) return 0; + if (m_bAuthorized) + { + if (IsFakeClient()) + return 0; auto engine = g_ifaceService.FetchInterface(INTERFACEVERSION_VENGINESERVER); + if (!engine) + return 0; auto steamid = engine->GetClientSteamID(m_iPlayerId); - if (!steamid) return 0; + if (!steamid) + return 0; return steamid->ConvertToUint64(); } - else if (*s == "flexible") { + else if (*s == "flexible") + { return GetUnauthorizedSteamID(); } - else return 0; + else + return 0; } extern void* g_pOnClientSteamAuthorizeCallback; @@ -248,13 +283,15 @@ void CPlayer::ChangeAuthorizationState(bool bAuthorized) { m_bAuthorized = bAuthorized; - if (bAuthorized) { + if (bAuthorized) + { if (g_pOnClientSteamAuthorizeCallback) - reinterpret_cast(g_pOnClientSteamAuthorizeCallback)(m_iPlayerId); + reinterpret_cast(g_pOnClientSteamAuthorizeCallback)(m_iPlayerId); } - else { + else + { if (g_pOnClientSteamAuthorizeFailCallback) - reinterpret_cast(g_pOnClientSteamAuthorizeFailCallback)(m_iPlayerId); + reinterpret_cast(g_pOnClientSteamAuthorizeFailCallback)(m_iPlayerId); } } @@ -266,18 +303,26 @@ std::string& CPlayer::GetLanguage() void* CPlayer::GetController() { static auto entsystem = g_ifaceService.FetchInterface(ENTITYSYSTEM_INTERFACE_VERSION); - CEntityInstance* controller = entsystem->GetEntitySystem()->GetEntityInstance(CEntityIndex(m_iPlayerId + 1)); + + auto entitySystem = entsystem->GetEntitySystem(); + if (!entitySystem) + return nullptr; + + CEntityInstance* controller = entitySystem->GetEntityInstance(CEntityIndex(m_iPlayerId + 1)); return controller; } void* CPlayer::GetPawn() { static auto schema = g_ifaceService.FetchInterface(SDKSCHEMA_INTERFACE_VERSION); + auto controller = GetController(); - if (!controller) return nullptr; + if (!controller) + return nullptr; auto pawn = schema->GetPropPtr(controller, CBasePlayerController_m_hPawn); - if (!pawn) return nullptr; + if (!pawn) + return nullptr; CHandle& pawnHandle = *(CHandle*)pawn; return pawnHandle.Get(); @@ -286,11 +331,14 @@ void* CPlayer::GetPawn() void* CPlayer::GetPlayerPawn() { static auto schema = g_ifaceService.FetchInterface(SDKSCHEMA_INTERFACE_VERSION); + auto controller = GetController(); - if (!controller) return nullptr; + if (!controller) + return nullptr; auto playerPawn = schema->GetPropPtr(controller, CCSPlayerController_m_hPlayerPawn); - if (!playerPawn) return nullptr; + if (!playerPawn) + return nullptr; CHandle& playerPawnHandle = *(CHandle*)playerPawn; return playerPawnHandle.Get(); @@ -319,13 +367,19 @@ uint64_t& CPlayer::GetPressedButtons() void CPlayer::PerformCommand(const std::string& command) { auto engine = g_ifaceService.FetchInterface(INTERFACEVERSION_VENGINESERVER); + if (!engine) + return; engine->ClientCommand(CPlayerSlot(m_iPlayerId), command.c_str()); } std::string CPlayer::GetIPAddress() { auto engine = g_ifaceService.FetchInterface(INTERFACEVERSION_VENGINESERVER); + if (!engine) + return ""; auto pNetChan = engine->GetPlayerNetInfo(m_iPlayerId); + if (!pNetChan) + return ""; return explode(pNetChan->GetAddress(), ":")[0]; } @@ -333,6 +387,8 @@ std::string CPlayer::GetIPAddress() void CPlayer::Kick(const std::string& sReason, int uReason) { auto engine = g_ifaceService.FetchInterface(INTERFACEVERSION_VENGINESERVER); + if (!engine) + return; engine->DisconnectClient(m_iPlayerId, uReason, sReason.c_str()); } @@ -348,33 +404,37 @@ void CPlayer::Think() { static auto gamedata = g_ifaceService.FetchInterface(GAMEDATA_INTERFACE_VERSION); static auto eventmanager = g_ifaceService.FetchInterface(GAMEEVENTMANAGER_INTERFACE_VERSION); - static auto pListenerSig = gamedata->GetSignatures()->Fetch("LegacyGameEventListener"); if (pListenerSig) { auto listener = reinterpret_cast(pListenerSig)(m_iPlayerId); if (listener) { - if (!centerMessageEvent) centerMessageEvent = eventmanager->GetGameEventManager()->CreateEvent("show_survival_respawn_status"); + if (!centerMessageEvent) + centerMessageEvent = eventmanager->GetGameEventManager()->CreateEvent("show_survival_respawn_status"); if (centerMessageEvent) { - if (centerMenuText != "") { + if (centerMenuText != "") + { centerMessageEvent->SetString("loc_token", centerMenuText.c_str()); centerMessageEvent->SetInt("duration", 1); centerMessageEvent->SetInt("userid", m_iPlayerId); listener->FireGameEvent(centerMessageEvent); } - else { - if (centerMessageEndTime >= GetTime()) { + else + { + if (centerMessageEndTime >= GetTime()) + { centerMessageEvent->SetString("loc_token", centerMessageText.c_str()); centerMessageEvent->SetInt("duration", 1); centerMessageEvent->SetInt("userid", m_iPlayerId); listener->FireGameEvent(centerMessageEvent); } - else { + else + { centerMessageEndTime = 0; } } @@ -401,13 +461,15 @@ void CPlayer::Think() { for (int i = 0; i < 64; i++) { - if ((m_uPressedButtons & (1ULL << i)) == 0 && (newButtons & (1ULL << i)) != 0) { + if ((m_uPressedButtons & (1ULL << i)) == 0 && (newButtons & (1ULL << i)) != 0) + { if (g_pOnClientKeyStateChangedCallback) - reinterpret_cast(g_pOnClientKeyStateChangedCallback)(m_iPlayerId, i, true); + reinterpret_cast(g_pOnClientKeyStateChangedCallback)(m_iPlayerId, i, true); } - else if ((m_uPressedButtons & (1ULL << i)) != 0 && (newButtons & (1ULL << i)) == 0) { + else if ((m_uPressedButtons & (1ULL << i)) != 0 && (newButtons & (1ULL << i)) == 0) + { if (g_pOnClientKeyStateChangedCallback) - reinterpret_cast(g_pOnClientKeyStateChangedCallback)(m_iPlayerId, i, false); + reinterpret_cast(g_pOnClientKeyStateChangedCallback)(m_iPlayerId, i, false); } } @@ -417,12 +479,12 @@ void CPlayer::Think() } auto& observerServices = *(void**)sdkschema->GetPropPtr(pawn, 14568842447348147577); // CBasePlayerPawn::m_pObserverServices - if (observerServices) { + if (observerServices) + { CHandle& observerTarget = *(CHandle*)sdkschema->GetPropPtr(observerServices, 1590106406667131980); // CPlayer_ObserverServices::m_hObserverTarget vgui->CheckRenderForPlayer(this, observerTarget); } } - } void CPlayer::RenderMenuCenterText(const std::string& text)