mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
First work-in-progress dedicated implementation
Based on MrSteyk's dedicated patch. Additional patches targets the disabling of the client.dll library and VGUI. The disabling of the client.dll library initialization caused several issues to be investigated still (currently loops fine in _Host_RunFrame()). but executing a map command currently makes it only load the mp_common VPK before getting stuck somewhere. Setting hoststate to a valid map with HS_NEW_GAME (manually) does something to the engine but does not force the server to load anything yet. Added enums and classes from r5dev project.
This commit is contained in:
parent
fad7906fd8
commit
b42e85b1f4
@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "hooks.h"
|
||||
#include "opcodes.h"
|
||||
#include "console.h"
|
||||
|
||||
//#############################################################################
|
||||
@ -80,6 +81,7 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
|
||||
// Exec toggles
|
||||
if (sCommand == "1") { addr_CommandExecute(NULL, "exec autoexec_dev"); }
|
||||
if (sCommand == "2") { g_bDebugLoading = !g_bDebugLoading; continue; }
|
||||
if (sCommand == "3") { SetCHostState(); continue; } // TEST
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Execute the command in the r5 SQVM
|
||||
|
36
r5dedicated/csourceappsystemgroup.cpp
Normal file
36
r5dedicated/csourceappsystemgroup.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "pch.h"
|
||||
#include "hooks.h"
|
||||
|
||||
namespace Hooks
|
||||
{
|
||||
CSourceAppSystemGroup_CreateFn originalCSourceAppSystemGroup_Create = nullptr;
|
||||
}
|
||||
auto g_bIsDedicated = (uint8_t*)0x162C61208;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets 'EbisuSDK' globals required in certain engine callbacks.
|
||||
//-----------------------------------------------------------------------------
|
||||
void HEbisuSDK_Init()
|
||||
{
|
||||
auto ofs000 = (uint8_t*)0x1634F1690;
|
||||
auto ofs001 = (uint8_t*)0x1634F16B0;
|
||||
auto ofs002 = (uint8_t*)0x1634F1695;
|
||||
auto ofs003 = (uint8_t*)0x1634F30D8;
|
||||
auto ofs004 = (uint8_t*)0x1634F31D8;
|
||||
|
||||
*(char*)(ofs000) = (char)0x1; // <-- | 1st EbisuSDK boolean to be checked.
|
||||
*(char*)(ofs001) = (char)0x1; // <-- | 2nd EbisuSDK boolean to be checked.
|
||||
*(char*)(ofs002) = (char)0x1; // <-- | 3rd EbisuSDK boolean to be checked.
|
||||
*(char*)(ofs003) = (char)0x1; // <-- | Gets tested on listenserver for certain ConCommands.
|
||||
*(char*)(ofs004) = (char)0x0; // <-- | TODO: enforces Necleus cvars when not equal to NULL.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: hook 'SourceAppSystemGroup::Create' and set m_bIsDedicated to true.
|
||||
//-----------------------------------------------------------------------------
|
||||
char __fastcall Hooks::CSourceAppSystemGroup_Create(__int64 a1)
|
||||
{
|
||||
*g_bIsDedicated = 1; // HAS TO BE HERE!!!
|
||||
HEbisuSDK_Init();
|
||||
return originalCSourceAppSystemGroup_Create(a1);
|
||||
}
|
@ -11,6 +11,7 @@ void InitializeR5Dedicated()
|
||||
{
|
||||
SetupConsole();
|
||||
Hooks::InstallHooks();
|
||||
Hooks::DedicatedPatch();
|
||||
printf("+-----------------------------------------------------------------------------+\n");
|
||||
printf("| R5 DEDICATED SERVER --------------------------------------------------- |\n");
|
||||
printf("+-----------------------------------------------------------------------------+\n");
|
||||
|
422
r5dedicated/enums.h
Normal file
422
r5dedicated/enums.h
Normal file
@ -0,0 +1,422 @@
|
||||
#pragma once
|
||||
|
||||
/* Enumerations */
|
||||
enum class D3D11DeviceVTbl : short
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface = 0,
|
||||
AddRef = 1,
|
||||
Release = 2,
|
||||
|
||||
// ID3D11Device
|
||||
CreateBuffer = 3,
|
||||
CreateTexture1D = 4,
|
||||
CreateTexture2D = 5,
|
||||
CreateTexture3D = 6,
|
||||
CreateShaderResourceView = 7,
|
||||
CreateUnorderedAccessView = 8,
|
||||
CreateRenderTargetView = 9,
|
||||
CreateDepthStencilView = 10,
|
||||
CreateInputLayout = 11,
|
||||
CreateVertexShader = 12,
|
||||
CreateGeometryShader = 13,
|
||||
CreateGeometryShaderWithStreamOutput = 14,
|
||||
CreatePixelShader = 15,
|
||||
CreateHullShader = 16,
|
||||
CreateDomainShader = 17,
|
||||
CreateComputeShader = 18,
|
||||
CreateClassLinkage = 19,
|
||||
CreateBlendState = 20,
|
||||
CreateDepthStencilState = 21,
|
||||
CreateRasterizerState = 22,
|
||||
CreateSamplerState = 23,
|
||||
CreateQuery = 24,
|
||||
CreatePredicate = 25,
|
||||
CreateCounter = 26,
|
||||
CreateDeferredContext = 27,
|
||||
OpenSharedResource = 28,
|
||||
CheckFormatSupport = 29,
|
||||
CheckMultisampleQualityLevels = 30,
|
||||
CheckCounterInfo = 31,
|
||||
CheckCounter = 32,
|
||||
CheckFeatureSupport = 33,
|
||||
GetPrivateData = 34,
|
||||
SetPrivateData = 35,
|
||||
SetPrivateDataInterface = 36,
|
||||
GetFeatureLevel = 37,
|
||||
GetCreationFlags = 38,
|
||||
GetDeviceRemovedReason = 39,
|
||||
GetImmediateContext = 40,
|
||||
SetExceptionMode = 41,
|
||||
GetExceptionMode = 42,
|
||||
};
|
||||
|
||||
enum class DXGISwapChainVTbl : short
|
||||
{
|
||||
// IUnknown
|
||||
QueryInterface = 0,
|
||||
AddRef = 1,
|
||||
Release = 2,
|
||||
|
||||
// IDXGIObject
|
||||
SetPrivateData = 3,
|
||||
SetPrivateDataInterface = 4,
|
||||
GetPrivateData = 5,
|
||||
GetParent = 6,
|
||||
|
||||
// IDXGIDeviceSubObject
|
||||
GetDevice = 7,
|
||||
|
||||
// IDXGISwapChain
|
||||
Present = 8,
|
||||
GetBuffer = 9,
|
||||
SetFullscreenState = 10,
|
||||
GetFullscreenState = 11,
|
||||
GetDesc = 12,
|
||||
ResizeBuffers = 13,
|
||||
ResizeTarget = 14,
|
||||
GetContainingOutput = 15,
|
||||
GetFrameStatistics = 16,
|
||||
GetLastPresentCount = 17,
|
||||
};
|
||||
|
||||
#define MAX_SPLITSCREEN_CLIENT_BITS 2
|
||||
#define MAX_SPLITSCREEN_CLIENTS ( 1 << MAX_SPLITSCREEN_CLIENT_BITS ) // 4
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_JOYSTICKS = MAX_SPLITSCREEN_CLIENTS,
|
||||
MOUSE_BUTTON_COUNT = 5,
|
||||
};
|
||||
|
||||
enum JoystickAxis_t
|
||||
{
|
||||
JOY_AXIS_X = 0,
|
||||
JOY_AXIS_Y,
|
||||
JOY_AXIS_Z,
|
||||
JOY_AXIS_R,
|
||||
JOY_AXIS_U,
|
||||
JOY_AXIS_V,
|
||||
MAX_JOYSTICK_AXES,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
JOYSTICK_MAX_BUTTON_COUNT = 32,
|
||||
JOYSTICK_POV_BUTTON_COUNT = 4,
|
||||
JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2,
|
||||
};
|
||||
|
||||
#define JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_BUTTON + ((_joystick) * JOYSTICK_MAX_BUTTON_COUNT) + (_button) )
|
||||
#define JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_POV_BUTTON + ((_joystick) * JOYSTICK_POV_BUTTON_COUNT) + (_button) )
|
||||
#define JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_AXIS_BUTTON + ((_joystick) * JOYSTICK_AXIS_BUTTON_COUNT) + (_button) )
|
||||
|
||||
#define JOYSTICK_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) )
|
||||
#define JOYSTICK_POV_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) )
|
||||
#define JOYSTICK_AXIS_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) )
|
||||
|
||||
enum ButtonCode_t
|
||||
{
|
||||
BUTTON_CODE_INVALID = -1,
|
||||
BUTTON_CODE_NONE = 0,
|
||||
|
||||
KEY_FIRST = 0,
|
||||
|
||||
KEY_NONE = KEY_FIRST,
|
||||
KEY_0,
|
||||
KEY_1,
|
||||
KEY_2,
|
||||
KEY_3,
|
||||
KEY_4,
|
||||
KEY_5,
|
||||
KEY_6,
|
||||
KEY_7,
|
||||
KEY_8,
|
||||
KEY_9,
|
||||
KEY_A,
|
||||
KEY_B,
|
||||
KEY_C,
|
||||
KEY_D,
|
||||
KEY_E,
|
||||
KEY_F,
|
||||
KEY_G,
|
||||
KEY_H,
|
||||
KEY_I,
|
||||
KEY_J,
|
||||
KEY_K,
|
||||
KEY_L,
|
||||
KEY_M,
|
||||
KEY_N,
|
||||
KEY_O,
|
||||
KEY_P,
|
||||
KEY_Q,
|
||||
KEY_R,
|
||||
KEY_S,
|
||||
KEY_T,
|
||||
KEY_U,
|
||||
KEY_V,
|
||||
KEY_W,
|
||||
KEY_X,
|
||||
KEY_Y,
|
||||
KEY_Z,
|
||||
KEY_PAD_0,
|
||||
KEY_PAD_1,
|
||||
KEY_PAD_2,
|
||||
KEY_PAD_3,
|
||||
KEY_PAD_4,
|
||||
KEY_PAD_5,
|
||||
KEY_PAD_6,
|
||||
KEY_PAD_7,
|
||||
KEY_PAD_8,
|
||||
KEY_PAD_9,
|
||||
KEY_PAD_DIVIDE,
|
||||
KEY_PAD_MULTIPLY,
|
||||
KEY_PAD_MINUS,
|
||||
KEY_PAD_PLUS,
|
||||
KEY_PAD_ENTER,
|
||||
KEY_PAD_DECIMAL,
|
||||
KEY_LBRACKET,
|
||||
KEY_RBRACKET,
|
||||
KEY_SEMICOLON,
|
||||
KEY_APOSTROPHE,
|
||||
KEY_BACKQUOTE,
|
||||
KEY_COMMA,
|
||||
KEY_PERIOD,
|
||||
KEY_SLASH,
|
||||
KEY_BACKSLASH,
|
||||
KEY_MINUS,
|
||||
KEY_EQUAL,
|
||||
KEY_ENTER,
|
||||
KEY_SPACE,
|
||||
KEY_BACKSPACE,
|
||||
KEY_TAB,
|
||||
KEY_CAPSLOCK,
|
||||
KEY_NUMLOCK,
|
||||
KEY_ESCAPE,
|
||||
KEY_SCROLLLOCK,
|
||||
KEY_INSERT,
|
||||
KEY_DELETE,
|
||||
KEY_HOME,
|
||||
KEY_END,
|
||||
KEY_PAGEUP,
|
||||
KEY_PAGEDOWN,
|
||||
KEY_BREAK,
|
||||
KEY_LSHIFT,
|
||||
KEY_RSHIFT,
|
||||
KEY_LALT,
|
||||
KEY_RALT,
|
||||
KEY_LCONTROL,
|
||||
KEY_RCONTROL,
|
||||
KEY_LWIN,
|
||||
KEY_RWIN,
|
||||
KEY_APP,
|
||||
KEY_UP,
|
||||
KEY_LEFT,
|
||||
KEY_DOWN,
|
||||
KEY_RIGHT,
|
||||
KEY_F1,
|
||||
KEY_F2,
|
||||
KEY_F3,
|
||||
KEY_F4,
|
||||
KEY_F5,
|
||||
KEY_F6,
|
||||
KEY_F7,
|
||||
KEY_F8,
|
||||
KEY_F9,
|
||||
KEY_F10,
|
||||
KEY_F11,
|
||||
KEY_F12,
|
||||
KEY_CAPSLOCKTOGGLE,
|
||||
KEY_NUMLOCKTOGGLE,
|
||||
KEY_SCROLLLOCKTOGGLE,
|
||||
|
||||
KEY_LAST = KEY_SCROLLLOCKTOGGLE,
|
||||
KEY_COUNT = KEY_LAST - KEY_FIRST + 1,
|
||||
|
||||
// Mouse
|
||||
MOUSE_FIRST = KEY_LAST + 1,
|
||||
|
||||
MOUSE_LEFT = MOUSE_FIRST,
|
||||
MOUSE_RIGHT,
|
||||
MOUSE_MIDDLE,
|
||||
MOUSE_4,
|
||||
MOUSE_5,
|
||||
MOUSE_WHEEL_UP, // A fake button which is 'pressed' and 'released' when the wheel is moved up
|
||||
MOUSE_WHEEL_DOWN, // A fake button which is 'pressed' and 'released' when the wheel is moved down
|
||||
|
||||
MOUSE_LAST = MOUSE_WHEEL_DOWN,
|
||||
MOUSE_COUNT = MOUSE_LAST - MOUSE_FIRST + 1,
|
||||
|
||||
// Joystick
|
||||
JOYSTICK_FIRST = MOUSE_LAST + 1,
|
||||
|
||||
JOYSTICK_FIRST_BUTTON = JOYSTICK_FIRST,
|
||||
JOYSTICK_LAST_BUTTON = JOYSTICK_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_MAX_BUTTON_COUNT - 1),
|
||||
JOYSTICK_FIRST_POV_BUTTON,
|
||||
JOYSTICK_LAST_POV_BUTTON = JOYSTICK_POV_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_POV_BUTTON_COUNT - 1),
|
||||
JOYSTICK_FIRST_AXIS_BUTTON,
|
||||
JOYSTICK_LAST_AXIS_BUTTON = JOYSTICK_AXIS_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_AXIS_BUTTON_COUNT - 1),
|
||||
|
||||
JOYSTICK_LAST = JOYSTICK_LAST_AXIS_BUTTON,
|
||||
|
||||
BUTTON_CODE_LAST,
|
||||
BUTTON_CODE_COUNT = BUTTON_CODE_LAST - KEY_FIRST + 1,
|
||||
|
||||
// Helpers for XBox 360
|
||||
KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons
|
||||
KEY_XBUTTON_RIGHT,
|
||||
KEY_XBUTTON_DOWN,
|
||||
KEY_XBUTTON_LEFT,
|
||||
|
||||
KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons
|
||||
KEY_XBUTTON_B,
|
||||
KEY_XBUTTON_X,
|
||||
KEY_XBUTTON_Y,
|
||||
KEY_XBUTTON_LEFT_SHOULDER,
|
||||
KEY_XBUTTON_RIGHT_SHOULDER,
|
||||
KEY_XBUTTON_BACK,
|
||||
KEY_XBUTTON_START,
|
||||
KEY_XBUTTON_STICK1,
|
||||
KEY_XBUTTON_STICK2,
|
||||
KEY_XBUTTON_INACTIVE_START,
|
||||
|
||||
KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE
|
||||
KEY_XSTICK1_LEFT, // XAXIS NEGATIVE
|
||||
KEY_XSTICK1_DOWN, // YAXIS POSITIVE
|
||||
KEY_XSTICK1_UP, // YAXIS NEGATIVE
|
||||
KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE
|
||||
KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE
|
||||
KEY_XSTICK2_RIGHT, // UAXIS POSITIVE
|
||||
KEY_XSTICK2_LEFT, // UAXIS NEGATIVE
|
||||
KEY_XSTICK2_DOWN, // VAXIS POSITIVE
|
||||
KEY_XSTICK2_UP, // VAXIS NEGATIVE
|
||||
};
|
||||
|
||||
// Buttons are not confirmed to be the same. They have been always the same throughout the source engine. Lets hope they did not change them.
|
||||
|
||||
enum KeyValuesTypes
|
||||
{
|
||||
TYPE_NONE = 0x0,
|
||||
TYPE_STRING = 0x1,
|
||||
TYPE_INT = 0x2,
|
||||
TYPE_FLOAT = 0x3,
|
||||
TYPE_PTR = 0x4,
|
||||
TYPE_WSTRING = 0x5,
|
||||
TYPE_COLOR = 0x6,
|
||||
TYPE_UINT64 = 0x7,
|
||||
TYPE_COMPILED_INT_BYTE = 0x8,
|
||||
TYPE_COMPILED_INT_0 = 0x9,
|
||||
TYPE_COMPILED_INT_1 = 0xA,
|
||||
TYPE_NUMTYPES = 0xB,
|
||||
};
|
||||
|
||||
enum ClientFrameStage_t
|
||||
{
|
||||
FRAME_UNDEFINED = -1, // (haven't run any frames yet)
|
||||
FRAME_START,
|
||||
|
||||
// A network packet is being recieved
|
||||
FRAME_NET_UPDATE_START,
|
||||
// Data has been received and we're going to start calling PostDataUpdate
|
||||
FRAME_NET_UPDATE_POSTDATAUPDATE_START,
|
||||
// Data has been received and we've called PostDataUpdate on all data recipients
|
||||
FRAME_NET_UPDATE_POSTDATAUPDATE_END,
|
||||
// We've received all packets, we can now do interpolation, prediction, etc..
|
||||
FRAME_NET_UPDATE_END,
|
||||
|
||||
// We're about to start rendering the scene
|
||||
FRAME_RENDER_START,
|
||||
// We've finished rendering the scene.
|
||||
FRAME_RENDER_END,
|
||||
|
||||
FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE
|
||||
};
|
||||
|
||||
enum HostStates_t
|
||||
{
|
||||
HS_NEW_GAME = 0x0,
|
||||
HS_LOAD_GAME = 0x1,
|
||||
HS_CHANGE_LEVEL_SP = 0x2,
|
||||
HS_CHANGE_LEVEL_MP = 0x3,
|
||||
HS_RUN = 0x4,
|
||||
HS_GAME_SHUTDOWN = 0x5,
|
||||
HS_SHUTDOWN = 0x6,
|
||||
HS_RESTART = 0x7,
|
||||
};
|
||||
|
||||
enum SIGNONSTATE
|
||||
{
|
||||
SIGNONSTATE_NONE = 0, // no state yet; about to connect
|
||||
SIGNONSTATE_CHALLENGE = 1, // client challenging server; all OOB packets
|
||||
SIGNONSTATE_CONNECTED = 2, // client is connected to server; netchans ready
|
||||
SIGNONSTATE_NEW = 3, // just got serverinfo and string tables
|
||||
SIGNONSTATE_PRESPAWN = 4, // received signon buffers
|
||||
SIGNONSTATE_GETTING_DATA = 5, // getting persistence data I assume?
|
||||
SIGNONSTATE_SPAWN = 6, // ready to receive entity packets
|
||||
SIGNONSTATE_FIRST_SNAP = 7, // ???
|
||||
SIGNONSTATE_FULL = 8, // we are fully connected; first non-delta packet received
|
||||
SIGNONSTATE_CHANGELEVEL = 9, // server is changing level; please wait
|
||||
};
|
||||
|
||||
enum FileWarningLevel_t
|
||||
{
|
||||
FILESYSTEM_WARNING = -1,
|
||||
FILESYSTEM_WARNING_QUIET = 0,
|
||||
FILESYSTEM_WARNING_REPORTUNCLOSED,
|
||||
FILESYSTEM_WARNING_REPORTUSAGE,
|
||||
FILESYSTEM_WARNING_REPORTALLACCESSES,
|
||||
FILESYSTEM_WARNING_REPORTALLACCESSES_READ,
|
||||
FILESYSTEM_WARNING_REPORTALLACCESSES_READWRITE,
|
||||
FILESYSTEM_WARNING_REPORTALLACCESSES_ASYNC
|
||||
};
|
||||
|
||||
#define FCVAR_NONE 0
|
||||
|
||||
// Command to ConVars and ConCommands
|
||||
// ConVar Systems
|
||||
#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc.
|
||||
#define FCVAR_DEVELOPMENTONLY (1<<1) // Hidden in released products. Flag is removed automatically if ALLOW_DEVELOPMENT_CVARS is defined.
|
||||
#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL
|
||||
#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL
|
||||
#define FCVAR_HIDDEN (1<<4) // Hidden. Doesn't appear in find or auto complete. Like DEVELOPMENTONLY, but can't be compiled out.
|
||||
|
||||
// ConVar only
|
||||
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
|
||||
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
|
||||
#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc
|
||||
#define FCVAR_NOTIFY (1<<8) // notifies players when changed
|
||||
#define FCVAR_USERINFO (1<<9) // changes the client's info string
|
||||
|
||||
#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
|
||||
|
||||
#define FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS (1<<10) // When on concommands this allows remote clients to execute this cmd on the server.
|
||||
// We are changing the default behavior of concommands to disallow execution by remote clients without
|
||||
// this flag due to the number existing concommands that can lag or crash the server when clients abuse them.
|
||||
|
||||
#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
|
||||
#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar
|
||||
|
||||
// It's a ConVar that's shared between the client and the server.
|
||||
// At signon, the values of all such ConVars are sent from the server to the client (skipped for local
|
||||
// client, of course )
|
||||
// If a change is requested it must come from the console (i.e., no remote client changes)
|
||||
// If a value is changed while a server is active, it's replicated to all connected clients
|
||||
#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time
|
||||
#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats
|
||||
#define FCVAR_SS (1<<15) // causes varnameN where N == 2 through max splitscreen slots for mod to be autogenerated
|
||||
#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file
|
||||
#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles
|
||||
#define FCVAR_SS_ADDED (1<<18) // This is one of the "added" FCVAR_SS variables for the splitscreen players
|
||||
#define FCVAR_RELEASE (1<<19) // Cvars tagged with this are the only cvars avaliable to customers
|
||||
#define FCVAR_RELOAD_MATERIALS (1<<20) // If this cvar changes, it forces a material reload
|
||||
#define FCVAR_RELOAD_TEXTURES (1<<21) // If this cvar changes, if forces a texture reload
|
||||
|
||||
#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server
|
||||
#define FCVAR_MATERIAL_SYSTEM_THREAD (1<<23) // Indicates this cvar is read from the material system thread
|
||||
#define FCVAR_ARCHIVE_GAMECONSOLE (1<<24) // cvar written to config.cfg on the Xbox
|
||||
|
||||
#define FCVAR_SERVER_CAN_EXECUTE (1<<28)// the server is allowed to execute this command on clients via ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd.
|
||||
#define FCVAR_SERVER_CANNOT_QUERY (1<<29)// If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue).
|
||||
#define FCVAR_CLIENTCMD_CAN_EXECUTE (1<<30) // IVEngineClient::ClientCmd is allowed to execute this command.
|
||||
|
||||
#define MAX_PLAYERS 128 // Max R5 players.
|
470
r5dedicated/gameclasses.cpp
Normal file
470
r5dedicated/gameclasses.cpp
Normal file
@ -0,0 +1,470 @@
|
||||
#include "pch.h"
|
||||
#include "enums.h"
|
||||
#include "gameclasses.h"
|
||||
|
||||
// Need this for a re-factor later.
|
||||
// Interface* interfaces = *reinterpret_cast<Interface**>(0x167F4FA48);
|
||||
|
||||
// for (Interface* current = interfaces; current; current = reinterpret_cast<Interface*>(current->NextInterfacePtr))
|
||||
// {
|
||||
// printf("%s: %p\n", current->InterfaceName, current->InterfacePtr);
|
||||
// }
|
||||
|
||||
namespace GameGlobals
|
||||
{
|
||||
bool IsInitialized = false;
|
||||
CHostState* HostState = nullptr;
|
||||
CInputSystem* InputSystem = nullptr;
|
||||
CCVar* Cvar = nullptr;
|
||||
CClient* Client = nullptr;
|
||||
BanList* BanSystem = new BanList();
|
||||
|
||||
CKeyValuesSystem* KeyValuesSystem = nullptr;
|
||||
KeyValues** PlaylistKeyValues = nullptr;
|
||||
|
||||
std::vector<std::string> allPlaylists = { "none" };
|
||||
|
||||
namespace CustomCommandVariations
|
||||
{
|
||||
|
||||
void Kick_Callback(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
if (argSize < 2) // Do we atleast have 2 arguments?
|
||||
return;
|
||||
|
||||
CCommand& cmdReference = *cmd; // Get reference.
|
||||
const char* firstArg = cmdReference[1]; // Get first arg.
|
||||
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) // Loop through all possible client instances.
|
||||
{
|
||||
CClient* client = GameGlobals::Client->GetClientInstance(i); // Get client instance.
|
||||
if (!client)
|
||||
continue;
|
||||
|
||||
if (!client->GetNetChan()) // Netchan valid?
|
||||
continue;
|
||||
|
||||
void* clientNamePtr = (void**)(((std::uintptr_t)client->GetNetChan()) + 0x1A8D); // Get client name from netchan.
|
||||
std::string clientName((char*)clientNamePtr, 32); // Get full name.
|
||||
|
||||
if (clientName.empty()) // Empty name?
|
||||
continue;
|
||||
|
||||
if (strcmp(firstArg, clientName.c_str()) != 0) // Our wanted name?
|
||||
continue;
|
||||
|
||||
DisconnectClient(client, "Kicked from Server", 0, 1); // Disconnect client.
|
||||
}
|
||||
}
|
||||
|
||||
void KickID_Callback(CCommand* cmd)
|
||||
{
|
||||
static auto HasOnlyDigits = [](const std::string& string)
|
||||
{
|
||||
for (const char& character : string)
|
||||
{
|
||||
if (std::isdigit(character) == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
if (argSize < 2) // Do we atleast have 2 arguments?
|
||||
return;
|
||||
|
||||
CCommand& cmdReference = *cmd; // Get reference.
|
||||
std::string firstArg = cmdReference[1]; // Get first arg.
|
||||
|
||||
try
|
||||
{
|
||||
bool onlyDigits = HasOnlyDigits(firstArg); // Only has digits?
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) // Loop through all possible client instances.
|
||||
{
|
||||
CClient* client = GameGlobals::Client->GetClientInstance(i); // Get client instance.
|
||||
if (!client)
|
||||
continue;
|
||||
|
||||
if (!client->GetNetChan()) // Netchan valid?
|
||||
continue;
|
||||
|
||||
std::string finalIPAddress = "null"; // If this stays null they modified the packet somehow.
|
||||
MemoryAddress ipAddressField = MemoryAddress(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan.
|
||||
if (ipAddressField)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::to_string(ipAddressField.GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x1).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x2).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x3).GetValue<std::uint8_t>());
|
||||
|
||||
finalIPAddress = ss.str();
|
||||
}
|
||||
|
||||
if (onlyDigits)
|
||||
{
|
||||
std::int64_t ID = static_cast<std::int64_t>(std::stoll(firstArg));
|
||||
if (ID > MAX_PLAYERS) // Is it a possible originID?
|
||||
{
|
||||
std::int64_t originID = client->m_iOriginID;
|
||||
if (originID != ID) // See if they match.
|
||||
continue;
|
||||
}
|
||||
else // If its not try by userID.
|
||||
{
|
||||
std::int64_t clientID = static_cast<std::int64_t>(client->m_iUserID + 1); // Get UserID + 1.
|
||||
if (clientID != ID) // See if they match.
|
||||
continue;
|
||||
}
|
||||
|
||||
DisconnectClient(client, "Kicked from Server", 0, 1); // Disconnect client.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (firstArg.compare(finalIPAddress) != NULL) // Do the string equal?
|
||||
continue;
|
||||
|
||||
DisconnectClient(client, "Kicked from Server", 0, 1); // Disconnect client.
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "Kick UID asked for a userID or originID :( You can get the userID with the 'status' command. Error: " << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Unban_Callback(CCommand* cmd)
|
||||
{
|
||||
static auto HasOnlyDigits = [](const std::string& string)
|
||||
{
|
||||
for (const char& character : string)
|
||||
{
|
||||
if (std::isdigit(character) == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
if (argSize < 2) // Do we atleast have 2 arguments?
|
||||
return;
|
||||
|
||||
CCommand& cmdReference = *cmd; // Get reference.
|
||||
|
||||
try
|
||||
{
|
||||
const char* firstArg = cmdReference[1];
|
||||
if (HasOnlyDigits(firstArg)) // Check if we have an ip address or origin ID.
|
||||
{
|
||||
GameGlobals::BanSystem->DeleteEntry("noIP", std::stoll(firstArg)); // Delete ban entry.
|
||||
GameGlobals::BanSystem->Save(); // Save modified vector to file.
|
||||
}
|
||||
else
|
||||
{
|
||||
GameGlobals::BanSystem->DeleteEntry(firstArg, 1); // Delete ban entry.
|
||||
GameGlobals::BanSystem->Save(); // Save modified vector to file.
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "Unban Error: " << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ReloadBanList_Callback(CCommand* cmd)
|
||||
{
|
||||
GameGlobals::BanSystem->Load(); // Reload banlist.
|
||||
}
|
||||
|
||||
void Ban_Callback(CCommand* cmd)
|
||||
{
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
if (argSize < 2) // Do we atleast have 2 arguments?
|
||||
return;
|
||||
|
||||
CCommand& cmdReference = *cmd; // Get reference.
|
||||
const char* firstArg = cmdReference[1]; // Get first arg.
|
||||
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) // Loop through all possible client instances.
|
||||
{
|
||||
CClient* client = GameGlobals::Client->GetClientInstance(i); // Get client instance.
|
||||
if (!client)
|
||||
continue;
|
||||
|
||||
if (!client->GetNetChan()) // Netchan valid?
|
||||
continue;
|
||||
|
||||
void* clientNamePtr = (void**)(((std::uintptr_t)client->GetNetChan()) + 0x1A8D); // Get client name from netchan.
|
||||
std::string clientName((char*)clientNamePtr, 32); // Get full name.
|
||||
|
||||
if (clientName.empty()) // Empty name?
|
||||
continue;
|
||||
|
||||
if (strcmp(firstArg, clientName.c_str()) != 0) // Our wanted name?
|
||||
continue;
|
||||
|
||||
std::string finalIPAddress = "null"; // If this stays null they modified the packet somehow.
|
||||
MemoryAddress ipAddressField = MemoryAddress(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan.
|
||||
if (ipAddressField && ipAddressField.GetValue<int>() != 0x0)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::to_string(ipAddressField.GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x1).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x2).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x3).GetValue<std::uint8_t>());
|
||||
|
||||
finalIPAddress = ss.str();
|
||||
}
|
||||
|
||||
GameGlobals::BanSystem->AddEntry(finalIPAddress, client->m_iOriginID); // Add ban entry.
|
||||
GameGlobals::BanSystem->Save(); // Save ban list.
|
||||
DisconnectClient(client, "Banned from Server", 0, 1); // Disconnect client.
|
||||
}
|
||||
}
|
||||
|
||||
void BanID_Callback(CCommand* cmd)
|
||||
{
|
||||
static auto HasOnlyDigits = [](const std::string& string)
|
||||
{
|
||||
for (const char& character : string)
|
||||
{
|
||||
if (std::isdigit(character) == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
std::int32_t argSize = *(std::int32_t*)((std::uintptr_t)cmd + 0x4);
|
||||
if (argSize < 2) // Do we atleast have 2 arguments?
|
||||
return;
|
||||
|
||||
CCommand& cmdReference = *cmd; // Get reference.
|
||||
std::string firstArg = cmdReference[1];
|
||||
|
||||
try
|
||||
{
|
||||
bool onlyDigits = HasOnlyDigits(firstArg); // Only has digits?
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) // Loop through all possible client instances.
|
||||
{
|
||||
CClient* client = GameGlobals::Client->GetClientInstance(i); // Get client instance.
|
||||
if (!client)
|
||||
continue;
|
||||
|
||||
if (!client->GetNetChan()) // Netchan valid?
|
||||
continue;
|
||||
|
||||
std::string finalIPAddress = "null"; // If this stays null they modified the packet somehow.
|
||||
MemoryAddress ipAddressField = MemoryAddress(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan.
|
||||
if (ipAddressField)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::to_string(ipAddressField.GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x1).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x2).GetValue<std::uint8_t>()) << "."
|
||||
<< std::to_string(ipAddressField.Offset(0x3).GetValue<std::uint8_t>());
|
||||
|
||||
finalIPAddress = ss.str();
|
||||
}
|
||||
|
||||
if (onlyDigits)
|
||||
{
|
||||
std::int64_t ID = static_cast<std::int64_t>(std::stoll(firstArg));
|
||||
if (ID > MAX_PLAYERS) // Is it a possible originID?
|
||||
{
|
||||
std::int64_t originID = client->m_iOriginID;
|
||||
if (originID != ID) // See if they match.
|
||||
continue;
|
||||
}
|
||||
else // If its not try by userID.
|
||||
{
|
||||
std::int64_t clientID = static_cast<std::int64_t>(client->m_iUserID + 1); // Get UserID + 1.
|
||||
if (clientID != ID) // See if they match.
|
||||
continue;
|
||||
}
|
||||
|
||||
GameGlobals::BanSystem->AddEntry(finalIPAddress, client->m_iOriginID); // Add ban entry.
|
||||
GameGlobals::BanSystem->Save(); // Save ban list.
|
||||
DisconnectClient(client, "Banned from Server", 0, 1); // Disconnect client.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (firstArg.compare(finalIPAddress) != NULL) // Do the string equal?
|
||||
continue;
|
||||
|
||||
GameGlobals::BanSystem->AddEntry(finalIPAddress, client->m_iOriginID); // Add ban entry.
|
||||
GameGlobals::BanSystem->Save(); // Save ban list.
|
||||
DisconnectClient(client, "Banned from Server", 0, 1); // Disconnect client.
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "Banid Error: " << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NullHostNames()
|
||||
{
|
||||
const char* hostnameArray[] =
|
||||
{
|
||||
"pin_telemetry_hostname",
|
||||
"assetdownloads_hostname",
|
||||
"users_hostname",
|
||||
"persistence_hostname",
|
||||
"speechtotexttoken_hostname",
|
||||
"communities_hostname",
|
||||
"persistenceDef_hostname",
|
||||
"party_hostname",
|
||||
"speechtotext_hostname",
|
||||
"serverReports_hostname",
|
||||
"subscription_hostname",
|
||||
"steamlink_hostname",
|
||||
"staticfile_hostname",
|
||||
"matchmaking_hostname",
|
||||
"skill_hostname",
|
||||
"publication_hostname",
|
||||
"stats_hostname"
|
||||
};
|
||||
|
||||
for (int i = 0; i < 17; i++)
|
||||
{
|
||||
const char* name = hostnameArray[i];
|
||||
Cvar->FindVar(name)->m_pzsCurrentValue = "0.0.0.0";
|
||||
}
|
||||
}
|
||||
|
||||
void InitGameGlobals()
|
||||
{
|
||||
HostState = reinterpret_cast<CHostState*>(0x141736120); // Get CHostState from memory.
|
||||
InputSystem = *reinterpret_cast<CInputSystem**>(0x14D40B380); // Get IInputSystem from memory.
|
||||
Cvar = *reinterpret_cast<CCVar**>(0x14D40B348); // Get CCVar from memory.
|
||||
//KeyValuesSystem = reinterpret_cast<CKeyValuesSystem*>(0x141F105C0); // Get CKeyValuesSystem from memory.
|
||||
//PlaylistKeyValues = reinterpret_cast<KeyValues**>(0x16705B980); // Get the KeyValue for the playlist file.
|
||||
//Client = reinterpret_cast<CClient*>(0x16073B200);
|
||||
|
||||
//NullHostNames(); // Null all hostnames.
|
||||
//InitAllCommandVariations(); // Initialize our custom ConVars.
|
||||
//*(char*)addr_m_bRestrictServerCommands = true; // Restrict commands.
|
||||
//void* disconnect = Cvar->FindCommand("disconnect");
|
||||
//*(std::int32_t*)((std::uintptr_t)disconnect + 0x38) |= FCVAR_SERVER_CAN_EXECUTE; // Make sure server is not restricted to this.
|
||||
|
||||
//std::thread t1(InitPlaylist); // Start thread to grab playlists.
|
||||
//t1.detach(); // Detach thread from current one.
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
void InitPlaylist()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if ((*PlaylistKeyValues))
|
||||
{
|
||||
KeyValues* playlists = (*PlaylistKeyValues)->FindKey("Playlists", false); // Find playlists key.
|
||||
if (playlists)
|
||||
{
|
||||
allPlaylists.clear();
|
||||
for (KeyValues* dat = playlists->m_pSub; dat != nullptr; dat = dat->m_pPeer) // Parse through all sub keys.
|
||||
{
|
||||
allPlaylists.push_back(dat->GetName()); // Get all playlist names.
|
||||
}
|
||||
|
||||
break; // Break if playlist got filled.
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
}
|
||||
|
||||
void InitAllCommandVariations()
|
||||
{
|
||||
void* KickConCommand = CreateCustomConCommand("kick", "Kick a client from the Server via name. | Usage: kick (name).", 0, CustomCommandVariations::Kick_Callback, nullptr);
|
||||
void* KickIDConCommand = CreateCustomConCommand("kickid", "Kick a client from the Server via userID or originID | Usage: kickid (originID/userID)", 0, CustomCommandVariations::KickID_Callback, nullptr);
|
||||
void* UnbanConCommand = CreateCustomConCommand("unban", "Unbans a client from the Server via IP or originID | Usage: unban (originID/ipAddress)", 0, CustomCommandVariations::Unban_Callback, nullptr);
|
||||
void* ReloadBanListConCommand = CreateCustomConCommand("reloadbanlist", "Reloads the ban list from disk.", 0, CustomCommandVariations::ReloadBanList_Callback, nullptr);
|
||||
void* BanConCommand = CreateCustomConCommand("ban", "Bans a client from the Server via name. | Usage: ban (name)", 0, CustomCommandVariations::Ban_Callback, nullptr);
|
||||
void* BanIDConCommand = CreateCustomConCommand("banid", "Bans a client from the Server via originID, userID or IP | Usage: banid (originID/ipAddress/userID)", 0, CustomCommandVariations::BanID_Callback, nullptr);
|
||||
}
|
||||
|
||||
void* CreateCustomConCommand(const char* name, const char* helpString, int flags, void* callback, void* callbackAfterExecution)
|
||||
{
|
||||
static MemoryAddress ConCommandVtable = MemoryAddress(0x14136BD70);
|
||||
static MemoryAddress NullSub = MemoryAddress(0x1401B3280);
|
||||
static MemoryAddress CallbackCompletion = MemoryAddress(0x1401E3990);
|
||||
static MemoryAddress RegisterConCommand = MemoryAddress(0x14046F470);
|
||||
|
||||
void* command = reinterpret_cast<void*>(addr_MemAlloc_Wrapper(0x68)); // Allocate new memory with StdMemAlloc else we crash.
|
||||
memset(command, 0, 0x68); // Set all to null.
|
||||
std::uintptr_t commandPtr = reinterpret_cast<std::uintptr_t>(command); // To ptr.
|
||||
|
||||
*(void**)commandPtr = ConCommandVtable.RCast<void*>(); // 0x0 to ConCommand vtable.
|
||||
*(const char**)(commandPtr + 0x18) = name; // 0x18 to ConCommand Name.
|
||||
*(const char**)(commandPtr + 0x20) = helpString; // 0x20 to ConCommand help string.
|
||||
*(std::int32_t*)(commandPtr + 0x38) = flags; // 0x38 to ConCommand Flags.
|
||||
*(void**)(commandPtr + 0x40) = NullSub.RCast<void*>(); // 0x40 Nullsub since every concommand has it.
|
||||
*(void**)(commandPtr + 0x50) = callback; // 0x50 has function callback.
|
||||
*(std::int32_t*)(commandPtr + 0x60) = 2; // 0x60 Set to use callback and newcommand callback.
|
||||
|
||||
if (callbackAfterExecution) // Do we wanna have a callback after execution?
|
||||
{
|
||||
*(void**)(commandPtr + 0x58) = callbackAfterExecution; // 0x58 to our callback after execution.
|
||||
}
|
||||
else
|
||||
{
|
||||
*(void**)(commandPtr + 0x58) = CallbackCompletion.RCast<void*>(); // 0x58 nullsub.
|
||||
}
|
||||
|
||||
RegisterConCommand.RCast<void(*)(void*)>()((void*)commandPtr); // Register command in ConVarAccessor.
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk)
|
||||
{
|
||||
static MemoryAddress ConVarVtable = MemoryAddress(0x14046FB50).Offset(0x12).ResolveRelativeAddress(); // Get vtable ptr for ConVar table.
|
||||
static MemoryAddress ICvarVtable = MemoryAddress(0x14046FB50).Offset(0x29).ResolveRelativeAddress(); // Get vtable ptr for ICvar table.
|
||||
static MemoryAddress CreateConVar = MemoryAddress(0x140470540); // Get CreateConvar address.
|
||||
|
||||
ConVar* allocatedConvar = reinterpret_cast<ConVar*>(addr_MemAlloc_Wrapper(0xA0)); // Allocate new memory with StdMemAlloc else we crash.
|
||||
memset(allocatedConvar, 0, 0xA0); // Set all to null.
|
||||
std::uintptr_t cvarPtr = reinterpret_cast<std::uintptr_t>(allocatedConvar); // To ptr.
|
||||
|
||||
*(void**)(cvarPtr + 0x40) = ICvarVtable.RCast<void*>(); // 0x40 to ICvar table.
|
||||
*(void**)cvarPtr = ConVarVtable.RCast<void*>(); // 0x0 to ConVar vtable.
|
||||
|
||||
CreateConVar.RCast<void(*)(ConVar*, const char*, const char*, int, const char*, bool, float, bool, float, void*, void*)>() // Call to create ConVar.
|
||||
(allocatedConvar, name, defaultValue, flags, helpString, bMin, fMin, bMax, fMax, callback, unk);
|
||||
|
||||
return allocatedConvar; // Return allocated ConVar.
|
||||
}
|
||||
|
||||
void DisconnectClient(CClient* client, const char* reason, unsigned __int8 unk1, char unk2)
|
||||
{
|
||||
if (!client) // Client valid?
|
||||
return;
|
||||
|
||||
if (std::strlen(reason) == NULL) // Is reason null?
|
||||
return;
|
||||
|
||||
if (!client->GetNetChan())
|
||||
return;
|
||||
|
||||
addr_NetChan_Shutdown(client->GetNetChan(), reason, unk1, unk2); // Shutdown netchan.
|
||||
client->GetNetChan() = nullptr; // Null netchan.
|
||||
MemoryAddress(0x140302FD0).RCast<void(*)(CClient*)>()(client); // Reset CClient instance for client.
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region KeyValues
|
||||
const char* KeyValues::GetName()
|
||||
{
|
||||
return GameGlobals::KeyValuesSystem->GetStringForSymbol(MAKE_3_BYTES_FROM_1_AND_2(m_iKeyNameCaseSensitive, m_iKeyNameCaseSensitive2));
|
||||
}
|
||||
#pragma endregion
|
487
r5dedicated/gameclasses.h
Normal file
487
r5dedicated/gameclasses.h
Normal file
@ -0,0 +1,487 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
#include "hooks.h"
|
||||
#include "enums.h"
|
||||
#include "banlist.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Classes and Structs
|
||||
class CInputSystem
|
||||
{
|
||||
public:
|
||||
void EnableInput(bool bEnabled)// @0x14039F100 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CInputSystem*, bool);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[10](this, bEnabled);
|
||||
}
|
||||
|
||||
void EnableMessagePump(bool bEnabled) // @0x14039F110 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CInputSystem*, bool);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[11](this, bEnabled);
|
||||
}
|
||||
|
||||
bool IsButtonDown(ButtonCode_t Button) // @0x1403A0140 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = bool(__thiscall*)(CInputSystem*, ButtonCode_t);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[13](this, Button);
|
||||
}
|
||||
|
||||
private:
|
||||
char pad_0000[16]; //0x0000
|
||||
public:
|
||||
bool m_bEnabled; //0x0010 IsInputEnabled variable.
|
||||
bool m_bPumpEnabled; //0x0011 EnabledMessagePump variable.
|
||||
};
|
||||
|
||||
typedef int HKeySymbol;
|
||||
|
||||
#define MAKE_3_BYTES_FROM_1_AND_2( x1, x2 ) (( (( std::uint16_t )x2) << 8 ) | (std::uint8_t)(x1))
|
||||
|
||||
class CKeyValuesSystem // VTABLE @ 0x1413AA1E8 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
public:
|
||||
|
||||
void RegisterSizeofKeyValues(__int64 size) //@0x1413AA1F0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, __int64);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[0](this, size);
|
||||
}
|
||||
|
||||
void* AllocKeyValuesMemory(__int64 size) // @0x1413AA1F8 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void* (__thiscall*)(CKeyValuesSystem*, __int64);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[1](this, size);
|
||||
}
|
||||
|
||||
void FreeKeyValuesMemory(void* pMem) // @0x1413AA200 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, void*);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[2](this, pMem);
|
||||
}
|
||||
|
||||
HKeySymbol GetSymbolForString(const char* name, bool bCreate) // @0x1413AA208 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = HKeySymbol(__thiscall*)(CKeyValuesSystem*, const char*, bool);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[3](this, name, bCreate);
|
||||
}
|
||||
|
||||
const char* GetStringForSymbol(HKeySymbol symbol) // @0x1413AA210 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = const char* (__thiscall*)(CKeyValuesSystem*, HKeySymbol);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[4](this, symbol);
|
||||
}
|
||||
|
||||
// void __fastcall CKeyValuesSystem::FreeKeyValuesMemory(CKeyValuesSystem* this_arg, void* ptr_mem_arg)
|
||||
// {
|
||||
// __int64* v2; // rax
|
||||
// __int64 v4; // rax
|
||||
// __int64* v5; // rax
|
||||
//
|
||||
// v2 = qword_14D40B538;
|
||||
// if (!qword_14D40B538)
|
||||
// {
|
||||
// v2 = sub_140462930();
|
||||
// qword_14D40B538 = v2;
|
||||
// }
|
||||
// v4 = (*(*v2 + 48))(v2, ptr_mem_arg);
|
||||
// if (v4 > 0)
|
||||
// CKeyValuesSystem::m_pMemPool -= v4;
|
||||
// v5 = qword_14D40B538;
|
||||
// if (!qword_14D40B538)
|
||||
// {
|
||||
// v5 = sub_140462930();
|
||||
// qword_14D40B538 = v5;
|
||||
// }
|
||||
// (*(*v5 + 40))(v5, ptr_mem_arg);
|
||||
// }
|
||||
|
||||
// GetMemPool return a global variable called m_pMemPool it gets modified by AllocKeyValuesMemory and FreeKeyValuesMemory above you can see where the find it in FreeKeyValuesMemory.
|
||||
void* GetMemPool() // @0x1413AA228 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
return reinterpret_cast<void*>(0x14D412768); // May need to dereference is once more not sure right now.
|
||||
}
|
||||
|
||||
void SetKeyValuesExpressionSymbol(const char* name, bool bValue) // @0x1413AA230 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, const char*, bool);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[8](this, name, bValue);
|
||||
}
|
||||
|
||||
bool GetKeyValuesExpressionSymbol(const char* name) // @0x1413AA238 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = bool(__thiscall*)(CKeyValuesSystem*, const char*);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[9](this, name);
|
||||
}
|
||||
|
||||
HKeySymbol GetSymbolForStringCaseSensitive(HKeySymbol& hCaseInsensitiveSymbol, const char* name, bool bCreate) // @0x1413AA240 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = HKeySymbol(__thiscall*)(CKeyValuesSystem*, HKeySymbol&, const char*, bool);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[10](this, hCaseInsensitiveSymbol, name, bCreate);
|
||||
}
|
||||
|
||||
// Datatypes aren't accurate. But full fill the actual byte distance.
|
||||
public:
|
||||
void* vtable; // 0x0000
|
||||
__int64 m_iMaxKeyValuesSize; // 0x0008
|
||||
private:
|
||||
char gap10[240]; // 0x0010
|
||||
public:
|
||||
__int32 m_KvConditionalSymbolTable; // 0x0100
|
||||
private:
|
||||
char gap104[4]; // 0x0104
|
||||
public:
|
||||
__int64 field_108; // 0x0108
|
||||
private:
|
||||
char gap110[32]; // 0x0110
|
||||
public:
|
||||
int m_mutex; // 0x0130
|
||||
};
|
||||
|
||||
class KeyValues
|
||||
{
|
||||
public:
|
||||
|
||||
KeyValues* FindKey(const char* keyName, bool bCreate)
|
||||
{
|
||||
static auto func = reinterpret_cast<KeyValues*(__thiscall*)(KeyValues*, const char*, bool)>(addr_KeyValues_FindKey);
|
||||
return func(this, keyName, bCreate);
|
||||
}
|
||||
|
||||
const char* GetName();
|
||||
|
||||
int GetInt(const char* keyName, int defaultValue)
|
||||
{
|
||||
KeyValues* dat = FindKey(keyName, false);
|
||||
|
||||
if (!dat)
|
||||
return defaultValue;
|
||||
|
||||
switch (dat->m_iDataType)
|
||||
{
|
||||
case TYPE_STRING:
|
||||
return atoi(dat->m_sValue);
|
||||
case TYPE_FLOAT:
|
||||
return static_cast<int>(m_flValue());
|
||||
case TYPE_WSTRING:
|
||||
return _wtoi(dat->m_wsValue);
|
||||
case TYPE_UINT64:
|
||||
return 0;
|
||||
default:
|
||||
return dat->m_iValue();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void SetInt(const char* keyName, int iValue)
|
||||
{
|
||||
KeyValues* dat = FindKey(keyName, true);
|
||||
if (dat)
|
||||
{
|
||||
dat->m_iValue() = iValue;
|
||||
dat->m_iDataType = TYPE_INT;
|
||||
}
|
||||
}
|
||||
|
||||
void SetFloat(const char* keyName, float flValue)
|
||||
{
|
||||
KeyValues* dat = FindKey(keyName, true);
|
||||
if (dat)
|
||||
{
|
||||
dat->m_flValue() = flValue;
|
||||
dat->m_iDataType = TYPE_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
// Compiler makes it so m_Value shares the offset spot with m_flValue that why we cast it like this.
|
||||
float& m_flValue()
|
||||
{
|
||||
static __int32 offset = 0x18;
|
||||
return *(float*)((std::uintptr_t)this + offset);
|
||||
}
|
||||
|
||||
int& m_iValue()
|
||||
{
|
||||
static __int32 offset = 0x18;
|
||||
return *(int*)((std::uintptr_t)this + offset);
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned __int32 m_iKeyName : 24; // 0x0000
|
||||
unsigned __int32 m_iKeyNameCaseSensitive : 8; // 0x0003
|
||||
char* m_sValue; // 0x0008
|
||||
wchar_t* m_wsValue; // 0x0010
|
||||
int m_Value; // 0x0018
|
||||
private:
|
||||
char gap1C[12]; // 0x0020
|
||||
public:
|
||||
char m_iDataType; // 0x0028
|
||||
unsigned __int16 m_iKeyNameCaseSensitive2; // 0x002A
|
||||
KeyValues* m_pPeer; // 0x0030
|
||||
KeyValues* m_pSub; // 0x0038
|
||||
KeyValues* m_pChain; // 0x0040
|
||||
};
|
||||
|
||||
struct Vector3 // Implement the proper class of this at some point.
|
||||
{
|
||||
float x; // 0x0000
|
||||
float y; // 0x0004
|
||||
float z; // 0x0008
|
||||
};
|
||||
|
||||
struct QAngle // Implement the proper class of this at some point.
|
||||
{
|
||||
float pitch; //0x0000
|
||||
float yaw; // 0x0004
|
||||
float roll; // 0x0008
|
||||
};
|
||||
|
||||
class CHostState
|
||||
{
|
||||
public:
|
||||
int m_iCurrentState; //0x0000
|
||||
int m_iNextState; //0x0004
|
||||
Vector3 m_vecLocation; //0x0008
|
||||
QAngle m_angLocation; //0x0014
|
||||
char m_levelName[64]; //0x0020
|
||||
char m_mapGroupName[256]; //0x0060
|
||||
char m_landMarkName[256]; //0x0160
|
||||
float m_flShortFrameTime; //0x0260
|
||||
bool m_bActiveGame; //0x0264
|
||||
bool m_bRememberLocation; //0x0265
|
||||
bool m_bBackgroundLevel; //0x0266
|
||||
bool m_bWaitingForConnection; //0x0267
|
||||
bool m_bSplitScreenConnect; //0x0268
|
||||
bool m_bGameHasShutDownAndFlushedMemory; //0x0269
|
||||
bool m_bWorkshopMapDownloadPending; //0x026A
|
||||
};
|
||||
|
||||
class CHLClient
|
||||
{
|
||||
public:
|
||||
void FrameStageNotify(ClientFrameStage_t curStage) // @0x1405C0740 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CHLClient*, ClientFrameStage_t);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[58](this, curStage); /* 48 83 EC 28 89 15 ? ? ? ? */
|
||||
}
|
||||
};
|
||||
|
||||
class CClient
|
||||
{
|
||||
public:
|
||||
inline CClient* GetClientInstance(int index)
|
||||
{
|
||||
return (CClient*)(std::uintptr_t)(0x16073B200 + (index * (std::uintptr_t)0x4A4C0));
|
||||
}
|
||||
|
||||
void*& GetNetChan()
|
||||
{
|
||||
return m_nNetChannel;
|
||||
}
|
||||
private:
|
||||
char pad_0000[16]; //0x0000
|
||||
public:
|
||||
int m_iUserID; //0x0010
|
||||
private:
|
||||
char pad_0014[908]; //0x0014
|
||||
public:
|
||||
void* m_nNetChannel; //0x03A0
|
||||
private:
|
||||
char pad_03A8[8]; //0x03A8
|
||||
public:
|
||||
int m_iSignonstate; //0x03B0
|
||||
private:
|
||||
char pad_03B4[4]; //0x03B4
|
||||
public:
|
||||
std::int64_t m_iOriginID; //0x03B8
|
||||
private:
|
||||
char pad_03C0[303360]; //0x03C0
|
||||
};
|
||||
|
||||
class CCommand
|
||||
{
|
||||
private:
|
||||
enum
|
||||
{
|
||||
COMMAND_MAX_ARGC = 64,
|
||||
COMMAND_MAX_LENGTH = 512,
|
||||
};
|
||||
|
||||
public:
|
||||
CCommand() = delete;
|
||||
|
||||
inline int MaxCommandLength()
|
||||
{
|
||||
return COMMAND_MAX_LENGTH - 1;
|
||||
}
|
||||
|
||||
inline int64_t ArgC() const
|
||||
{
|
||||
return m_nArgc;
|
||||
}
|
||||
|
||||
inline const char** ArgV() const
|
||||
{
|
||||
return m_nArgc ? (const char**)m_ppArgv : NULL;
|
||||
}
|
||||
|
||||
inline const char* ArgS() const
|
||||
{
|
||||
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
|
||||
}
|
||||
|
||||
inline const char* GetCommandString() const
|
||||
{
|
||||
return m_nArgc ? m_pArgSBuffer : "";
|
||||
}
|
||||
|
||||
inline const char* Arg(int nIndex) const
|
||||
{
|
||||
// FIXME: Many command handlers appear to not be particularly careful
|
||||
// about checking for valid argc range. For now, we're going to
|
||||
// do the extra check and return an empty string if it's out of range
|
||||
if (nIndex < 0 || nIndex >= m_nArgc)
|
||||
return "";
|
||||
return m_ppArgv[nIndex];
|
||||
}
|
||||
|
||||
inline const char* operator[](int nIndex) const
|
||||
{
|
||||
return Arg(nIndex);
|
||||
}
|
||||
|
||||
private:
|
||||
std::int64_t m_nArgc;
|
||||
std::int64_t m_nArgv0Size;
|
||||
char m_pArgSBuffer[COMMAND_MAX_LENGTH];
|
||||
char m_pArgvBuffer[COMMAND_MAX_LENGTH];
|
||||
const char* m_ppArgv[COMMAND_MAX_ARGC];
|
||||
};
|
||||
|
||||
class ConCommandBase
|
||||
{
|
||||
public:
|
||||
void* m_pConCommandBaseVTable; //0x0000
|
||||
ConCommandBase* m_pNext; //0x0008
|
||||
bool m_bRegistered; //0x0010
|
||||
private:
|
||||
char pad_0011[7]; //0x0011
|
||||
public:
|
||||
const char* m_pszName; //0x0018
|
||||
const char* m_pszHelpString; //0x0020
|
||||
private:
|
||||
char pad_0028[16]; //0x0028
|
||||
public:
|
||||
__int32 m_nFlags; //0x0038
|
||||
private:
|
||||
char pad_003C[4]; //0x003C
|
||||
}; //Size: 0x0038
|
||||
|
||||
class ConVar
|
||||
{
|
||||
public:
|
||||
ConCommandBase m_ConCommandBase; // 0x0000
|
||||
void* m_pConVarVTable; //0x0040
|
||||
ConVar* m_pParent; //0x0048
|
||||
const char* n_pszDefaultValue; //0x0050
|
||||
const char* m_pzsCurrentValue; //0x0058
|
||||
__int64 m_iStringLength; //0x0060
|
||||
float m_flValue; //0x0068
|
||||
int m_iValue; //0x006C
|
||||
bool m_bHasMin; //0x0070
|
||||
float m_flMinValue; //0x0074
|
||||
bool m_bHasMax; //0x0078
|
||||
float m_flMaxValue; //0x007C
|
||||
char pad_0080[32]; //0x0080
|
||||
}; //Size: 0x00A0
|
||||
|
||||
class CCVarIteratorInternal // Fully reversed table, just look at the virtual function table and rename the function.
|
||||
{
|
||||
public:
|
||||
virtual void SetFirst(void) = 0; //0
|
||||
virtual void Next(void) = 0; //1
|
||||
virtual bool IsValid(void) = 0; //2
|
||||
virtual ConCommandBase* Get(void) = 0; //3
|
||||
};
|
||||
|
||||
class CCVar
|
||||
{
|
||||
public:
|
||||
ConCommandBase* FindCommandBase(const char* szCommandName) // @0x1405983A0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = ConCommandBase*(__thiscall*)(CCVar*, const char*);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[14](this, szCommandName);
|
||||
}
|
||||
|
||||
ConVar* FindVar(const char* szVarName) // @0x1405983B0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = ConVar*(__thiscall*)(CCVar*, const char*);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[16](this, szVarName);
|
||||
}
|
||||
|
||||
void* /*Implement ConCommand class.*/ FindCommand(const char* szCommandName) // @0x1405983F0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void*(__thiscall*)(CCVar*, const char*);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[18](this, szCommandName);
|
||||
}
|
||||
|
||||
CCVarIteratorInternal* FactoryInternalIterator() // @0x140597C10 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = CCVarIteratorInternal*(__thiscall*)(CCVar*);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[41](this);
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, ConCommandBase*> DumpToMap()
|
||||
{
|
||||
std::stringstream ss;
|
||||
CCVarIteratorInternal* itint = FactoryInternalIterator(); // Allocatd new InternalIterator.
|
||||
|
||||
std::unordered_map<std::string, ConCommandBase*> allConVars;
|
||||
|
||||
for (itint->SetFirst(); itint->IsValid(); itint->Next()) // Loop through all instances.
|
||||
{
|
||||
ConCommandBase* command = itint->Get();
|
||||
const char* commandName = command->m_pszName;
|
||||
allConVars[commandName] = command;
|
||||
}
|
||||
|
||||
return allConVars;
|
||||
}
|
||||
};
|
||||
|
||||
struct Interface
|
||||
{
|
||||
__int64 (*InterfacePtr)(void);
|
||||
const char* InterfaceName;
|
||||
__int64* NextInterfacePtr;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Initialize Game Globals
|
||||
namespace GameGlobals
|
||||
{
|
||||
// Class Instances
|
||||
extern CHostState* HostState;
|
||||
extern CInputSystem* InputSystem;
|
||||
extern CCVar* Cvar;
|
||||
extern KeyValues** PlaylistKeyValues;
|
||||
extern CKeyValuesSystem* KeyValuesSystem;
|
||||
extern CClient* Client;
|
||||
extern BanList* BanSystem;
|
||||
|
||||
// Var
|
||||
ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk);
|
||||
void* CreateCustomConCommand(const char* name, const char* helpString, int flags, void* callback, void* callbackAfterExecution);
|
||||
|
||||
// Init
|
||||
void InitGameGlobals();
|
||||
void InitAllCommandVariations();
|
||||
void InitPlaylist();
|
||||
|
||||
extern std::vector<std::string> allPlaylists;
|
||||
extern bool IsInitialized;
|
||||
|
||||
// Utility
|
||||
void DisconnectClient(CClient* client, const char* reason, unsigned __int8 unk1, char unk2);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "hooks.h"
|
||||
#include "opcodes.h"
|
||||
#include "gameclasses.h"
|
||||
|
||||
void Hooks::InstallHooks()
|
||||
{
|
||||
@ -8,6 +9,11 @@ void Hooks::InstallHooks()
|
||||
// Initialize Minhook
|
||||
MH_Initialize();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hook SourceAppSystemGroup functions
|
||||
MH_CreateHook(addr_CSourceAppSystemGroup_Create, &Hooks::CSourceAppSystemGroup_Create, reinterpret_cast<void**>(&originalCSourceAppSystemGroup_Create));
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hook Squirrel functions
|
||||
MH_CreateHook(addr_SQVM_Print, &Hooks::SQVM_Print, NULL);
|
||||
MH_CreateHook(addr_SQVM_LoadRson, &Hooks::SQVM_LoadRson, reinterpret_cast<void**>(&originalSQVM_LoadRson));
|
||||
@ -32,6 +38,10 @@ void Hooks::InstallHooks()
|
||||
// Hook Utility functions
|
||||
MH_CreateHook(addr_MSG_EngineError, &Hooks::MSG_EngineError, reinterpret_cast<void**>(&originalMSG_EngineError));
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Enable SourceAppSystemGroup hooks
|
||||
MH_EnableHook(addr_CSourceAppSystemGroup_Create);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Enable Squirrel hooks
|
||||
MH_EnableHook(addr_SQVM_Print);
|
||||
@ -52,11 +62,17 @@ void Hooks::InstallHooks()
|
||||
// Enabled Utility hooks
|
||||
MH_EnableHook(addr_MSG_EngineError);
|
||||
|
||||
InstallOpcodes();
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Set global variables
|
||||
GameGlobals::InitGameGlobals();
|
||||
}
|
||||
|
||||
void Hooks::RemoveHooks()
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Hook SourceAppSystemGroup functions
|
||||
MH_RemoveHook(addr_CSourceAppSystemGroup_Create);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Unhook Squirrel functions
|
||||
MH_RemoveHook(addr_SQVM_Print);
|
||||
|
@ -5,6 +5,10 @@ namespace
|
||||
{
|
||||
Module r5_patterns = Module("r5apex.exe"); // Create module class instance.
|
||||
|
||||
#pragma region CSourceAppSystemGroup
|
||||
FUNC_AT_ADDRESS(addr_CSourceAppSystemGroup_Create, char(*)(__int64), r5_patterns.PatternSearch("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B F9 E8 ? ? ? ? 33 C9").GetPtr());
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Console
|
||||
/*0x140202090*/
|
||||
FUNC_AT_ADDRESS(addr_CommandExecute, void(*)(void*, const char*), r5_patterns.PatternSearch("48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8").GetPtr());
|
||||
@ -36,6 +40,9 @@ namespace
|
||||
|
||||
/*0x1402662D0*/
|
||||
FUNC_AT_ADDRESS(addr_NET_SendDatagram, int(*)(SOCKET, const char*, int, int), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?").GetPtr());
|
||||
|
||||
/*0x14025F190*/
|
||||
FUNC_AT_ADDRESS(addr_NetChan_Shutdown, void(*)(void*, const char*, unsigned __int8, char), r5_patterns.StringSearch("Disconnect by server.\n").FindPatternSelf("E8 ? ? ? ? 4C 89 B3 ? ? ? ?", MemoryAddress::Direction::DOWN).FollowNearCallSelf().GetPtr());
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CHLClient
|
||||
@ -43,6 +50,11 @@ namespace
|
||||
FUNC_AT_ADDRESS(addr_CHLClient_FrameStageNotify, void(*)(void* rcx, int curStage), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr());
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CClientState
|
||||
/*0x1418223E4*/
|
||||
FUNC_AT_ADDRESS(addr_m_bRestrictServerCommands, void*, r5_patterns.StringSearch("DevShotGenerator_Init()").FindPatternSelf("88 05", MemoryAddress::Direction::UP).ResolveRelativeAddressSelf(0x2).OffsetSelf(0x2).GetPtr());
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CVEngineServer
|
||||
/*0x140315CF0*/
|
||||
FUNC_AT_ADDRESS(addr_CVEngineServer_IsPersistenceDataAvailable, bool(*)(__int64, int), r5_patterns.PatternSearch("3B 15 ?? ?? ?? ?? 7D 33").GetPtr());
|
||||
@ -51,13 +63,23 @@ namespace
|
||||
#pragma region Utility
|
||||
/*0x140295600*/
|
||||
FUNC_AT_ADDRESS(addr_MSG_EngineError, int(*)(char*, va_list), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA").GetPtr());
|
||||
|
||||
/*0x1401B31C0*/
|
||||
FUNC_AT_ADDRESS(addr_MemAlloc_Wrapper, void* (*)(__int64), r5_patterns.StringSearch("ConversionModeMenu").FindPatternSelf("E8 ? ? ? ? 48", MemoryAddress::Direction::UP).FollowNearCallSelf().GetPtr());
|
||||
#pragma endregion
|
||||
// Un-used atm.
|
||||
// DWORD64 p_KeyValues_FindKey = /*1404744E0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45"));
|
||||
|
||||
#pragma region KeyValues
|
||||
/*0x1404744E0*/
|
||||
FUNC_AT_ADDRESS(addr_KeyValues_FindKey, void* (*)(void*, const char*, bool), r5_patterns.PatternSearch("40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45").GetPtr());
|
||||
#pragma endregion
|
||||
|
||||
|
||||
void PrintHAddress() // Test the sigscan results
|
||||
{
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
PRINT_ADDRESS("CSourceAppSystemGroup::Create", addr_CSourceAppSystemGroup_Create);
|
||||
PRINT_ADDRESS("CommandExecute", addr_CommandExecute);
|
||||
PRINT_ADDRESS("ConVar_IsFlagSet", addr_ConVar_IsFlagSet);
|
||||
PRINT_ADDRESS("ConCommand_IsFlagSet", addr_ConCommand_IsFlagSet);
|
||||
@ -66,9 +88,12 @@ namespace
|
||||
PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson);
|
||||
PRINT_ADDRESS("NET_ReceiveDatagram", addr_NET_ReceiveDatagram);
|
||||
PRINT_ADDRESS("NET_SendDatagram ", addr_NET_SendDatagram);
|
||||
PRINT_ADDRESS("NetChan_Shutdown ", addr_NetChan_Shutdown);
|
||||
PRINT_ADDRESS("CHLClient::FrameStageNotify", addr_CHLClient_FrameStageNotify);
|
||||
PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", addr_CVEngineServer_IsPersistenceDataAvailable);
|
||||
PRINT_ADDRESS("MSG_EngineError", addr_MSG_EngineError);
|
||||
PRINT_ADDRESS("MemAlloc_Wrapper", addr_MemAlloc_Wrapper);
|
||||
PRINT_ADDRESS("KeyValues_FindKey", addr_KeyValues_FindKey);
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
// TODO implement error handling when sigscan fails or result is 0
|
||||
}
|
||||
@ -80,6 +105,13 @@ inline bool g_bDebugConsole = false;
|
||||
|
||||
namespace Hooks
|
||||
{
|
||||
#pragma region CSourceAppSystemGroup
|
||||
char __fastcall CSourceAppSystemGroup_Create(__int64 a1);
|
||||
|
||||
using CSourceAppSystemGroup_CreateFn = char(*)(__int64);
|
||||
extern CSourceAppSystemGroup_CreateFn originalCSourceAppSystemGroup_Create;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region CHLClient
|
||||
// void __fastcall FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curStage);
|
||||
|
||||
@ -122,7 +154,7 @@ namespace Hooks
|
||||
bool ConCommand_IsFlagSet(int* cmd, int flag);
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Other
|
||||
#pragma region Utility
|
||||
int MSG_EngineError(char* fmt, va_list args);
|
||||
|
||||
using MSG_EngineErrorFn = int(*)(char*, va_list);
|
||||
@ -133,4 +165,5 @@ namespace Hooks
|
||||
void RemoveHooks();
|
||||
void ToggleNetTrace();
|
||||
void ToggleDevCommands();
|
||||
void DedicatedPatch();
|
||||
}
|
@ -1,29 +1,152 @@
|
||||
#include "pch.h"
|
||||
#include "hooks.h"
|
||||
#include "enums.h"
|
||||
#include "opcodes.h"
|
||||
#include "gameclasses.h"
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* _opcodes.cpp
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
void InstallOpcodes() /* .TEXT */
|
||||
void DisableRenderer()
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// JNZ --> JMP | Prevent OriginSDK from initializing on the client
|
||||
//Origin_Init.Offset(0x0B).Patch({ 0xE9, 0x63, 0x02, 0x00, 0x00, 0x00 });
|
||||
//Origin_SetState.Offset(0x0E).Patch({ 0xE9, 0xCB, 0x03, 0x00, 0x00 });
|
||||
// FUN --> RET | Called from CEngineClient and CEngineVGUI (Init()?).
|
||||
r0.Patch({ 0xC3 }); // This patch is likely not required if client.dll isn't initialized.
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Allow games to be loaded without the optional texture streaming file
|
||||
dst002.Offset(0x8E5).Patch({ 0xEB, 0x19 });
|
||||
// FUN --> RET | Skip ShaderSetup(). CShaderGlue.
|
||||
r1.Patch({ 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Prevent connect command from crashing by invalid call to UI function
|
||||
dst004.Offset(0x1D6).Patch({ 0xEB, 0x27 });
|
||||
// FUN --> RET | Skip Matsync. Called from CMaterialSystem.
|
||||
r2.Patch({ 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Prevent connect localhost from being executed after listenserver init
|
||||
//Host_NewGame.Offset(0x637).Patch({ 0xE9, 0xC1, 0x00, 0x00, 0x00});
|
||||
// JE --> JMP | Matsys mode init (CMaterialSystem).
|
||||
r3.Offset(0x22).Patch({ 0xEB, 0x66 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JA --> JMP | Disable server-side verification for duplicate accounts on the server
|
||||
CServer_Auth.Offset(0x284).Patch({ 0x90, 0x90 });
|
||||
// FUN --> RET | Clear render buffer? Called from CMatRenderContext and CTexture.
|
||||
r4.Patch({ 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JA --> JMP | Prevent FairFight anti-cheat from initializing on the server
|
||||
// FUN --> RET | Heavy render stuff. Called from CMatRenderContext.
|
||||
r5.Patch({ 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// FUN --> RET | Set shader resource.
|
||||
r6.Patch({ 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// FUN --> RET | Begin.
|
||||
r7.Patch({ 0xC3, 0x90, 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// FUN --> RET | End.
|
||||
r8.Patch({ 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
}
|
||||
|
||||
void DisableClient()
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// JNZ --> JMP | Prevent EbisuSDK from initializing on the engine and server.
|
||||
Origin_Init.Offset(0x0B).Patch({ 0xE9, 0x63, 0x02, 0x00, 0x00, 0x00 });
|
||||
Origin_SetState.Offset(0x0E).Patch({ 0xE9, 0xCB, 0x03, 0x00, 0x00 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JE --> JMP | Skip CreateGameWindow initialization code.
|
||||
CreateGameWindow.Offset(0x3DD).Patch({ 0xEB, 0x6D });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNZ --> JMP | Skip CreateGameWindow validation code.
|
||||
CreateGameWindow.Offset(0x44C).Patch({ 0xEB, 0x49 });
|
||||
//-------------------------------------------------------------------------
|
||||
// PUS --> XOR | Prevent ShowWindow and CreateGameWindow from being initialized.
|
||||
c1.Patch({ 0x30, 0xC0, 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// PUS --> XOR | Prevent ShowWindow and CreateGameWindow from being initialized.
|
||||
c1.Patch({ 0x30, 0xC0, 0xC3 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> NOP | TODO: NOP 'particle_script' instead.
|
||||
c2.Offset(0x23C).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// MOV --> NOP | TODO: NOP 'particle_script' instead.
|
||||
c2.Offset(0x2BD).Patch({ 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// MOV --> NOP | TODO: NOP 'highlight_system' instead.
|
||||
c3.Offset(0xA9).Patch({ 0x90, 0x90, 0x90, 0x90 });
|
||||
}
|
||||
|
||||
void DisableVGUI()
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// CMP --> XOR | Skip VGUI initialization jumptable.
|
||||
v0.Patch({ 0x48, 0x33, 0xC0, 0xC3, 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Skip call to VGUI loadscreen func.
|
||||
SCR_BeginLoadingPlaque.Offset(0x427).Patch({ 0xEB, 0x09 });
|
||||
}
|
||||
|
||||
void Hooks::DedicatedPatch()
|
||||
{
|
||||
//Sleep(10000);
|
||||
// for future reference 14171A9B4 - matsys mode
|
||||
|
||||
*(uintptr_t*)0x14D415040 = 0x1417304E8;
|
||||
*(uintptr_t*)0x14B37C3C0 = 0x141F10CA0;
|
||||
|
||||
*(uintptr_t*)0x14B3800D7 = 0x1; // bDedicated
|
||||
|
||||
DisableRenderer();
|
||||
DisableClient();
|
||||
DisableVGUI();
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CAL --> NOP | HLClient call inside eng->frame.
|
||||
addr_CEngine_Frame.Offset(0x410).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JA --> JMP | Prevent FairFight anti-cheat from initializing on the server.
|
||||
// TODO: fix and re-enable this.
|
||||
FairFight_Init.Offset(0x61).Patch({ 0xE9, 0xED, 0x00, 0x00, 0x00, 0x00 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Take dedicated initialization routine instead.
|
||||
s0.Offset(0x19).Patch({ 0xEB, 0x6E });
|
||||
//-------------------------------------------------------------------------
|
||||
// JE --> JMP | Skip client.dll Init_PostVideo() validation code.
|
||||
s0.Offset(0x609).Patch({ 0xEB, 0x2B });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Skip client.dll Init_PostVideo() validation code.
|
||||
s0.Offset(0x621).Patch({ 0xEB, 0x0C });
|
||||
//-------------------------------------------------------------------------
|
||||
// JE --> JMP | Skip NULL call as client is never initialized.
|
||||
s0.Offset(0x658).Patch({ 0xE9, 0x8C, 0x00, 0x00, 0x00 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Skip shader preloading as cvar can't be checked due to client being NULL.
|
||||
s0.Offset(0x6E9).Patch({ 0xE9, 0xB0, 0x00, 0x00, 0x00 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Return early in _Host_RunFrame() for debugging perposes.
|
||||
//s1.Offset(0x1C6).Patch({ 0xE9, 0xAD, 0x11, 0x00, 0x00 }); // <-- this one was only used to debug.
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JMP | Return early in _Host_RunFrame() for debugging perposes.
|
||||
s1.Offset(0x1010).Patch({ 0xEB, 0x14 });
|
||||
//-------------------------------------------------------------------------
|
||||
// CAL --> NOP | NOP NULL call as client is never initialized.
|
||||
s1.Offset(0x1023).Patch({ 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JS --> JMP | Skip ListenServer HeartBeat.
|
||||
s2.Offset(0xF).Patch({ 0xE9, 0x22, 0x01, 0x00, 0x00 });
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CAL --> NOP | NOP call to UI texture asset preloading.
|
||||
e0.Offset(0x182).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> JNP | Skip client.dll library initialization.
|
||||
e0.Offset(0xA7D).Patch({ 0xE9, 0xF0, 0x01, 0x00, 0x00 });
|
||||
//-------------------------------------------------------------------------
|
||||
// JNE --> NOP | Skip settings field loading for client texture assets.
|
||||
// TODO: this is also used by server.dll library.
|
||||
e1.Offset(0x213).Patch({ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ??? 1403DFC30 = 0x94490 ??? // an expensive stuff that wasted many CPU cycles, this one seems to be the best candidate to return
|
||||
}
|
||||
|
||||
// TEST
|
||||
void SetCHostState()
|
||||
{
|
||||
static std::string ServerMap = std::string();
|
||||
ServerMap = "mp_rr_canyonlands_64k_x_64k";
|
||||
strncpy_s(GameGlobals::HostState->m_levelName, ServerMap.c_str(), 64); // Copy new map into hoststate levelname. 64 is size of m_levelname.
|
||||
GameGlobals::HostState->m_iNextState = HostStates_t::HS_NEW_GAME; // Force CHostState::FrameUpdate to start a server.
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
void InstallOpcodes();
|
||||
inline HANDLE GameProcess = GetCurrentProcess();
|
||||
void SetCHostState();
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -36,6 +36,42 @@ namespace
|
||||
MemoryAddress FairFight_Init = r5_op.PatternSearch("40 53 48 83 EC 20 8B 81 B0 03 ? ? 48 8B D9 C6");
|
||||
#pragma endregion
|
||||
|
||||
|
||||
// TODO: create patterns instead and rename to function names.
|
||||
// Renderer
|
||||
MemoryAddress r0 = 0x00000001402FE280; //
|
||||
MemoryAddress r1 = 0x00000001403B3A50; //
|
||||
MemoryAddress r2 = 0x00000001403DEE90; //
|
||||
MemoryAddress r3 = 0x00000001403BD120; //
|
||||
MemoryAddress r4 = 0x0000000140404380; //
|
||||
MemoryAddress r5 = 0x000000014040D850; //
|
||||
MemoryAddress r6 = 0x0000000140413260; //
|
||||
MemoryAddress r7 = 0x00000001404093F0; //
|
||||
MemoryAddress r8 = 0x00000001403D2E60; //
|
||||
MemoryAddress d3d11init = 0x000000014043CDF0; //
|
||||
|
||||
// Engine
|
||||
MemoryAddress e0 = 0x0000000140236E40; // main Host_Init()?
|
||||
MemoryAddress e1 = 0x0000000140FB2F10; // also used by CServerGameDLL
|
||||
MemoryAddress addr_CEngine_Frame = 0x00000001402970E0;
|
||||
|
||||
// SERVER
|
||||
MemoryAddress s0 = 0x0000000140237B00; // server Host_Init()?
|
||||
MemoryAddress s1 = 0x0000000140231C00; // _Host_RunFrame() with inlined CFrameTimer::MarkFrame()?
|
||||
MemoryAddress s2 = 0x00000001402312A0; // server HeartBeat? (baseserver.cpp)
|
||||
|
||||
// CLIENT
|
||||
MemoryAddress c0 = 0x0000000140236640; // client Host_Init()?
|
||||
MemoryAddress c1 = 0x0000000140299100; // CreateGameWindowInit()?
|
||||
MemoryAddress c2 = 0x00000001403F4360; // 1403DF870 --> 1403F4360
|
||||
MemoryAddress c3 = 0x00000001403F8A80; // 1403DF870 --> 1403F8A40
|
||||
MemoryAddress CreateGameWindow = 0x0000000140343DE0;
|
||||
|
||||
// VGUI
|
||||
MemoryAddress v0 = 0x0000000140282E40; // jumptable
|
||||
MemoryAddress SCR_BeginLoadingPlaque = 0x000000014023E870;
|
||||
|
||||
|
||||
void PrintOAddress() // Test the sigscan results
|
||||
{
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#pragma message("Pre-compiling headers.\n")
|
||||
#pragma message("[DEDICATED] pre-compiling headers.\n")
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Prevent winsock2 redefinition.
|
||||
#include <windows.h>
|
||||
@ -27,8 +27,8 @@
|
||||
#include "sinks/stdout_sinks.h"
|
||||
#include "sinks/ostream_sink.h"
|
||||
#include "utility.h"
|
||||
//#include "httplib.h"
|
||||
//#include "json.hpp"
|
||||
#include "httplib.h"
|
||||
#include "json.hpp"
|
||||
|
||||
#include "address.h"
|
||||
|
||||
|
@ -185,7 +185,9 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\shared\utility.cpp" />
|
||||
<ClCompile Include="console.cpp" />
|
||||
<ClCompile Include="csourceappsystemgroup.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="gameclasses.cpp" />
|
||||
<ClCompile Include="hooks.cpp" />
|
||||
<ClCompile Include="iconvar.cpp" />
|
||||
<ClCompile Include="msgbox.cpp" />
|
||||
@ -300,6 +302,8 @@
|
||||
<ClInclude Include="..\shared\include\utility.h" />
|
||||
<ClInclude Include="console.h" />
|
||||
<ClInclude Include="dllmain.h" />
|
||||
<ClInclude Include="enums.h" />
|
||||
<ClInclude Include="gameclasses.h" />
|
||||
<ClInclude Include="hooks.h" />
|
||||
<ClInclude Include="opcodes.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
|
@ -50,36 +50,36 @@
|
||||
<Filter Include="shared\libraries\minhook\include">
|
||||
<UniqueIdentifier>{485b5648-149f-4664-a961-be9cd520e9e3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="r5-sdk">
|
||||
<UniqueIdentifier>{f5326cf2-826e-4499-98de-e818e096939d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="r5-sdk\include">
|
||||
<UniqueIdentifier>{4c680991-cc41-4265-a6f3-b46d698bd72f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="r5-sdk\src">
|
||||
<UniqueIdentifier>{8aac7eb6-9810-4fa2-bbfe-499fb2950f01}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\src">
|
||||
<UniqueIdentifier>{f28b1a49-9b41-48d2-9462-1674af3d72a2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\src\other">
|
||||
<UniqueIdentifier>{cc424eef-0c7a-4fb0-9d84-30bf8db2e253}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\src\squirrel">
|
||||
<UniqueIdentifier>{74afa89f-72af-4e13-aa90-70f7a1957154}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\src\netchannel">
|
||||
<UniqueIdentifier>{05e6e9a7-801b-49b0-9c5a-21c4868befb7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\src\iconvar">
|
||||
<UniqueIdentifier>{06affed3-5a59-4b95-88ca-72d92c91909b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\src\cvengineserver">
|
||||
<UniqueIdentifier>{338a4fb7-7519-4628-9206-679d33824965}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\include">
|
||||
<UniqueIdentifier>{31cdde4d-3641-497c-9b34-20d3d7c89d87}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\cvengineserver">
|
||||
<UniqueIdentifier>{338a4fb7-7519-4628-9206-679d33824965}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\iconvar">
|
||||
<UniqueIdentifier>{06affed3-5a59-4b95-88ca-72d92c91909b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\netchannel">
|
||||
<UniqueIdentifier>{05e6e9a7-801b-49b0-9c5a-21c4868befb7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\other">
|
||||
<UniqueIdentifier>{cc424eef-0c7a-4fb0-9d84-30bf8db2e253}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\squirrel">
|
||||
<UniqueIdentifier>{74afa89f-72af-4e13-aa90-70f7a1957154}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hooks\csourceappsystemgroup">
|
||||
<UniqueIdentifier>{9381fa63-cf89-4980-8e5a-bf6e43cb2283}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="r5-sdk">
|
||||
<UniqueIdentifier>{7fd080e8-390a-430b-a94c-e19c5792bf10}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="r5-sdk\src">
|
||||
<UniqueIdentifier>{e7e154b6-398e-42f9-bfb9-e80cd306254e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="r5-sdk\include">
|
||||
<UniqueIdentifier>{3c89e0ef-e415-4a91-86b7-2a04a5f03340}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\shared\include\address.h">
|
||||
@ -388,12 +388,18 @@
|
||||
<ClInclude Include="..\external\minhook\include\MinHook.h">
|
||||
<Filter>shared\libraries\minhook\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="opcodes.h">
|
||||
<Filter>r5-sdk\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hooks.h">
|
||||
<Filter>hooks\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="opcodes.h">
|
||||
<Filter>hooks\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gameclasses.h">
|
||||
<Filter>r5-sdk\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="enums.h">
|
||||
<Filter>r5-sdk\include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="console.cpp">
|
||||
@ -406,28 +412,34 @@
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="net.cpp">
|
||||
<Filter>hooks\src\netchannel</Filter>
|
||||
<Filter>hooks\netchannel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cvengineserver.cpp">
|
||||
<Filter>hooks\src\cvengineserver</Filter>
|
||||
<Filter>hooks\cvengineserver</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sqvm.cpp">
|
||||
<Filter>hooks\src\squirrel</Filter>
|
||||
<Filter>hooks\squirrel</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="msgbox.cpp">
|
||||
<Filter>hooks\src\other</Filter>
|
||||
<Filter>hooks\other</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\shared\utility.cpp">
|
||||
<Filter>shared</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="iconvar.cpp">
|
||||
<Filter>hooks\src\iconvar</Filter>
|
||||
<Filter>hooks\iconvar</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="opcodes.cpp">
|
||||
<Filter>r5-sdk\src</Filter>
|
||||
<Filter>hooks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hooks.cpp">
|
||||
<Filter>hooks\src</Filter>
|
||||
<Filter>hooks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="csourceappsystemgroup.cpp">
|
||||
<Filter>hooks\csourceappsystemgroup</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gameclasses.cpp">
|
||||
<Filter>r5-sdk\src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#pragma message("Pre-compiling headers.\n")
|
||||
#pragma message("[DEV] pre-compiling headers.\n")
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Prevent winsock2 redefinition.
|
||||
#include <windows.h>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "pch.h"
|
||||
|
||||
class BanList
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user