Add A2S_Rules fix for CS:GO to CStrike extension. (#614)
* Add A2S_Rules fix for CS:GO to CStrike extension. * Dont force set the cvar. Add checks before patching. * Remove incorrect and useless check. * Remove checking value as it is in the signature. * Update build script changes to AMBuild 2.1 API to fix build. * Fix bad check and ConVarRef being resolved too early. * Whoops. This line is kinda important. Got nuked when refactoring. * Remove unused variable. * Updatet gamedata. * Switch to "Addresses" gamedata lookup * Add linux64 gamedata * Fix mac build Co-authored-by: Ruben Gonzalez <drifter01620@gmail.com> Co-authored-by: Peace-Maker <peace-maker@wcfan.de>
This commit is contained in:
parent
6c2be9bdcc
commit
ae485c3115
@ -24,11 +24,46 @@ for sdk_name in ['css', 'csgo']:
|
||||
if sdk_name not in SM.sdks:
|
||||
continue
|
||||
sdk = SM.sdks[sdk_name]
|
||||
|
||||
if sdk_name == 'csgo':
|
||||
project.sources += ['rulesfix.cpp']
|
||||
|
||||
for cxx in builder.targets:
|
||||
if not cxx.target.arch in sdk.platformSpec[cxx.target.platform]:
|
||||
continue
|
||||
|
||||
cxx.defines += ['HAVE_STRING_H'];
|
||||
SM.HL2ExtConfig(project, builder, cxx, 'game.cstrike.ext.' + sdk.ext, sdk)
|
||||
cxx.defines += ['HAVE_STRING_H']
|
||||
binary = SM.HL2ExtConfig(project, builder, cxx, 'game.cstrike.ext.' + sdk.ext, sdk)
|
||||
if sdk_name == 'csgo':
|
||||
compiler = binary.compiler
|
||||
compiler.cxxincludes += [os.path.join(sdk.path, 'public', 'steam')]
|
||||
compiler.defines += ['VERSION_SAFE_STEAM_API_INTERFACES']
|
||||
|
||||
library_name = ''
|
||||
if cxx.target.platform == 'windows':
|
||||
compiler.linkflags += [os.path.join(sdk.path, 'lib', 'public', 'steam_api.lib')]
|
||||
elif cxx.target.platform == 'linux':
|
||||
library_name = 'libsteam_api.so'
|
||||
if cxx.target.arch == 'x86_64':
|
||||
source_path = os.path.join(sdk.path, 'lib', 'linux64')
|
||||
else:
|
||||
source_path = os.path.join(sdk.path, 'lib', 'linux')
|
||||
elif cxx.target.platform == 'mac':
|
||||
library_name = 'libsteam_api.dylib'
|
||||
if cxx.target.arch == 'x86_64':
|
||||
source_path = os.path.join(sdk.path, 'lib', 'osx64')
|
||||
else:
|
||||
source_path = os.path.join(sdk.path, 'lib', 'mac')
|
||||
|
||||
if library_name:
|
||||
source_path = os.path.join(source_path, library_name)
|
||||
output_path = os.path.join(binary.localFolder, library_name)
|
||||
|
||||
# Ensure the output path exists.
|
||||
builder.AddFolder(binary.localFolder)
|
||||
output = builder.AddSymlink(source_path, output_path)
|
||||
|
||||
compiler.weaklinkdeps += [output]
|
||||
compiler.linkflags[0:0] = [library_name]
|
||||
|
||||
SM.extensions += builder.Add(project)
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include "iplayerinfo.h"
|
||||
#include "ISDKTools.h"
|
||||
#include "forwards.h"
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
#include "rulesfix.h"
|
||||
#endif
|
||||
#include "util_cstrike.h"
|
||||
|
||||
/**
|
||||
@ -88,6 +91,10 @@ bool CStrike::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
|
||||
playerhelpers->RegisterCommandTargetProcessor(this);
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
rulesfix.OnLoad();
|
||||
#endif
|
||||
|
||||
CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf);
|
||||
|
||||
g_pHandleBuyForward = forwards->CreateForward("CS_OnBuyCommand", ET_Event, 2, NULL, Param_Cell, Param_String);
|
||||
@ -110,6 +117,12 @@ bool CStrike::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
|
||||
gpGlobals = ismm->GetCGlobals();
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
ICvar *icvar;
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
|
||||
g_pCVar = icvar;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -153,6 +166,7 @@ void CStrike::SDK_OnUnload()
|
||||
forwards->ReleaseForward(g_pCSWeaponDropForward);
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
rulesfix.OnUnload();
|
||||
ClearHashMaps();
|
||||
#endif
|
||||
}
|
||||
|
232
extensions/cstrike/rulesfix.cpp
Normal file
232
extensions/cstrike/rulesfix.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Counter-Strike:Source Extension
|
||||
* Copyright (C) 2017 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "rulesfix.h"
|
||||
#include "extension.h"
|
||||
#include <sh_memory.h>
|
||||
|
||||
// Grab the convar ref
|
||||
ConVar *host_rules_show = nullptr;
|
||||
bool bPatched = false;
|
||||
|
||||
RulesFix rulesfix;
|
||||
|
||||
SH_DECL_HOOK1_void(IServerGameDLL, GameServerSteamAPIActivated, SH_NOATTRIB, 0, bool);
|
||||
|
||||
RulesFix::RulesFix() :
|
||||
m_OnSteamServersConnected(this, &RulesFix::OnSteamServersConnected)
|
||||
{
|
||||
}
|
||||
|
||||
void SetMTUMax(int iValue)
|
||||
{
|
||||
static int iOriginalValue = -1;
|
||||
static int *m_pMaxMTU = nullptr;
|
||||
|
||||
//If we never changed skip resetting
|
||||
if (iOriginalValue == -1 && iValue == -1)
|
||||
return;
|
||||
|
||||
if (m_pMaxMTU == nullptr)
|
||||
{
|
||||
if (!g_pGameConf->GetAddress("MaxMTU", (void **)&m_pMaxMTU))
|
||||
{
|
||||
g_pSM->LogMessage(myself, "[CStrike] Failed to locate NET_SendPacket signature.");
|
||||
return;
|
||||
}
|
||||
|
||||
SourceHook::SetMemAccess(m_pMaxMTU, sizeof(int), SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC);
|
||||
|
||||
iOriginalValue = *m_pMaxMTU;
|
||||
}
|
||||
|
||||
if (iValue == -1)
|
||||
*m_pMaxMTU = iOriginalValue;
|
||||
else
|
||||
*m_pMaxMTU = iValue;
|
||||
}
|
||||
|
||||
void RulesFix::OnLoad()
|
||||
{
|
||||
host_rules_show = g_pCVar->FindVar("host_rules_show");
|
||||
if (host_rules_show)
|
||||
{
|
||||
// Default to enabled. Explicit disable via cfg will still be obeyed.
|
||||
host_rules_show->SetValue(true);
|
||||
|
||||
SetMTUMax(5000);
|
||||
bPatched = true;
|
||||
}
|
||||
|
||||
SH_ADD_HOOK(IServerGameDLL, GameServerSteamAPIActivated, gamedll, SH_MEMBER(this, &RulesFix::Hook_GameServerSteamAPIActivated), true);
|
||||
}
|
||||
|
||||
void RulesFix::OnUnload()
|
||||
{
|
||||
SetMTUMax(-1);
|
||||
SH_REMOVE_HOOK(IServerGameDLL, GameServerSteamAPIActivated, gamedll, SH_MEMBER(this, &RulesFix::Hook_GameServerSteamAPIActivated), true);
|
||||
}
|
||||
|
||||
void NotifyAllCVars()
|
||||
{
|
||||
ICvar::Iterator iter(g_pCVar);
|
||||
for (iter.SetFirst(); iter.IsValid(); iter.Next())
|
||||
{
|
||||
ConCommandBase *cmd = iter.Get();
|
||||
if (!cmd->IsCommand() && cmd->IsFlagSet(FCVAR_NOTIFY))
|
||||
{
|
||||
rulesfix.OnNotifyConVarChanged((ConVar *)cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RulesFix::OnSteamServersConnected(SteamServersConnected_t *)
|
||||
{
|
||||
// The engine clears all after the Steam interfaces become available after they've been gone.
|
||||
NotifyAllCVars();
|
||||
}
|
||||
|
||||
static void OnConVarChanged(IConVar *var, const char *pOldValue, float flOldValue)
|
||||
{
|
||||
if (host_rules_show && var == host_rules_show)
|
||||
{
|
||||
if (host_rules_show->GetBool())
|
||||
{
|
||||
if (!bPatched)
|
||||
{
|
||||
SetMTUMax(5000);
|
||||
bPatched = true;
|
||||
NotifyAllCVars();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bPatched)
|
||||
{
|
||||
SetMTUMax(-1);
|
||||
bPatched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (var->IsFlagSet(FCVAR_NOTIFY))
|
||||
{
|
||||
rulesfix.OnNotifyConVarChanged((ConVar *)var);
|
||||
}
|
||||
}
|
||||
|
||||
void RulesFix::OnNotifyConVarChanged(ConVar *pVar)
|
||||
{
|
||||
if (!bPatched)
|
||||
return;
|
||||
|
||||
if (m_Steam.SteamMasterServerUpdater())
|
||||
{
|
||||
if (pVar->IsFlagSet(FCVAR_PROTECTED))
|
||||
{
|
||||
if (!pVar->GetString()[0])
|
||||
{
|
||||
m_Steam.SteamMasterServerUpdater()->SetKeyValue(pVar->GetName(), "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Steam.SteamMasterServerUpdater()->SetKeyValue(pVar->GetName(), "1");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Steam.SteamMasterServerUpdater()->SetKeyValue(pVar->GetName(), pVar->GetString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RulesFix::Hook_GameServerSteamAPIActivated(bool bActivated)
|
||||
{
|
||||
if (bActivated)
|
||||
{
|
||||
FixSteam();
|
||||
m_Steam.Init();
|
||||
|
||||
g_pCVar->InstallGlobalChangeCallback(OnConVarChanged);
|
||||
OnSteamServersConnected(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pCVar->RemoveGlobalChangeCallback(OnConVarChanged);
|
||||
m_Steam.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void RulesFix::FixSteam()
|
||||
{
|
||||
if (!g_pSteamClientGameServer)
|
||||
{
|
||||
void *(*pGSInternalCreateAddress)(const char *) = nullptr;
|
||||
void *(*pInternalCreateAddress)(const char *) = nullptr;
|
||||
|
||||
// CS:GO currently uses the old name, but will use the new name when they update to a
|
||||
// newer Steamworks SDK. Stay compatible.
|
||||
const char *pGSInternalFuncName = "SteamGameServerInternal_CreateInterface";
|
||||
const char *pInternalFuncName = "SteamInternal_CreateInterface";
|
||||
|
||||
ILibrary *pLibrary = libsys->OpenLibrary(
|
||||
#if defined ( PLATFORM_WINDOWS )
|
||||
"steam_api.dll"
|
||||
#elif defined( PLATFORM_LINUX )
|
||||
"libsteam_api.so"
|
||||
#elif defined( PLATFORM_APPLE )
|
||||
"libsteam_api.dylib"
|
||||
#else
|
||||
#error Unsupported platform
|
||||
#endif
|
||||
, nullptr, 0);
|
||||
if (pLibrary != nullptr)
|
||||
{
|
||||
if (pGSInternalCreateAddress == nullptr)
|
||||
{
|
||||
pGSInternalCreateAddress = reinterpret_cast<void *(*)(const char *)>(pLibrary->GetSymbolAddress(pGSInternalFuncName));
|
||||
}
|
||||
|
||||
if (pInternalCreateAddress == nullptr)
|
||||
{
|
||||
pInternalCreateAddress = reinterpret_cast<void *(*)(const char *)>(pLibrary->GetSymbolAddress(pInternalFuncName));
|
||||
}
|
||||
|
||||
pLibrary->CloseLibrary();
|
||||
}
|
||||
|
||||
if (pGSInternalCreateAddress != nullptr)
|
||||
g_pSteamClientGameServer = reinterpret_cast<ISteamClient *>((*pGSInternalCreateAddress)(STEAMCLIENT_INTERFACE_VERSION));
|
||||
|
||||
if (g_pSteamClientGameServer == nullptr && pInternalCreateAddress != nullptr)
|
||||
g_pSteamClientGameServer = reinterpret_cast<ISteamClient *>((*pInternalCreateAddress)(STEAMCLIENT_INTERFACE_VERSION));
|
||||
}
|
||||
}
|
52
extensions/cstrike/rulesfix.h
Normal file
52
extensions/cstrike/rulesfix.h
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Counter-Strike:Source Extension
|
||||
* Copyright (C) 2017 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <steam_gameserver.h>
|
||||
class ConVar;
|
||||
|
||||
class RulesFix
|
||||
{
|
||||
public:
|
||||
RulesFix();
|
||||
void OnLoad();
|
||||
void OnUnload();
|
||||
void OnNotifyConVarChanged(ConVar *pVar);
|
||||
void Hook_GameServerSteamAPIActivated(bool bActivated);
|
||||
private:
|
||||
void FixSteam();
|
||||
private:
|
||||
CSteamGameServerAPIContext m_Steam;
|
||||
STEAM_GAMESERVER_CALLBACK(RulesFix, OnSteamServersConnected, SteamServersConnected_t, m_OnSteamServersConnected);
|
||||
};
|
||||
|
||||
extern RulesFix rulesfix;
|
@ -68,7 +68,9 @@
|
||||
#define SMEXT_ENABLE_GAMEHELPERS
|
||||
#define SMEXT_ENABLE_TIMERSYS
|
||||
//#define SMEXT_ENABLE_THREADER
|
||||
//#define SMEXT_ENABLE_LIBSYS
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
#define SMEXT_ENABLE_LIBSYS
|
||||
#endif
|
||||
#define SMEXT_ENABLE_USERMSGS
|
||||
#define SMEXT_ENABLE_PLUGINSYS
|
||||
|
||||
|
@ -264,4 +264,43 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"#default"
|
||||
{
|
||||
"Addresses"
|
||||
{
|
||||
// Offset from NET_SendPacket sig to MTU
|
||||
"MaxMTU"
|
||||
{
|
||||
"windows"
|
||||
{
|
||||
"signature" "NET_SendPacket"
|
||||
"offset" "6"
|
||||
}
|
||||
"linux"
|
||||
{
|
||||
"signature" "NET_SendPacket"
|
||||
"offset" "5"
|
||||
}
|
||||
"linux64"
|
||||
{
|
||||
"signature" "NET_SendPacket"
|
||||
"offset" "4"
|
||||
}
|
||||
}
|
||||
}
|
||||
"Signatures"
|
||||
{
|
||||
// This isn't the start of the function, but closer to where we want to patch, including the exact bytes we will replace
|
||||
"NET_SendPacket"
|
||||
{
|
||||
"library" "engine"
|
||||
// "[NET] Cannot send %d-byte packet to %s. MTU is %u. %02x %02x %02x %02x %02x\n"
|
||||
"windows" "\x89\x4C\x24\x14\x81\xFF\xB0\x04\x00\x00\x7E"
|
||||
// _Z14NET_SendPacketP11INetChanneliRK10ns_addressPKhiP8bf_writebj
|
||||
"linux" "\x8B\x7D\x10\x81\xFE\xB0\x04\x00\x00\x0F"
|
||||
"linux64" "\x31\xC0\x81\xF9\xB0\x04\x00\x00\x0F"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user