Initial commit.
This commit is contained in:
commit
3d10c578e0
68
.gitignore
vendored
Normal file
68
.gitignore
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
||||
# OSX
|
||||
# =========================
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
*.obj
|
||||
*.tlog
|
||||
*.log
|
||||
*.lastbuildstate
|
||||
*.idb
|
||||
*.exp
|
||||
*.ilk
|
||||
*.unsuccessfulbuild
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.pdb
|
||||
*.suo
|
||||
|
||||
# Additional stuff
|
||||
Release
|
||||
iw4/Release
|
||||
|
||||
# IDA
|
||||
# =========================
|
||||
*.id0
|
||||
*.id1
|
||||
*.id2
|
||||
*.nam
|
||||
*.til
|
19
iw4.sln
Normal file
19
iw4.sln
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.40629.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iw4", "iw4\iw4.vcxproj", "{38B4FC13-CEBC-4099-8698-3E62943C1EAA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{38B4FC13-CEBC-4099-8698-3E62943C1EAA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{38B4FC13-CEBC-4099-8698-3E62943C1EAA}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
83
iw4/Components/Colors.cpp
Normal file
83
iw4/Components/Colors.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
void Colors::Strip(const char* in, char* out, int max)
|
||||
{
|
||||
max--;
|
||||
int current = 0;
|
||||
while (*in != 0 && current < max)
|
||||
{
|
||||
if (!Q_IsColorString(in))
|
||||
{
|
||||
*out = *in;
|
||||
out++;
|
||||
current++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*in++;
|
||||
}
|
||||
*in++;
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
void __declspec(naked) Colors::ClientUserinfoChanged(int length)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h] // length
|
||||
sub eax, 1
|
||||
push eax
|
||||
|
||||
push ecx // name
|
||||
push edx // buffer
|
||||
|
||||
call strncpy
|
||||
|
||||
add esp, 0Ch
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
char* Colors::CL_GetClientName(int a1, int a2, char* buffer, size_t _length)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push _length
|
||||
push buffer
|
||||
push a2
|
||||
push a1
|
||||
mov eax, 4563D0h
|
||||
call eax
|
||||
add esp, 10h
|
||||
}
|
||||
|
||||
// Remove the colors
|
||||
char tempBuffer[100] = { 0 };
|
||||
Colors::Strip(buffer, tempBuffer, _length);
|
||||
strncpy(buffer, tempBuffer, _length);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Colors::Colors()
|
||||
{
|
||||
DWORD* color_table = (DWORD*)0x78DC70;
|
||||
|
||||
// Apply NTA's W² colors :3 (slightly modified though^^)
|
||||
color_table[1] = RGB(255, 49, 49);
|
||||
color_table[2] = RGB(134, 192, 0);
|
||||
color_table[3] = RGB(255, 173, 34);
|
||||
color_table[4] = RGB(0, 135, 193);
|
||||
color_table[5] = RGB(32, 197, 255);
|
||||
color_table[6] = RGB(151, 80, 221);
|
||||
|
||||
// Allow colored names ingame
|
||||
Utils::Hook(0x5D8B40, Colors::ClientUserinfoChanged, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Though, don't apply that to overhead names.
|
||||
Utils::Hook(0x581932, Colors::CL_GetClientName, HOOK_CALL).Install()->Quick();
|
||||
}
|
||||
}
|
17
iw4/Components/Colors.hpp
Normal file
17
iw4/Components/Colors.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#define Q_IsColorString( p ) ( ( p ) && *( p ) == '^' && *( ( p ) + 1 ) && isdigit( *( ( p ) + 1 ) ) ) // ^[0-9]
|
||||
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Colors : public Component
|
||||
{
|
||||
public:
|
||||
Colors();
|
||||
const char* GetName() { return "Colors"; };
|
||||
|
||||
static void ClientUserinfoChanged(int length);
|
||||
static char* CL_GetClientName(int a1, int a2, char* buffer, size_t _length);
|
||||
|
||||
static void Strip(const char* in, char* out, int max);
|
||||
};
|
||||
}
|
63
iw4/Components/Command.cpp
Normal file
63
iw4/Components/Command.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::vector<Game::cmd_function_t*> Command::Functions;
|
||||
std::map<std::string, Command::Callback> Command::FunctionMap;
|
||||
|
||||
const char* Command::Params::operator[](size_t index)
|
||||
{
|
||||
if (index >= this->Length())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return Game::cmd_argv[this->CommandId][index];
|
||||
}
|
||||
|
||||
size_t Command::Params::Length()
|
||||
{
|
||||
return Game::cmd_argc[this->CommandId];
|
||||
}
|
||||
|
||||
Command::~Command()
|
||||
{
|
||||
for (auto command : Command::Functions)
|
||||
{
|
||||
delete command;
|
||||
}
|
||||
|
||||
Command::Functions.clear();
|
||||
}
|
||||
|
||||
void Command::Add(const char* name, Command::Callback callback)
|
||||
{
|
||||
Command::FunctionMap[Utils::StrToLower(name)] = callback;
|
||||
Game::Cmd_AddCommand(name, Command::MainCallback, Command::Allocate(), 0);
|
||||
}
|
||||
|
||||
Game::cmd_function_t* Command::Allocate()
|
||||
{
|
||||
Game::cmd_function_t* cmd = new Game::cmd_function_t;
|
||||
Command::Functions.push_back(cmd);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void Command::MainCallback()
|
||||
{
|
||||
Command::Params params(*Game::cmd_id);
|
||||
|
||||
std::string command = Utils::StrToLower(params[0]);
|
||||
|
||||
if (Command::FunctionMap.find(command) != Command::FunctionMap.end())
|
||||
{
|
||||
Command::FunctionMap[command](params);
|
||||
}
|
||||
}
|
||||
|
||||
Command::Command()
|
||||
{
|
||||
// TODO: Add commands here?
|
||||
}
|
||||
}
|
37
iw4/Components/Command.hpp
Normal file
37
iw4/Components/Command.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#define Q_IsColorString( p ) ( ( p ) && *( p ) == '^' && *( ( p ) + 1 ) && isdigit( *( ( p ) + 1 ) ) ) // ^[0-9]
|
||||
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Command : public Component
|
||||
{
|
||||
public:
|
||||
class Params
|
||||
{
|
||||
public:
|
||||
Params(DWORD id) : CommandId(id) {};
|
||||
Params(const Params &obj) { this->CommandId = obj.CommandId; };
|
||||
|
||||
const char* operator[](size_t index);
|
||||
size_t Length();
|
||||
|
||||
private:
|
||||
DWORD CommandId;
|
||||
};
|
||||
|
||||
typedef void(*Callback)(Command::Params params);
|
||||
|
||||
Command();
|
||||
~Command();
|
||||
const char* GetName() { return "Command"; };
|
||||
|
||||
static void Add(const char* name, Callback callback);
|
||||
static int ArgCount();
|
||||
|
||||
private:
|
||||
static Game::cmd_function_t* Allocate();
|
||||
static std::vector<Game::cmd_function_t*> Functions;
|
||||
static std::map<std::string, Callback> FunctionMap;
|
||||
static void MainCallback();
|
||||
};
|
||||
}
|
30
iw4/Components/Console.cpp
Normal file
30
iw4/Components/Console.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
void Console::ToggleConsole()
|
||||
{
|
||||
// possibly cls.keyCatchers?
|
||||
DWORD catcher = 0xB2C538;
|
||||
Utils::Hook::Set<DWORD>(catcher, Utils::Hook::Get<DWORD>(catcher) ^ 1);
|
||||
|
||||
// g_consoleField
|
||||
Game::Field_Clear((void*)0xA1B6B0);
|
||||
|
||||
// show console output?
|
||||
Utils::Hook::Set<BYTE>(0xA15F38, 0);
|
||||
}
|
||||
|
||||
Console::Console()
|
||||
{
|
||||
// External console
|
||||
Utils::Hook::Nop(0x60BB58, 11);
|
||||
|
||||
// Console '%s: %s> ' string
|
||||
Utils::Hook::Set<char*>(0x5A44B4, "IW4x > ");
|
||||
|
||||
// Internal console
|
||||
Utils::Hook(0x4F690C, Console::ToggleConsole, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x4F65A5, Console::ToggleConsole, HOOK_JUMP).Install()->Quick();
|
||||
}
|
||||
}
|
12
iw4/Components/Console.hpp
Normal file
12
iw4/Components/Console.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Components
|
||||
{
|
||||
class Console : public Component
|
||||
{
|
||||
public:
|
||||
Console();
|
||||
const char* GetName() { return "Console"; };
|
||||
|
||||
private:
|
||||
static void ToggleConsole();
|
||||
};
|
||||
}
|
131
iw4/Components/Dvar.cpp
Normal file
131
iw4/Components/Dvar.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
Dvar::Var::Var(std::string dvarName) : Var()
|
||||
{
|
||||
this->dvar = Game::Dvar_FindVar(dvarName.data());
|
||||
|
||||
if (!this->dvar)
|
||||
{
|
||||
// Register the dvar?
|
||||
}
|
||||
}
|
||||
|
||||
template <> char* Dvar::Var::Get()
|
||||
{
|
||||
if (this->dvar && this->dvar->type == Game::dvar_type::DVAR_TYPE_STRING && this->dvar->current.string)
|
||||
{
|
||||
return this->dvar->current.string;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
template <> const char* Dvar::Var::Get()
|
||||
{
|
||||
return this->Get<char*>();
|
||||
}
|
||||
|
||||
template <> int Dvar::Var::Get()
|
||||
{
|
||||
if (this->dvar && this->dvar->type == Game::dvar_type::DVAR_TYPE_INT)
|
||||
{
|
||||
return this->dvar->current.integer;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <> float Dvar::Var::Get()
|
||||
{
|
||||
if (this->dvar && this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT)
|
||||
{
|
||||
return this->dvar->current.value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <> float* Dvar::Var::Get()
|
||||
{
|
||||
static float val[4] = { 0 };
|
||||
|
||||
if (this->dvar && (this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT_2 || this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT_3 || this->dvar->type == Game::dvar_type::DVAR_TYPE_FLOAT_4))
|
||||
{
|
||||
return this->dvar->current.vec4;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
template <> bool Dvar::Var::Get()
|
||||
{
|
||||
if (this->dvar && this->dvar->type == Game::dvar_type::DVAR_TYPE_BOOL)
|
||||
{
|
||||
return this->dvar->current.boolean;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Dvar::Var::Set(char* string)
|
||||
{
|
||||
this->Set(reinterpret_cast<const char*>(string));
|
||||
}
|
||||
|
||||
void Dvar::Var::Set(const char* string)
|
||||
{
|
||||
if (this->dvar && this->dvar->name)
|
||||
{
|
||||
Game::Dvar_SetCommand(this->dvar->name, string);
|
||||
}
|
||||
}
|
||||
|
||||
void Dvar::Var::Set(std::string string)
|
||||
{
|
||||
this->Set(string.data());
|
||||
}
|
||||
|
||||
void Dvar::Var::Set(int integer)
|
||||
{
|
||||
if (this->dvar && this->dvar->name)
|
||||
{
|
||||
Game::Dvar_SetCommand(this->dvar->name, Utils::VA("%i", integer));
|
||||
}
|
||||
}
|
||||
|
||||
void Dvar::Var::Set(float value)
|
||||
{
|
||||
if (this->dvar && this->dvar->name)
|
||||
{
|
||||
Game::Dvar_SetCommand(this->dvar->name, Utils::VA("%f", value));
|
||||
}
|
||||
}
|
||||
|
||||
template<> static Dvar::Var Dvar::Var::Register(const char* name, bool value, Game::dvar_flag flag, const char* description)
|
||||
{
|
||||
return Game::Dvar_RegisterBool(name, value, flag, description);
|
||||
}
|
||||
|
||||
template<> static Dvar::Var Dvar::Var::Register(const char* name, const char* value, Game::dvar_flag flag, const char* description)
|
||||
{
|
||||
return Game::Dvar_RegisterString(name, value, flag, description);
|
||||
}
|
||||
|
||||
Dvar::Dvar()
|
||||
{
|
||||
// set flags of cg_drawFPS to archive
|
||||
*(BYTE*)0x4F8F69 |= Game::dvar_flag::DVAR_FLAG_SAVED;
|
||||
|
||||
// un-cheat cg_fov and add archive flags
|
||||
*(BYTE*)0x4F8E35 ^= Game::dvar_flag::DVAR_FLAG_CHEAT | Game::dvar_flag::DVAR_FLAG_SAVED;
|
||||
|
||||
// set cg_fov max to 90.0
|
||||
static float cgFov90 = 90.0f;
|
||||
*(DWORD*)0x4F8E28 = (DWORD)&cgFov90;
|
||||
|
||||
Dvar::Var::Register<bool>("zob", true, Game::dvar_flag::DVAR_FLAG_NONE, "test dvar");
|
||||
//Dvar::Var::Register<const char*>("zob2", "test", Game::dvar_flag::DVAR_FLAG_NONE, "test dvar3");
|
||||
}
|
||||
}
|
36
iw4/Components/Dvar.hpp
Normal file
36
iw4/Components/Dvar.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
namespace Components
|
||||
{
|
||||
class Dvar : public Component
|
||||
{
|
||||
public:
|
||||
class Var
|
||||
{
|
||||
public:
|
||||
Var() : dvar(0) {};
|
||||
Var(const Var &obj) { this->dvar = obj.dvar; };
|
||||
Var(Game::dvar_t* _dvar) : dvar(_dvar) {};
|
||||
Var(std::string dvarName);
|
||||
|
||||
template<typename T> T Get();
|
||||
|
||||
void Set(char* string);
|
||||
void Set(const char* string);
|
||||
void Set(std::string string);
|
||||
|
||||
void Set(int integer);
|
||||
void Set(float value);
|
||||
|
||||
// Only strings and bools use this type of declaration
|
||||
template<typename T> static Var Register(const char* name, T value, Game::dvar_flag flag, const char* description);
|
||||
|
||||
private:
|
||||
Game::dvar_t* dvar;
|
||||
};
|
||||
|
||||
Dvar();
|
||||
const char* GetName() { return "Dvar"; };
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
37
iw4/Components/Loader.cpp
Normal file
37
iw4/Components/Loader.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::vector<Component*> Loader::Components;
|
||||
|
||||
void Loader::Initialize()
|
||||
{
|
||||
Loader::Register(new Dvar());
|
||||
Loader::Register(new Colors());
|
||||
Loader::Register(new Window());
|
||||
Loader::Register(new Command());
|
||||
Loader::Register(new Console());
|
||||
Loader::Register(new RawFiles());
|
||||
Loader::Register(new QuickPatch());
|
||||
}
|
||||
|
||||
void Loader::Uninitialize()
|
||||
{
|
||||
for (auto component : Loader::Components)
|
||||
{
|
||||
OutputDebugStringA(Utils::VA("Unregistering component: %s", component->GetName()));
|
||||
delete component;
|
||||
}
|
||||
|
||||
Loader::Components.clear();
|
||||
}
|
||||
|
||||
void Loader::Register(Component* component)
|
||||
{
|
||||
if (component)
|
||||
{
|
||||
OutputDebugStringA(Utils::VA("Component registered: %s", component->GetName()));
|
||||
Loader::Components.push_back(component);
|
||||
}
|
||||
}
|
||||
}
|
29
iw4/Components/Loader.hpp
Normal file
29
iw4/Components/Loader.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
namespace Components
|
||||
{
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
Component() {};
|
||||
virtual ~Component() {};
|
||||
virtual const char* GetName() { return "Unknown"; };
|
||||
};
|
||||
|
||||
class Loader
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Uninitialize();
|
||||
static void Register(Component* component);
|
||||
|
||||
private:
|
||||
static std::vector<Component*> Components;
|
||||
};
|
||||
}
|
||||
|
||||
#include "Dvar.hpp"
|
||||
#include "Colors.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "Command.hpp"
|
||||
#include "Console.hpp"
|
||||
#include "RawFiles.hpp"
|
||||
#include "QuickPatch.hpp"
|
44
iw4/Components/QuickPatch.cpp
Normal file
44
iw4/Components/QuickPatch.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
QuickPatch::QuickPatch()
|
||||
{
|
||||
// remove system pre-init stuff (improper quit, disk full)
|
||||
Utils::Hook::Set<BYTE>(0x411350, 0xC3);
|
||||
|
||||
// remove STEAMSTART checking for DRM IPC
|
||||
Utils::Hook::Nop(0x451145, 5);
|
||||
Utils::Hook::Set<BYTE>(0x45114C, 0xEB);
|
||||
|
||||
// disable playlist download function
|
||||
Utils::Hook::Set<BYTE>(0x4D4790, 0xC3);
|
||||
|
||||
// disable playlist.ff loading function
|
||||
Utils::Hook::Set<BYTE>(0x4D6E60, 0xC3);
|
||||
|
||||
// playlist dvar 'validity check'
|
||||
Utils::Hook::Set<BYTE>(0x4B1170, 0xC3);
|
||||
|
||||
//Got playlists is true
|
||||
Utils::Hook::Set<bool>(0x1AD3680, true);
|
||||
|
||||
// LSP disabled
|
||||
Utils::Hook::Set<BYTE>(0x435950, 0xC3); // LSP HELLO
|
||||
Utils::Hook::Set<BYTE>(0x49C220, 0xC3); // We wanted to send a logging packet, but we haven't connected to LSP!
|
||||
Utils::Hook::Set<BYTE>(0x4BD900, 0xC3); // main LSP response func
|
||||
Utils::Hook::Set<BYTE>(0x682170, 0xC3); // Telling LSP that we're playing a private match
|
||||
|
||||
// Don't delete config files if corrupted
|
||||
Utils::Hook::Set<BYTE>(0x47DCB3, 0xEB);
|
||||
|
||||
// hopefully allow alt-tab during game, used at least in alt-enter handling
|
||||
Utils::Hook::Set<DWORD>(0x45ACE0, 0xC301B0);
|
||||
|
||||
// fs_basegame
|
||||
Utils::Hook::Set<char*>(0x6431D1, "data");
|
||||
|
||||
// Why?
|
||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, 2400);
|
||||
}
|
||||
}
|
9
iw4/Components/QuickPatch.hpp
Normal file
9
iw4/Components/QuickPatch.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Components
|
||||
{
|
||||
class QuickPatch : public Component
|
||||
{
|
||||
public:
|
||||
QuickPatch();
|
||||
const char* GetName() { return "QuickPatch"; };
|
||||
};
|
||||
}
|
24
iw4/Components/RawFiles.cpp
Normal file
24
iw4/Components/RawFiles.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
void* RawFiles::LoadModdableRawfileFunc(const char* filename)
|
||||
{
|
||||
return Game::LoadModdableRawfile(0, filename);
|
||||
}
|
||||
|
||||
RawFiles::RawFiles()
|
||||
{
|
||||
Utils::Hook(0x632155, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x5FA46C, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x5FA4D6, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x6321EF, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x630A88, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x59A6F8, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x57F1E6, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x57ED36, RawFiles::LoadModdableRawfileFunc, HOOK_CALL).Install()->Quick();
|
||||
|
||||
// remove fs_game check for moddable rawfiles - allows non-fs_game to modify rawfiles
|
||||
Utils::Hook::Nop(0x61AB76, 2);
|
||||
}
|
||||
}
|
14
iw4/Components/RawFiles.hpp
Normal file
14
iw4/Components/RawFiles.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#define Q_IsColorString( p ) ( ( p ) && *( p ) == '^' && *( ( p ) + 1 ) && isdigit( *( ( p ) + 1 ) ) ) // ^[0-9]
|
||||
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class RawFiles : public Component
|
||||
{
|
||||
public:
|
||||
RawFiles();
|
||||
const char* GetName() { return "RawFiles"; };
|
||||
|
||||
static void* RawFiles::LoadModdableRawfileFunc(const char* filename);
|
||||
};
|
||||
}
|
27
iw4/Components/Window.cpp
Normal file
27
iw4/Components/Window.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
Dvar::Var Window::NoBorder;
|
||||
|
||||
void __declspec(naked) Window::StyleHookStub()
|
||||
{
|
||||
if (Window::NoBorder.Get<bool>())
|
||||
{
|
||||
__asm mov ebp, WS_VISIBLE | WS_POPUP
|
||||
}
|
||||
else
|
||||
{
|
||||
__asm mov ebp, WS_VISIBLE | WS_SYSMENU | WS_CAPTION
|
||||
}
|
||||
|
||||
__asm retn
|
||||
}
|
||||
|
||||
Window::Window()
|
||||
{
|
||||
// Borderless window
|
||||
Window::NoBorder = Dvar::Var::Register<bool>("r_noborder", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Do not use a border in windowed mode");
|
||||
Utils::Hook(0x507643, Window::StyleHookStub, HOOK_CALL).Install()->Quick();
|
||||
}
|
||||
}
|
12
iw4/Components/Window.hpp
Normal file
12
iw4/Components/Window.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Components
|
||||
{
|
||||
class Window : public Component
|
||||
{
|
||||
public:
|
||||
Window();
|
||||
const char* GetName() { return "Window"; };
|
||||
|
||||
static Dvar::Var NoBorder;
|
||||
static void Window::StyleHookStub();
|
||||
};
|
||||
}
|
41
iw4/Game/Functions.cpp
Normal file
41
iw4/Game/Functions.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Game
|
||||
{
|
||||
Cmd_AddCommand_t Cmd_AddCommand = (Cmd_AddCommand_t)0x470090;
|
||||
|
||||
DB_GetXAssetSizeHandler_t* DB_GetXAssetSizeHandlers = (DB_GetXAssetSizeHandler_t*)0x799488;
|
||||
|
||||
Dvar_RegisterBool_t Dvar_RegisterBool = (Dvar_RegisterBool_t)0x4CE1A0;
|
||||
Dvar_RegisterFloat_t Dvar_RegisterFloat = (Dvar_RegisterFloat_t)0x648440;
|
||||
Dvar_RegisterFloat2_t Dvar_RegisterFloat2 = (Dvar_RegisterFloat2_t)0x4F6070;
|
||||
Dvar_RegisterFloat3_t Dvar_RegisterFloat3 = (Dvar_RegisterFloat3_t)0x4EF8E0;
|
||||
Dvar_RegisterFloat4_t Dvar_RegisterFloat4 = (Dvar_RegisterFloat4_t)0x4F28E0;
|
||||
Dvar_RegisterInt_t Dvar_RegisterInt = (Dvar_RegisterInt_t)0x479830;
|
||||
Dvar_RegisterEnum_t Dvar_RegisterEnum = (Dvar_RegisterEnum_t)0x412E40;
|
||||
Dvar_RegisterString_t Dvar_RegisterString = (Dvar_RegisterString_t)0x4FC7E0;
|
||||
Dvar_RegisterColor_t Dvar_RegisterColor = (Dvar_RegisterColor_t)0x471500;
|
||||
|
||||
Dvar_FindVar_t Dvar_FindVar = (Dvar_FindVar_t)0x4D5390;
|
||||
Dvar_SetCommand_t Dvar_SetCommand = (Dvar_SetCommand_t)0x4EE430;
|
||||
|
||||
Field_Clear_t Field_Clear = (Field_Clear_t)0x437EB0;
|
||||
|
||||
LoadModdableRawfile_t LoadModdableRawfile = (LoadModdableRawfile_t)0x61ABC0;
|
||||
|
||||
void** DB_XAssetPool = (void**)0x7998A8;
|
||||
unsigned int* g_poolSize = (unsigned int*)0x7995E8;
|
||||
|
||||
DWORD* cmd_id = (DWORD*)0x1AAC5D0;
|
||||
DWORD* cmd_argc = (DWORD*)0x1AAC614;
|
||||
char*** cmd_argv = (char***)0x1AAC634;
|
||||
|
||||
void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
||||
{
|
||||
int elSize = DB_GetXAssetSizeHandlers[type]();
|
||||
void* poolEntry = new char[newSize * elSize];
|
||||
DB_XAssetPool[type] = poolEntry;
|
||||
g_poolSize[type] = newSize;
|
||||
return poolEntry;
|
||||
}
|
||||
}
|
56
iw4/Game/Functions.hpp
Normal file
56
iw4/Game/Functions.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
namespace Game
|
||||
{
|
||||
typedef void(__cdecl * Cmd_AddCommand_t)(const char* name, void(*callback), cmd_function_t* data, char);
|
||||
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||
|
||||
typedef int(__cdecl * DB_GetXAssetSizeHandler_t)();
|
||||
extern DB_GetXAssetSizeHandler_t* DB_GetXAssetSizeHandlers;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterBool_t)(const char* name, bool default, int flags, const char* description);
|
||||
extern Dvar_RegisterBool_t Dvar_RegisterBool;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat_t)(const char* name, float default, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat_t Dvar_RegisterFloat;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat2_t)(const char* name, float defx, float defy, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat2_t Dvar_RegisterFloat2;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat3_t)(const char* name, float defx, float defy, float defz, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat3_t Dvar_RegisterFloat3;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterFloat4_t)(const char* name, float defx, float defy, float defz, float defw, float min, float max, int flags, const char* description);
|
||||
extern Dvar_RegisterFloat4_t Dvar_RegisterFloat4;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterInt_t)(const char* name, int default, int min, int max, int flags, const char* description);
|
||||
extern Dvar_RegisterInt_t Dvar_RegisterInt;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterEnum_t)(const char* name, char** enumValues, int default, int flags, const char* description);
|
||||
extern Dvar_RegisterEnum_t Dvar_RegisterEnum;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterString_t)(const char* name, const char* default, int, const char*);
|
||||
extern Dvar_RegisterString_t Dvar_RegisterString;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterColor_t)(const char* name, float r, float g, float b, float a, int flags, const char* description);
|
||||
extern Dvar_RegisterColor_t Dvar_RegisterColor;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_FindVar_t)(const char *dvarName);
|
||||
extern Dvar_FindVar_t Dvar_FindVar;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_SetCommand_t)(const char* name, const char* value);
|
||||
extern Dvar_SetCommand_t Dvar_SetCommand;
|
||||
|
||||
typedef void(__cdecl * Field_Clear_t)(void* field);
|
||||
extern Field_Clear_t Field_Clear;
|
||||
|
||||
typedef void* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename);
|
||||
extern LoadModdableRawfile_t LoadModdableRawfile;
|
||||
|
||||
extern void** DB_XAssetPool;
|
||||
extern unsigned int* g_poolSize;
|
||||
|
||||
extern DWORD* cmd_id;
|
||||
extern DWORD* cmd_argc;
|
||||
extern char*** cmd_argv;
|
||||
|
||||
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
||||
}
|
123
iw4/Game/Structs.hpp
Normal file
123
iw4/Game/Structs.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
namespace Game
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
ASSET_TYPE_PHYSPRESET = 0,
|
||||
ASSET_TYPE_PHYS_COLLMAP = 1,
|
||||
ASSET_TYPE_XANIM = 2,
|
||||
ASSET_TYPE_XMODELSURFS = 3,
|
||||
ASSET_TYPE_XMODEL = 4,
|
||||
ASSET_TYPE_MATERIAL = 5,
|
||||
ASSET_TYPE_PIXELSHADER = 6,
|
||||
ASSET_TYPE_VERTEXSHADER = 7,
|
||||
ASSET_TYPE_VERTEXDECL = 8,
|
||||
ASSET_TYPE_TECHSET = 9,
|
||||
ASSET_TYPE_IMAGE = 10,
|
||||
ASSET_TYPE_SOUND = 11,
|
||||
ASSET_TYPE_SNDCURVE = 12,
|
||||
ASSET_TYPE_LOADED_SOUND = 13,
|
||||
ASSET_TYPE_COL_MAP_SP = 14,
|
||||
ASSET_TYPE_COL_MAP_MP = 15,
|
||||
ASSET_TYPE_COM_MAP = 16,
|
||||
ASSET_TYPE_GAME_MAP_SP = 17,
|
||||
ASSET_TYPE_GAME_MAP_MP = 18,
|
||||
ASSET_TYPE_MAP_ENTS = 19,
|
||||
ASSET_TYPE_FX_MAP = 20,
|
||||
ASSET_TYPE_GFX_MAP = 21,
|
||||
ASSET_TYPE_LIGHTDEF = 22,
|
||||
ASSET_TYPE_UI_MAP = 23,
|
||||
ASSET_TYPE_FONT = 24,
|
||||
ASSET_TYPE_MENUFILE = 25,
|
||||
ASSET_TYPE_MENU = 26,
|
||||
ASSET_TYPE_LOCALIZE = 27,
|
||||
ASSET_TYPE_WEAPON = 28,
|
||||
ASSET_TYPE_SNDDRIVERGLOBALS = 29,
|
||||
ASSET_TYPE_FX = 30,
|
||||
ASSET_TYPE_IMPACTFX = 31,
|
||||
ASSET_TYPE_AITYPE = 32,
|
||||
ASSET_TYPE_MPTYPE = 33,
|
||||
ASSET_TYPE_CHARACTER = 34,
|
||||
ASSET_TYPE_XMODELALIAS = 35,
|
||||
ASSET_TYPE_RAWFILE = 36,
|
||||
ASSET_TYPE_STRINGTABLE = 37,
|
||||
ASSET_TYPE_LEADERBOARDDEF = 38,
|
||||
ASSET_TYPE_STRUCTUREDDATADEF = 39,
|
||||
ASSET_TYPE_TRACER = 40,
|
||||
ASSET_TYPE_VEHICLE = 41,
|
||||
ASSET_TYPE_ADDON_MAP_ENTS = 42,
|
||||
ASSET_TYPE_MAX = 43
|
||||
} XAssetType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DVAR_FLAG_NONE = 0x0, //no flags
|
||||
DVAR_FLAG_SAVED = 0x1, //saves in config_mp.cfg for clients
|
||||
DVAR_FLAG_LATCHED = 0x2, //no changing apart from initial value (although it might apply on a map reload, I think)
|
||||
DVAR_FLAG_CHEAT = 0x4, //cheat
|
||||
DVAR_FLAG_REPLICATED = 0x8, //on change, this is sent to all clients (if you are host)
|
||||
DVAR_FLAG_UNKNOWN10 = 0x10, //unknown
|
||||
DVAR_FLAG_UNKNOWN20 = 0x20, //unknown
|
||||
DVAR_FLAG_UNKNOWN40 = 0x40, //unknown
|
||||
DVAR_FLAG_UNKNOWN80 = 0x80, //unknown
|
||||
DVAR_FLAG_USERCREATED = 0x100, //a 'set' type command created it
|
||||
DVAR_FLAG_USERINFO = 0x200, //userinfo?
|
||||
DVAR_FLAG_SERVERINFO = 0x400, //in the getstatus oob
|
||||
DVAR_FLAG_WRITEPROTECTED = 0x800, //write protected
|
||||
DVAR_FLAG_UNKNOWN1000 = 0x1000, //unknown
|
||||
DVAR_FLAG_READONLY = 0x2000, //read only (same as 0x800?)
|
||||
DVAR_FLAG_UNKNOWN4000 = 0x4000, //unknown
|
||||
DVAR_FLAG_UNKNOWN8000 = 0x8000, //unknown
|
||||
DVAR_FLAG_UNKNOWN10000 = 0x10000, //unknown
|
||||
DVAR_FLAG_DEDISAVED = 0x1000000, //unknown
|
||||
DVAR_FLAG_NONEXISTENT = 0xFFFFFFFF //no such dvar
|
||||
} dvar_flag;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DVAR_TYPE_BOOL = 0,
|
||||
DVAR_TYPE_FLOAT = 1,
|
||||
DVAR_TYPE_FLOAT_2 = 2,
|
||||
DVAR_TYPE_FLOAT_3 = 3,
|
||||
DVAR_TYPE_FLOAT_4 = 4,
|
||||
DVAR_TYPE_INT = 5,
|
||||
DVAR_TYPE_ENUM = 6,
|
||||
DVAR_TYPE_STRING = 7,
|
||||
DVAR_TYPE_COLOR = 8,
|
||||
//DVAR_TYPE_INT64 = 9 only in Tx
|
||||
} dvar_type;
|
||||
// 67/72 bytes figured out
|
||||
union dvar_value_t {
|
||||
char* string;
|
||||
int integer;
|
||||
float value;
|
||||
bool boolean;
|
||||
float vec2[2];
|
||||
float vec3[3];
|
||||
float vec4[4];
|
||||
BYTE color[4]; //to get float: multiply by 0.003921568859368563 - BaberZz
|
||||
//__int64 integer64; only in Tx
|
||||
};
|
||||
union dvar_maxmin_t {
|
||||
int i;
|
||||
float f;
|
||||
};
|
||||
typedef struct dvar_t
|
||||
{
|
||||
//startbyte:endbyte
|
||||
const char* name; //0:3
|
||||
const char* description; //4:7
|
||||
unsigned int flags; //8:11
|
||||
char type; //12:12
|
||||
char pad2[3]; //13:15
|
||||
dvar_value_t current; //16:31
|
||||
dvar_value_t latched; //32:47
|
||||
dvar_value_t default; //48:64
|
||||
dvar_maxmin_t min; //65:67
|
||||
dvar_maxmin_t max; //68:72 woooo
|
||||
} dvar_t;
|
||||
|
||||
typedef struct cmd_function_s
|
||||
{
|
||||
char pad[24];
|
||||
} cmd_function_t;
|
||||
}
|
27
iw4/Main.cpp
Normal file
27
iw4/Main.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
Utils::Hook EntryPointHook;
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
FreeConsole();
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(GetModuleHandle(NULL), 0x6C73000, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
EntryPointHook.Initialize(0x6BAC0F, static_cast<void __declspec(naked)(*)()>([] ()
|
||||
{
|
||||
EntryPointHook.Uninstall();
|
||||
Components::Loader::Initialize();
|
||||
__asm jmp EntryPointHook.Place
|
||||
}))->Install();
|
||||
}
|
||||
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
|
||||
{
|
||||
Components::Loader::Uninitialize();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
22
iw4/STDInclude.hpp
Normal file
22
iw4/STDInclude.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Game\Structs.hpp"
|
||||
#include "Game\Functions.hpp"
|
||||
|
||||
#include "Utils\Utils.hpp"
|
||||
#include "Utils\Hooking.hpp"
|
||||
|
||||
#include "Steam\Steam.hpp"
|
||||
|
||||
#include "Components\Loader.hpp"
|
120
iw4/Steam/Interfaces/SteamFriends.cpp
Normal file
120
iw4/Steam/Interfaces/SteamFriends.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
using namespace Components;
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
const char *Friends::GetPersonaName()
|
||||
{
|
||||
return Dvar::Var("name").Get<const char*>();
|
||||
}
|
||||
|
||||
void Friends::SetPersonaName(const char *pchPersonaName)
|
||||
{
|
||||
Dvar::Var("name").Set(pchPersonaName);
|
||||
}
|
||||
|
||||
int Friends::GetPersonaState()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Friends::GetFriendCount(int eFriendFlags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SteamID Friends::GetFriendByIndex(int iFriend, int iFriendFlags)
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
int Friends::GetFriendRelationship(SteamID steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Friends::GetFriendPersonaState(SteamID steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *Friends::GetFriendPersonaName(SteamID steamIDFriend)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int Friends::GetFriendAvatar(SteamID steamIDFriend, int eAvatarSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Friends::GetFriendGamePlayed(SteamID steamIDFriend, void *pFriendGameInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *Friends::GetFriendPersonaNameHistory(SteamID steamIDFriend, int iPersonaName)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Friends::HasFriend(SteamID steamIDFriend, int eFriendFlags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Friends::GetClanCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SteamID Friends::GetClanByIndex(int iClan)
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
const char *Friends::GetClanName(SteamID steamIDClan)
|
||||
{
|
||||
return "3arc";
|
||||
}
|
||||
|
||||
int Friends::GetFriendCountFromSource(SteamID steamIDSource)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SteamID Friends::GetFriendFromSourceByIndex(SteamID steamIDSource, int iFriend)
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
bool Friends::IsUserInSource(SteamID steamIDUser, SteamID steamIDSource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Friends::SetInGameVoiceSpeaking(SteamID steamIDUser, bool bSpeaking)
|
||||
{
|
||||
}
|
||||
|
||||
void Friends::ActivateGameOverlay(const char *pchDialog)
|
||||
{
|
||||
}
|
||||
|
||||
void Friends::ActivateGameOverlayToUser(const char *pchDialog, SteamID steamID)
|
||||
{
|
||||
}
|
||||
|
||||
void Friends::ActivateGameOverlayToWebPage(const char *pchURL)
|
||||
{
|
||||
}
|
||||
|
||||
void Friends::ActivateGameOverlayToStore(unsigned int nAppID)
|
||||
{
|
||||
}
|
||||
|
||||
void Friends::SetPlayedWith(SteamID steamIDUserPlayedWith)
|
||||
{
|
||||
}
|
||||
}
|
31
iw4/Steam/Interfaces/SteamFriends.hpp
Normal file
31
iw4/Steam/Interfaces/SteamFriends.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
namespace Steam
|
||||
{
|
||||
class Friends
|
||||
{
|
||||
public:
|
||||
virtual const char *GetPersonaName();
|
||||
virtual void SetPersonaName(const char *pchPersonaName);
|
||||
virtual int GetPersonaState();
|
||||
virtual int GetFriendCount(int eFriendFlags);
|
||||
virtual SteamID GetFriendByIndex(int iFriend, int iFriendFlags);
|
||||
virtual int GetFriendRelationship(SteamID steamIDFriend);
|
||||
virtual int GetFriendPersonaState(SteamID steamIDFriend);
|
||||
virtual const char *GetFriendPersonaName(SteamID steamIDFriend);
|
||||
virtual int GetFriendAvatar(SteamID steamIDFriend, int eAvatarSize);
|
||||
virtual bool GetFriendGamePlayed(SteamID steamIDFriend, void *pFriendGameInfo);
|
||||
virtual const char *GetFriendPersonaNameHistory(SteamID steamIDFriend, int iPersonaName);
|
||||
virtual bool HasFriend(SteamID steamIDFriend, int eFriendFlags);
|
||||
virtual int GetClanCount();
|
||||
virtual SteamID GetClanByIndex(int iClan);
|
||||
virtual const char *GetClanName(SteamID steamIDClan);
|
||||
virtual int GetFriendCountFromSource(SteamID steamIDSource);
|
||||
virtual SteamID GetFriendFromSourceByIndex(SteamID steamIDSource, int iFriend);
|
||||
virtual bool IsUserInSource(SteamID steamIDUser, SteamID steamIDSource);
|
||||
virtual void SetInGameVoiceSpeaking(SteamID steamIDUser, bool bSpeaking);
|
||||
virtual void ActivateGameOverlay(const char *pchDialog);
|
||||
virtual void ActivateGameOverlayToUser(const char *pchDialog, SteamID steamID);
|
||||
virtual void ActivateGameOverlayToWebPage(const char *pchURL);
|
||||
virtual void ActivateGameOverlayToStore(unsigned int nAppID);
|
||||
virtual void SetPlayedWith(SteamID steamIDUserPlayedWith);
|
||||
};
|
||||
}
|
91
iw4/Steam/Interfaces/SteamGameServer.cpp
Normal file
91
iw4/Steam/Interfaces/SteamGameServer.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
void GameServer::LogOn()
|
||||
{
|
||||
}
|
||||
|
||||
void GameServer::LogOff()
|
||||
{
|
||||
}
|
||||
|
||||
bool GameServer::LoggedOn()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameServer::Secure()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SteamID GameServer::GetSteamID()
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
bool GameServer::SendUserConnectAndAuthenticate(unsigned int unIPClient, const void *pvAuthBlob, unsigned int cubAuthBlobSize, SteamID *pSteamIDUser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SteamID GameServer::CreateUnauthenticatedUserConnection()
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
void GameServer::SendUserDisconnect(SteamID steamIDUser)
|
||||
{
|
||||
}
|
||||
|
||||
bool GameServer::UpdateUserData(SteamID steamIDUser, const char *pchPlayerName, unsigned int uScore)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameServer::SetServerType(unsigned int unServerFlags, unsigned int unGameIP, unsigned short unGamePort, unsigned short unSpectatorPort, unsigned short usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void GameServer::UpdateServerStatus(int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pSpectatorServerName, const char *pchMapName)
|
||||
{
|
||||
}
|
||||
|
||||
void GameServer::UpdateSpectatorPort(unsigned short unSpectatorPort)
|
||||
{
|
||||
}
|
||||
|
||||
void GameServer::SetGameType(const char *pchGameType)
|
||||
{
|
||||
}
|
||||
|
||||
bool GameServer::GetUserAchievementStatus(SteamID steamID, const char *pchAchievementName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GameServer::GetGameplayStats()
|
||||
{
|
||||
}
|
||||
|
||||
bool GameServer::RequestUserGroupStatus(SteamID steamIDUser, SteamID steamIDGroup)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int GameServer::GetPublicIP()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GameServer::SetGameData(const char *pchGameData)
|
||||
{
|
||||
}
|
||||
|
||||
int GameServer::UserHasLicenseForApp(SteamID steamID, unsigned int appID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
26
iw4/Steam/Interfaces/SteamGameServer.hpp
Normal file
26
iw4/Steam/Interfaces/SteamGameServer.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
namespace Steam
|
||||
{
|
||||
class GameServer
|
||||
{
|
||||
public:
|
||||
virtual void LogOn();
|
||||
virtual void LogOff();
|
||||
virtual bool LoggedOn();
|
||||
virtual bool Secure();
|
||||
virtual SteamID GetSteamID();
|
||||
virtual bool SendUserConnectAndAuthenticate(unsigned int unIPClient, const void *pvAuthBlob, unsigned int cubAuthBlobSize, SteamID *pSteamIDUser);
|
||||
virtual SteamID CreateUnauthenticatedUserConnection();
|
||||
virtual void SendUserDisconnect(SteamID steamIDUser);
|
||||
virtual bool UpdateUserData(SteamID steamIDUser, const char *pchPlayerName, unsigned int uScore);
|
||||
virtual bool SetServerType(unsigned int unServerFlags, unsigned int unGameIP, unsigned short unGamePort, unsigned short unSpectatorPort, unsigned short usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode);
|
||||
virtual void UpdateServerStatus(int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pSpectatorServerName, const char *pchMapName);
|
||||
virtual void UpdateSpectatorPort(unsigned short unSpectatorPort);
|
||||
virtual void SetGameType(const char *pchGameType);
|
||||
virtual bool GetUserAchievementStatus(SteamID steamID, const char *pchAchievementName);
|
||||
virtual void GetGameplayStats();
|
||||
virtual bool RequestUserGroupStatus(SteamID steamIDUser, SteamID steamIDGroup);
|
||||
virtual unsigned int GetPublicIP();
|
||||
virtual void SetGameData(const char *pchGameData);
|
||||
virtual int UserHasLicenseForApp(SteamID steamID, unsigned int appID);
|
||||
};
|
||||
}
|
67
iw4/Steam/Interfaces/SteamMasterServerUpdater.cpp
Normal file
67
iw4/Steam/Interfaces/SteamMasterServerUpdater.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
void MasterServerUpdater::SetActive(bool bActive)
|
||||
{
|
||||
}
|
||||
|
||||
void MasterServerUpdater::SetHeartbeatInterval(int iHeartbeatInterval)
|
||||
{
|
||||
}
|
||||
|
||||
bool MasterServerUpdater::HandleIncomingPacket(const void *pData, int cbData, unsigned int srcIP, unsigned short srcPort)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int MasterServerUpdater::GetNextOutgoingPacket(void *pOut, int cbMaxOut, unsigned int *pNetAdr, unsigned short *pPort)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MasterServerUpdater::SetBasicServerData(unsigned short nProtocolVersion, bool bDedicatedServer, const char *pRegionName, const char *pProductName, unsigned short nMaxReportedClients, bool bPasswordProtected, const char *pGameDescription)
|
||||
{
|
||||
}
|
||||
|
||||
void MasterServerUpdater::ClearAllKeyValues()
|
||||
{
|
||||
}
|
||||
|
||||
void MasterServerUpdater::SetKeyValue(const char *pKey, const char *pValue)
|
||||
{
|
||||
}
|
||||
|
||||
void MasterServerUpdater::NotifyShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
bool MasterServerUpdater::WasRestartRequested()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MasterServerUpdater::ForceHeartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
bool MasterServerUpdater::AddMasterServer(const char *pServerAddress)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MasterServerUpdater::RemoveMasterServer(const char *pServerAddress)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int MasterServerUpdater::GetNumMasterServers()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MasterServerUpdater::GetMasterServerAddress(int iServer, char *pOut, int outBufferSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
21
iw4/Steam/Interfaces/SteamMasterServerUpdater.hpp
Normal file
21
iw4/Steam/Interfaces/SteamMasterServerUpdater.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
namespace Steam
|
||||
{
|
||||
class MasterServerUpdater
|
||||
{
|
||||
public:
|
||||
virtual void SetActive(bool bActive);
|
||||
virtual void SetHeartbeatInterval(int iHeartbeatInterval);
|
||||
virtual bool HandleIncomingPacket(const void *pData, int cbData, unsigned int srcIP, unsigned short srcPort);
|
||||
virtual int GetNextOutgoingPacket(void *pOut, int cbMaxOut, unsigned int *pNetAdr, unsigned short *pPort);
|
||||
virtual void SetBasicServerData(unsigned short nProtocolVersion, bool bDedicatedServer, const char *pRegionName, const char *pProductName, unsigned short nMaxReportedClients, bool bPasswordProtected, const char *pGameDescription);
|
||||
virtual void ClearAllKeyValues();
|
||||
virtual void SetKeyValue(const char *pKey, const char *pValue);
|
||||
virtual void NotifyShutdown();
|
||||
virtual bool WasRestartRequested();
|
||||
virtual void ForceHeartbeat();
|
||||
virtual bool AddMasterServer(const char *pServerAddress);
|
||||
virtual bool RemoveMasterServer(const char *pServerAddress);
|
||||
virtual int GetNumMasterServers();
|
||||
virtual int GetMasterServerAddress(int iServer, char *pOut, int outBufferSize);
|
||||
};
|
||||
}
|
170
iw4/Steam/Interfaces/SteamMatchmaking.cpp
Normal file
170
iw4/Steam/Interfaces/SteamMatchmaking.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
int Matchmaking::GetFavoriteGameCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Matchmaking::GetFavoriteGame(int iGame, unsigned int *pnAppID, unsigned int *pnIP, unsigned short *pnConnPort, unsigned short *pnQueryPort, unsigned int *punFlags, unsigned int *pRTime32LastPlayedOnServer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Matchmaking::AddFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, unsigned short nQueryPort, unsigned int unFlags, unsigned int rTime32LastPlayedOnServer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Matchmaking::RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, unsigned short nQueryPort, unsigned int unFlags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned __int64 Matchmaking::RequestLobbyList()
|
||||
{
|
||||
// TODO: Implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Matchmaking::AddRequestLobbyListStringFilter(const char *pchKeyToMatch, const char *pchValueToMatch, int eComparisonType)
|
||||
{
|
||||
}
|
||||
|
||||
void Matchmaking::AddRequestLobbyListNumericalFilter(const char *pchKeyToMatch, int nValueToMatch, int eComparisonType)
|
||||
{
|
||||
}
|
||||
|
||||
void Matchmaking::AddRequestLobbyListNearValueFilter(const char *pchKeyToMatch, int nValueToBeCloseTo)
|
||||
{
|
||||
}
|
||||
|
||||
void Matchmaking::AddRequestLobbyListFilterSlotsAvailable(int nSlotsAvailable)
|
||||
{
|
||||
}
|
||||
|
||||
SteamID Matchmaking::GetLobbyByIndex(int iLobby)
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
unsigned __int64 Matchmaking::CreateLobby(int eLobbyType, int cMaxMembers)
|
||||
{
|
||||
// TODO: Implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned __int64 Matchmaking::JoinLobby(SteamID steamIDLobby)
|
||||
{
|
||||
// TODO: Implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Matchmaking::LeaveLobby(SteamID steamIDLobby)
|
||||
{
|
||||
}
|
||||
|
||||
bool Matchmaking::InviteUserToLobby(SteamID steamIDLobby, SteamID steamIDInvitee)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Matchmaking::GetNumLobbyMembers(SteamID steamIDLobby)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SteamID Matchmaking::GetLobbyMemberByIndex(SteamID steamIDLobby, int iMember)
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
const char *Matchmaking::GetLobbyData(SteamID steamIDLobby, const char *pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Matchmaking::SetLobbyData(SteamID steamIDLobby, const char *pchKey, const char *pchValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Matchmaking::GetLobbyDataCount(SteamID steamIDLobby)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Matchmaking::GetLobbyDataByIndex(SteamID steamIDLobby, int iLobbyData, char *pchKey, int cchKeyBufferSize, char *pchValue, int cchValueBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Matchmaking::DeleteLobbyData(SteamID steamIDLobby, const char *pchKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *Matchmaking::GetLobbyMemberData(SteamID steamIDLobby, SteamID steamIDUser, const char *pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void Matchmaking::SetLobbyMemberData(SteamID steamIDLobby, const char *pchKey, const char *pchValue)
|
||||
{
|
||||
}
|
||||
|
||||
bool Matchmaking::SendLobbyChatMsg(SteamID steamIDLobby, const void *pvMsgBody, int cubMsgBody)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Matchmaking::GetLobbyChatEntry(SteamID steamIDLobby, int iChatID, SteamID *pSteamIDUser, void *pvData, int cubData, int *peChatEntryType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Matchmaking::RequestLobbyData(SteamID steamIDLobby)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Matchmaking::SetLobbyGameServer(SteamID steamIDLobby, unsigned int unGameServerIP, unsigned short unGameServerPort, SteamID steamIDGameServer)
|
||||
{
|
||||
}
|
||||
|
||||
bool Matchmaking::GetLobbyGameServer(SteamID steamIDLobby, unsigned int *punGameServerIP, unsigned short *punGameServerPort, SteamID *psteamIDGameServer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Matchmaking::SetLobbyMemberLimit(SteamID steamIDLobby, int cMaxMembers)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Matchmaking::GetLobbyMemberLimit(SteamID steamIDLobby)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Matchmaking::SetLobbyType(SteamID steamIDLobby, int eLobbyType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matchmaking::SetLobbyJoinable(SteamID steamIDLobby, bool bLobbyJoinable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SteamID Matchmaking::GetLobbyOwner(SteamID steamIDLobby)
|
||||
{
|
||||
return SteamID();
|
||||
}
|
||||
|
||||
bool Matchmaking::SetLobbyOwner(SteamID steamIDLobby, SteamID steamIDNewOwner)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
41
iw4/Steam/Interfaces/SteamMatchmaking.hpp
Normal file
41
iw4/Steam/Interfaces/SteamMatchmaking.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
namespace Steam
|
||||
{
|
||||
class Matchmaking
|
||||
{
|
||||
public:
|
||||
virtual int GetFavoriteGameCount();
|
||||
virtual bool GetFavoriteGame(int iGame, unsigned int *pnAppID, unsigned int *pnIP, unsigned short *pnConnPort, unsigned short *pnQueryPort, unsigned int *punFlags, unsigned int *pRTime32LastPlayedOnServer);
|
||||
virtual int AddFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, unsigned short nQueryPort, unsigned int unFlags, unsigned int rTime32LastPlayedOnServer);
|
||||
virtual bool RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, unsigned short nQueryPort, unsigned int unFlags);
|
||||
virtual unsigned __int64 RequestLobbyList();
|
||||
virtual void AddRequestLobbyListStringFilter(const char *pchKeyToMatch, const char *pchValueToMatch, int eComparisonType);
|
||||
virtual void AddRequestLobbyListNumericalFilter(const char *pchKeyToMatch, int nValueToMatch, int eComparisonType);
|
||||
virtual void AddRequestLobbyListNearValueFilter(const char *pchKeyToMatch, int nValueToBeCloseTo);
|
||||
virtual void AddRequestLobbyListFilterSlotsAvailable(int nSlotsAvailable);
|
||||
virtual SteamID GetLobbyByIndex(int iLobby);
|
||||
virtual unsigned __int64 CreateLobby(int eLobbyType, int cMaxMembers);
|
||||
virtual unsigned __int64 JoinLobby(SteamID steamIDLobby);
|
||||
virtual void LeaveLobby(SteamID steamIDLobby);
|
||||
virtual bool InviteUserToLobby(SteamID steamIDLobby, SteamID steamIDInvitee);
|
||||
virtual int GetNumLobbyMembers(SteamID steamIDLobby);
|
||||
virtual SteamID GetLobbyMemberByIndex(SteamID steamIDLobby, int iMember);
|
||||
virtual const char *GetLobbyData(SteamID steamIDLobby, const char *pchKey);
|
||||
virtual bool SetLobbyData(SteamID steamIDLobby, const char *pchKey, const char *pchValue);
|
||||
virtual int GetLobbyDataCount(SteamID steamIDLobby);
|
||||
virtual bool GetLobbyDataByIndex(SteamID steamIDLobby, int iLobbyData, char *pchKey, int cchKeyBufferSize, char *pchValue, int cchValueBufferSize);
|
||||
virtual bool DeleteLobbyData(SteamID steamIDLobby, const char *pchKey);
|
||||
virtual const char *GetLobbyMemberData(SteamID steamIDLobby, SteamID steamIDUser, const char *pchKey);
|
||||
virtual void SetLobbyMemberData(SteamID steamIDLobby, const char *pchKey, const char *pchValue);
|
||||
virtual bool SendLobbyChatMsg(SteamID steamIDLobby, const void *pvMsgBody, int cubMsgBody);
|
||||
virtual int GetLobbyChatEntry(SteamID steamIDLobby, int iChatID, SteamID *pSteamIDUser, void *pvData, int cubData, int *peChatEntryType);
|
||||
virtual bool RequestLobbyData(SteamID steamIDLobby);
|
||||
virtual void SetLobbyGameServer(SteamID steamIDLobby, unsigned int unGameServerIP, unsigned short unGameServerPort, SteamID steamIDGameServer);
|
||||
virtual bool GetLobbyGameServer(SteamID steamIDLobby, unsigned int *punGameServerIP, unsigned short *punGameServerPort, SteamID *psteamIDGameServer);
|
||||
virtual bool SetLobbyMemberLimit(SteamID steamIDLobby, int cMaxMembers);
|
||||
virtual int GetLobbyMemberLimit(SteamID steamIDLobby);
|
||||
virtual bool SetLobbyType(SteamID steamIDLobby, int eLobbyType);
|
||||
virtual bool SetLobbyJoinable(SteamID steamIDLobby, bool bLobbyJoinable);
|
||||
virtual SteamID GetLobbyOwner(SteamID steamIDLobby);
|
||||
virtual bool SetLobbyOwner(SteamID steamIDLobby, SteamID steamIDNewOwner);
|
||||
};
|
||||
}
|
104
iw4/Steam/Interfaces/SteamNetworking.cpp
Normal file
104
iw4/Steam/Interfaces/SteamNetworking.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
bool Networking::SendP2PPacket(SteamID steamIDRemote, const void *pubData, unsigned int cubData, int eP2PSendType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::IsP2PPacketAvailable(unsigned int *pcubMsgSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::ReadP2PPacket(void *pubDest, unsigned int cubDest, unsigned int *pcubMsgSize, SteamID *psteamIDRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::AcceptP2PSessionWithUser(SteamID steamIDRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::CloseP2PSessionWithUser(SteamID steamIDRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::GetP2PSessionState(SteamID steamIDRemote, void *pConnectionState)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int Networking::CreateListenSocket(int nVirtualP2PPort, unsigned int nIP, unsigned short nPort, bool bAllowUseOfPacketRelay)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int Networking::CreateP2PConnectionSocket(SteamID steamIDTarget, int nVirtualPort, int nTimeoutSec, bool bAllowUseOfPacketRelay)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int Networking::CreateConnectionSocket(unsigned int nIP, unsigned short nPort, int nTimeoutSec)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Networking::DestroySocket(unsigned int hSocket, bool bNotifyRemoteEnd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::DestroyListenSocket(unsigned int hSocket, bool bNotifyRemoteEnd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::SendDataOnSocket(unsigned int hSocket, void *pubData, unsigned int cubData, bool bReliable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::IsDataAvailableOnSocket(unsigned int hSocket, unsigned int *pcubMsgSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::RetrieveDataFromSocket(unsigned int hSocket, void *pubDest, unsigned int cubDest, unsigned int *pcubMsgSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::IsDataAvailable(unsigned int hListenSocket, unsigned int *pcubMsgSize, unsigned int *phSocket)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::RetrieveData(unsigned int hListenSocket, void *pubDest, unsigned int cubDest, unsigned int *pcubMsgSize, unsigned int *phSocket)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::GetSocketInfo(unsigned int hSocket, SteamID *pSteamIDRemote, int *peSocketStatus, unsigned int *punIPRemote, unsigned short *punPortRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Networking::GetListenSocketInfo(unsigned int hListenSocket, unsigned int *pnIP, unsigned short *pnPort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Networking::GetSocketConnectionType(unsigned int hSocket)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Networking::GetMaxPacketSize(unsigned int hSocket)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
27
iw4/Steam/Interfaces/SteamNetworking.hpp
Normal file
27
iw4/Steam/Interfaces/SteamNetworking.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
namespace Steam
|
||||
{
|
||||
class Networking
|
||||
{
|
||||
public:
|
||||
virtual bool SendP2PPacket(SteamID steamIDRemote, const void *pubData, unsigned int cubData, int eP2PSendType);
|
||||
virtual bool IsP2PPacketAvailable(unsigned int *pcubMsgSize);
|
||||
virtual bool ReadP2PPacket(void *pubDest, unsigned int cubDest, unsigned int *pcubMsgSize, SteamID *psteamIDRemote);
|
||||
virtual bool AcceptP2PSessionWithUser(SteamID steamIDRemote);
|
||||
virtual bool CloseP2PSessionWithUser(SteamID steamIDRemote);
|
||||
virtual bool GetP2PSessionState(SteamID steamIDRemote, void *pConnectionState);
|
||||
virtual unsigned int CreateListenSocket(int nVirtualP2PPort, unsigned int nIP, unsigned short nPort, bool bAllowUseOfPacketRelay);
|
||||
virtual unsigned int CreateP2PConnectionSocket(SteamID steamIDTarget, int nVirtualPort, int nTimeoutSec, bool bAllowUseOfPacketRelay);
|
||||
virtual unsigned int CreateConnectionSocket(unsigned int nIP, unsigned short nPort, int nTimeoutSec);
|
||||
virtual bool DestroySocket(unsigned int hSocket, bool bNotifyRemoteEnd);
|
||||
virtual bool DestroyListenSocket(unsigned int hSocket, bool bNotifyRemoteEnd);
|
||||
virtual bool SendDataOnSocket(unsigned int hSocket, void *pubData, unsigned int cubData, bool bReliable);
|
||||
virtual bool IsDataAvailableOnSocket(unsigned int hSocket, unsigned int *pcubMsgSize);
|
||||
virtual bool RetrieveDataFromSocket(unsigned int hSocket, void *pubDest, unsigned int cubDest, unsigned int *pcubMsgSize);
|
||||
virtual bool IsDataAvailable(unsigned int hListenSocket, unsigned int *pcubMsgSize, unsigned int *phSocket);
|
||||
virtual bool RetrieveData(unsigned int hListenSocket, void *pubDest, unsigned int cubDest, unsigned int *pcubMsgSize, unsigned int *phSocket);
|
||||
virtual bool GetSocketInfo(unsigned int hSocket, SteamID *pSteamIDRemote, int *peSocketStatus, unsigned int *punIPRemote, unsigned short *punPortRemote);
|
||||
virtual bool GetListenSocketInfo(unsigned int hListenSocket, unsigned int *pnIP, unsigned short *pnPort);
|
||||
virtual int GetSocketConnectionType(unsigned int hSocket);
|
||||
virtual int GetMaxPacketSize(unsigned int hSocket);
|
||||
};
|
||||
}
|
43
iw4/Steam/Interfaces/SteamRemoteStorage.cpp
Normal file
43
iw4/Steam/Interfaces/SteamRemoteStorage.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
bool RemoteStorage::FileWrite(const char *pchFile, const void *pvData, int cubData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int RemoteStorage::GetFileSize(const char *pchFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RemoteStorage::FileRead(const char *pchFile, void *pvData, int cubDataToRead)
|
||||
{
|
||||
OutputDebugStringA(pchFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RemoteStorage::FileExists(const char *pchFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int RemoteStorage::GetFileCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *RemoteStorage::GetFileNameAndSize(int iFile, int *pnFileSizeInBytes)
|
||||
{
|
||||
*pnFileSizeInBytes = 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
bool RemoteStorage::GetQuota(int *pnTotalBytes, int *puAvailableBytes)
|
||||
{
|
||||
*pnTotalBytes = 0x10000000;
|
||||
*puAvailableBytes = 0x10000000;
|
||||
return false;
|
||||
}
|
||||
}
|
14
iw4/Steam/Interfaces/SteamRemoteStorage.hpp
Normal file
14
iw4/Steam/Interfaces/SteamRemoteStorage.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Steam
|
||||
{
|
||||
class RemoteStorage
|
||||
{
|
||||
public:
|
||||
virtual bool FileWrite(const char *pchFile, const void *pvData, int cubData);
|
||||
virtual int GetFileSize(const char *pchFile);
|
||||
virtual int FileRead(const char *pchFile, void *pvData, int cubDataToRead);
|
||||
virtual bool FileExists(const char *pchFile);
|
||||
virtual int GetFileCount();
|
||||
virtual const char *GetFileNameAndSize(int iFile, int *pnFileSizeInBytes);
|
||||
virtual bool GetQuota(int *pnTotalBytes, int *puAvailableBytes);
|
||||
};
|
||||
}
|
81
iw4/Steam/Interfaces/SteamUser.cpp
Normal file
81
iw4/Steam/Interfaces/SteamUser.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
int User::GetHSteamUser()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool User::LoggedOn()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SteamID User::GetSteamID()
|
||||
{
|
||||
SteamID id;
|
||||
id.m_Bits = 0x110000100000000 | 0x1337;
|
||||
return id;
|
||||
}
|
||||
|
||||
int User::InitiateGameConnection(void *pAuthBlob, int cbMaxAuthBlob, SteamID steamIDGameServer, unsigned int unIPServer, unsigned short usPortServer, bool bSecure)
|
||||
{
|
||||
// TODO: Generate auth ticket!
|
||||
return 0;
|
||||
}
|
||||
|
||||
void User::TerminateGameConnection(unsigned int unIPServer, unsigned short usPortServer)
|
||||
{
|
||||
}
|
||||
|
||||
void User::TrackAppUsageEvent(SteamID gameID, int eAppUsageEvent, const char *pchExtraInfo)
|
||||
{
|
||||
}
|
||||
|
||||
bool User::GetUserDataFolder(char *pchBuffer, int cubBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void User::StartVoiceRecording()
|
||||
{
|
||||
}
|
||||
|
||||
void User::StopVoiceRecording()
|
||||
{
|
||||
}
|
||||
|
||||
int User::GetCompressedVoice(void *pDestBuffer, unsigned int cbDestBufferSize, unsigned int *nBytesWritten)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int User::DecompressVoice(void *pCompressed, unsigned int cbCompressed, void *pDestBuffer, unsigned int cbDestBufferSize, unsigned int *nBytesWritten)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int User::GetAuthSessionTicket(void *pTicket, int cbMaxTicket, unsigned int *pcbTicket)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int User::BeginAuthSession(const void *pAuthTicket, int cbAuthTicket, SteamID steamID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void User::EndAuthSession(SteamID steamID)
|
||||
{
|
||||
}
|
||||
|
||||
void User::CancelAuthTicket(unsigned int hAuthTicket)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int User::UserHasLicenseForApp(SteamID steamID, unsigned int appID)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
24
iw4/Steam/Interfaces/SteamUser.hpp
Normal file
24
iw4/Steam/Interfaces/SteamUser.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
namespace Steam
|
||||
{
|
||||
class User
|
||||
{
|
||||
public:
|
||||
virtual int GetHSteamUser();
|
||||
virtual bool LoggedOn();
|
||||
virtual SteamID GetSteamID();
|
||||
|
||||
virtual int InitiateGameConnection(void *pAuthBlob, int cbMaxAuthBlob, SteamID steamIDGameServer, unsigned int unIPServer, unsigned short usPortServer, bool bSecure);
|
||||
virtual void TerminateGameConnection(unsigned int unIPServer, unsigned short usPortServer);
|
||||
virtual void TrackAppUsageEvent(SteamID gameID, int eAppUsageEvent, const char *pchExtraInfo = "");
|
||||
virtual bool GetUserDataFolder(char *pchBuffer, int cubBuffer);
|
||||
virtual void StartVoiceRecording();
|
||||
virtual void StopVoiceRecording();
|
||||
virtual int GetCompressedVoice(void *pDestBuffer, unsigned int cbDestBufferSize, unsigned int *nBytesWritten);
|
||||
virtual int DecompressVoice(void *pCompressed, unsigned int cbCompressed, void *pDestBuffer, unsigned int cbDestBufferSize, unsigned int *nBytesWritten);
|
||||
virtual unsigned int GetAuthSessionTicket(void *pTicket, int cbMaxTicket, unsigned int *pcbTicket);
|
||||
virtual int BeginAuthSession(const void *pAuthTicket, int cbAuthTicket, SteamID steamID);
|
||||
virtual void EndAuthSession(SteamID steamID);
|
||||
virtual void CancelAuthTicket(unsigned int hAuthTicket);
|
||||
virtual unsigned int UserHasLicenseForApp(SteamID steamID, unsigned int appID);
|
||||
};
|
||||
}
|
96
iw4/Steam/Interfaces/SteamUtils.cpp
Normal file
96
iw4/Steam/Interfaces/SteamUtils.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
#include "..\..\STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
unsigned int Utils::GetSecondsSinceAppActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetSecondsSinceComputerActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Utils::GetConnectedUniverse()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetServerRealTime()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* Utils::GetIPCountry()
|
||||
{
|
||||
return "US";
|
||||
}
|
||||
|
||||
bool Utils::GetImageSize(int iImage, unsigned int *pnWidth, unsigned int *pnHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::GetImageRGBA(int iImage, unsigned char *pubDest, int nDestBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::GetCSERIPPort(unsigned int *unIP, unsigned short *usPort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char Utils::GetCurrentBatteryPower()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetAppID()
|
||||
{
|
||||
return 10190;
|
||||
}
|
||||
|
||||
void Utils::SetOverlayNotificationPosition(int eNotificationPosition)
|
||||
{
|
||||
}
|
||||
|
||||
bool Utils::IsAPICallCompleted(unsigned __int64 hSteamAPICall, bool *pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Utils::GetAPICallFailureReason(unsigned __int64 hSteamAPICall)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Utils::GetAPICallResult(unsigned __int64 hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Utils::RunFrame()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int Utils::GetIPCCallCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Utils::SetWarningMessageHook(void(*pFunction)(int hpipe, const char *message))
|
||||
{
|
||||
}
|
||||
|
||||
bool Utils::IsOverlayEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::BOverlayNeedsPresent()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
26
iw4/Steam/Interfaces/SteamUtils.hpp
Normal file
26
iw4/Steam/Interfaces/SteamUtils.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
namespace Steam
|
||||
{
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
virtual unsigned int GetSecondsSinceAppActive();
|
||||
virtual unsigned int GetSecondsSinceComputerActive();
|
||||
virtual int GetConnectedUniverse();
|
||||
virtual unsigned int GetServerRealTime();
|
||||
virtual const char *GetIPCountry();
|
||||
virtual bool GetImageSize(int iImage, unsigned int *pnWidth, unsigned int *pnHeight);
|
||||
virtual bool GetImageRGBA(int iImage, unsigned char *pubDest, int nDestBufferSize);
|
||||
virtual bool GetCSERIPPort(unsigned int *unIP, unsigned short *usPort);
|
||||
virtual unsigned char GetCurrentBatteryPower();
|
||||
virtual unsigned int GetAppID();
|
||||
virtual void SetOverlayNotificationPosition(int eNotificationPosition);
|
||||
virtual bool IsAPICallCompleted(unsigned __int64 hSteamAPICall, bool *pbFailed);
|
||||
virtual int GetAPICallFailureReason(unsigned __int64 hSteamAPICall);
|
||||
virtual bool GetAPICallResult(unsigned __int64 hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed);
|
||||
virtual void RunFrame();
|
||||
virtual unsigned int GetIPCCallCount();
|
||||
virtual void SetWarningMessageHook(void(*pFunction)(int hpipe, const char *message));
|
||||
virtual bool IsOverlayEnabled();
|
||||
virtual bool BOverlayNeedsPresent();
|
||||
};
|
||||
}
|
100
iw4/Steam/Steam.cpp
Normal file
100
iw4/Steam/Steam.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
#include "Steam.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
bool SteamAPI_Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SteamAPI_RegisterCallResult()
|
||||
{
|
||||
}
|
||||
|
||||
void SteamAPI_RegisterCallback()
|
||||
{
|
||||
}
|
||||
|
||||
void SteamAPI_RunCallbacks()
|
||||
{
|
||||
}
|
||||
|
||||
void SteamAPI_Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
void SteamAPI_UnregisterCallResult()
|
||||
{
|
||||
}
|
||||
|
||||
void SteamAPI_UnregisterCallback()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool SteamGameServer_Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SteamGameServer_RunCallbacks()
|
||||
{
|
||||
}
|
||||
|
||||
void SteamGameServer_Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Steam::Friends* SteamFriends()
|
||||
{
|
||||
static Steam::Friends iFriends;
|
||||
return &iFriends;
|
||||
}
|
||||
|
||||
Steam::Matchmaking* SteamMatchmaking()
|
||||
{
|
||||
static Steam::Matchmaking iMatchmaking;
|
||||
return &iMatchmaking;
|
||||
}
|
||||
|
||||
Steam::GameServer* SteamGameServer()
|
||||
{
|
||||
static Steam::GameServer iGameServer;
|
||||
return &iGameServer;
|
||||
}
|
||||
|
||||
Steam::MasterServerUpdater* SteamMasterServerUpdater()
|
||||
{
|
||||
static Steam::MasterServerUpdater iMasterServerUpdater;
|
||||
return &iMasterServerUpdater;
|
||||
}
|
||||
|
||||
Steam::Networking* SteamNetworking()
|
||||
{
|
||||
static Steam::Networking iNetworking;
|
||||
return &iNetworking;
|
||||
}
|
||||
|
||||
Steam::RemoteStorage* SteamRemoteStorage()
|
||||
{
|
||||
static Steam::RemoteStorage iRemoteStorage;
|
||||
return &iRemoteStorage;
|
||||
}
|
||||
|
||||
Steam::User* SteamUser()
|
||||
{
|
||||
static Steam::User iUser;
|
||||
return &iUser;
|
||||
}
|
||||
|
||||
Steam::Utils* SteamUtils()
|
||||
{
|
||||
static Steam::Utils iUtils;
|
||||
return &iUtils;
|
||||
}
|
||||
}
|
||||
}
|
49
iw4/Steam/Steam.hpp
Normal file
49
iw4/Steam/Steam.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#define STEAM_EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct SteamIDComponent_t
|
||||
{
|
||||
unsigned int m_unAccountID : 32;
|
||||
unsigned int m_unAccountInstance : 20;
|
||||
unsigned int m_EAccountType : 4;
|
||||
int m_EUniverse : 8;
|
||||
} m_comp;
|
||||
|
||||
unsigned long long m_Bits;
|
||||
} SteamID;
|
||||
|
||||
#include "Interfaces\SteamUser.hpp"
|
||||
#include "Interfaces\SteamUtils.hpp"
|
||||
#include "Interfaces\SteamFriends.hpp"
|
||||
#include "Interfaces\SteamGameServer.hpp"
|
||||
#include "Interfaces\SteamNetworking.hpp"
|
||||
#include "Interfaces\SteamMatchmaking.hpp"
|
||||
#include "Interfaces\SteamRemoteStorage.hpp"
|
||||
#include "Interfaces\SteamMasterServerUpdater.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
STEAM_EXPORT bool SteamAPI_Init();
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallResult();
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallback();
|
||||
STEAM_EXPORT void SteamAPI_RunCallbacks();
|
||||
STEAM_EXPORT void SteamAPI_Shutdown();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallResult();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallback();
|
||||
|
||||
STEAM_EXPORT bool SteamGameServer_Init();
|
||||
STEAM_EXPORT void SteamGameServer_RunCallbacks();
|
||||
STEAM_EXPORT void SteamGameServer_Shutdown();
|
||||
|
||||
STEAM_EXPORT Steam::Friends* SteamFriends();
|
||||
STEAM_EXPORT Steam::Matchmaking* SteamMatchmaking();
|
||||
STEAM_EXPORT Steam::GameServer* SteamGameServer();
|
||||
STEAM_EXPORT Steam::MasterServerUpdater* SteamMasterServerUpdater();
|
||||
STEAM_EXPORT Steam::Networking* SteamNetworking();
|
||||
STEAM_EXPORT Steam::RemoteStorage* SteamRemoteStorage();
|
||||
STEAM_EXPORT Steam::User* SteamUser();
|
||||
STEAM_EXPORT Steam::Utils* SteamUtils();
|
||||
}
|
109
iw4/Utils/Hooking.cpp
Normal file
109
iw4/Utils/Hooking.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
Hook::~Hook()
|
||||
{
|
||||
if (Hook::Initialized)
|
||||
{
|
||||
Hook::Uninstall();
|
||||
}
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(DWORD place, void* stub, bool useJump)
|
||||
{
|
||||
return Hook::Initialize((void*)place, stub, useJump);
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(void* place, void* stub, bool useJump)
|
||||
{
|
||||
if (Hook::Initialized) return this;
|
||||
Hook::Initialized = true;
|
||||
|
||||
Hook::UseJump = useJump;
|
||||
Hook::Place = place;
|
||||
Hook::Stub = stub;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook* Hook::Install()
|
||||
{
|
||||
Hook::StateMutex.lock();
|
||||
|
||||
if (!Hook::Initialized || Hook::Installed)
|
||||
{
|
||||
Hook::StateMutex.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook::Installed = true;
|
||||
|
||||
DWORD d;
|
||||
VirtualProtect(Hook::Place, sizeof(Hook::Buffer), PAGE_EXECUTE_READWRITE, &d);
|
||||
memcpy(Hook::Buffer, Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
char* Code = (char*)Hook::Place;
|
||||
|
||||
*Code = (char)(Hook::UseJump ? 0xE9 : 0xE8);
|
||||
|
||||
*(size_t*)&Code[1] = (size_t)Hook::Stub - ((size_t)Hook::Place + 5);
|
||||
|
||||
VirtualProtect(Hook::Place, sizeof(Hook::Buffer), d, &d);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
Hook::StateMutex.unlock();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Hook::Quick()
|
||||
{
|
||||
if (Hook::Installed)
|
||||
{
|
||||
Hook::Installed = false;
|
||||
}
|
||||
}
|
||||
|
||||
Hook* Hook::Uninstall()
|
||||
{
|
||||
Hook::StateMutex.lock();
|
||||
|
||||
if (!Hook::Initialized || !Hook::Installed)
|
||||
{
|
||||
Hook::StateMutex.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook::Installed = false;
|
||||
|
||||
DWORD d;
|
||||
VirtualProtect(Hook::Place, sizeof(Hook::Buffer), PAGE_EXECUTE_READWRITE, &d);
|
||||
|
||||
memcpy(Hook::Place, Hook::Buffer, sizeof(Hook::Buffer));
|
||||
|
||||
VirtualProtect(Hook::Place, sizeof(Hook::Buffer), d, &d);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
Hook::StateMutex.unlock();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void* Hook::GetAddress()
|
||||
{
|
||||
return Hook::Place;
|
||||
}
|
||||
|
||||
void Hook::Nop(void* place, size_t length)
|
||||
{
|
||||
memset(place, 0x90, length);
|
||||
}
|
||||
|
||||
void Hook::Nop(DWORD place, size_t length)
|
||||
{
|
||||
Nop((void*)place, length);
|
||||
}
|
||||
}
|
60
iw4/Utils/Hooking.hpp
Normal file
60
iw4/Utils/Hooking.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#define HOOK_JUMP true
|
||||
#define HOOK_CALL false
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
class Hook
|
||||
{
|
||||
public:
|
||||
Hook() : Place(nullptr), Stub(nullptr), Initialized(false), Installed(false), UseJump(false) { ZeroMemory(Hook::Buffer, sizeof(Hook::Buffer)); }
|
||||
Hook(void* place, void* stub, bool useJump = true) : Hook() { Hook::Initialize(place, stub, useJump); }
|
||||
Hook(DWORD place, void* stub, bool useJump = true) : Hook((void*)place, stub, useJump) {}
|
||||
|
||||
~Hook();
|
||||
|
||||
Hook* Initialize(void* place, void* stub, bool useJump = true);
|
||||
Hook* Initialize(DWORD place, void* stub, bool useJump = true);
|
||||
Hook* Install();
|
||||
Hook* Uninstall();
|
||||
|
||||
void* GetAddress();
|
||||
void Quick();
|
||||
|
||||
static void Nop(void* place, size_t length);
|
||||
static void Nop(DWORD place, size_t length);
|
||||
|
||||
template <typename T> static void Set(void* place, T value)
|
||||
{
|
||||
*(T*)place = value;
|
||||
FlushInstructionCache(GetCurrentProcess(), place, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T> static void Set(DWORD place, T value)
|
||||
{
|
||||
return Set<T>((void*)place, value);
|
||||
}
|
||||
|
||||
template <typename T> static T Get(void* place)
|
||||
{
|
||||
return *(T*)place;
|
||||
}
|
||||
|
||||
template <typename T> static T Get(DWORD place)
|
||||
{
|
||||
return Get<T>((void*)place);
|
||||
}
|
||||
|
||||
private:
|
||||
bool Initialized;
|
||||
bool Installed;
|
||||
|
||||
void* Place;
|
||||
void* Stub;
|
||||
char Buffer[5];
|
||||
bool UseJump;
|
||||
|
||||
std::mutex StateMutex;
|
||||
};
|
||||
}
|
27
iw4/Utils/Utils.cpp
Normal file
27
iw4/Utils/Utils.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "..\STDInclude.hpp"
|
||||
|
||||
#define VA_BUFFER_COUNT 4
|
||||
#define VA_BUFFER_SIZE 4096
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
const char *VA(const char *fmt, ...)
|
||||
{
|
||||
static char g_vaBuffer[VA_BUFFER_COUNT][VA_BUFFER_SIZE];
|
||||
static int g_vaNextBufferIndex = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char* dest = g_vaBuffer[g_vaNextBufferIndex];
|
||||
vsprintf_s(g_vaBuffer[g_vaNextBufferIndex], fmt, ap);
|
||||
g_vaNextBufferIndex = (g_vaNextBufferIndex + 1) % VA_BUFFER_COUNT;
|
||||
va_end(ap);
|
||||
return dest;
|
||||
}
|
||||
|
||||
std::string StrToLower(std::string input)
|
||||
{
|
||||
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
|
||||
return input;
|
||||
}
|
||||
}
|
5
iw4/Utils/Utils.hpp
Normal file
5
iw4/Utils/Utils.hpp
Normal file
@ -0,0 +1,5 @@
|
||||
namespace Utils
|
||||
{
|
||||
const char *VA(const char *fmt, ...);
|
||||
std::string StrToLower(std::string input);
|
||||
}
|
107
iw4/iw4.vcxproj
Normal file
107
iw4/iw4.vcxproj
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{38B4FC13-CEBC-4099-8698-3E62943C1EAA}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>iw4</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>iw4m</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IW4_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /y "$(TargetPath)" "D:\Games\SteamLibrary\steamapps\common\Call of Duty Modern Warfare 2\"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Components\Colors.hpp" />
|
||||
<ClInclude Include="Components\Command.hpp" />
|
||||
<ClInclude Include="Components\Console.hpp" />
|
||||
<ClInclude Include="Components\Dvar.hpp" />
|
||||
<ClInclude Include="Components\Loader.hpp" />
|
||||
<ClInclude Include="Components\QuickPatch.hpp" />
|
||||
<ClInclude Include="Components\RawFiles.hpp" />
|
||||
<ClInclude Include="Components\Window.hpp" />
|
||||
<ClInclude Include="Game\Functions.hpp" />
|
||||
<ClInclude Include="Game\Structs.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamFriends.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamGameServer.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamMasterServerUpdater.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamMatchmaking.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamNetworking.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamRemoteStorage.hpp" />
|
||||
<ClInclude Include="Steam\Steam.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamUser.hpp" />
|
||||
<ClInclude Include="Steam\Interfaces\SteamUtils.hpp" />
|
||||
<ClInclude Include="STDInclude.hpp" />
|
||||
<ClInclude Include="Utils\Hooking.hpp" />
|
||||
<ClInclude Include="Utils\Utils.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Components\Colors.cpp" />
|
||||
<ClCompile Include="Components\Command.cpp" />
|
||||
<ClCompile Include="Components\Console.cpp" />
|
||||
<ClCompile Include="Components\Dvar.cpp" />
|
||||
<ClCompile Include="Components\Loader.cpp" />
|
||||
<ClCompile Include="Components\QuickPatch.cpp" />
|
||||
<ClCompile Include="Components\RawFiles.cpp" />
|
||||
<ClCompile Include="Components\Window.cpp" />
|
||||
<ClCompile Include="Game\Functions.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamFriends.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamGameServer.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamMasterServerUpdater.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamMatchmaking.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamNetworking.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamRemoteStorage.cpp" />
|
||||
<ClCompile Include="Steam\Steam.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamUser.cpp" />
|
||||
<ClCompile Include="Steam\Interfaces\SteamUtils.cpp" />
|
||||
<ClCompile Include="Main.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils\Hooking.cpp" />
|
||||
<ClCompile Include="Utils\Utils.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
164
iw4/iw4.vcxproj.filters
Normal file
164
iw4/iw4.vcxproj.filters
Normal file
@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Ressourcendateien">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source\Steam">
|
||||
<UniqueIdentifier>{c97341f6-b778-4acf-bdce-24c602206b5a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source\Steam\Interfaces">
|
||||
<UniqueIdentifier>{d46d7650-0188-47ba-865f-c78e5b7e9910}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source\Utils">
|
||||
<UniqueIdentifier>{88e00811-087a-4881-8abf-5e8eb4695a3b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source\Components">
|
||||
<UniqueIdentifier>{3e48fe95-8760-4a3d-b4b7-5b9b3025886d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source\Components\Modules">
|
||||
<UniqueIdentifier>{ff889d4b-f01e-4c7f-9ba8-39ab0326c32b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source\Game">
|
||||
<UniqueIdentifier>{42cf4b9a-e10a-4c28-ac06-2bfa9e259784}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Main.cpp">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamUser.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamUtils.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamFriends.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamRemoteStorage.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamNetworking.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamMatchmaking.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamGameServer.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Interfaces\SteamMasterServerUpdater.cpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils\Utils.cpp">
|
||||
<Filter>Source\Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils\Hooking.cpp">
|
||||
<Filter>Source\Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Loader.cpp">
|
||||
<Filter>Source\Components</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\QuickPatch.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Console.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Game\Functions.cpp">
|
||||
<Filter>Source\Game</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Steam\Steam.cpp">
|
||||
<Filter>Source\Steam</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Dvar.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Colors.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Command.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\Window.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Components\RawFiles.cpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Steam\Interfaces\SteamUser.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamUtils.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamFriends.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamRemoteStorage.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamNetworking.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamMatchmaking.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamGameServer.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Interfaces\SteamMasterServerUpdater.hpp">
|
||||
<Filter>Source\Steam\Interfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils\Hooking.hpp">
|
||||
<Filter>Source\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils\Utils.hpp">
|
||||
<Filter>Source\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Loader.hpp">
|
||||
<Filter>Source\Components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\QuickPatch.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Console.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Game\Functions.hpp">
|
||||
<Filter>Source\Game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Game\Structs.hpp">
|
||||
<Filter>Source\Game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Steam\Steam.hpp">
|
||||
<Filter>Source\Steam</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Dvar.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="STDInclude.hpp">
|
||||
<Filter>Source</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Colors.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Command.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\Window.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Components\RawFiles.hpp">
|
||||
<Filter>Source\Components\Modules</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
8
iw4/iw4.vcxproj.user
Normal file
8
iw4/iw4.vcxproj.user
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerCommand>iw4m.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerWorkingDirectory>D:\Games\SteamLibrary\steamapps\common\Call of Duty Modern Warfare 2\</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
10
package.json
Normal file
10
package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "iw4",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
Loading…
Reference in New Issue
Block a user