Add progress
This commit is contained in:
parent
11ae72c759
commit
6aae741b9b
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.vs
|
||||
.vscode
|
||||
build/
|
||||
usergenerate.bat
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "deps/minhook"]
|
||||
path = deps/minhook
|
||||
url = https://github.com/TsudaKageyu/minhook.git
|
||||
[submodule "deps/asmjit"]
|
||||
path = deps/asmjit
|
||||
url = https://github.com/asmjit/asmjit.git
|
2
LICENSE
Normal file
2
LICENSE
Normal file
@ -0,0 +1,2 @@
|
||||
All rights reserved.
|
||||
Nobody may use anything from here.
|
1
deps/asmjit
vendored
Submodule
1
deps/asmjit
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit a4cb51b532af0f8137c4182914244c3b05d7745f
|
1
deps/minhook
vendored
Submodule
1
deps/minhook
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 4a455528f61b5a375b1f9d44e7d296d47f18bb18
|
34
deps/premake/asmjit.lua
vendored
Normal file
34
deps/premake/asmjit.lua
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
asmjit = {
|
||||
source = path.join(dependencies.basePath, "asmjit"),
|
||||
}
|
||||
|
||||
function asmjit.import()
|
||||
links { "asmjit" }
|
||||
asmjit.includes()
|
||||
end
|
||||
|
||||
function asmjit.includes()
|
||||
includedirs {
|
||||
path.join(asmjit.source, "src")
|
||||
}
|
||||
|
||||
defines {
|
||||
"ASMJIT_STATIC"
|
||||
}
|
||||
end
|
||||
|
||||
function asmjit.project()
|
||||
project "asmjit"
|
||||
language "C++"
|
||||
|
||||
asmjit.includes()
|
||||
|
||||
files {
|
||||
path.join(asmjit.source, "src/**.cpp"),
|
||||
}
|
||||
|
||||
warnings "Off"
|
||||
kind "StaticLib"
|
||||
end
|
||||
|
||||
table.insert(dependencies, asmjit)
|
31
deps/premake/minhook.lua
vendored
Normal file
31
deps/premake/minhook.lua
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
minhook = {
|
||||
source = path.join(dependencies.basePath, "minhook"),
|
||||
}
|
||||
|
||||
function minhook.import()
|
||||
links { "minhook" }
|
||||
minhook.includes()
|
||||
end
|
||||
|
||||
function minhook.includes()
|
||||
includedirs {
|
||||
path.join(minhook.source, "include")
|
||||
}
|
||||
end
|
||||
|
||||
function minhook.project()
|
||||
project "minhook"
|
||||
language "C"
|
||||
|
||||
minhook.includes()
|
||||
|
||||
files {
|
||||
path.join(minhook.source, "src/**.h"),
|
||||
path.join(minhook.source, "src/**.c"),
|
||||
}
|
||||
|
||||
warnings "Off"
|
||||
kind "StaticLib"
|
||||
end
|
||||
|
||||
table.insert(dependencies, minhook)
|
3
generate.bat
Normal file
3
generate.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
git submodule update --init --recursive
|
||||
tools\premake5 %* vs2022
|
310
premake5.lua
Normal file
310
premake5.lua
Normal file
@ -0,0 +1,310 @@
|
||||
gitVersioningCommand = "git describe --tags --dirty --always"
|
||||
gitCurrentBranchCommand = "git symbolic-ref -q --short HEAD"
|
||||
|
||||
-- Quote the given string input as a C string
|
||||
function cstrquote(value)
|
||||
if value == nil then
|
||||
return "\"\""
|
||||
end
|
||||
result = value:gsub("\\", "\\\\")
|
||||
result = result:gsub("\"", "\\\"")
|
||||
result = result:gsub("\n", "\\n")
|
||||
result = result:gsub("\t", "\\t")
|
||||
result = result:gsub("\r", "\\r")
|
||||
result = result:gsub("\a", "\\a")
|
||||
result = result:gsub("\b", "\\b")
|
||||
result = "\"" .. result .. "\""
|
||||
return result
|
||||
end
|
||||
|
||||
-- Converts tags in "vX.X.X" format and given revision number Y to an array of numbers {X,X,X,Y}.
|
||||
-- In the case where the format does not work fall back to padding with zeroes and just ending with the revision number.
|
||||
-- partscount can be either 3 or 4.
|
||||
function vertonumarr(value, vernumber, partscount)
|
||||
vernum = {}
|
||||
for num in string.gmatch(value or "", "%d+") do
|
||||
if #vernum < 3 then
|
||||
table.insert(vernum, tonumber(num))
|
||||
end
|
||||
end
|
||||
while #vernum < 3 do
|
||||
table.insert(vernum, 0)
|
||||
end
|
||||
if #vernum < partscount then
|
||||
table.insert(vernum, tonumber(vernumber))
|
||||
end
|
||||
return vernum
|
||||
end
|
||||
|
||||
dependencies = {
|
||||
basePath = "./deps"
|
||||
}
|
||||
|
||||
function dependencies.load()
|
||||
dir = path.join(dependencies.basePath, "premake/*.lua")
|
||||
deps = os.matchfiles(dir)
|
||||
|
||||
for i, dep in pairs(deps) do
|
||||
dep = dep:gsub(".lua", "")
|
||||
require(dep)
|
||||
end
|
||||
end
|
||||
|
||||
function dependencies.imports()
|
||||
for i, proj in pairs(dependencies) do
|
||||
if type(i) == 'number' then
|
||||
proj.import()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function dependencies.projects()
|
||||
for i, proj in pairs(dependencies) do
|
||||
if type(i) == 'number' then
|
||||
proj.project()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newoption {
|
||||
trigger = "copy-to",
|
||||
description = "Optional, copy the EXE to a custom folder after build, define the path here if wanted.",
|
||||
value = "PATH"
|
||||
}
|
||||
|
||||
newoption {
|
||||
trigger = "dev-build",
|
||||
description = "Enable development builds of the client."
|
||||
}
|
||||
|
||||
newaction {
|
||||
trigger = "version",
|
||||
description = "Returns the version string for the current commit of the source code.",
|
||||
onWorkspace = function(wks)
|
||||
-- get current version via git
|
||||
local proc = assert(io.popen(gitVersioningCommand, "r"))
|
||||
local gitDescribeOutput = assert(proc:read('*a')):gsub("%s+", "")
|
||||
proc:close()
|
||||
local version = gitDescribeOutput
|
||||
|
||||
proc = assert(io.popen(gitCurrentBranchCommand, "r"))
|
||||
local gitCurrentBranchOutput = assert(proc:read('*a')):gsub("%s+", "")
|
||||
local gitCurrentBranchSuccess = proc:close()
|
||||
if gitCurrentBranchSuccess then
|
||||
-- We got a branch name, check if it is a feature branch
|
||||
if gitCurrentBranchOutput ~= "develop" and gitCurrentBranchOutput ~= "master" then
|
||||
version = version .. "-" .. gitCurrentBranchOutput
|
||||
end
|
||||
end
|
||||
|
||||
print(version)
|
||||
os.exit(0)
|
||||
end
|
||||
}
|
||||
|
||||
newaction {
|
||||
trigger = "generate-buildinfo",
|
||||
description = "Sets up build information file like version.h.",
|
||||
onWorkspace = function(wks)
|
||||
-- get old version number from version.hpp if any
|
||||
local oldVersion = "(none)"
|
||||
local oldVersionHeader = io.open(wks.location .. "/src/version.h", "r")
|
||||
if oldVersionHeader ~= nil then
|
||||
local oldVersionHeaderContent = assert(oldVersionHeader:read('*l'))
|
||||
while oldVersionHeaderContent do
|
||||
m = string.match(oldVersionHeaderContent, "#define GIT_DESCRIBE (.+)%s*$")
|
||||
if m ~= nil then
|
||||
oldVersion = m
|
||||
end
|
||||
|
||||
oldVersionHeaderContent = oldVersionHeader:read('*l')
|
||||
end
|
||||
end
|
||||
|
||||
-- get current version via git
|
||||
local proc = assert(io.popen(gitVersioningCommand, "r"))
|
||||
local gitDescribeOutput = assert(proc:read('*a')):gsub("%s+", "")
|
||||
proc:close()
|
||||
|
||||
-- generate version.hpp with a revision number if not equal
|
||||
gitDescribeOutputQuoted = cstrquote(gitDescribeOutput)
|
||||
if oldVersion ~= gitDescribeOutputQuoted then
|
||||
-- get current git hash and write to version.txt (used by the preliminary updater)
|
||||
-- TODO - remove once proper updater and release versioning exists
|
||||
local proc = assert(io.popen("git rev-parse HEAD", "r"))
|
||||
local gitCommitHash = assert(proc:read('*a')):gsub("%s+", "")
|
||||
proc:close()
|
||||
|
||||
-- get whether this is a clean revision (no uncommitted changes)
|
||||
proc = assert(io.popen("git status --porcelain", "r"))
|
||||
local revDirty = (assert(proc:read('*a')) ~= "")
|
||||
if revDirty then revDirty = 1 else revDirty = 0 end
|
||||
proc:close()
|
||||
|
||||
-- get current tag name
|
||||
proc = assert(io.popen("git describe --tags --abbrev=0"))
|
||||
local tagName = proc:read('*l')
|
||||
|
||||
-- get current branch name
|
||||
proc = assert(io.popen("git branch --show-current"))
|
||||
local branchName = proc:read('*l')
|
||||
|
||||
-- branch for ci
|
||||
if branchName == nil or branchName == '' then
|
||||
proc = assert(io.popen("git show -s --pretty=%d HEAD"))
|
||||
local branchInfo = proc:read('*l')
|
||||
m = string.match(branchInfo, ".+,.+, ([^)]+)")
|
||||
if m ~= nil then
|
||||
branchName = m
|
||||
end
|
||||
end
|
||||
|
||||
if branchName == nil then
|
||||
branchName = "develop"
|
||||
end
|
||||
|
||||
print("Detected branch: " .. branchName)
|
||||
|
||||
-- get revision number via git
|
||||
local proc = assert(io.popen("git rev-list --count HEAD", "r"))
|
||||
local revNumber = assert(proc:read('*a')):gsub("%s+", "")
|
||||
|
||||
print ("Update " .. oldVersion .. " -> " .. gitDescribeOutputQuoted)
|
||||
|
||||
-- write to version.txt for preliminary updater
|
||||
-- NOTE - remove this once we have a proper updater and proper release versioning
|
||||
local versionFile = assert(io.open(wks.location .. "/version.txt", "w"))
|
||||
versionFile:write(gitCommitHash)
|
||||
versionFile:close()
|
||||
|
||||
-- write version header
|
||||
local versionHeader = assert(io.open(wks.location .. "/src/version.h", "w"))
|
||||
versionHeader:write("/*\n")
|
||||
versionHeader:write(" * Automatically generated by premake5.\n")
|
||||
versionHeader:write(" * Do not touch!\n")
|
||||
versionHeader:write(" */\n")
|
||||
versionHeader:write("\n")
|
||||
versionHeader:write("#define GIT_DESCRIBE " .. gitDescribeOutputQuoted .. "\n")
|
||||
versionHeader:write("#define GIT_DIRTY " .. revDirty .. "\n")
|
||||
versionHeader:write("#define GIT_HASH " .. cstrquote(gitCommitHash) .. "\n")
|
||||
versionHeader:write("#define GIT_TAG " .. cstrquote(tagName) .. "\n")
|
||||
versionHeader:write("#define GIT_BRANCH " .. cstrquote(branchName) .. "\n")
|
||||
versionHeader:write("\n")
|
||||
versionHeader:write("// Version transformed for RC files\n")
|
||||
versionHeader:write("#define VERSION_PRODUCT_RC " .. table.concat(vertonumarr(tagName, revNumber, 3), ",") .. "\n")
|
||||
versionHeader:write("#define VERSION_PRODUCT " .. cstrquote(table.concat(vertonumarr(tagName, revNumber, 3), ".")) .. "\n")
|
||||
versionHeader:write("#define VERSION_FILE_RC " .. table.concat(vertonumarr(tagName, revNumber, 4), ",") .. "\n")
|
||||
versionHeader:write("#define VERSION_FILE " .. cstrquote(table.concat(vertonumarr(tagName, revNumber, 4), ".")) .. "\n")
|
||||
versionHeader:write("\n")
|
||||
versionHeader:write("// Alias definitions\n")
|
||||
versionHeader:write("#define VERSION GIT_DESCRIBE\n")
|
||||
versionHeader:write("#define SHORTVERSION VERSION_PRODUCT\n")
|
||||
versionHeader:close()
|
||||
local versionHeader = assert(io.open(wks.location .. "/src/version.hpp", "w"))
|
||||
versionHeader:write("/*\n")
|
||||
versionHeader:write(" * Automatically generated by premake5.\n")
|
||||
versionHeader:write(" * Do not touch!\n")
|
||||
versionHeader:write(" *\n")
|
||||
versionHeader:write(" * This file exists for reasons of complying with our coding standards.\n")
|
||||
versionHeader:write(" *\n")
|
||||
versionHeader:write(" * The Resource Compiler will ignore any content from C++ header files if they're not from STDInclude.hpp.\n")
|
||||
versionHeader:write(" * That's the reason why we now place all version info in version.h instead.\n")
|
||||
versionHeader:write(" */\n")
|
||||
versionHeader:write("\n")
|
||||
versionHeader:write("#include \".\\version.h\"\n")
|
||||
versionHeader:close()
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
dependencies.load()
|
||||
|
||||
workspace "bo3"
|
||||
startproject "client"
|
||||
location "./build"
|
||||
objdir "%{wks.location}/obj"
|
||||
targetdir "%{wks.location}/bin/%{cfg.platform}/%{cfg.buildcfg}"
|
||||
|
||||
configurations {"Debug", "Release"}
|
||||
|
||||
language "C++"
|
||||
cppdialect "C++20"
|
||||
|
||||
architecture "x86_64"
|
||||
platforms "x64"
|
||||
|
||||
systemversion "latest"
|
||||
symbols "On"
|
||||
staticruntime "On"
|
||||
editandcontinue "Off"
|
||||
warnings "Extra"
|
||||
characterset "ASCII"
|
||||
|
||||
if _OPTIONS["dev-build"] then
|
||||
defines {"DEV_BUILD"}
|
||||
end
|
||||
|
||||
if os.getenv("CI") then
|
||||
defines {"CI"}
|
||||
end
|
||||
|
||||
flags {"NoIncrementalLink", "NoMinimalRebuild", "MultiProcessorCompile", "No64BitChecks"}
|
||||
|
||||
filter "platforms:x64"
|
||||
defines {"_WINDOWS", "WIN32"}
|
||||
filter {}
|
||||
|
||||
filter "configurations:Release"
|
||||
optimize "Size"
|
||||
buildoptions {"/GL"}
|
||||
linkoptions { "/IGNORE:4702", "/LTCG" }
|
||||
defines {"NDEBUG"}
|
||||
flags {"FatalCompileWarnings"}
|
||||
filter {}
|
||||
|
||||
filter "configurations:Debug"
|
||||
optimize "Debug"
|
||||
defines {"DEBUG", "_DEBUG"}
|
||||
filter {}
|
||||
|
||||
project "common"
|
||||
kind "StaticLib"
|
||||
language "C++"
|
||||
|
||||
files {"./src/common/**.hpp", "./src/common/**.cpp"}
|
||||
|
||||
includedirs {"./src/common", "%{prj.location}/src"}
|
||||
|
||||
resincludedirs {"$(ProjectDir)src"}
|
||||
|
||||
dependencies.imports()
|
||||
|
||||
project "client"
|
||||
kind "SharedLib"
|
||||
language "C++"
|
||||
|
||||
targetname "d3d11"
|
||||
|
||||
pchheader "std_include.hpp"
|
||||
pchsource "src/client/std_include.cpp"
|
||||
|
||||
files {"./src/client/**.rc", "./src/client/**.hpp", "./src/client/**.cpp", "./src/client/resources/**.*"}
|
||||
|
||||
includedirs {"./src/client", "./src/common", "%{prj.location}/src"}
|
||||
|
||||
resincludedirs {"$(ProjectDir)src"}
|
||||
|
||||
dependson {"tlsdll", "runner"}
|
||||
|
||||
links {"common"}
|
||||
|
||||
prebuildcommands {"pushd %{_MAIN_SCRIPT_DIR}", "tools\\premake5 generate-buildinfo", "popd"}
|
||||
|
||||
if _OPTIONS["copy-to"] then
|
||||
postbuildcommands {"copy /y \"$(TargetPath)\" \"" .. _OPTIONS["copy-to"] .. "\""}
|
||||
end
|
||||
|
||||
dependencies.imports()
|
||||
|
||||
group "Dependencies"
|
||||
dependencies.projects()
|
122
src/client/component/arxan.cpp
Normal file
122
src/client/component/arxan.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
namespace arxan
|
||||
{
|
||||
namespace
|
||||
{
|
||||
DWORD get_steam_pid()
|
||||
{
|
||||
static auto steam_pid = [] {
|
||||
HKEY hRegKey;
|
||||
DWORD pid{};
|
||||
|
||||
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE,
|
||||
&hRegKey) != ERROR_SUCCESS)
|
||||
return pid;
|
||||
|
||||
DWORD dwLength = sizeof(pid);
|
||||
RegQueryValueExA(hRegKey, "pid", nullptr, nullptr, reinterpret_cast<BYTE*>(&pid), &dwLength);
|
||||
RegCloseKey(hRegKey);
|
||||
|
||||
return pid;
|
||||
}();
|
||||
|
||||
return steam_pid;
|
||||
}
|
||||
|
||||
utils::hook::detour nt_close_hook;
|
||||
utils::hook::detour nt_query_information_process_hook;
|
||||
|
||||
NTSTATUS WINAPI nt_query_information_process_stub(const HANDLE handle, const PROCESSINFOCLASS info_class,
|
||||
const PVOID info,
|
||||
const ULONG info_length, const PULONG ret_length)
|
||||
{
|
||||
auto* orig = static_cast<decltype(NtQueryInformationProcess)*>(nt_query_information_process_hook.
|
||||
get_original());
|
||||
const auto status = orig(handle, info_class, info, info_length, ret_length);
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
if (info_class == ProcessBasicInformation)
|
||||
{
|
||||
static DWORD explorer_pid = 0;
|
||||
if (!explorer_pid)
|
||||
{
|
||||
auto* const shell_window = GetShellWindow();
|
||||
GetWindowThreadProcessId(shell_window, &explorer_pid);
|
||||
}
|
||||
|
||||
static_cast<PPROCESS_BASIC_INFORMATION>(info)->Reserved3 = PVOID(DWORD64(get_steam_pid()));
|
||||
}
|
||||
else if (info_class == 30) // ProcessDebugObjectHandle
|
||||
{
|
||||
*static_cast<HANDLE*>(info) = nullptr;
|
||||
|
||||
return 0xC0000353;
|
||||
}
|
||||
else if (info_class == 7) // ProcessDebugPort
|
||||
{
|
||||
*static_cast<HANDLE*>(info) = nullptr;
|
||||
}
|
||||
else if (info_class == 31)
|
||||
{
|
||||
*static_cast<ULONG*>(info) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI nt_close_stub(const HANDLE handle)
|
||||
{
|
||||
char info[16];
|
||||
if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS(4), &info, 2, nullptr) >= 0 && size_t(handle) != 0x12345)
|
||||
{
|
||||
auto* orig = static_cast<decltype(NtClose)*>(nt_close_hook.get_original());
|
||||
return orig(handle);
|
||||
}
|
||||
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS info)
|
||||
{
|
||||
if (info->ExceptionRecord->ExceptionCode == STATUS_INVALID_HANDLE)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void hide_being_debugged()
|
||||
{
|
||||
auto* const peb = PPEB(__readgsqword(0x60));
|
||||
peb->BeingDebugged = false;
|
||||
*reinterpret_cast<PDWORD>(LPSTR(peb) + 0xBC) &= ~0x70;
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_load() override
|
||||
{
|
||||
hide_being_debugged();
|
||||
scheduler::loop(hide_being_debugged, scheduler::pipeline::async);
|
||||
|
||||
const utils::nt::library ntdll("ntdll.dll");
|
||||
nt_close_hook.create(ntdll.get_proc<void*>("NtClose"), nt_close_stub);
|
||||
nt_query_information_process_hook.create(ntdll.get_proc<void*>("NtQueryInformationProcess"),
|
||||
nt_query_information_process_stub);
|
||||
|
||||
AddVectoredExceptionHandler(1, exception_filter);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(arxan::component)
|
61
src/client/component/console.cpp
Normal file
61
src/client/component/console.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <std_include.hpp>
|
||||
#include "console.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include <utils/thread.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
namespace console
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void create_game_console()
|
||||
{
|
||||
reinterpret_cast<void(*)()>(utils::nt::library{}.get_ptr() + 0x2333F80)();
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
this->terminate_runner_ = false;
|
||||
|
||||
this->console_runner_ = utils::thread::create_named_thread("Console IO", [this]
|
||||
{
|
||||
create_game_console();
|
||||
|
||||
MSG msg{};
|
||||
while (!this->terminate_runner_)
|
||||
{
|
||||
if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void pre_destroy() override
|
||||
{
|
||||
this->terminate_runner_ = true;
|
||||
|
||||
if (this->console_runner_.joinable())
|
||||
{
|
||||
this->console_runner_.join();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_bool terminate_runner_{false};
|
||||
std::thread console_runner_;
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(console::component)
|
6
src/client/component/console.hpp
Normal file
6
src/client/component/console.hpp
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace console
|
||||
{
|
||||
void print(int type, const char* fmt, ...);
|
||||
}
|
175
src/client/component/scheduler.cpp
Normal file
175
src/client/component/scheduler.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/concurrency.hpp>
|
||||
#include <utils/thread.hpp>
|
||||
|
||||
namespace scheduler
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct task
|
||||
{
|
||||
std::function<bool()> handler{};
|
||||
std::chrono::milliseconds interval{};
|
||||
std::chrono::high_resolution_clock::time_point last_call{};
|
||||
};
|
||||
|
||||
using task_list = std::vector<task>;
|
||||
|
||||
class task_pipeline
|
||||
{
|
||||
public:
|
||||
void add(task&& task)
|
||||
{
|
||||
new_callbacks_.access([&task](task_list& tasks)
|
||||
{
|
||||
tasks.emplace_back(std::move(task));
|
||||
});
|
||||
}
|
||||
|
||||
void execute()
|
||||
{
|
||||
callbacks_.access([&](task_list& tasks)
|
||||
{
|
||||
this->merge_callbacks();
|
||||
|
||||
for (auto i = tasks.begin(); i != tasks.end();)
|
||||
{
|
||||
const auto now = std::chrono::high_resolution_clock::now();
|
||||
const auto diff = now - i->last_call;
|
||||
|
||||
if (diff < i->interval)
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
i->last_call = now;
|
||||
|
||||
const auto res = i->handler();
|
||||
if (res == cond_end)
|
||||
{
|
||||
i = tasks.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
utils::concurrency::container<task_list> new_callbacks_;
|
||||
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
|
||||
|
||||
void merge_callbacks()
|
||||
{
|
||||
callbacks_.access([&](task_list& tasks)
|
||||
{
|
||||
new_callbacks_.access([&](task_list& new_tasks)
|
||||
{
|
||||
tasks.insert(tasks.end(), std::move_iterator<task_list::iterator>(new_tasks.begin()), std::move_iterator<task_list::iterator>(new_tasks.end()));
|
||||
new_tasks = {};
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
volatile bool kill = false;
|
||||
std::thread thread;
|
||||
task_pipeline pipelines[pipeline::count];
|
||||
utils::hook::detour r_end_frame_hook;
|
||||
utils::hook::detour g_run_frame_hook;
|
||||
utils::hook::detour main_frame_hook;
|
||||
|
||||
void execute(const pipeline type)
|
||||
{
|
||||
assert(type >= 0 && type < pipeline::count);
|
||||
pipelines[type].execute();
|
||||
}
|
||||
|
||||
void r_end_frame_stub()
|
||||
{
|
||||
execute(pipeline::renderer);
|
||||
r_end_frame_hook.invoke<void>();
|
||||
}
|
||||
|
||||
void server_frame_stub()
|
||||
{
|
||||
g_run_frame_hook.invoke<void>();
|
||||
execute(pipeline::server);
|
||||
}
|
||||
|
||||
void main_frame_stub()
|
||||
{
|
||||
main_frame_hook.invoke<void>();
|
||||
execute(pipeline::main);
|
||||
}
|
||||
}
|
||||
|
||||
void schedule(const std::function<bool()>& callback, const pipeline type,
|
||||
const std::chrono::milliseconds delay)
|
||||
{
|
||||
assert(type >= 0 && type < pipeline::count);
|
||||
|
||||
task task;
|
||||
task.handler = callback;
|
||||
task.interval = delay;
|
||||
task.last_call = std::chrono::high_resolution_clock::now();
|
||||
|
||||
pipelines[type].add(std::move(task));
|
||||
}
|
||||
|
||||
void loop(const std::function<void()>& callback, const pipeline type,
|
||||
const std::chrono::milliseconds delay)
|
||||
{
|
||||
schedule([callback]()
|
||||
{
|
||||
callback();
|
||||
return cond_continue;
|
||||
}, type, delay);
|
||||
}
|
||||
|
||||
void once(const std::function<void()>& callback, const pipeline type,
|
||||
const std::chrono::milliseconds delay)
|
||||
{
|
||||
schedule([callback]()
|
||||
{
|
||||
callback();
|
||||
return cond_end;
|
||||
}, type, delay);
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_load() override
|
||||
{
|
||||
thread = utils::thread::create_named_thread("Async Scheduler", []()
|
||||
{
|
||||
while (!kill)
|
||||
{
|
||||
execute(pipeline::async);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void pre_destroy() override
|
||||
{
|
||||
kill = true;
|
||||
if (thread.joinable())
|
||||
{
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(scheduler::component)
|
33
src/client/component/scheduler.hpp
Normal file
33
src/client/component/scheduler.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
namespace scheduler
|
||||
{
|
||||
enum pipeline
|
||||
{
|
||||
// Asynchronuous pipeline, disconnected from the game
|
||||
async = 0,
|
||||
|
||||
// The game's rendering pipeline
|
||||
renderer,
|
||||
|
||||
// The game's server thread
|
||||
server,
|
||||
|
||||
// The game's main thread
|
||||
main,
|
||||
|
||||
count,
|
||||
};
|
||||
|
||||
static const bool cond_continue = false;
|
||||
static const bool cond_end = true;
|
||||
|
||||
void schedule(const std::function<bool()>& callback, pipeline type = pipeline::async,
|
||||
std::chrono::milliseconds delay = 0ms);
|
||||
void loop(const std::function<void()>& callback, pipeline type = pipeline::async,
|
||||
std::chrono::milliseconds delay = 0ms);
|
||||
void once(const std::function<void()>& callback, pipeline type = pipeline::async,
|
||||
std::chrono::milliseconds delay = 0ms);
|
||||
void on_game_initialized(const std::function<void()>& callback, pipeline type = pipeline::async,
|
||||
std::chrono::milliseconds delay = 0ms);
|
||||
}
|
131
src/client/component/splash.cpp
Normal file
131
src/client/component/splash.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "resource.hpp"
|
||||
|
||||
#include <utils/nt.hpp>
|
||||
|
||||
namespace splash
|
||||
{
|
||||
namespace
|
||||
{
|
||||
HANDLE load_splash_image()
|
||||
{
|
||||
const auto self = utils::nt::library::get_by_address(load_splash_image);
|
||||
return LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_load() override
|
||||
{
|
||||
image_ = load_splash_image();
|
||||
|
||||
this->show();
|
||||
}
|
||||
|
||||
void pre_destroy() override
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
MSG msg;
|
||||
while (this->window_ && IsWindow(this->window_))
|
||||
{
|
||||
if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
|
||||
this->window_ = nullptr;
|
||||
}
|
||||
|
||||
void post_unpack() override
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
private:
|
||||
HWND window_{};
|
||||
HANDLE image_{};
|
||||
|
||||
void destroy() const
|
||||
{
|
||||
if (this->window_ && IsWindow(this->window_))
|
||||
{
|
||||
ShowWindow(this->window_, SW_HIDE);
|
||||
DestroyWindow(this->window_);
|
||||
UnregisterClassA("Black Ops III Splash Screen", utils::nt::library{});
|
||||
}
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
WNDCLASSA wnd_class;
|
||||
|
||||
const utils::nt::library host{};
|
||||
|
||||
wnd_class.style = CS_DROPSHADOW;
|
||||
wnd_class.cbClsExtra = 0;
|
||||
wnd_class.cbWndExtra = 0;
|
||||
wnd_class.lpszMenuName = nullptr;
|
||||
wnd_class.lpfnWndProc = DefWindowProcA;
|
||||
wnd_class.hInstance = host;
|
||||
wnd_class.hIcon = LoadIconA(host, reinterpret_cast<LPCSTR>(102));
|
||||
wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING);
|
||||
wnd_class.hbrBackground = reinterpret_cast<HBRUSH>(6);
|
||||
wnd_class.lpszClassName = "Black Ops III Splash Screen";
|
||||
|
||||
if (RegisterClassA(&wnd_class))
|
||||
{
|
||||
const auto x_pixels = GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
const auto y_pixels = GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
|
||||
if (image_)
|
||||
{
|
||||
this->window_ = CreateWindowExA(WS_EX_APPWINDOW, "Black Ops III Splash Screen", "BOIII",
|
||||
WS_POPUP | WS_SYSMENU,
|
||||
(x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr,
|
||||
nullptr,
|
||||
host, nullptr);
|
||||
|
||||
if (this->window_)
|
||||
{
|
||||
auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu,
|
||||
0, 0,
|
||||
320, 100, this->window_, nullptr, host, nullptr);
|
||||
if (image_window)
|
||||
{
|
||||
RECT rect;
|
||||
SendMessageA(image_window, 0x172u, 0, reinterpret_cast<LPARAM>(image_));
|
||||
GetWindowRect(image_window, &rect);
|
||||
|
||||
const int width = rect.right - rect.left;
|
||||
rect.left = (x_pixels - width) / 2;
|
||||
|
||||
const int height = rect.bottom - rect.top;
|
||||
rect.top = (y_pixels - height) / 2;
|
||||
|
||||
rect.right = rect.left + width;
|
||||
rect.bottom = rect.top + height;
|
||||
AdjustWindowRect(&rect, WS_CHILD | WS_VISIBLE | 0xEu, 0);
|
||||
SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left,
|
||||
rect.bottom - rect.top, SWP_NOZORDER);
|
||||
|
||||
ShowWindow(this->window_, SW_SHOW);
|
||||
UpdateWindow(this->window_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(splash::component)
|
24
src/client/loader/component_interface.hpp
Normal file
24
src/client/loader/component_interface.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
class component_interface
|
||||
{
|
||||
public:
|
||||
virtual ~component_interface() = default;
|
||||
|
||||
virtual void post_load()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void pre_destroy()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void post_unpack()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool is_supported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
90
src/client/loader/component_loader.cpp
Normal file
90
src/client/loader/component_loader.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include <std_include.hpp>
|
||||
#include "component_loader.hpp"
|
||||
|
||||
void component_loader::register_component(std::unique_ptr<component_interface>&& component_)
|
||||
{
|
||||
get_components().push_back(std::move(component_));
|
||||
}
|
||||
|
||||
bool component_loader::post_load()
|
||||
{
|
||||
static auto handled = false;
|
||||
if (handled) return true;
|
||||
handled = true;
|
||||
|
||||
clean();
|
||||
|
||||
try
|
||||
{
|
||||
for (const auto& component_ : get_components())
|
||||
{
|
||||
component_->post_load();
|
||||
}
|
||||
}
|
||||
catch (premature_shutdown_trigger&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void component_loader::post_unpack()
|
||||
{
|
||||
static auto handled = false;
|
||||
if (handled) return;
|
||||
handled = true;
|
||||
|
||||
for (const auto& component_ : get_components())
|
||||
{
|
||||
component_->post_unpack();
|
||||
}
|
||||
}
|
||||
|
||||
void component_loader::pre_destroy()
|
||||
{
|
||||
static auto handled = false;
|
||||
if (handled) return;
|
||||
handled = true;
|
||||
|
||||
for (const auto& component_ : get_components())
|
||||
{
|
||||
component_->pre_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void component_loader::clean()
|
||||
{
|
||||
auto& components = get_components();
|
||||
for (auto i = components.begin(); i != components.end();)
|
||||
{
|
||||
if (!(*i)->is_supported())
|
||||
{
|
||||
(*i)->pre_destroy();
|
||||
i = components.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void component_loader::trigger_premature_shutdown()
|
||||
{
|
||||
throw premature_shutdown_trigger();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<component_interface>>& component_loader::get_components()
|
||||
{
|
||||
using component_vector = std::vector<std::unique_ptr<component_interface>>;
|
||||
using component_vector_container = std::unique_ptr<component_vector, std::function<void(component_vector*)>>;
|
||||
|
||||
static component_vector_container components(new component_vector, [](const component_vector* component_vector)
|
||||
{
|
||||
pre_destroy();
|
||||
delete component_vector;
|
||||
});
|
||||
|
||||
return *components;
|
||||
}
|
58
src/client/loader/component_loader.hpp
Normal file
58
src/client/loader/component_loader.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include "component_interface.hpp"
|
||||
|
||||
class component_loader final
|
||||
{
|
||||
public:
|
||||
class premature_shutdown_trigger final : public std::exception
|
||||
{
|
||||
[[nodiscard]] const char* what() const noexcept override
|
||||
{
|
||||
return "Premature shutdown requested";
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class installer final
|
||||
{
|
||||
static_assert(std::is_base_of_v<component_interface, T>, "component has invalid base class");
|
||||
|
||||
public:
|
||||
installer()
|
||||
{
|
||||
register_component(std::make_unique<T>());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static T* get()
|
||||
{
|
||||
for (const auto& component_ : get_components())
|
||||
{
|
||||
if (typeid(*component_.get()) == typeid(T))
|
||||
{
|
||||
return reinterpret_cast<T*>(component_.get());
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void register_component(std::unique_ptr<component_interface>&& component);
|
||||
|
||||
static bool post_load();
|
||||
static void post_unpack();
|
||||
static void pre_destroy();
|
||||
static void clean();
|
||||
|
||||
static void trigger_premature_shutdown();
|
||||
|
||||
private:
|
||||
static std::vector<std::unique_ptr<component_interface>>& get_components();
|
||||
};
|
||||
|
||||
#define REGISTER_COMPONENT(name) \
|
||||
namespace \
|
||||
{ \
|
||||
static component_loader::installer<name> __component; \
|
||||
}
|
131
src/client/main.cpp
Normal file
131
src/client/main.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include <std_include.hpp>
|
||||
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include <utils/finally.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/nt.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
DECLSPEC_NORETURN void WINAPI exit_hook(const int code)
|
||||
{
|
||||
component_loader::pre_destroy();
|
||||
exit(code);
|
||||
}
|
||||
|
||||
VOID WINAPI initialize_critical_section(const LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
component_loader::post_unpack();
|
||||
InitializeCriticalSection(lpCriticalSection);
|
||||
}
|
||||
|
||||
void patch_imports()
|
||||
{
|
||||
const utils::nt::library game{};
|
||||
const auto self = utils::nt::library::get_by_address(patch_imports);
|
||||
|
||||
auto patch_steam_import = [&](const std::string& func) {
|
||||
const auto game_entry = game.get_iat_entry("steam_api64.dll", func);
|
||||
if (!game_entry) {
|
||||
throw std::runtime_error("Import '" + func + "' not found!");
|
||||
}
|
||||
|
||||
const auto self_proc = self.get_proc<void*>(func);
|
||||
if (!self_proc) {
|
||||
throw std::runtime_error(func + " export not found");
|
||||
}
|
||||
utils::hook::set(game_entry, self_proc);
|
||||
};
|
||||
|
||||
patch_steam_import("SteamAPI_RegisterCallback");
|
||||
patch_steam_import("SteamAPI_RegisterCallResult");
|
||||
patch_steam_import("SteamGameServer_Shutdown");
|
||||
patch_steam_import("SteamGameServer_RunCallbacks");
|
||||
patch_steam_import("SteamGameServer_GetHSteamPipe");
|
||||
patch_steam_import("SteamGameServer_GetHSteamUser");
|
||||
patch_steam_import("SteamInternal_GameServer_Init");
|
||||
patch_steam_import("SteamAPI_UnregisterCallResult");
|
||||
patch_steam_import("SteamAPI_UnregisterCallback");
|
||||
patch_steam_import("SteamAPI_RunCallbacks");
|
||||
//patch_steam_import("SteamAPI_Shutdown");
|
||||
patch_steam_import("SteamInternal_CreateInterface");
|
||||
patch_steam_import("SteamAPI_GetHSteamUser");
|
||||
patch_steam_import("SteamAPI_GetHSteamPipe");
|
||||
patch_steam_import("SteamAPI_Init");
|
||||
patch_steam_import("SteamAPI_RestartAppIfNecessary");
|
||||
|
||||
utils::hook::set(game.get_iat_entry("kernel32.dll", "InitializeCriticalSection"), initialize_critical_section);
|
||||
utils::hook::set(game.get_iat_entry("kernel32.dll", "ExitProcess"), exit_hook);
|
||||
}
|
||||
|
||||
bool run()
|
||||
{
|
||||
srand(uint32_t(time(nullptr)) ^ (~GetTickCount()));
|
||||
|
||||
{
|
||||
auto premature_shutdown = true;
|
||||
const auto _ = utils::finally([&premature_shutdown]()
|
||||
{
|
||||
if (premature_shutdown)
|
||||
{
|
||||
component_loader::pre_destroy();
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
patch_imports();
|
||||
|
||||
if (!component_loader::post_load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
premature_shutdown = false;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE, const DWORD reason, LPVOID)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
if(!run()) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport)
|
||||
HRESULT D3D11CreateDevice(
|
||||
void* pAdapter,
|
||||
uint64_t DriverType,
|
||||
HMODULE Software,
|
||||
UINT Flags,
|
||||
const void* pFeatureLevels,
|
||||
UINT FeatureLevels,
|
||||
UINT SDKVersion,
|
||||
void** ppDevice,
|
||||
void* pFeatureLevel,
|
||||
void** ppImmediateContext
|
||||
)
|
||||
{
|
||||
static auto func = [] {
|
||||
char dir[MAX_PATH]{ 0 };
|
||||
GetSystemDirectoryA(dir, sizeof(dir));
|
||||
|
||||
const auto d3d11 = utils::nt::library::load(dir + "/d3d11.dll"s);
|
||||
return d3d11.get_proc<decltype(&D3D11CreateDevice)>("D3D11CreateDevice");
|
||||
}();
|
||||
|
||||
return func(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext);
|
||||
}
|
4
src/client/resource.hpp
Normal file
4
src/client/resource.hpp
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define ID_ICON 102
|
||||
#define IMAGE_SPLASH 300
|
111
src/client/resource.rc
Normal file
111
src/client/resource.rc
Normal file
@ -0,0 +1,111 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#pragma code_page(65001)
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "windows.h"
|
||||
#include "version.h"
|
||||
#include "resource.hpp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""windows.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_FILE_RC
|
||||
PRODUCTVERSION VERSION_PRODUCT_RC
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
#ifdef PRERELEASE
|
||||
FILEFLAGS VS_FF_PRERELEASE
|
||||
#else
|
||||
#ifndef CI
|
||||
FILEFLAGS VS_FF_PRIVATEBUILD
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", ""
|
||||
VALUE "FileDescription", "bo3"
|
||||
VALUE "FileVersion", VERSION_FILE
|
||||
VALUE "InternalName", "something"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2022. All rights reserved."
|
||||
VALUE "OriginalFilename", "d3d11.dll"
|
||||
VALUE "ProductName", "bo3"
|
||||
VALUE "ProductVersion", VERSION_PRODUCT
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Binary Data
|
||||
//
|
||||
|
||||
//ID_ICON ICON "resources/icon.ico"
|
||||
IMAGE_SPLASH BITMAP "resources/splash.bmp"
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
BIN
src/client/resources/icon.ico
Normal file
BIN
src/client/resources/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 161 KiB |
BIN
src/client/resources/splash.bmp
Normal file
BIN
src/client/resources/splash.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
50
src/client/std_include.cpp
Normal file
50
src/client/std_include.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include <std_include.hpp>
|
||||
|
||||
#pragma comment(linker, "/stack:0x1000000")
|
||||
|
||||
#ifdef INJECT_HOST_AS_LIB
|
||||
//#pragma comment(linker, "/base:0x160000000")
|
||||
#else
|
||||
#pragma comment(linker, "/base:0x140000000")
|
||||
#pragma comment(linker, "/merge:.data=.cld")
|
||||
#pragma comment(linker, "/merge:.rdata=.clr")
|
||||
#pragma comment(linker, "/merge:.cl=.main")
|
||||
#pragma comment(linker, "/merge:.text=.main")
|
||||
#endif
|
||||
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language=''\"")
|
||||
|
||||
#ifndef INJECT_HOST_AS_LIB
|
||||
#pragma bss_seg(".payload")
|
||||
char payload_data[BINARY_PAYLOAD_SIZE];
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
||||
__declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int s_read_arc4random(void*, size_t)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int s_read_getrandom(void*, size_t)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int s_read_urandom(void*, size_t)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int s_read_ltm_rng(void*, size_t)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
93
src/client/std_include.hpp
Normal file
93
src/client/std_include.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#define BINARY_PAYLOAD_SIZE 0x14000000
|
||||
|
||||
// Decide whether to load the game as lib or to inject it
|
||||
#define INJECT_HOST_AS_LIB
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4100)
|
||||
#pragma warning(disable: 4127)
|
||||
#pragma warning(disable: 4244)
|
||||
#pragma warning(disable: 4458)
|
||||
#pragma warning(disable: 4702)
|
||||
#pragma warning(disable: 4996)
|
||||
#pragma warning(disable: 5054)
|
||||
#pragma warning(disable: 5056)
|
||||
#pragma warning(disable: 6011)
|
||||
#pragma warning(disable: 6297)
|
||||
#pragma warning(disable: 6385)
|
||||
#pragma warning(disable: 6386)
|
||||
#pragma warning(disable: 6387)
|
||||
#pragma warning(disable: 26110)
|
||||
#pragma warning(disable: 26451)
|
||||
#pragma warning(disable: 26444)
|
||||
#pragma warning(disable: 26451)
|
||||
#pragma warning(disable: 26489)
|
||||
#pragma warning(disable: 26495)
|
||||
#pragma warning(disable: 26498)
|
||||
#pragma warning(disable: 26812)
|
||||
#pragma warning(disable: 28020)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <Windows.h>
|
||||
#include <MsHTML.h>
|
||||
#include <MsHtmHst.h>
|
||||
#include <ExDisp.h>
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <corecrt_io.h>
|
||||
#include <fcntl.h>
|
||||
#include <shellapi.h>
|
||||
#include <csetjmp>
|
||||
#include <ShlObj.h>
|
||||
#include <winternl.h>
|
||||
#include <VersionHelpers.h>
|
||||
#include <Psapi.h>
|
||||
#include <urlmon.h>
|
||||
#include <atlbase.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
// min and max is required by gdi, therefore NOMINMAX won't work
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <regex>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <variant>
|
||||
|
||||
#include <MinHook.h>
|
||||
#include <asmjit/core/jitruntime.h>
|
||||
#include <asmjit/x86/x86assembler.h>
|
||||
|
||||
#pragma warning(pop)
|
||||
#pragma warning(disable: 4100)
|
||||
|
||||
#pragma comment(lib, "ntdll.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#pragma comment(lib, "urlmon.lib" )
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#pragma comment(lib, "Crypt32.lib")
|
||||
|
||||
using namespace std::literals;
|
140
src/client/steam/interfaces/apps.cpp
Normal file
140
src/client/steam/interfaces/apps.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
bool apps::BIsSubscribed()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool apps::BIsLowViolence()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool apps::BIsCybercafe()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool apps::BIsVACBanned()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* apps::GetCurrentGameLanguage()
|
||||
{
|
||||
return "english";
|
||||
}
|
||||
|
||||
const char* apps::GetAvailableGameLanguages()
|
||||
{
|
||||
return "english";
|
||||
}
|
||||
|
||||
bool apps::BIsSubscribedApp(unsigned int appID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool apps::BIsDlcInstalled(unsigned int appID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int apps::GetEarliestPurchaseUnixTime(unsigned int nAppID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool apps::BIsSubscribedFromFreeWeekend()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int apps::GetDLCCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool apps::BGetDLCDataByIndex(int iDLC, unsigned int* pAppID, bool* pbAvailable, char* pchName,
|
||||
int cchNameBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void apps::InstallDLC(unsigned int nAppID)
|
||||
{
|
||||
}
|
||||
|
||||
void apps::UninstallDLC(unsigned int nAppID)
|
||||
{
|
||||
}
|
||||
|
||||
void apps::RequestAppProofOfPurchaseKey(unsigned int nAppID)
|
||||
{
|
||||
}
|
||||
|
||||
bool apps::GetCurrentBetaName(char* pchName, int cchNameBufferSize)
|
||||
{
|
||||
strncpy_s(pchName, cchNameBufferSize, "public", cchNameBufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool apps::MarkContentCorrupt(bool bMissingFilesOnly)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int apps::GetInstalledDepots(int* pvecDepots, unsigned int cMaxDepots)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int apps::GetAppInstallDir(unsigned int appID, char* pchFolder, unsigned int cchFolderBufferSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool apps::BIsAppInstalled(unsigned int appID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
steam_id apps::GetAppOwner()
|
||||
{
|
||||
return SteamUser()->GetSteamID();
|
||||
}
|
||||
|
||||
const char* apps::GetLaunchQueryParam(const char* pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
bool apps::GetDlcDownloadProgress(uint32_t nAppID, uint64_t* punBytesDownloaded, uint64_t* punBytesTotal)
|
||||
{
|
||||
*punBytesTotal = 0;
|
||||
*punBytesDownloaded = 0;
|
||||
return false;
|
||||
}
|
||||
int apps::GetAppBuildId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void apps::RequestAllProofOfPurchaseKeys()
|
||||
{
|
||||
|
||||
}
|
||||
uint64_t apps::GetFileDetails(const char* pszFileName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int apps::GetLaunchCommandLine(char* pszCommandLine, int cubCommandLine)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bool apps::BIsSubscribedFromFamilySharing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
41
src/client/steam/interfaces/apps.hpp
Normal file
41
src/client/steam/interfaces/apps.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class apps
|
||||
{
|
||||
public:
|
||||
~apps() = default;
|
||||
|
||||
virtual bool BIsSubscribed();
|
||||
virtual bool BIsLowViolence();
|
||||
virtual bool BIsCybercafe();
|
||||
virtual bool BIsVACBanned();
|
||||
virtual const char* GetCurrentGameLanguage();
|
||||
virtual const char* GetAvailableGameLanguages();
|
||||
virtual bool BIsSubscribedApp(unsigned int appID);
|
||||
virtual bool BIsDlcInstalled(unsigned int appID);
|
||||
virtual unsigned int GetEarliestPurchaseUnixTime(unsigned int nAppID);
|
||||
virtual bool BIsSubscribedFromFreeWeekend();
|
||||
virtual int GetDLCCount();
|
||||
virtual bool BGetDLCDataByIndex(int iDLC, unsigned int* pAppID, bool* pbAvailable, char* pchName,
|
||||
int cchNameBufferSize);
|
||||
virtual void InstallDLC(unsigned int nAppID);
|
||||
virtual void UninstallDLC(unsigned int nAppID);
|
||||
virtual void RequestAppProofOfPurchaseKey(unsigned int nAppID);
|
||||
virtual bool GetCurrentBetaName(char* pchName, int cchNameBufferSize);
|
||||
virtual bool MarkContentCorrupt(bool bMissingFilesOnly);
|
||||
virtual unsigned int GetInstalledDepots(int* pvecDepots, unsigned int cMaxDepots);
|
||||
virtual unsigned int GetAppInstallDir(unsigned int appID, char* pchFolder, unsigned int cchFolderBufferSize);
|
||||
virtual bool BIsAppInstalled(unsigned int appID);
|
||||
|
||||
virtual steam_id GetAppOwner();
|
||||
virtual const char* GetLaunchQueryParam(const char* pchKey);
|
||||
virtual bool GetDlcDownloadProgress(uint32_t nAppID, uint64_t* punBytesDownloaded, uint64_t* punBytesTotal);
|
||||
virtual int GetAppBuildId();
|
||||
virtual void RequestAllProofOfPurchaseKeys();
|
||||
virtual uint64_t GetFileDetails(const char* pszFileName);
|
||||
virtual int GetLaunchCommandLine(char* pszCommandLine, int cubCommandLine);
|
||||
virtual bool BIsSubscribedFromFamilySharing();
|
||||
};
|
||||
}
|
356
src/client/steam/interfaces/client.cpp
Normal file
356
src/client/steam/interfaces/client.cpp
Normal file
@ -0,0 +1,356 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam {
|
||||
namespace {
|
||||
|
||||
void* get_dummy()
|
||||
{
|
||||
static class blub {
|
||||
public:
|
||||
virtual uint64_t m0() { return 0; }
|
||||
virtual uint64_t m1() { return 0; }
|
||||
virtual uint64_t m2() { return 0; }
|
||||
virtual uint64_t m3() { return 0; }
|
||||
virtual uint64_t m4() { return 0; }
|
||||
virtual uint64_t m5() { return 0; }
|
||||
virtual uint64_t m6() { return 0; }
|
||||
virtual uint64_t m7() { return 0; }
|
||||
virtual uint64_t m8() { return 0; }
|
||||
virtual uint64_t m9() { return 0; }
|
||||
|
||||
virtual uint64_t m10() { return 0; }
|
||||
virtual uint64_t m11() { return 0; }
|
||||
virtual uint64_t m12() { return 0; }
|
||||
virtual uint64_t m13() { return 0; }
|
||||
virtual uint64_t m14() { return 0; }
|
||||
virtual uint64_t m15() { return 0; }
|
||||
virtual uint64_t m16() { return 0; }
|
||||
virtual uint64_t m17() { return 0; }
|
||||
virtual uint64_t m18() { return 0; }
|
||||
virtual uint64_t m19() { return 0; }
|
||||
|
||||
virtual uint64_t m20() { return 0; }
|
||||
virtual uint64_t m21() { return 0; }
|
||||
virtual uint64_t m22() { return 0; }
|
||||
virtual uint64_t m23() { return 0; }
|
||||
virtual uint64_t m24() { return 0; }
|
||||
virtual uint64_t m25() { return 0; }
|
||||
virtual uint64_t m26() { return 0; }
|
||||
virtual uint64_t m27() { return 0; }
|
||||
virtual uint64_t m28() { return 0; }
|
||||
virtual uint64_t m29() { return 0; }
|
||||
|
||||
virtual uint64_t m30() { return 0; }
|
||||
virtual uint64_t m31() { return 0; }
|
||||
virtual uint64_t m32() { return 0; }
|
||||
virtual uint64_t m33() { return 0; }
|
||||
virtual uint64_t m34() { return 0; }
|
||||
virtual uint64_t m35() { return 0; }
|
||||
virtual uint64_t m36() { return 0; }
|
||||
virtual uint64_t m37() { return 0; }
|
||||
virtual uint64_t m38() { return 0; }
|
||||
virtual uint64_t m39() { return 0; }
|
||||
|
||||
virtual uint64_t m40() { return 0; }
|
||||
virtual uint64_t m41() { return 0; }
|
||||
virtual uint64_t m42() { return 0; }
|
||||
virtual uint64_t m43() { return 0; }
|
||||
virtual uint64_t m44() { return 0; }
|
||||
virtual uint64_t m45() { return 0; }
|
||||
virtual uint64_t m46() { return 0; }
|
||||
virtual uint64_t m47() { return 0; }
|
||||
virtual uint64_t m48() { return 0; }
|
||||
virtual uint64_t m49() { return 0; }
|
||||
|
||||
virtual uint64_t m50() { return 0; }
|
||||
virtual uint64_t m51() { return 0; }
|
||||
virtual uint64_t m52() { return 0; }
|
||||
virtual uint64_t m53() { return 0; }
|
||||
virtual uint64_t m54() { return 0; }
|
||||
virtual uint64_t m55() { return 0; }
|
||||
virtual uint64_t m56() { return 0; }
|
||||
virtual uint64_t m57() { return 0; }
|
||||
virtual uint64_t m58() { return 0; }
|
||||
virtual uint64_t m59() { return 0; }
|
||||
|
||||
virtual uint64_t m60() { return 0; }
|
||||
virtual uint64_t m61() { return 0; }
|
||||
virtual uint64_t m62() { return 0; }
|
||||
virtual uint64_t m63() { return 0; }
|
||||
virtual uint64_t m64() { return 0; }
|
||||
virtual uint64_t m65() { return 0; }
|
||||
virtual uint64_t m66() { return 0; }
|
||||
virtual uint64_t m67() { return 0; }
|
||||
virtual uint64_t m68() { return 0; }
|
||||
virtual uint64_t m69() { return 0; }
|
||||
|
||||
} x;
|
||||
return &x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HSteamPipe client::CreateSteamPipe()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool client::BReleaseSteamPipe(HSteamPipe hSteamPipe)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
HSteamUser client::ConnectToGlobalUser(HSteamPipe hSteamPipe)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HSteamUser client::CreateLocalUser(HSteamPipe* phSteamPipe, uint32_t eAccountType)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void client::ReleaseUser(HSteamPipe hSteamPipe, HSteamUser hUser)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void* client::GetISteamUser(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
return SteamUser();
|
||||
}
|
||||
|
||||
void* client::GetISteamGameServer(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamGameServer();
|
||||
}
|
||||
|
||||
void client::SetLocalIPBinding(uint32_t unIP, uint16_t usPort)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void* client::GetISteamFriends(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
return SteamFriends();
|
||||
}
|
||||
|
||||
void* client::GetISteamUtils(HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamUtils();
|
||||
}
|
||||
|
||||
void* client::GetISteamMatchmaking(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamMatchmaking();
|
||||
}
|
||||
|
||||
void* client::GetISteamMatchmakingServers(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
static matchmaking_servers u;
|
||||
return &u;
|
||||
}
|
||||
|
||||
void* client::GetISteamGenericInterface(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* client::GetISteamUserStats(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamUserStats();
|
||||
}
|
||||
|
||||
void* client::GetISteamGameServerStats(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
static game_server_stats u;
|
||||
return &u;
|
||||
}
|
||||
|
||||
void* client::GetISteamApps(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamApps();
|
||||
}
|
||||
|
||||
void* client::GetISteamNetworking(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamNetworking();
|
||||
}
|
||||
|
||||
void* client::GetISteamRemoteStorage(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
return SteamRemoteStorage();
|
||||
}
|
||||
|
||||
void* client::GetISteamScreenshots(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
static screenshots s;
|
||||
return &s;
|
||||
}
|
||||
|
||||
void client::RunFrame()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
uint32_t client::GetIPCCallCount()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void client::SetWarningMessageHook(void* pFunction)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
bool client::BShutdownIfAllPipesClosed()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* client::GetISteamHTTP(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
|
||||
static http h;
|
||||
return &h;
|
||||
}
|
||||
|
||||
void* client::GetISteamUnifiedMessages(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
static unified_messages u;
|
||||
return &u; //
|
||||
}
|
||||
|
||||
void* client::GetISteamController(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
|
||||
static controller c;
|
||||
return &c; //
|
||||
}
|
||||
|
||||
void* client::GetISteamUGC(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy(); //
|
||||
}
|
||||
|
||||
void* client::GetISteamAppList(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy(); //
|
||||
}
|
||||
|
||||
void* client::GetISteamMusic(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy(); //
|
||||
}
|
||||
|
||||
void* client::GetISteamMusicRemote(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy(); //
|
||||
}
|
||||
|
||||
void* client::GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy(); //
|
||||
}
|
||||
|
||||
void client::Set_SteamAPI_CPostAPIResultInProcess(void* func)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void client::Remove_SteamAPI_CPostAPIResultInProcess(void* func)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void client::Set_SteamAPI_CCheckCallbackRegisteredInProcess(void* func)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void* client::GetISteamInventory(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy();
|
||||
}
|
||||
|
||||
void* client::GetISteamVideo(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy();//
|
||||
}
|
||||
|
||||
void* client::GetISteamParentalSettings(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(pchVersion);
|
||||
//MessageBoxA(0, pchVersion, 0, 0);
|
||||
return get_dummy();
|
||||
}
|
||||
}
|
52
src/client/steam/interfaces/client.hpp
Normal file
52
src/client/steam/interfaces/client.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace steam
|
||||
{
|
||||
using HSteamPipe = uint64_t;
|
||||
using HSteamUser = uint64_t;
|
||||
|
||||
class client
|
||||
{
|
||||
public:
|
||||
~client() = default;
|
||||
|
||||
virtual HSteamPipe CreateSteamPipe();
|
||||
virtual bool BReleaseSteamPipe(HSteamPipe hSteamPipe);
|
||||
virtual HSteamUser ConnectToGlobalUser(HSteamPipe hSteamPipe);
|
||||
virtual HSteamUser CreateLocalUser(HSteamPipe* phSteamPipe, uint32_t eAccountType);
|
||||
virtual void ReleaseUser(HSteamPipe hSteamPipe, HSteamUser hUser);
|
||||
virtual void* GetISteamUser(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamGameServer(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void SetLocalIPBinding(uint32_t unIP, uint16_t usPort);
|
||||
virtual void* GetISteamFriends(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamUtils(HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamMatchmaking(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamMatchmakingServers(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamGenericInterface(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamUserStats(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamGameServerStats(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamApps(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamNetworking(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamRemoteStorage(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamScreenshots(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void RunFrame();
|
||||
virtual uint32_t GetIPCCallCount();
|
||||
virtual void SetWarningMessageHook(void* pFunction);
|
||||
virtual bool BShutdownIfAllPipesClosed();
|
||||
virtual void* GetISteamHTTP(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamUnifiedMessages(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamController(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamUGC(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamAppList(HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamMusic(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamMusicRemote(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void Set_SteamAPI_CPostAPIResultInProcess(void* func);
|
||||
virtual void Remove_SteamAPI_CPostAPIResultInProcess(void* func);
|
||||
virtual void Set_SteamAPI_CCheckCallbackRegisteredInProcess(void* func);
|
||||
virtual void* GetISteamInventory(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamVideo(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
virtual void* GetISteamParentalSettings(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char* pchVersion);
|
||||
};
|
||||
}
|
74
src/client/steam/interfaces/controller.cpp
Normal file
74
src/client/steam/interfaces/controller.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
bool controller::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool controller::Shutdown()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void controller::RunFrame()
|
||||
{
|
||||
|
||||
}
|
||||
int controller::GetConnectedControllers(ControllerHandle_t* handlesOut)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool controller::ShowBindingPanel(ControllerHandle_t controllerHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint64_t controller::GetActionSetHandle(const char* pszActionSetName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void controller::ActivateActionSet(ControllerHandle_t controllerHandle, uint64_t actionSetHandle)
|
||||
{
|
||||
|
||||
}
|
||||
uint64_t controller::GetCurrentActionSet(ControllerHandle_t controllerHandle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint64_t controller::GetDigitalActionHandle(const char* pszActionName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t controller::GetDigitalActionData(ControllerHandle_t controllerHandle, uint64_t digitalActionHandle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int controller::GetDigitalActionOrigins(ControllerHandle_t controllerHandle, uint64_t actionSetHandle, uint64_t digitalActionHandle, uint64_t* originsOut)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint64_t controller::GetAnalogActionHandle(const char* pszActionName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint64_t controller::GetAnalogActionData(ControllerHandle_t controllerHandle, uint64_t analogActionHandle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int controller::GetAnalogActionOrigins(ControllerHandle_t controllerHandle, uint64_t actionSetHandle, uint64_t analogActionHandle, uint64_t* originsOut)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void controller::StopAnalogActionMomentum(ControllerHandle_t controllerHandle, uint64_t eAction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void controller::TriggerHapticPulse(ControllerHandle_t controllerHandle, uint64_t eTargetPad, unsigned short usDurationMicroSec)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
28
src/client/steam/interfaces/controller.hpp
Normal file
28
src/client/steam/interfaces/controller.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
using ControllerHandle_t = uint64_t;
|
||||
class controller
|
||||
{
|
||||
public:
|
||||
~controller() = default;
|
||||
|
||||
virtual bool Init();
|
||||
virtual bool Shutdown();
|
||||
virtual void RunFrame();
|
||||
virtual int GetConnectedControllers(ControllerHandle_t* handlesOut);
|
||||
virtual bool ShowBindingPanel(ControllerHandle_t controllerHandle);
|
||||
virtual uint64_t GetActionSetHandle(const char* pszActionSetName);
|
||||
virtual void ActivateActionSet(ControllerHandle_t controllerHandle, uint64_t actionSetHandle);
|
||||
virtual uint64_t GetCurrentActionSet(ControllerHandle_t controllerHandle);
|
||||
virtual uint64_t GetDigitalActionHandle(const char* pszActionName);
|
||||
virtual uint64_t GetDigitalActionData(ControllerHandle_t controllerHandle, uint64_t digitalActionHandle);
|
||||
virtual int GetDigitalActionOrigins(ControllerHandle_t controllerHandle, uint64_t actionSetHandle, uint64_t digitalActionHandle, uint64_t* originsOut);
|
||||
virtual uint64_t GetAnalogActionHandle(const char* pszActionName);
|
||||
virtual uint64_t GetAnalogActionData(ControllerHandle_t controllerHandle, uint64_t analogActionHandle);
|
||||
virtual int GetAnalogActionOrigins(ControllerHandle_t controllerHandle, uint64_t actionSetHandle, uint64_t analogActionHandle, uint64_t* originsOut);
|
||||
virtual void StopAnalogActionMomentum(ControllerHandle_t controllerHandle, uint64_t eAction);
|
||||
virtual void TriggerHapticPulse(ControllerHandle_t controllerHandle, uint64_t eTargetPad, unsigned short usDurationMicroSec);
|
||||
};
|
||||
}
|
315
src/client/steam/interfaces/friends.cpp
Normal file
315
src/client/steam/interfaces/friends.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
//#include <game/game.hpp>
|
||||
|
||||
namespace steam
|
||||
{
|
||||
const char* friends::GetPersonaName()
|
||||
{
|
||||
return "T7x User";
|
||||
}
|
||||
|
||||
unsigned long long friends::SetPersonaName(const char* pchPersonaName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int friends::GetPersonaState()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int friends::GetFriendCount(int eFriendFlags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetFriendByIndex(int iFriend, int iFriendFlags)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
int friends::GetFriendRelationship(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int friends::GetFriendPersonaState(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* friends::GetFriendPersonaName(steam_id steamIDFriend)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool friends::GetFriendGamePlayed(steam_id steamIDFriend, void* pFriendGameInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* friends::GetFriendPersonaNameHistory(steam_id steamIDFriend, int iPersonaName)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool friends::HasFriend(steam_id steamIDFriend, int eFriendFlags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int friends::GetClanCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetClanByIndex(int iClan)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
const char* friends::GetClanName(steam_id steamIDClan)
|
||||
{
|
||||
return "3arc";
|
||||
}
|
||||
|
||||
const char* friends::GetClanTag(steam_id steamIDClan)
|
||||
{
|
||||
return this->GetClanName(steamIDClan);
|
||||
}
|
||||
|
||||
bool friends::GetClanActivityCounts(steam_id steamID, int* pnOnline, int* pnInGame, int* pnChatting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long friends::DownloadClanActivityCounts(steam_id groupIDs[], int nIds)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int friends::GetFriendCountFromSource(steam_id steamIDSource)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetFriendFromSourceByIndex(steam_id steamIDSource, int iFriend)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
bool friends::IsUserInSource(steam_id steamIDUser, steam_id steamIDSource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void friends::SetInGameVoiceSpeaking(steam_id steamIDUser, bool bSpeaking)
|
||||
{
|
||||
}
|
||||
|
||||
void friends::ActivateGameOverlay(const char* pchDialog)
|
||||
{
|
||||
}
|
||||
|
||||
void friends::ActivateGameOverlayToUser(const char* pchDialog, steam_id steamID)
|
||||
{
|
||||
}
|
||||
|
||||
void friends::ActivateGameOverlayToWebPage(const char* pchURL)
|
||||
{
|
||||
}
|
||||
|
||||
void friends::ActivateGameOverlayToStore(unsigned int nAppID, unsigned int eFlag)
|
||||
{
|
||||
}
|
||||
|
||||
void friends::SetPlayedWith(steam_id steamIDUserPlayedWith)
|
||||
{
|
||||
}
|
||||
|
||||
void friends::ActivateGameOverlayInviteDialog(steam_id steamIDLobby)
|
||||
{
|
||||
}
|
||||
|
||||
int friends::GetSmallFriendAvatar(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int friends::GetMediumFriendAvatar(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int friends::GetLargeFriendAvatar(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool friends::RequestUserInformation(steam_id steamIDUser, bool bRequireNameOnly)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long friends::RequestClanOfficerList(steam_id steamIDClan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetClanOwner(steam_id steamIDClan)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
int friends::GetClanOfficerCount(steam_id steamIDClan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetClanOfficerByIndex(steam_id steamIDClan, int iOfficer)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
int friends::GetUserRestrictions()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool friends::SetRichPresence(const char* pchKey, const char* pchValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void friends::ClearRichPresence()
|
||||
{
|
||||
}
|
||||
|
||||
const char* friends::GetFriendRichPresence(steam_id steamIDFriend, const char* pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int friends::GetFriendRichPresenceKeyCount(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* friends::GetFriendRichPresenceKeyByIndex(steam_id steamIDFriend, int iKey)
|
||||
{
|
||||
return "a";
|
||||
}
|
||||
|
||||
void friends::RequestFriendRichPresence(steam_id steamIDFriend)
|
||||
{
|
||||
}
|
||||
|
||||
bool friends::InviteUserToGame(steam_id steamIDFriend, const char* pchConnectString)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int friends::GetCoplayFriendCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetCoplayFriend(int iCoplayFriend)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
int friends::GetFriendCoplayTime(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int friends::GetFriendCoplayGame(steam_id steamIDFriend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long friends::JoinClanChatRoom(steam_id steamIDClan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool friends::LeaveClanChatRoom(steam_id steamIDClan)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int friends::GetClanChatMemberCount(steam_id steamIDClan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id friends::GetChatMemberByIndex(steam_id steamIDClan, int iUser)
|
||||
{
|
||||
return steam_id();
|
||||
}
|
||||
|
||||
bool friends::SendClanChatMessage(steam_id steamIDClanChat, const char* pchText)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int friends::GetClanChatMessage(steam_id steamIDClanChat, int iMessage, void* prgchText, int cchTextMax,
|
||||
unsigned int* peChatEntryType, steam_id* pSteamIDChatter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool friends::IsClanChatAdmin(steam_id steamIDClanChat, steam_id steamIDUser)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool friends::IsClanChatWindowOpenInSteam(steam_id steamIDClanChat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool friends::OpenClanChatWindowInSteam(steam_id steamIDClanChat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool friends::CloseClanChatWindowInSteam(steam_id steamIDClanChat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool friends::SetListenForFriendsMessages(bool bInterceptEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool friends::ReplyToFriendMessage(steam_id steamIDFriend, const char* pchMsgToSend)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int friends::GetFriendMessage(steam_id steamIDFriend, int iMessageID, void* pvData, int cubData,
|
||||
unsigned int* peChatEntryType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long friends::GetFollowerCount(steam_id steamID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long friends::IsFollowing(steam_id steamID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long friends::EnumerateFollowingList(unsigned int unStartIndex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
76
src/client/steam/interfaces/friends.hpp
Normal file
76
src/client/steam/interfaces/friends.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class friends
|
||||
{
|
||||
public:
|
||||
~friends() = default;
|
||||
|
||||
virtual const char* GetPersonaName();
|
||||
virtual unsigned long long SetPersonaName(const char* pchPersonaName);
|
||||
virtual int GetPersonaState();
|
||||
virtual int GetFriendCount(int eFriendFlags);
|
||||
virtual steam_id GetFriendByIndex(int iFriend, int iFriendFlags);
|
||||
virtual int GetFriendRelationship(steam_id steamIDFriend);
|
||||
virtual int GetFriendPersonaState(steam_id steamIDFriend);
|
||||
virtual const char* GetFriendPersonaName(steam_id steamIDFriend);
|
||||
virtual bool GetFriendGamePlayed(steam_id steamIDFriend, void* pFriendGameInfo);
|
||||
virtual const char* GetFriendPersonaNameHistory(steam_id steamIDFriend, int iPersonaName);
|
||||
virtual bool HasFriend(steam_id steamIDFriend, int eFriendFlags);
|
||||
virtual int GetClanCount();
|
||||
virtual steam_id GetClanByIndex(int iClan);
|
||||
virtual const char* GetClanName(steam_id steamIDClan);
|
||||
virtual const char* GetClanTag(steam_id steamIDClan);
|
||||
virtual bool GetClanActivityCounts(steam_id steamID, int* pnOnline, int* pnInGame, int* pnChatting);
|
||||
virtual unsigned long long DownloadClanActivityCounts(steam_id groupIDs[], int nIds);
|
||||
virtual int GetFriendCountFromSource(steam_id steamIDSource);
|
||||
virtual steam_id GetFriendFromSourceByIndex(steam_id steamIDSource, int iFriend);
|
||||
virtual bool IsUserInSource(steam_id steamIDUser, steam_id steamIDSource);
|
||||
virtual void SetInGameVoiceSpeaking(steam_id steamIDUser, bool bSpeaking);
|
||||
virtual void ActivateGameOverlay(const char* pchDialog);
|
||||
virtual void ActivateGameOverlayToUser(const char* pchDialog, steam_id steamID);
|
||||
virtual void ActivateGameOverlayToWebPage(const char* pchURL);
|
||||
virtual void ActivateGameOverlayToStore(unsigned int nAppID, unsigned int eFlag);
|
||||
virtual void SetPlayedWith(steam_id steamIDUserPlayedWith);
|
||||
virtual void ActivateGameOverlayInviteDialog(steam_id steamIDLobby);
|
||||
virtual int GetSmallFriendAvatar(steam_id steamIDFriend);
|
||||
virtual int GetMediumFriendAvatar(steam_id steamIDFriend);
|
||||
virtual int GetLargeFriendAvatar(steam_id steamIDFriend);
|
||||
virtual bool RequestUserInformation(steam_id steamIDUser, bool bRequireNameOnly);
|
||||
virtual unsigned long long RequestClanOfficerList(steam_id steamIDClan);
|
||||
virtual steam_id GetClanOwner(steam_id steamIDClan);
|
||||
virtual int GetClanOfficerCount(steam_id steamIDClan);
|
||||
virtual steam_id GetClanOfficerByIndex(steam_id steamIDClan, int iOfficer);
|
||||
virtual int GetUserRestrictions();
|
||||
virtual bool SetRichPresence(const char* pchKey, const char* pchValue);
|
||||
virtual void ClearRichPresence();
|
||||
virtual const char* GetFriendRichPresence(steam_id steamIDFriend, const char* pchKey);
|
||||
virtual int GetFriendRichPresenceKeyCount(steam_id steamIDFriend);
|
||||
virtual const char* GetFriendRichPresenceKeyByIndex(steam_id steamIDFriend, int iKey);
|
||||
virtual void RequestFriendRichPresence(steam_id steamIDFriend);
|
||||
virtual bool InviteUserToGame(steam_id steamIDFriend, const char* pchConnectString);
|
||||
virtual int GetCoplayFriendCount();
|
||||
virtual steam_id GetCoplayFriend(int iCoplayFriend);
|
||||
virtual int GetFriendCoplayTime(steam_id steamIDFriend);
|
||||
virtual unsigned int GetFriendCoplayGame(steam_id steamIDFriend);
|
||||
virtual unsigned long long JoinClanChatRoom(steam_id steamIDClan);
|
||||
virtual bool LeaveClanChatRoom(steam_id steamIDClan);
|
||||
virtual int GetClanChatMemberCount(steam_id steamIDClan);
|
||||
virtual steam_id GetChatMemberByIndex(steam_id steamIDClan, int iUser);
|
||||
virtual bool SendClanChatMessage(steam_id steamIDClanChat, const char* pchText);
|
||||
virtual int GetClanChatMessage(steam_id steamIDClanChat, int iMessage, void* prgchText, int cchTextMax,
|
||||
unsigned int* peChatEntryType, steam_id* pSteamIDChatter);
|
||||
virtual bool IsClanChatAdmin(steam_id steamIDClanChat, steam_id steamIDUser);
|
||||
virtual bool IsClanChatWindowOpenInSteam(steam_id steamIDClanChat);
|
||||
virtual bool OpenClanChatWindowInSteam(steam_id steamIDClanChat);
|
||||
virtual bool CloseClanChatWindowInSteam(steam_id steamIDClanChat);
|
||||
virtual bool SetListenForFriendsMessages(bool bInterceptEnabled);
|
||||
virtual bool ReplyToFriendMessage(steam_id steamIDFriend, const char* pchMsgToSend);
|
||||
virtual int GetFriendMessage(steam_id steamIDFriend, int iMessageID, void* pvData, int cubData,
|
||||
unsigned int* peChatEntryType);
|
||||
virtual unsigned long long GetFollowerCount(steam_id steamID);
|
||||
virtual unsigned long long IsFollowing(steam_id steamID);
|
||||
virtual unsigned long long EnumerateFollowingList(unsigned int unStartIndex);
|
||||
};
|
||||
}
|
204
src/client/steam/interfaces/game_server.cpp
Normal file
204
src/client/steam/interfaces/game_server.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
bool game_server::InitGameServer(unsigned int unGameIP, unsigned short unGamePort, unsigned short usQueryPort,
|
||||
unsigned int unServerFlags, unsigned int nAppID, const char* pchVersion)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void game_server::SetProduct(const char* pchProductName)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetGameDescription(const char* pchGameDescription)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetModDir(const char* pchModDir)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetDedicatedServer(bool bDedicatedServer)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::LogOn(const char* pszAccountName, const char* pszPassword)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::LogOnAnonymous()
|
||||
{
|
||||
auto* const retvals = calloc(1, 1);
|
||||
const auto result = callbacks::register_call();
|
||||
callbacks::return_call(retvals, 0, 101, result);
|
||||
}
|
||||
|
||||
void game_server::LogOff()
|
||||
{
|
||||
}
|
||||
|
||||
bool game_server::BLoggedOn()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool game_server::BSecure()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
steam_id game_server::GetSteamID()
|
||||
{
|
||||
return SteamUser()->GetSteamID();
|
||||
}
|
||||
|
||||
bool game_server::WasRestartRequested()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void game_server::SetMaxPlayerCount(int cPlayersMax)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetBotPlayerCount(int cBotPlayers)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetServerName(const char* pszServerName)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetMapName(const char* pszMapName)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetPasswordProtected(bool bPasswordProtected)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetSpectatorPort(unsigned short unSpectatorPort)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetSpectatorServerName(const char* pszSpectatorServerName)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::ClearAllKeyValues()
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetKeyValue(const char* pKey, const char* pValue)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetGameTags(const char* pchGameTags)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetGameData(const char* pchGameData)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetRegion(const char* pchRegionName)
|
||||
{
|
||||
}
|
||||
|
||||
int game_server::SendUserConnectAndAuthenticate(unsigned int unIPClient, const void* pvAuthBlob,
|
||||
unsigned int cubAuthBlobSize, steam_id* pSteamIDUser)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
steam_id game_server::CreateUnauthenticatedUserConnection()
|
||||
{
|
||||
return SteamUser()->GetSteamID();
|
||||
}
|
||||
|
||||
void game_server::SendUserDisconnect(steam_id steamIDUser)
|
||||
{
|
||||
}
|
||||
|
||||
bool game_server::BUpdateUserData(steam_id steamIDUser, const char* pchPlayerName, unsigned int uScore)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int game_server::GetAuthSessionTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int game_server::BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, steam_id steamID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void game_server::EndAuthSession(steam_id steamID)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::CancelAuthTicket(int hAuthTicket)
|
||||
{
|
||||
}
|
||||
|
||||
int game_server::UserHasLicenseForApp(steam_id steamID, unsigned int appID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool game_server::RequestUserGroupStatus(steam_id steamIDUser, steam_id steamIDGroup)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void game_server::GetGameplayStats()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long long game_server::GetServerReputation()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int game_server::GetPublicIP()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool game_server::HandleIncomingPacket(const void* pData, int cbData, unsigned int srcIP, unsigned short srcPort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int game_server::GetNextOutgoingPacket(void* pOut, int cbMaxOut, unsigned int* pNetAdr, unsigned short* pPort)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void game_server::EnableHeartbeats(bool bActive)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::SetHeartbeatInterval(int iHeartbeatInterval)
|
||||
{
|
||||
}
|
||||
|
||||
void game_server::ForceHeartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long long game_server::AssociateWithClan(steam_id clanID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long game_server::ComputeNewPlayerCompatibility(steam_id steamID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
57
src/client/steam/interfaces/game_server.hpp
Normal file
57
src/client/steam/interfaces/game_server.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class game_server
|
||||
{
|
||||
public:
|
||||
~game_server() = default;
|
||||
|
||||
virtual bool InitGameServer(unsigned int unGameIP, unsigned short unGamePort, unsigned short usQueryPort,
|
||||
unsigned int unServerFlags, unsigned int nAppID, const char* pchVersion);
|
||||
virtual void SetProduct(const char* pchProductName);
|
||||
virtual void SetGameDescription(const char* pchGameDescription);
|
||||
virtual void SetModDir(const char* pchModDir);
|
||||
virtual void SetDedicatedServer(bool bDedicatedServer);
|
||||
virtual void LogOn(const char* pszAccountName, const char* pszPassword);
|
||||
virtual void LogOnAnonymous();
|
||||
virtual void LogOff();
|
||||
virtual bool BLoggedOn();
|
||||
virtual bool BSecure();
|
||||
virtual steam_id GetSteamID();
|
||||
virtual bool WasRestartRequested();
|
||||
virtual void SetMaxPlayerCount(int cPlayersMax);
|
||||
virtual void SetBotPlayerCount(int cBotPlayers);
|
||||
virtual void SetServerName(const char* pszServerName);
|
||||
virtual void SetMapName(const char* pszMapName);
|
||||
virtual void SetPasswordProtected(bool bPasswordProtected);
|
||||
virtual void SetSpectatorPort(unsigned short unSpectatorPort);
|
||||
virtual void SetSpectatorServerName(const char* pszSpectatorServerName);
|
||||
virtual void ClearAllKeyValues();
|
||||
virtual void SetKeyValue(const char* pKey, const char* pValue);
|
||||
virtual void SetGameTags(const char* pchGameTags);
|
||||
virtual void SetGameData(const char* pchGameData);
|
||||
virtual void SetRegion(const char* pchRegionName);
|
||||
virtual int SendUserConnectAndAuthenticate(unsigned int unIPClient, const void* pvAuthBlob,
|
||||
unsigned int cubAuthBlobSize, steam_id* pSteamIDUser);
|
||||
virtual steam_id CreateUnauthenticatedUserConnection();
|
||||
virtual void SendUserDisconnect(steam_id steamIDUser);
|
||||
virtual bool BUpdateUserData(steam_id steamIDUser, const char* pchPlayerName, unsigned int uScore);
|
||||
virtual int GetAuthSessionTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket);
|
||||
virtual int BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, steam_id steamID);
|
||||
virtual void EndAuthSession(steam_id steamID);
|
||||
virtual void CancelAuthTicket(int hAuthTicket);
|
||||
virtual int UserHasLicenseForApp(steam_id steamID, unsigned int appID);
|
||||
virtual bool RequestUserGroupStatus(steam_id steamIDUser, steam_id steamIDGroup);
|
||||
virtual void GetGameplayStats();
|
||||
virtual unsigned long long GetServerReputation();
|
||||
virtual unsigned int GetPublicIP();
|
||||
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 EnableHeartbeats(bool bActive);
|
||||
virtual void SetHeartbeatInterval(int iHeartbeatInterval);
|
||||
virtual void ForceHeartbeat();
|
||||
virtual unsigned long long AssociateWithClan(steam_id clanID);
|
||||
virtual unsigned long long ComputeNewPlayerCompatibility(steam_id steamID);
|
||||
};
|
||||
}
|
56
src/client/steam/interfaces/game_server_stats.cpp
Normal file
56
src/client/steam/interfaces/game_server_stats.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam {
|
||||
uint64_t game_server_stats::RequestUserStats(steam_id steamIDUser)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool game_server_stats::GetUserStat(steam_id steamIDUser, const char* pchName, int32_t* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::GetUserStat(steam_id steamIDUser, const char* pchName, float* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::GetUserAchievement(steam_id steamIDUser, const char* pchName, bool* pbAchieved)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::SetUserStat(steam_id steamIDUser, const char* pchName, int32_t nData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::SetUserStat(steam_id steamIDUser, const char* pchName, float fData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::UpdateUserAvgRateStat(steam_id steamIDUser, const char* pchName, float flCountThisSession,
|
||||
double dSessionLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::SetUserAchievement(steam_id steamIDUser, const char* pchName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool game_server_stats::ClearUserAchievement(steam_id steamIDUser, const char* pchName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t game_server_stats::StoreUserStats(steam_id steamIDUser)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
21
src/client/steam/interfaces/game_server_stats.hpp
Normal file
21
src/client/steam/interfaces/game_server_stats.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class game_server_stats
|
||||
{
|
||||
public:
|
||||
~game_server_stats() = default;
|
||||
|
||||
virtual uint64_t RequestUserStats(steam_id steamIDUser);
|
||||
virtual bool GetUserStat(steam_id steamIDUser, const char* pchName, int32_t* pData);
|
||||
virtual bool GetUserStat(steam_id steamIDUser, const char* pchName, float* pData);
|
||||
virtual bool GetUserAchievement(steam_id steamIDUser, const char* pchName, bool* pbAchieved);
|
||||
virtual bool SetUserStat(steam_id steamIDUser, const char* pchName, int32_t nData);
|
||||
virtual bool SetUserStat(steam_id steamIDUser, const char* pchName, float fData);
|
||||
virtual bool UpdateUserAvgRateStat(steam_id steamIDUser, const char* pchName, float flCountThisSession, double dSessionLength);
|
||||
virtual bool SetUserAchievement(steam_id steamIDUser, const char* pchName);
|
||||
virtual bool ClearUserAchievement(steam_id steamIDUser, const char* pchName);
|
||||
virtual uint64_t StoreUserStats(steam_id steamIDUser);
|
||||
};
|
||||
}
|
131
src/client/steam/interfaces/http.cpp
Normal file
131
src/client/steam/interfaces/http.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
|
||||
namespace steam
|
||||
{
|
||||
HTTPRequestHandle http::http::CreateHTTPRequest(uint32_t eHTTPRequestMethod, const char* pchAbsoluteURL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestContextValue(HTTPRequestHandle hRequest, uint64_t ulContextValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestNetworkActivityTimeout(HTTPRequestHandle hRequest, uint32_t unTimeoutSeconds)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestHeaderValue(HTTPRequestHandle hRequest, const char* pchHeaderName, const char* pchHeaderValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestGetOrPostParameter(HTTPRequestHandle hRequest, const char* pchParamName, const char* pchParamValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SendHTTPRequest(HTTPRequestHandle hRequest, uint64_t* pCallHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SendHTTPRequestAndStreamResponse(HTTPRequestHandle hRequest, uint64_t* pCallHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::DeferHTTPRequest(HTTPRequestHandle hRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::PrioritizeHTTPRequest(HTTPRequestHandle hRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPResponseHeaderSize(HTTPRequestHandle hRequest, const char* pchHeaderName, uint32_t* unResponseHeaderSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPResponseHeaderValue(HTTPRequestHandle hRequest, const char* pchHeaderName, uint8_t* pHeaderValueBuffer, uint32_t unBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPResponseBodySize(HTTPRequestHandle hRequest, uint32_t* unBodySize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPResponseBodyData(HTTPRequestHandle hRequest, uint8_t* pBodyDataBuffer, uint32_t unBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPStreamingResponseBodyData(HTTPRequestHandle hRequest, uint32_t cOffset, uint8_t* pBodyDataBuffer, uint32_t unBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::ReleaseHTTPRequest(HTTPRequestHandle hRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPDownloadProgressPct(HTTPRequestHandle hRequest, float* pflPercentOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestRawPostBody(HTTPRequestHandle hRequest, const char* pchContentType, uint8_t* pubBody, uint32_t unBodyLen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HTTPCookieContainerHandle http::CreateCookieContainer(bool bAllowResponsesToModify)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool http::ReleaseCookieContainer(HTTPCookieContainerHandle hCookieContainer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetCookie(HTTPCookieContainerHandle hCookieContainer, const char* pchHost, const char* pchUrl, const char* pchCookie)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestCookieContainer(HTTPRequestHandle hRequest, HTTPCookieContainerHandle hCookieContainer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestUserAgentInfo(HTTPRequestHandle hRequest, const char* pchUserAgentInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestRequiresVerifiedCertificate(HTTPRequestHandle hRequest, bool bRequireVerifiedCertificate)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::SetHTTPRequestAbsoluteTimeoutMS(HTTPRequestHandle hRequest, uint32_t unMilliseconds)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http::GetHTTPRequestWasTimedOut(HTTPRequestHandle hRequest, bool* pbWasTimedOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
39
src/client/steam/interfaces/http.hpp
Normal file
39
src/client/steam/interfaces/http.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
using HTTPRequestHandle = uint64_t;
|
||||
using HTTPCookieContainerHandle = uint64_t;
|
||||
|
||||
class http
|
||||
{
|
||||
public:
|
||||
~http() = default;
|
||||
|
||||
virtual HTTPRequestHandle CreateHTTPRequest(uint32_t eHTTPRequestMethod, const char* pchAbsoluteURL);
|
||||
virtual bool SetHTTPRequestContextValue(HTTPRequestHandle hRequest, uint64_t ulContextValue);
|
||||
virtual bool SetHTTPRequestNetworkActivityTimeout(HTTPRequestHandle hRequest, uint32_t unTimeoutSeconds);
|
||||
virtual bool SetHTTPRequestHeaderValue(HTTPRequestHandle hRequest, const char* pchHeaderName, const char* pchHeaderValue);
|
||||
virtual bool SetHTTPRequestGetOrPostParameter(HTTPRequestHandle hRequest, const char* pchParamName, const char* pchParamValue);
|
||||
virtual bool SendHTTPRequest(HTTPRequestHandle hRequest, uint64_t* pCallHandle);
|
||||
virtual bool SendHTTPRequestAndStreamResponse(HTTPRequestHandle hRequest, uint64_t* pCallHandle);
|
||||
virtual bool DeferHTTPRequest(HTTPRequestHandle hRequest);
|
||||
virtual bool PrioritizeHTTPRequest(HTTPRequestHandle hRequest);
|
||||
virtual bool GetHTTPResponseHeaderSize(HTTPRequestHandle hRequest, const char* pchHeaderName, uint32_t* unResponseHeaderSize);
|
||||
virtual bool GetHTTPResponseHeaderValue(HTTPRequestHandle hRequest, const char* pchHeaderName, uint8_t* pHeaderValueBuffer, uint32_t unBufferSize);
|
||||
virtual bool GetHTTPResponseBodySize(HTTPRequestHandle hRequest, uint32_t* unBodySize);
|
||||
virtual bool GetHTTPResponseBodyData(HTTPRequestHandle hRequest, uint8_t* pBodyDataBuffer, uint32_t unBufferSize);
|
||||
virtual bool GetHTTPStreamingResponseBodyData(HTTPRequestHandle hRequest, uint32_t cOffset, uint8_t* pBodyDataBuffer, uint32_t unBufferSize);
|
||||
virtual bool ReleaseHTTPRequest(HTTPRequestHandle hRequest);
|
||||
virtual bool GetHTTPDownloadProgressPct(HTTPRequestHandle hRequest, float* pflPercentOut);
|
||||
virtual bool SetHTTPRequestRawPostBody(HTTPRequestHandle hRequest, const char* pchContentType, uint8_t* pubBody, uint32_t unBodyLen);
|
||||
virtual HTTPCookieContainerHandle CreateCookieContainer(bool bAllowResponsesToModify);
|
||||
virtual bool ReleaseCookieContainer(HTTPCookieContainerHandle hCookieContainer);
|
||||
virtual bool SetCookie(HTTPCookieContainerHandle hCookieContainer, const char* pchHost, const char* pchUrl, const char* pchCookie);
|
||||
virtual bool SetHTTPRequestCookieContainer(HTTPRequestHandle hRequest, HTTPCookieContainerHandle hCookieContainer);
|
||||
virtual bool SetHTTPRequestUserAgentInfo(HTTPRequestHandle hRequest, const char* pchUserAgentInfo);
|
||||
virtual bool SetHTTPRequestRequiresVerifiedCertificate(HTTPRequestHandle hRequest, bool bRequireVerifiedCertificate);
|
||||
virtual bool SetHTTPRequestAbsoluteTimeoutMS(HTTPRequestHandle hRequest, uint32_t unMilliseconds);
|
||||
virtual bool GetHTTPRequestWasTimedOut(HTTPRequestHandle hRequest, bool* pbWasTimedOut);
|
||||
};
|
||||
}
|
230
src/client/steam/interfaces/matchmaking.cpp
Normal file
230
src/client/steam/interfaces/matchmaking.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.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 long long matchmaking::RequestLobbyList()
|
||||
{
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
void matchmaking::AddRequestLobbyListDistanceFilter(int eLobbyDistanceFilter)
|
||||
{
|
||||
}
|
||||
|
||||
void matchmaking::AddRequestLobbyListResultCountFilter(int cMaxResults)
|
||||
{
|
||||
}
|
||||
|
||||
void matchmaking::AddRequestLobbyListCompatibleMembersFilter(steam_id steamID)
|
||||
{
|
||||
}
|
||||
|
||||
steam_id matchmaking::GetLobbyByIndex(int iLobby)
|
||||
{
|
||||
steam_id id;
|
||||
|
||||
id.raw.account_id = SteamUser()->GetSteamID().raw.account_id;
|
||||
id.raw.universe = 1;
|
||||
id.raw.account_type = 8;
|
||||
id.raw.account_instance = 0x40000;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
unsigned long long matchmaking::CreateLobby(int eLobbyType, int cMaxMembers)
|
||||
{
|
||||
const auto result = callbacks::register_call();
|
||||
auto retvals = static_cast<lobby_created*>(calloc(1, sizeof(lobby_created)));
|
||||
//::Utils::Memory::AllocateArray<LobbyCreated>();
|
||||
steam_id id;
|
||||
|
||||
id.raw.account_id = SteamUser()->GetSteamID().raw.account_id;
|
||||
id.raw.universe = 1;
|
||||
id.raw.account_type = 8;
|
||||
id.raw.account_instance = 0x40000;
|
||||
|
||||
retvals->m_e_result = 1;
|
||||
retvals->m_ul_steam_id_lobby = id;
|
||||
|
||||
callbacks::return_call(retvals, sizeof(lobby_created), lobby_created::callback_id, result);
|
||||
|
||||
matchmaking::JoinLobby(id);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long long matchmaking::JoinLobby(steam_id steamIDLobby)
|
||||
{
|
||||
const auto result = callbacks::register_call();
|
||||
auto* retvals = static_cast<lobby_enter*>(calloc(1, sizeof(lobby_enter)));
|
||||
//::Utils::Memory::AllocateArray<LobbyEnter>();
|
||||
retvals->m_b_locked = false;
|
||||
retvals->m_e_chat_room_enter_response = 1;
|
||||
retvals->m_rgf_chat_permissions = 0xFFFFFFFF;
|
||||
retvals->m_ul_steam_id_lobby = steamIDLobby;
|
||||
|
||||
callbacks::return_call(retvals, sizeof(lobby_enter), lobby_enter::callback_id, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void matchmaking::LeaveLobby(steam_id steamIDLobby)
|
||||
{
|
||||
}
|
||||
|
||||
bool matchmaking::InviteUserToLobby(steam_id steamIDLobby, steam_id steamIDInvitee)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int matchmaking::GetNumLobbyMembers(steam_id steamIDLobby)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
steam_id matchmaking::GetLobbyMemberByIndex(steam_id steamIDLobby, int iMember)
|
||||
{
|
||||
return SteamUser()->GetSteamID();
|
||||
}
|
||||
|
||||
const char* matchmaking::GetLobbyData(steam_id steamIDLobby, const char* pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool matchmaking::SetLobbyData(steam_id steamIDLobby, const char* pchKey, const char* pchValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int matchmaking::GetLobbyDataCount(steam_id steamIDLobby)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool matchmaking::GetLobbyDataByIndex(steam_id steamIDLobby, int iLobbyData, char* pchKey, int cchKeyBufferSize,
|
||||
char* pchValue, int cchValueBufferSize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool matchmaking::DeleteLobbyData(steam_id steamIDLobby, const char* pchKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* matchmaking::GetLobbyMemberData(steam_id steamIDLobby, steam_id steamIDUser, const char* pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void matchmaking::SetLobbyMemberData(steam_id steamIDLobby, const char* pchKey, const char* pchValue)
|
||||
{
|
||||
}
|
||||
|
||||
bool matchmaking::SendLobbyChatMsg(steam_id steamIDLobby, const void* pvMsgBody, int cubMsgBody)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int matchmaking::GetLobbyChatEntry(steam_id steamIDLobby, int iChatID, steam_id* pSteamIDUser, void* pvData,
|
||||
int cubData, int* peChatEntryType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool matchmaking::RequestLobbyData(steam_id steamIDLobby)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void matchmaking::SetLobbyGameServer(steam_id steamIDLobby, unsigned int unGameServerIP,
|
||||
unsigned short unGameServerPort, steam_id steamIDGameServer)
|
||||
{
|
||||
}
|
||||
|
||||
bool matchmaking::GetLobbyGameServer(steam_id steamIDLobby, unsigned int* punGameServerIP,
|
||||
unsigned short* punGameServerPort, steam_id* psteamIDGameServer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool matchmaking::SetLobbyMemberLimit(steam_id steamIDLobby, int cMaxMembers)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int matchmaking::GetLobbyMemberLimit(steam_id steamIDLobby)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool matchmaking::SetLobbyType(steam_id steamIDLobby, int eLobbyType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool matchmaking::SetLobbyJoinable(steam_id steamIDLobby, bool bLobbyJoinable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
steam_id matchmaking::GetLobbyOwner(steam_id steamIDLobby)
|
||||
{
|
||||
return SteamUser()->GetSteamID();
|
||||
}
|
||||
|
||||
bool matchmaking::SetLobbyOwner(steam_id steamIDLobby, steam_id steamIDNewOwner)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool matchmaking::SetLinkedLobby(steam_id steamIDLobby, steam_id steamIDLobby2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
79
src/client/steam/interfaces/matchmaking.hpp
Normal file
79
src/client/steam/interfaces/matchmaking.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
struct lobby_created final
|
||||
{
|
||||
enum { callback_id = 513 };
|
||||
|
||||
int m_e_result;
|
||||
int m_pad;
|
||||
steam_id m_ul_steam_id_lobby;
|
||||
};
|
||||
|
||||
struct lobby_enter final
|
||||
{
|
||||
enum { callback_id = 504 };
|
||||
|
||||
steam_id m_ul_steam_id_lobby;
|
||||
int m_rgf_chat_permissions;
|
||||
bool m_b_locked;
|
||||
int m_e_chat_room_enter_response;
|
||||
};
|
||||
|
||||
class matchmaking
|
||||
{
|
||||
public:
|
||||
~matchmaking() = default;
|
||||
|
||||
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 long long 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 void AddRequestLobbyListDistanceFilter(int eLobbyDistanceFilter);
|
||||
virtual void AddRequestLobbyListResultCountFilter(int cMaxResults);
|
||||
virtual void AddRequestLobbyListCompatibleMembersFilter(steam_id steamID);
|
||||
virtual steam_id GetLobbyByIndex(int iLobby);
|
||||
virtual unsigned long long CreateLobby(int eLobbyType, int cMaxMembers);
|
||||
virtual unsigned long long JoinLobby(steam_id steamIDLobby);
|
||||
virtual void LeaveLobby(steam_id steamIDLobby);
|
||||
virtual bool InviteUserToLobby(steam_id steamIDLobby, steam_id steamIDInvitee);
|
||||
virtual int GetNumLobbyMembers(steam_id steamIDLobby);
|
||||
virtual steam_id GetLobbyMemberByIndex(steam_id steamIDLobby, int iMember);
|
||||
virtual const char* GetLobbyData(steam_id steamIDLobby, const char* pchKey);
|
||||
virtual bool SetLobbyData(steam_id steamIDLobby, const char* pchKey, const char* pchValue);
|
||||
virtual int GetLobbyDataCount(steam_id steamIDLobby);
|
||||
virtual bool GetLobbyDataByIndex(steam_id steamIDLobby, int iLobbyData, char* pchKey, int cchKeyBufferSize,
|
||||
char* pchValue, int cchValueBufferSize);
|
||||
virtual bool DeleteLobbyData(steam_id steamIDLobby, const char* pchKey);
|
||||
virtual const char* GetLobbyMemberData(steam_id steamIDLobby, steam_id steamIDUser, const char* pchKey);
|
||||
virtual void SetLobbyMemberData(steam_id steamIDLobby, const char* pchKey, const char* pchValue);
|
||||
virtual bool SendLobbyChatMsg(steam_id steamIDLobby, const void* pvMsgBody, int cubMsgBody);
|
||||
virtual int GetLobbyChatEntry(steam_id steamIDLobby, int iChatID, steam_id* pSteamIDUser, void* pvData,
|
||||
int cubData, int* peChatEntryType);
|
||||
virtual bool RequestLobbyData(steam_id steamIDLobby);
|
||||
virtual void SetLobbyGameServer(steam_id steamIDLobby, unsigned int unGameServerIP,
|
||||
unsigned short unGameServerPort, steam_id steamIDGameServer);
|
||||
virtual bool GetLobbyGameServer(steam_id steamIDLobby, unsigned int* punGameServerIP,
|
||||
unsigned short* punGameServerPort, steam_id* psteamIDGameServer);
|
||||
virtual bool SetLobbyMemberLimit(steam_id steamIDLobby, int cMaxMembers);
|
||||
virtual int GetLobbyMemberLimit(steam_id steamIDLobby);
|
||||
virtual bool SetLobbyType(steam_id steamIDLobby, int eLobbyType);
|
||||
virtual bool SetLobbyJoinable(steam_id steamIDLobby, bool bLobbyJoinable);
|
||||
virtual steam_id GetLobbyOwner(steam_id steamIDLobby);
|
||||
virtual bool SetLobbyOwner(steam_id steamIDLobby, steam_id steamIDNewOwner);
|
||||
virtual bool SetLinkedLobby(steam_id steamIDLobby, steam_id steamIDLobby2);
|
||||
};
|
||||
}
|
90
src/client/steam/interfaces/matchmaking_servers.cpp
Normal file
90
src/client/steam/interfaces/matchmaking_servers.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
void* matchmaking_servers::RequestInternetServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* matchmaking_servers::RequestLANServerList(unsigned int iApp, void* pRequestServersResponse)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* matchmaking_servers::RequestFriendsServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* matchmaking_servers::RequestFavoritesServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* matchmaking_servers::RequestHistoryServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* matchmaking_servers::RequestSpectatorServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void matchmaking_servers::ReleaseRequest(void* hServerListRequest)
|
||||
{
|
||||
}
|
||||
|
||||
void* matchmaking_servers::GetServerDetails(void* hRequest, int iServer)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void matchmaking_servers::CancelQuery(void* hRequest)
|
||||
{
|
||||
}
|
||||
|
||||
void matchmaking_servers::RefreshQuery(void* hRequest)
|
||||
{
|
||||
}
|
||||
|
||||
bool matchmaking_servers::IsRefreshing(void* hRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int matchmaking_servers::GetServerCount(void* hRequest)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void matchmaking_servers::RefreshServer(void* hRequest, int iServer)
|
||||
{
|
||||
}
|
||||
|
||||
int matchmaking_servers::PingServer(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int matchmaking_servers::PlayerDetails(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int matchmaking_servers::ServerRules(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void matchmaking_servers::CancelServerQuery(int hServerQuery)
|
||||
{
|
||||
}
|
||||
}
|
33
src/client/steam/interfaces/matchmaking_servers.hpp
Normal file
33
src/client/steam/interfaces/matchmaking_servers.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class matchmaking_servers
|
||||
{
|
||||
public:
|
||||
~matchmaking_servers() = default;
|
||||
|
||||
virtual void* RequestInternetServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse);
|
||||
virtual void* RequestLANServerList(unsigned int iApp, void* pRequestServersResponse);
|
||||
virtual void* RequestFriendsServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse);
|
||||
virtual void* RequestFavoritesServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse);
|
||||
virtual void* RequestHistoryServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse);
|
||||
virtual void* RequestSpectatorServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
|
||||
void* pRequestServersResponse);
|
||||
virtual void ReleaseRequest(void* hServerListRequest);
|
||||
virtual void* GetServerDetails(void* hRequest, int iServer);
|
||||
virtual void CancelQuery(void* hRequest);
|
||||
virtual void RefreshQuery(void* hRequest);
|
||||
virtual bool IsRefreshing(void* hRequest);
|
||||
virtual int GetServerCount(void* hRequest);
|
||||
virtual void RefreshServer(void* hRequest, int iServer);
|
||||
virtual int PingServer(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse);
|
||||
virtual int PlayerDetails(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse);
|
||||
virtual int ServerRules(unsigned int unIP, unsigned short usPort, void* pRequestServersResponse);
|
||||
virtual void CancelServerQuery(int hServerQuery);
|
||||
};
|
||||
}
|
121
src/client/steam/interfaces/networking.cpp
Normal file
121
src/client/steam/interfaces/networking.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
bool networking::SendP2PPacket(steam_id steamIDRemote, const void* pubData, unsigned int cubData, int eP2PSendType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::IsP2PPacketAvailable(unsigned int* pcubMsgSize, int idk)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::ReadP2PPacket(void* pubDest, unsigned int cubDest, unsigned int* pcubMsgSize,
|
||||
steam_id* psteamIDRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::AcceptP2PSessionWithUser(steam_id steamIDRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::CloseP2PSessionWithUser(steam_id steamIDRemote)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::CloseP2PChannelWithUser(steam_id steamIDRemote, int iVirtualPort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::GetP2PSessionState(steam_id steamIDRemote, void* pConnectionState)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool networking::AllowP2PPacketRelay(bool bAllow)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int networking::CreateListenSocket(int nVirtualP2PPort, unsigned int nIP, unsigned short nPort,
|
||||
bool bAllowUseOfPacketRelay)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int networking::CreateP2PConnectionSocket(steam_id 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, steam_id* 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;
|
||||
}
|
||||
}
|
39
src/client/steam/interfaces/networking.hpp
Normal file
39
src/client/steam/interfaces/networking.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class networking
|
||||
{
|
||||
public:
|
||||
~networking() = default;
|
||||
|
||||
virtual bool SendP2PPacket(steam_id steamIDRemote, const void* pubData, unsigned int cubData, int eP2PSendType);
|
||||
virtual bool IsP2PPacketAvailable(unsigned int* pcubMsgSize, int idk);
|
||||
virtual bool ReadP2PPacket(void* pubDest, unsigned int cubDest, unsigned int* pcubMsgSize,
|
||||
steam_id* psteamIDRemote);
|
||||
virtual bool AcceptP2PSessionWithUser(steam_id steamIDRemote);
|
||||
virtual bool CloseP2PSessionWithUser(steam_id steamIDRemote);
|
||||
virtual bool CloseP2PChannelWithUser(steam_id steamIDRemote, int iVirtualPort);
|
||||
virtual bool GetP2PSessionState(steam_id steamIDRemote, void* pConnectionState);
|
||||
virtual bool AllowP2PPacketRelay(bool bAllow);
|
||||
virtual unsigned int CreateListenSocket(int nVirtualP2PPort, unsigned int nIP, unsigned short nPort,
|
||||
bool bAllowUseOfPacketRelay);
|
||||
virtual unsigned int CreateP2PConnectionSocket(steam_id 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, steam_id* 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);
|
||||
};
|
||||
}
|
283
src/client/steam/interfaces/remote_storage.cpp
Normal file
283
src/client/steam/interfaces/remote_storage.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
bool remote_storage::FileWrite(const char* pchFile, const void* pvData, int cubData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int remote_storage::FileRead(const char* pchFile, void* pvData, int cubDataToRead)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool remote_storage::FileForget(const char* pchFile)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remote_storage::FileDelete(const char* pchFile)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::FileShare(const char* pchFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool remote_storage::SetSyncPlatforms(const char* pchFile, unsigned int eRemoteStoragePlatform)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::FileWriteStreamOpen(const char* pchFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int remote_storage::FileWriteStreamWriteChunk(unsigned long long hStream, const void* pvData, int cubData)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int remote_storage::FileWriteStreamClose(unsigned long long hStream)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int remote_storage::FileWriteStreamCancel(unsigned long long hStream)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool remote_storage::FileExists(const char* pchFile)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remote_storage::FilePersisted(const char* pchFile)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int remote_storage::GetFileSize(const char* pchFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
long long remote_storage::GetFileTimestamp(const char* pchFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned remote_storage::GetSyncPlatforms(const char* pchFile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int remote_storage::GetFileCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* remote_storage::GetFileNameAndSize(int iFile, int* pnFileSizeInBytes)
|
||||
{
|
||||
*pnFileSizeInBytes = 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
bool remote_storage::GetQuota(int* pnTotalBytes, int* puAvailableBytes)
|
||||
{
|
||||
*pnTotalBytes = 0x10000000;
|
||||
*puAvailableBytes = 0x10000000;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::IsCloudEnabledForAccount()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::IsCloudEnabledForApp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void remote_storage::SetCloudEnabledForApp(bool bEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::UGCDownload(unsigned long long hContent, unsigned int uUnk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool remote_storage::GetUGCDownloadProgress(unsigned long long hContent, unsigned int* puDownloadedBytes,
|
||||
unsigned int* puTotalBytes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::GetUGCDetails(unsigned long long hContent, unsigned int* pnAppID, char** ppchName,
|
||||
int* pnFileSizeInBytes, steam_id* pSteamIDOwner)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int remote_storage::UGCRead(unsigned long long hContent, void* pvData, int cubDataToRead, unsigned int uOffset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int remote_storage::GetCachedUGCCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::GetCachedUGCHandle(int iCachedContent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::PublishWorkshopFile(const char* pchFile, const char* pchPreviewFile,
|
||||
unsigned int nConsumerAppId, const char* pchTitle,
|
||||
const char* pchDescription, unsigned int eVisibility,
|
||||
int* pTags, unsigned int eWorkshopFileType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::CreatePublishedFileUpdateRequest(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFileFile(unsigned long long hUpdateRequest, const char* pchFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFilePreviewFile(unsigned long long hUpdateRequest, const char* pchPreviewFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFileTitle(unsigned long long hUpdateRequest, const char* pchTitle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFileDescription(unsigned long long hUpdateRequest, const char* pchDescription)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFileVisibility(unsigned long long hUpdateRequest, unsigned int eVisibility)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFileTags(unsigned long long hUpdateRequest, int* pTags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::CommitPublishedFileUpdate(unsigned long long hUpdateRequest)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::GetPublishedFileDetails(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::DeletePublishedFile(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::EnumerateUserPublishedFiles(unsigned int uStartIndex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::SubscribePublishedFile(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::EnumerateUserSubscribedFiles(unsigned int uStartIndex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::UnsubscribePublishedFile(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool remote_storage::UpdatePublishedFileSetChangeDescription(unsigned long long hUpdateRequest,
|
||||
const char* cszDescription)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::GetPublishedItemVoteDetails(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::UpdateUserPublishedItemVote(unsigned long long unPublishedFileId, bool bVoteUp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::GetUserPublishedItemVoteDetails(unsigned long long unPublishedFileId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::EnumerateUserSharedWorkshopFiles(unsigned int nAppId, steam_id creatorSteamID,
|
||||
unsigned int uStartIndex, int* pRequiredTags,
|
||||
int* pExcludedTags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::PublishVideo(unsigned int eVideoProvider, const char* cszVideoAccountName,
|
||||
const char* cszVideoIdentifier, const char* cszFileName,
|
||||
unsigned int nConsumerAppId, const char* cszTitle,
|
||||
const char* cszDescription, unsigned int eVisibility, int* pTags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::SetUserPublishedFileAction(unsigned long long unPublishedFileId,
|
||||
unsigned int eAction)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::EnumeratePublishedFilesByUserAction(
|
||||
unsigned int eAction, unsigned int uStartIndex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::EnumeratePublishedWorkshopFiles(unsigned int eType, unsigned int uStartIndex,
|
||||
unsigned int cDays, unsigned int cCount,
|
||||
int* pTags, int* pUserTags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long remote_storage::UGCDownloadToLocation(unsigned long long hContent, const char* cszLocation,
|
||||
unsigned int uUnk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
78
src/client/steam/interfaces/remote_storage.hpp
Normal file
78
src/client/steam/interfaces/remote_storage.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class remote_storage
|
||||
{
|
||||
public:
|
||||
~remote_storage() = default;
|
||||
|
||||
virtual bool FileWrite(const char* pchFile, const void* pvData, int cubData);
|
||||
virtual int FileRead(const char* pchFile, void* pvData, int cubDataToRead);
|
||||
virtual bool FileForget(const char* pchFile);
|
||||
virtual bool FileDelete(const char* pchFile);
|
||||
virtual unsigned long long FileShare(const char* pchFile);
|
||||
virtual bool SetSyncPlatforms(const char* pchFile, unsigned int eRemoteStoragePlatform);
|
||||
virtual unsigned long long FileWriteStreamOpen(const char* pchFile);
|
||||
virtual int FileWriteStreamWriteChunk(unsigned long long hStream, const void* pvData, int cubData);
|
||||
virtual int FileWriteStreamClose(unsigned long long hStream);
|
||||
virtual int FileWriteStreamCancel(unsigned long long hStream);
|
||||
virtual bool FileExists(const char* pchFile);
|
||||
virtual bool FilePersisted(const char* pchFile);
|
||||
virtual int GetFileSize(const char* pchFile);
|
||||
virtual long long GetFileTimestamp(const char* pchFile);
|
||||
virtual unsigned int GetSyncPlatforms(const char* pchFile);
|
||||
virtual int GetFileCount();
|
||||
virtual const char* GetFileNameAndSize(int iFile, int* pnFileSizeInBytes);
|
||||
virtual bool GetQuota(int* pnTotalBytes, int* puAvailableBytes);
|
||||
virtual bool IsCloudEnabledForAccount();
|
||||
virtual bool IsCloudEnabledForApp();
|
||||
virtual void SetCloudEnabledForApp(bool bEnabled);
|
||||
virtual unsigned long long UGCDownload(unsigned long long hContent, unsigned int uUnk);
|
||||
virtual bool GetUGCDownloadProgress(unsigned long long hContent, unsigned int* puDownloadedBytes,
|
||||
unsigned int* puTotalBytes);
|
||||
virtual bool GetUGCDetails(unsigned long long hContent, unsigned int* pnAppID, char** ppchName,
|
||||
int* pnFileSizeInBytes, steam_id* pSteamIDOwner);
|
||||
virtual int UGCRead(unsigned long long hContent, void* pvData, int cubDataToRead, unsigned int uOffset);
|
||||
virtual int GetCachedUGCCount();
|
||||
virtual unsigned long long GetCachedUGCHandle(int iCachedContent);
|
||||
virtual unsigned long long PublishWorkshopFile(const char* pchFile, const char* pchPreviewFile,
|
||||
unsigned int nConsumerAppId, const char* pchTitle,
|
||||
const char* pchDescription, unsigned int eVisibility, int* pTags,
|
||||
unsigned int eWorkshopFileType);
|
||||
virtual unsigned long long CreatePublishedFileUpdateRequest(unsigned long long unPublishedFileId);
|
||||
virtual bool UpdatePublishedFileFile(unsigned long long hUpdateRequest, const char* pchFile);
|
||||
virtual bool UpdatePublishedFilePreviewFile(unsigned long long hUpdateRequest, const char* pchPreviewFile);
|
||||
virtual bool UpdatePublishedFileTitle(unsigned long long hUpdateRequest, const char* pchTitle);
|
||||
virtual bool UpdatePublishedFileDescription(unsigned long long hUpdateRequest, const char* pchDescription);
|
||||
virtual bool UpdatePublishedFileVisibility(unsigned long long hUpdateRequest, unsigned int eVisibility);
|
||||
virtual bool UpdatePublishedFileTags(unsigned long long hUpdateRequest, int* pTags);
|
||||
virtual unsigned long long CommitPublishedFileUpdate(unsigned long long hUpdateRequest);
|
||||
virtual unsigned long long GetPublishedFileDetails(unsigned long long unPublishedFileId);
|
||||
virtual unsigned long long DeletePublishedFile(unsigned long long unPublishedFileId);
|
||||
virtual unsigned long long EnumerateUserPublishedFiles(unsigned int uStartIndex);
|
||||
virtual unsigned long long SubscribePublishedFile(unsigned long long unPublishedFileId);
|
||||
virtual unsigned long long EnumerateUserSubscribedFiles(unsigned int uStartIndex);
|
||||
virtual unsigned long long UnsubscribePublishedFile(unsigned long long unPublishedFileId);
|
||||
virtual bool UpdatePublishedFileSetChangeDescription(unsigned long long hUpdateRequest,
|
||||
const char* cszDescription);
|
||||
virtual unsigned long long GetPublishedItemVoteDetails(unsigned long long unPublishedFileId);
|
||||
virtual unsigned long long UpdateUserPublishedItemVote(unsigned long long unPublishedFileId, bool bVoteUp);
|
||||
virtual unsigned long long GetUserPublishedItemVoteDetails(unsigned long long unPublishedFileId);
|
||||
virtual unsigned long long EnumerateUserSharedWorkshopFiles(unsigned int nAppId, steam_id creatorSteamID,
|
||||
unsigned int uStartIndex, int* pRequiredTags,
|
||||
int* pExcludedTags);
|
||||
virtual unsigned long long PublishVideo(unsigned int eVideoProvider, const char* cszVideoAccountName,
|
||||
const char* cszVideoIdentifier, const char* cszFileName,
|
||||
unsigned int nConsumerAppId, const char* cszTitle,
|
||||
const char* cszDescription, unsigned int eVisibility, int* pTags);
|
||||
virtual unsigned long long SetUserPublishedFileAction(unsigned long long unPublishedFileId,
|
||||
unsigned int eAction);
|
||||
virtual unsigned long long EnumeratePublishedFilesByUserAction(unsigned int eAction, unsigned int uStartIndex);
|
||||
virtual unsigned long long EnumeratePublishedWorkshopFiles(unsigned int eType, unsigned int uStartIndex,
|
||||
unsigned int cDays, unsigned int cCount, int* pTags,
|
||||
int* pUserTags);
|
||||
virtual unsigned long long UGCDownloadToLocation(unsigned long long hContent, const char* cszLocation,
|
||||
unsigned int uUnk);
|
||||
};
|
||||
}
|
40
src/client/steam/interfaces/screenshots.cpp
Normal file
40
src/client/steam/interfaces/screenshots.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
uint64_t screenshots::WriteScreenshot(void* pubRGB, uint32_t cubRGB, int nWidth, int nHeight)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t screenshots::AddScreenshotToLibrary(const char* pchFilename, const char* pchThumbnailFilename, int nWidth, int nHeight)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void screenshots::TriggerScreenshot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void screenshots::HookScreenshots(bool bHook)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool screenshots::SetLocation(uint64_t hScreenshot, const char* pchLocation)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool screenshots::TagUser(uint64_t hScreenshot, steam_id steamID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool screenshots::TagPublishedFile(uint64_t hScreenshot, uint64_t unPublishedFileID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
18
src/client/steam/interfaces/screenshots.hpp
Normal file
18
src/client/steam/interfaces/screenshots.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class screenshots
|
||||
{
|
||||
public:
|
||||
~screenshots() = default;
|
||||
|
||||
virtual uint64_t WriteScreenshot(void* pubRGB, uint32_t cubRGB, int nWidth, int nHeight);
|
||||
virtual uint64_t AddScreenshotToLibrary(const char* pchFilename, const char* pchThumbnailFilename, int nWidth, int nHeight);
|
||||
virtual void TriggerScreenshot();
|
||||
virtual void HookScreenshots(bool bHook);
|
||||
virtual bool SetLocation(uint64_t hScreenshot, const char* pchLocation);
|
||||
virtual bool TagUser(uint64_t hScreenshot, steam_id steamID);
|
||||
virtual bool TagPublishedFile(uint64_t hScreenshot, uint64_t unPublishedFileID);
|
||||
};
|
||||
}
|
30
src/client/steam/interfaces/unified_messages.cpp
Normal file
30
src/client/steam/interfaces/unified_messages.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
ClientUnifiedMessageHandle unified_messages::SendMethod(const char* pchServiceMethod, const void* pRequestBuffer, uint32_t unRequestBufferSize, uint64_t unContext)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool unified_messages::GetMethodResponseInfo(ClientUnifiedMessageHandle hHandle, uint32_t* punResponseSize, uint32_t* peResult)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool unified_messages::GetMethodResponseData(ClientUnifiedMessageHandle hHandle, void* pResponseBuffer, uint32_t unResponseBufferSize, bool bAutoRelease)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool unified_messages::ReleaseMethod(ClientUnifiedMessageHandle hHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool unified_messages::SendNotification(const char* pchServiceNotification, const void* pNotificationBuffer, uint32_t unNotificationBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
18
src/client/steam/interfaces/unified_messages.hpp
Normal file
18
src/client/steam/interfaces/unified_messages.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
using ClientUnifiedMessageHandle = uint64_t;
|
||||
|
||||
class unified_messages
|
||||
{
|
||||
public:
|
||||
~unified_messages() = default;
|
||||
|
||||
virtual ClientUnifiedMessageHandle SendMethod(const char* pchServiceMethod, const void* pRequestBuffer, uint32_t unRequestBufferSize, uint64_t unContext);
|
||||
virtual bool GetMethodResponseInfo(ClientUnifiedMessageHandle hHandle, uint32_t* punResponseSize, uint32_t* peResult);
|
||||
virtual bool GetMethodResponseData(ClientUnifiedMessageHandle hHandle, void* pResponseBuffer, uint32_t unResponseBufferSize, bool bAutoRelease);
|
||||
virtual bool ReleaseMethod(ClientUnifiedMessageHandle hHandle);
|
||||
virtual bool SendNotification(const char* pchServiceNotification, const void* pNotificationBuffer, uint32_t unNotificationBufferSize);
|
||||
};
|
||||
}
|
194
src/client/steam/interfaces/user.cpp
Normal file
194
src/client/steam/interfaces/user.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
|
||||
namespace steam
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::string auth_ticket;
|
||||
|
||||
steam_id generate_steam_id()
|
||||
{
|
||||
steam_id id{};
|
||||
id.bits = 76561197960287930;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
int user::GetHSteamUser()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool user::LoggedOn()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
steam_id user::GetSteamID()
|
||||
{
|
||||
static auto id = generate_steam_id();
|
||||
return id;
|
||||
}
|
||||
|
||||
int user::InitiateGameConnection(void* pAuthBlob, int cbMaxAuthBlob, steam_id steamIDGameServer,
|
||||
unsigned int unIPServer, unsigned short usPortServer, bool bSecure)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void user::TerminateGameConnection(unsigned int unIPServer, unsigned short usPortServer)
|
||||
{
|
||||
}
|
||||
|
||||
void user::TrackAppUsageEvent(steam_id gameID, int eAppUsageEvent, const char* pchExtraInfo)
|
||||
{
|
||||
}
|
||||
|
||||
bool user::GetUserDataFolder(char* pchBuffer, int cubBuffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void user::StartVoiceRecording()
|
||||
{
|
||||
}
|
||||
|
||||
void user::StopVoiceRecording()
|
||||
{
|
||||
}
|
||||
|
||||
int user::GetAvailableVoice(unsigned int* pcbCompressed, unsigned int* pcbUncompressed,
|
||||
unsigned int nUncompressedVoiceDesiredSampleRate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user::GetVoice(bool bWantCompressed, void* pDestBuffer, unsigned int cbDestBufferSize,
|
||||
unsigned int* nBytesWritten, bool bWantUncompressed, void* pUncompressedDestBuffer,
|
||||
unsigned int cbUncompressedDestBufferSize, unsigned int* nUncompressBytesWritten,
|
||||
unsigned int nUncompressedVoiceDesiredSampleRate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user::DecompressVoice(void* pCompressed, unsigned int cbCompressed, void* pDestBuffer,
|
||||
unsigned int cbDestBufferSize, unsigned int* nBytesWritten)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int user::GetVoiceOptimalSampleRate()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int user::GetAuthSessionTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
||||
{
|
||||
static uint32_t ticket = 0;
|
||||
*pcbTicket = 1;
|
||||
|
||||
const auto result = callbacks::register_call();
|
||||
auto* response = static_cast<get_auth_session_ticket_response*>(calloc(
|
||||
1, sizeof(get_auth_session_ticket_response)));
|
||||
response->m_h_auth_ticket = ++ticket;
|
||||
response->m_e_result = 1; // k_EResultOK;
|
||||
|
||||
callbacks::return_call(response, sizeof(get_auth_session_ticket_response),
|
||||
get_auth_session_ticket_response::callback_id, result);
|
||||
return response->m_h_auth_ticket;
|
||||
}
|
||||
|
||||
int user::BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, steam_id steamID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void user::EndAuthSession(steam_id steamID)
|
||||
{
|
||||
}
|
||||
|
||||
void user::CancelAuthTicket(unsigned int hAuthTicket)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int user::UserHasLicenseForApp(steam_id steamID, unsigned int appID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool user::BIsBehindNAT()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void user::AdvertiseGame(steam_id steamIDGameServer, unsigned int unIPServer, unsigned short usPortServer)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned long long user::RequestEncryptedAppTicket(void* pUserData, int cbUserData)
|
||||
{
|
||||
const auto id = this->GetSteamID();
|
||||
|
||||
auth_ticket = "S1";
|
||||
auth_ticket.resize(32);
|
||||
auth_ticket.append(static_cast<char*>(pUserData), 24); // key
|
||||
auth_ticket.append(reinterpret_cast<const char*>(&id.bits), sizeof(id.bits)); // user id
|
||||
auth_ticket.append(&static_cast<char*>(pUserData)[24], 64); // user name
|
||||
|
||||
// Create the call response
|
||||
const auto result = callbacks::register_call();
|
||||
const auto retvals = static_cast<encrypted_app_ticket_response*>(calloc(1, sizeof(encrypted_app_ticket_response)));
|
||||
//::Utils::Memory::AllocateArray<EncryptedAppTicketResponse>();
|
||||
retvals->m_e_result = 1;
|
||||
|
||||
// Return the call response
|
||||
callbacks::return_call(retvals, sizeof(encrypted_app_ticket_response),
|
||||
encrypted_app_ticket_response::callback_id, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool user::GetEncryptedAppTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket)
|
||||
{
|
||||
if (cbMaxTicket < 0 || auth_ticket.empty()) return false;
|
||||
|
||||
const auto size = std::min(size_t(cbMaxTicket), auth_ticket.size());
|
||||
std::memcpy(pTicket, auth_ticket.data(), size);
|
||||
*pcbTicket = static_cast<unsigned>(size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int user::GetGameBadgeLevel(int nSeries, bool bFoil)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int user::GetPlayerSteamLevel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint64_t user::RequestStoreAuthURL(const char* pchRedirectURL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
bool user::BIsPhoneVerified()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user::BIsTwoFactorEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user::BIsPhoneIdentifying()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool user::BIsPhoneRequiringVerification()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
63
src/client/steam/interfaces/user.hpp
Normal file
63
src/client/steam/interfaces/user.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
struct encrypted_app_ticket_response final
|
||||
{
|
||||
enum { callback_id = 154 };
|
||||
|
||||
int m_e_result;
|
||||
};
|
||||
|
||||
struct get_auth_session_ticket_response
|
||||
{
|
||||
enum { callback_id = 163 };
|
||||
|
||||
unsigned int m_h_auth_ticket;
|
||||
int m_e_result;
|
||||
};
|
||||
|
||||
class user
|
||||
{
|
||||
public:
|
||||
~user() = default;
|
||||
|
||||
virtual int GetHSteamUser();
|
||||
virtual bool LoggedOn();
|
||||
virtual steam_id GetSteamID();
|
||||
|
||||
virtual int InitiateGameConnection(void* pAuthBlob, int cbMaxAuthBlob, steam_id steamIDGameServer,
|
||||
unsigned int unIPServer, unsigned short usPortServer, bool bSecure);
|
||||
virtual void TerminateGameConnection(unsigned int unIPServer, unsigned short usPortServer);
|
||||
virtual void TrackAppUsageEvent(steam_id gameID, int eAppUsageEvent, const char* pchExtraInfo = "");
|
||||
virtual bool GetUserDataFolder(char* pchBuffer, int cubBuffer);
|
||||
virtual void StartVoiceRecording();
|
||||
virtual void StopVoiceRecording();
|
||||
virtual int GetAvailableVoice(unsigned int* pcbCompressed, unsigned int* pcbUncompressed,
|
||||
unsigned int nUncompressedVoiceDesiredSampleRate);
|
||||
virtual int GetVoice(bool bWantCompressed, void* pDestBuffer, unsigned int cbDestBufferSize,
|
||||
unsigned int* nBytesWritten, bool bWantUncompressed, void* pUncompressedDestBuffer,
|
||||
unsigned int cbUncompressedDestBufferSize, unsigned int* nUncompressBytesWritten,
|
||||
unsigned int nUncompressedVoiceDesiredSampleRate);
|
||||
virtual int DecompressVoice(void* pCompressed, unsigned int cbCompressed, void* pDestBuffer,
|
||||
unsigned int cbDestBufferSize, unsigned int* nBytesWritten);
|
||||
virtual unsigned int GetVoiceOptimalSampleRate();
|
||||
virtual unsigned int GetAuthSessionTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket);
|
||||
virtual int BeginAuthSession(const void* pAuthTicket, int cbAuthTicket, steam_id steamID);
|
||||
virtual void EndAuthSession(steam_id steamID);
|
||||
virtual void CancelAuthTicket(unsigned int hAuthTicket);
|
||||
virtual unsigned int UserHasLicenseForApp(steam_id steamID, unsigned int appID);
|
||||
virtual bool BIsBehindNAT();
|
||||
virtual void AdvertiseGame(steam_id steamIDGameServer, unsigned int unIPServer, unsigned short usPortServer);
|
||||
virtual unsigned long long RequestEncryptedAppTicket(void* pUserData, int cbUserData);
|
||||
virtual bool GetEncryptedAppTicket(void* pTicket, int cbMaxTicket, unsigned int* pcbTicket);
|
||||
|
||||
virtual int GetGameBadgeLevel(int nSeries, bool bFoil);
|
||||
virtual int GetPlayerSteamLevel();
|
||||
virtual uint64_t RequestStoreAuthURL(const char* pchRedirectURL);
|
||||
virtual bool BIsPhoneVerified();
|
||||
virtual bool BIsTwoFactorEnabled();
|
||||
virtual bool BIsPhoneIdentifying();
|
||||
virtual bool BIsPhoneRequiringVerification();
|
||||
};
|
||||
}
|
231
src/client/steam/interfaces/user_stats.cpp
Normal file
231
src/client/steam/interfaces/user_stats.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
bool user_stats::RequestCurrentStats()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::GetStat(const char* pchName, int* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::GetStat(const char* pchName, float* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::SetStat(const char* pchName, int nData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::SetStat(const char* pchName, float fData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::UpdateAvgRateStat(const char* pchName, float flCountThisSession, double dSessionLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::GetAchievement(const char* pchName, bool* pbAchieved)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::SetAchievement(const char* pchName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::ClearAchievement(const char* pchName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::GetAchievementAndUnlockTime(const char* pchName, bool* pbAchieved, unsigned int* punUnlockTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::StoreStats()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int user_stats::GetAchievementIcon(const char* pchName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* user_stats::GetAchievementDisplayAttribute(const char* pchName, const char* pchKey)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
bool user_stats::IndicateAchievementProgress(const char* pchName, unsigned int nCurProgress,
|
||||
unsigned int nMaxProgress)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int user_stats::GetNumAchievements()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* user_stats::GetAchievementName(unsigned int iAchievement)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned long long user_stats::RequestUserStats(steam_id steamIDUser)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool user_stats::GetUserStat(steam_id steamIDUser, const char* pchName, int* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::GetUserStat(steam_id steamIDUser, const char* pchName, float* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::GetUserAchievement(steam_id steamIDUser, const char* pchName, bool* pbAchieved)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::GetUserAchievementAndUnlockTime(steam_id steamIDUser, const char* pchName, bool* pbAchieved,
|
||||
unsigned int* punUnlockTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool user_stats::ResetAllStats(bool bAchievementsToo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::FindOrCreateLeaderboard(const char* pchLeaderboardName, int eLeaderboardSortMethod,
|
||||
int eLeaderboardDisplayType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::FindLeaderboard(const char* pchLeaderboardName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* user_stats::GetLeaderboardName(unsigned long long hSteamLeaderboard)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int user_stats::GetLeaderboardEntryCount(unsigned long long hSteamLeaderboard)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user_stats::GetLeaderboardSortMethod(unsigned long long hSteamLeaderboard)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user_stats::GetLeaderboardDisplayType(unsigned long long hSteamLeaderboard)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::DownloadLeaderboardEntries(unsigned long long hSteamLeaderboard,
|
||||
int eLeaderboardDataRequest, int nRangeStart,
|
||||
int nRangeEnd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::DownloadLeaderboardEntriesForUsers(unsigned long long hSteamLeaderboard,
|
||||
steam_id* prgUsers, int cUsers)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool user_stats::GetDownloadedLeaderboardEntry(unsigned long long hSteamLeaderboardEntries, int index,
|
||||
int* pLeaderboardEntry, int* pDetails, int cDetailsMax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::UploadLeaderboardScore(unsigned long long hSteamLeaderboard,
|
||||
int eLeaderboardUploadScoreMethod, int nScore,
|
||||
const int* pScoreDetails, int cScoreDetailsCount)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::AttachLeaderboardUGC(unsigned long long hSteamLeaderboard, unsigned long long hUGC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::GetNumberOfCurrentPlayers()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::RequestGlobalAchievementPercentages()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user_stats::GetMostAchievedAchievementInfo(char* pchName, unsigned int unNameBufLen, float* pflPercent,
|
||||
bool* pbAchieved)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user_stats::GetNextMostAchievedAchievementInfo(int iIteratorPrevious, char* pchName, unsigned int unNameBufLen,
|
||||
float* pflPercent, bool* pbAchieved)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool user_stats::GetAchievementAchievedPercent(const char* pchName, float* pflPercent)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long long user_stats::RequestGlobalStats(int nHistoryDays)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool user_stats::GetGlobalStat(const char* pchStatName, long long* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool user_stats::GetGlobalStat(const char* pchStatName, double* pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int user_stats::GetGlobalStatHistory(const char* pchStatName, long long* pData, unsigned int cubData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int user_stats::GetGlobalStatHistory(const char* pchStatName, double* pData, unsigned int cubData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
65
src/client/steam/interfaces/user_stats.hpp
Normal file
65
src/client/steam/interfaces/user_stats.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class user_stats
|
||||
{
|
||||
public:
|
||||
~user_stats() = default;
|
||||
|
||||
virtual bool RequestCurrentStats();
|
||||
virtual bool GetStat(const char* pchName, int* pData);
|
||||
virtual bool GetStat(const char* pchName, float* pData);
|
||||
virtual bool SetStat(const char* pchName, int nData);
|
||||
virtual bool SetStat(const char* pchName, float fData);
|
||||
virtual bool UpdateAvgRateStat(const char* pchName, float flCountThisSession, double dSessionLength);
|
||||
virtual bool GetAchievement(const char* pchName, bool* pbAchieved);
|
||||
virtual bool SetAchievement(const char* pchName);
|
||||
virtual bool ClearAchievement(const char* pchName);
|
||||
virtual bool GetAchievementAndUnlockTime(const char* pchName, bool* pbAchieved, unsigned int* punUnlockTime);
|
||||
virtual bool StoreStats();
|
||||
virtual int GetAchievementIcon(const char* pchName);
|
||||
virtual const char* GetAchievementDisplayAttribute(const char* pchName, const char* pchKey);
|
||||
virtual bool IndicateAchievementProgress(const char* pchName, unsigned int nCurProgress,
|
||||
unsigned int nMaxProgress);
|
||||
virtual unsigned int GetNumAchievements();
|
||||
virtual const char* GetAchievementName(unsigned int iAchievement);
|
||||
virtual unsigned long long RequestUserStats(steam_id steamIDUser);
|
||||
virtual bool GetUserStat(steam_id steamIDUser, const char* pchName, int* pData);
|
||||
virtual bool GetUserStat(steam_id steamIDUser, const char* pchName, float* pData);
|
||||
virtual bool GetUserAchievement(steam_id steamIDUser, const char* pchName, bool* pbAchieved);
|
||||
virtual bool GetUserAchievementAndUnlockTime(steam_id steamIDUser, const char* pchName, bool* pbAchieved,
|
||||
unsigned int* punUnlockTime);
|
||||
virtual bool ResetAllStats(bool bAchievementsToo);
|
||||
virtual unsigned long long FindOrCreateLeaderboard(const char* pchLeaderboardName, int eLeaderboardSortMethod,
|
||||
int eLeaderboardDisplayType);
|
||||
virtual unsigned long long FindLeaderboard(const char* pchLeaderboardName);
|
||||
virtual const char* GetLeaderboardName(unsigned long long hSteamLeaderboard);
|
||||
virtual int GetLeaderboardEntryCount(unsigned long long hSteamLeaderboard);
|
||||
virtual int GetLeaderboardSortMethod(unsigned long long hSteamLeaderboard);
|
||||
virtual int GetLeaderboardDisplayType(unsigned long long hSteamLeaderboard);
|
||||
virtual unsigned long long DownloadLeaderboardEntries(unsigned long long hSteamLeaderboard,
|
||||
int eLeaderboardDataRequest, int nRangeStart,
|
||||
int nRangeEnd);
|
||||
virtual unsigned long long DownloadLeaderboardEntriesForUsers(unsigned long long hSteamLeaderboard,
|
||||
steam_id* prgUsers, int cUsers);
|
||||
virtual bool GetDownloadedLeaderboardEntry(unsigned long long hSteamLeaderboardEntries, int index,
|
||||
int* pLeaderboardEntry, int* pDetails, int cDetailsMax);
|
||||
virtual unsigned long long UploadLeaderboardScore(unsigned long long hSteamLeaderboard,
|
||||
int eLeaderboardUploadScoreMethod, int nScore,
|
||||
const int* pScoreDetails, int cScoreDetailsCount);
|
||||
virtual unsigned long long AttachLeaderboardUGC(unsigned long long hSteamLeaderboard, unsigned long long hUGC);
|
||||
virtual unsigned long long GetNumberOfCurrentPlayers();
|
||||
virtual unsigned long long RequestGlobalAchievementPercentages();
|
||||
virtual int GetMostAchievedAchievementInfo(char* pchName, unsigned int unNameBufLen, float* pflPercent,
|
||||
bool* pbAchieved);
|
||||
virtual int GetNextMostAchievedAchievementInfo(int iIteratorPrevious, char* pchName, unsigned int unNameBufLen,
|
||||
float* pflPercent, bool* pbAchieved);
|
||||
virtual bool GetAchievementAchievedPercent(const char* pchName, float* pflPercent);
|
||||
virtual unsigned long long RequestGlobalStats(int nHistoryDays);
|
||||
virtual bool GetGlobalStat(const char* pchStatName, long long* pData);
|
||||
virtual bool GetGlobalStat(const char* pchStatName, double* pData);
|
||||
virtual int GetGlobalStatHistory(const char* pchStatName, long long* pData, unsigned int cubData);
|
||||
virtual int GetGlobalStatHistory(const char* pchStatName, double* pData, unsigned int cubData);
|
||||
};
|
||||
}
|
146
src/client/steam/interfaces/utils.cpp
Normal file
146
src/client/steam/interfaces/utils.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include <std_include.hpp>
|
||||
#include "../steam.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
unsigned int utils::GetSecondsSinceAppActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int utils::GetSecondsSinceComputerActive()
|
||||
{
|
||||
return (uint32_t)GetTickCount64() / 1000;
|
||||
}
|
||||
|
||||
int utils::GetConnectedUniverse()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int utils::GetServerRealTime()
|
||||
{
|
||||
return (uint32_t)time(NULL);
|
||||
}
|
||||
|
||||
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 209660;
|
||||
}
|
||||
|
||||
void utils::SetOverlayNotificationPosition(int eNotificationPosition)
|
||||
{
|
||||
//const auto& overlay = steam_proxy::get_overlay_module();
|
||||
//if (overlay)
|
||||
//{
|
||||
// overlay.invoke<void>("SetNotificationPosition", eNotificationPosition);
|
||||
//}
|
||||
}
|
||||
|
||||
bool utils::IsAPICallCompleted(unsigned long long hSteamAPICall, bool* pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int utils::GetAPICallFailureReason(unsigned long long hSteamAPICall)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool utils::GetAPICallResult(unsigned long long 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;
|
||||
}
|
||||
|
||||
unsigned long long utils::CheckFileSignature(const char* szFileName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool utils::ShowGamepadTextInput(int eInputMode, int eInputLineMode, const char* szText, unsigned int uMaxLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int utils::GetEnteredGamepadTextLength()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool utils::GetEnteredGamepadTextInput(char* pchValue, unsigned int cchValueMax)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* utils::GetSteamUILanguage()
|
||||
{
|
||||
return "english";
|
||||
}
|
||||
bool utils::IsSteamRunningInVR()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void utils::SetOverlayNotificationInset(int nHorizontalInset, int nVerticalInset)
|
||||
{
|
||||
|
||||
}
|
||||
bool utils::IsSteamInBigPictureMode()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void utils::StartVRDashboard()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
43
src/client/steam/interfaces/utils.hpp
Normal file
43
src/client/steam/interfaces/utils.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class utils
|
||||
{
|
||||
public:
|
||||
~utils() = default;
|
||||
|
||||
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 long long hSteamAPICall, bool* pbFailed);
|
||||
virtual int GetAPICallFailureReason(unsigned long long hSteamAPICall);
|
||||
virtual bool GetAPICallResult(unsigned long long 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();
|
||||
virtual unsigned long long CheckFileSignature(const char* szFileName);
|
||||
|
||||
virtual bool ShowGamepadTextInput(int eInputMode, int eInputLineMode, const char* szText,
|
||||
unsigned int uMaxLength);
|
||||
virtual unsigned int GetEnteredGamepadTextLength();
|
||||
virtual bool GetEnteredGamepadTextInput(char* pchValue, unsigned int cchValueMax);
|
||||
|
||||
virtual const char* GetSteamUILanguage();
|
||||
virtual bool IsSteamRunningInVR();
|
||||
virtual void SetOverlayNotificationInset(int nHorizontalInset, int nVerticalInset);
|
||||
virtual bool IsSteamInBigPictureMode();
|
||||
virtual void StartVRDashboard();
|
||||
};
|
||||
}
|
310
src/client/steam/steam.cpp
Normal file
310
src/client/steam/steam.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
#include <std_include.hpp>
|
||||
#include "steam.hpp"
|
||||
|
||||
#include <utils/nt.hpp>
|
||||
|
||||
namespace steam
|
||||
{
|
||||
uint64_t callbacks::call_id_ = 0;
|
||||
std::recursive_mutex callbacks::mutex_;
|
||||
std::map<uint64_t, bool> callbacks::calls_;
|
||||
std::map<uint64_t, callbacks::base*> callbacks::result_handlers_;
|
||||
std::vector<callbacks::result> callbacks::results_;
|
||||
std::vector<callbacks::base*> callbacks::callback_list_;
|
||||
|
||||
uint64_t callbacks::register_call()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
calls_[++call_id_] = false;
|
||||
return call_id_;
|
||||
}
|
||||
|
||||
void callbacks::register_callback(base* handler, const int callback)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
handler->set_i_callback(callback);
|
||||
callback_list_.push_back(handler);
|
||||
}
|
||||
|
||||
void callbacks::unregister_callback(base* handler)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
for (auto i = callback_list_.begin(); i != callback_list_.end();)
|
||||
{
|
||||
if (*i == handler)
|
||||
{
|
||||
i = callback_list_.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callbacks::register_call_result(const uint64_t call, base* result)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
result_handlers_[call] = result;
|
||||
}
|
||||
|
||||
void callbacks::unregister_call_result(const uint64_t call, base* /*result*/)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
const auto i = result_handlers_.find(call);
|
||||
if (i != result_handlers_.end())
|
||||
{
|
||||
result_handlers_.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void callbacks::return_call(void* data, const int size, const int type, const uint64_t call)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
|
||||
result result{};
|
||||
result.call = call;
|
||||
result.data = data;
|
||||
result.size = size;
|
||||
result.type = type;
|
||||
|
||||
calls_[call] = true;
|
||||
|
||||
results_.emplace_back(result);
|
||||
}
|
||||
|
||||
void callbacks::run_callbacks()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(mutex_);
|
||||
|
||||
for (const auto& result : results_)
|
||||
{
|
||||
if (result_handlers_.find(result.call) != result_handlers_.end())
|
||||
{
|
||||
result_handlers_[result.call]->run(result.data, false, result.call);
|
||||
}
|
||||
|
||||
for (const auto& callback : callback_list_)
|
||||
{
|
||||
if (callback && callback->get_i_callback() == result.type)
|
||||
{
|
||||
callback->run(result.data, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.data)
|
||||
{
|
||||
free(result.data);
|
||||
}
|
||||
}
|
||||
|
||||
results_.clear();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool SteamAPI_RestartAppIfNecessary()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SteamAPI_Init()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath();
|
||||
if (steam_path.empty()) return true;
|
||||
|
||||
::utils::nt::library::load(steam_path / "tier0_s64.dll");
|
||||
::utils::nt::library::load(steam_path / "vstdlib_s64.dll");
|
||||
::utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll");
|
||||
::utils::nt::library::load(steam_path / "steamclient64.dll");
|
||||
return true;
|
||||
}
|
||||
|
||||
void SteamAPI_RegisterCallResult(callbacks::base* result, const uint64_t call)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
callbacks::register_call_result(call, result);
|
||||
}
|
||||
|
||||
void SteamAPI_RegisterCallback(callbacks::base* handler, const int callback)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
callbacks::register_callback(handler, callback);
|
||||
}
|
||||
|
||||
void SteamAPI_RunCallbacks()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
callbacks::run_callbacks();
|
||||
}
|
||||
|
||||
void SteamAPI_Shutdown()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void SteamAPI_UnregisterCallResult(callbacks::base* result, const uint64_t call)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
callbacks::unregister_call_result(call, result);
|
||||
}
|
||||
|
||||
void SteamAPI_UnregisterCallback(callbacks::base* handler)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
callbacks::unregister_callback(handler);
|
||||
}
|
||||
|
||||
const char* SteamAPI_GetSteamInstallPath()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static std::string install_path{};
|
||||
if (!install_path.empty())
|
||||
{
|
||||
return install_path.data();
|
||||
}
|
||||
|
||||
HKEY reg_key;
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\WOW6432Node\\Valve\\Steam", 0, KEY_QUERY_VALUE,
|
||||
®_key) ==
|
||||
ERROR_SUCCESS)
|
||||
{
|
||||
char path[MAX_PATH] = {0};
|
||||
DWORD length = sizeof(path);
|
||||
RegQueryValueExA(reg_key, "InstallPath", nullptr, nullptr, reinterpret_cast<BYTE*>(path),
|
||||
&length);
|
||||
RegCloseKey(reg_key);
|
||||
|
||||
install_path = path;
|
||||
}
|
||||
|
||||
return install_path.data();
|
||||
}
|
||||
void* SteamGameServer_GetHSteamPipe()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void* SteamGameServer_GetHSteamUser()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void* SteamAPI_GetHSteamUser()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void* SteamAPI_GetHSteamPipe()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void* SteamInternal_CreateInterface(const char* interfacename)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
OutputDebugStringA(interfacename);
|
||||
if(std::string(interfacename) == "SteamClient017") {
|
||||
static client c;
|
||||
return &c;
|
||||
}
|
||||
|
||||
|
||||
MessageBoxA(0, interfacename, __FUNCTION__, 0);
|
||||
return nullptr;//::utils::nt::library("steam_api64.dll").invoke<void*>("SteamInternal_CreateInterface", interfacename);
|
||||
}
|
||||
|
||||
bool SteamInternal_GameServer_Init()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SteamGameServer_Init()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SteamGameServer_RunCallbacks()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
void SteamGameServer_Shutdown()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
friends* SteamFriends()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static friends friends;
|
||||
return &friends;
|
||||
}
|
||||
|
||||
matchmaking* SteamMatchmaking()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static matchmaking matchmaking;
|
||||
return &matchmaking;
|
||||
}
|
||||
|
||||
game_server* SteamGameServer()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static game_server game_server;
|
||||
return &game_server;
|
||||
}
|
||||
|
||||
networking* SteamNetworking()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static networking networking;
|
||||
return &networking;
|
||||
}
|
||||
|
||||
remote_storage* SteamRemoteStorage()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static remote_storage remote_storage;
|
||||
return &remote_storage;
|
||||
}
|
||||
|
||||
user* SteamUser()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static user user;
|
||||
return &user;
|
||||
}
|
||||
|
||||
utils* SteamUtils()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static utils utils;
|
||||
return &utils;
|
||||
}
|
||||
|
||||
apps* SteamApps()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static apps apps;
|
||||
return &apps;
|
||||
}
|
||||
|
||||
user_stats* SteamUserStats()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
static user_stats user_stats;
|
||||
return &user_stats;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
137
src/client/steam/steam.hpp
Normal file
137
src/client/steam/steam.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#define STEAM_EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
struct raw_steam_id final
|
||||
{
|
||||
unsigned int account_id : 32;
|
||||
unsigned int account_instance : 20;
|
||||
unsigned int account_type : 4;
|
||||
int universe : 8;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
raw_steam_id raw;
|
||||
unsigned long long bits;
|
||||
} steam_id;
|
||||
|
||||
#pragma pack( push, 1 )
|
||||
struct raw_game_id final
|
||||
{
|
||||
unsigned int app_id : 24;
|
||||
unsigned int type : 8;
|
||||
unsigned int mod_id : 32;
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
raw_game_id raw;
|
||||
unsigned long long bits;
|
||||
} game_id;
|
||||
#pragma pack( pop )
|
||||
|
||||
#include "interfaces/apps.hpp"
|
||||
#include "interfaces/user.hpp"
|
||||
#include "interfaces/utils.hpp"
|
||||
#include "interfaces/friends.hpp"
|
||||
#include "interfaces/user_stats.hpp"
|
||||
#include "interfaces/game_server.hpp"
|
||||
#include "interfaces/networking.hpp"
|
||||
#include "interfaces/matchmaking.hpp"
|
||||
#include "interfaces/matchmaking_servers.hpp"
|
||||
#include "interfaces/remote_storage.hpp"
|
||||
#include "interfaces/screenshots.hpp"
|
||||
#include "interfaces/game_server_stats.hpp"
|
||||
#include "interfaces/http.hpp"
|
||||
#include "interfaces/unified_messages.hpp"
|
||||
#include "interfaces/controller.hpp"
|
||||
#include "interfaces/client.hpp"
|
||||
|
||||
namespace steam
|
||||
{
|
||||
class callbacks
|
||||
{
|
||||
public:
|
||||
class base
|
||||
{
|
||||
public:
|
||||
base() : flags_(0), callback_(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void run(void* pv_param) = 0;
|
||||
virtual void run(void* pv_param, bool failure, uint64_t handle) = 0;
|
||||
virtual int get_callback_size_bytes() = 0;
|
||||
|
||||
int get_i_callback() const { return callback_; }
|
||||
void set_i_callback(const int i_callback) { callback_ = i_callback; }
|
||||
|
||||
protected:
|
||||
~base() = default;
|
||||
|
||||
unsigned char flags_;
|
||||
int callback_;
|
||||
};
|
||||
|
||||
struct result final
|
||||
{
|
||||
void* data{};
|
||||
int size{};
|
||||
int type{};
|
||||
uint64_t call{};
|
||||
};
|
||||
|
||||
static uint64_t register_call();
|
||||
|
||||
static void register_callback(base* handler, int callback);
|
||||
static void unregister_callback(base* handler);
|
||||
|
||||
static void register_call_result(uint64_t call, base* result);
|
||||
static void unregister_call_result(uint64_t call, base* result);
|
||||
|
||||
static void return_call(void* data, int size, int type, uint64_t call);
|
||||
static void run_callbacks();
|
||||
|
||||
private:
|
||||
static uint64_t call_id_;
|
||||
static std::recursive_mutex mutex_;
|
||||
static std::map<uint64_t, bool> calls_;
|
||||
static std::map<uint64_t, base*> result_handlers_;
|
||||
static std::vector<result> results_;
|
||||
static std::vector<base*> callback_list_;
|
||||
};
|
||||
|
||||
STEAM_EXPORT bool SteamAPI_RestartAppIfNecessary();
|
||||
STEAM_EXPORT bool SteamAPI_Init();
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallResult(callbacks::base* result, uint64_t call);
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallback(callbacks::base* handler, int callback);
|
||||
STEAM_EXPORT void SteamAPI_RunCallbacks();
|
||||
STEAM_EXPORT void SteamAPI_Shutdown();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallResult(callbacks::base* result, const uint64_t call);
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallback(callbacks::base* handler);
|
||||
STEAM_EXPORT const char* SteamAPI_GetSteamInstallPath();
|
||||
|
||||
STEAM_EXPORT void* SteamGameServer_GetHSteamPipe();
|
||||
STEAM_EXPORT void* SteamGameServer_GetHSteamUser();
|
||||
|
||||
STEAM_EXPORT void* SteamAPI_GetHSteamUser();
|
||||
STEAM_EXPORT void* SteamAPI_GetHSteamPipe();
|
||||
|
||||
STEAM_EXPORT void* SteamInternal_CreateInterface(const char* interfacename);
|
||||
|
||||
STEAM_EXPORT bool SteamInternal_GameServer_Init();
|
||||
STEAM_EXPORT bool SteamGameServer_Init();
|
||||
STEAM_EXPORT void SteamGameServer_RunCallbacks();
|
||||
STEAM_EXPORT void SteamGameServer_Shutdown();
|
||||
|
||||
STEAM_EXPORT friends* SteamFriends();
|
||||
STEAM_EXPORT matchmaking* SteamMatchmaking();
|
||||
STEAM_EXPORT game_server* SteamGameServer();
|
||||
STEAM_EXPORT networking* SteamNetworking();
|
||||
STEAM_EXPORT remote_storage* SteamRemoteStorage();
|
||||
STEAM_EXPORT user* SteamUser();
|
||||
STEAM_EXPORT utils* SteamUtils();
|
||||
STEAM_EXPORT apps* SteamApps();
|
||||
STEAM_EXPORT user_stats* SteamUserStats();
|
||||
}
|
75
src/common/utils/binary_resource.cpp
Normal file
75
src/common/utils/binary_resource.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "binary_resource.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include "nt.hpp"
|
||||
#include "io.hpp"
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::string get_temp_folder()
|
||||
{
|
||||
char path[MAX_PATH] = {0};
|
||||
if (!GetTempPathA(sizeof(path), path))
|
||||
{
|
||||
throw std::runtime_error("Unable to get temp path");
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string write_existing_temp_file(const std::string& file, const std::string& data,
|
||||
const bool fatal_if_overwrite_fails)
|
||||
{
|
||||
const auto temp = get_temp_folder();
|
||||
auto file_path = temp + file;
|
||||
|
||||
std::string current_data;
|
||||
if (!io::read_file(file_path, ¤t_data))
|
||||
{
|
||||
if (!io::write_file(file_path, data))
|
||||
{
|
||||
throw std::runtime_error("Failed to write file: " + file_path);
|
||||
}
|
||||
|
||||
return file_path;
|
||||
}
|
||||
|
||||
if (current_data == data || io::write_file(file_path, data) || !fatal_if_overwrite_fails)
|
||||
{
|
||||
return file_path;
|
||||
}
|
||||
|
||||
throw std::runtime_error(
|
||||
"Temporary file was already written, but differs. It can't be overwritten as it's still in use: " +
|
||||
file_path);
|
||||
}
|
||||
}
|
||||
|
||||
binary_resource::binary_resource(const int id, std::string file)
|
||||
: filename_(std::move(file))
|
||||
{
|
||||
this->resource_ = nt::load_resource(id);
|
||||
|
||||
if (this->resource_.empty())
|
||||
{
|
||||
throw std::runtime_error("Unable to load resource: " + std::to_string(id));
|
||||
}
|
||||
}
|
||||
|
||||
std::string binary_resource::get_extracted_file(const bool fatal_if_overwrite_fails)
|
||||
{
|
||||
if (this->path_.empty())
|
||||
{
|
||||
this->path_ = write_existing_temp_file(this->filename_, this->resource_, fatal_if_overwrite_fails);
|
||||
}
|
||||
|
||||
return this->path_;
|
||||
}
|
||||
|
||||
const std::string& binary_resource::get_data() const
|
||||
{
|
||||
return this->resource_;
|
||||
}
|
||||
}
|
20
src/common/utils/binary_resource.hpp
Normal file
20
src/common/utils/binary_resource.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class binary_resource
|
||||
{
|
||||
public:
|
||||
binary_resource(int id, std::string file);
|
||||
|
||||
std::string get_extracted_file(bool fatal_if_overwrite_fails = false);
|
||||
const std::string& get_data() const;
|
||||
|
||||
private:
|
||||
std::string resource_;
|
||||
std::string filename_;
|
||||
std::string path_;
|
||||
};
|
||||
}
|
46
src/common/utils/concurrency.hpp
Normal file
46
src/common/utils/concurrency.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace utils::concurrency
|
||||
{
|
||||
template <typename T, typename MutexType = std::mutex>
|
||||
class container
|
||||
{
|
||||
public:
|
||||
template <typename R = void, typename F>
|
||||
R access(F&& accessor) const
|
||||
{
|
||||
std::lock_guard<MutexType> _{mutex_};
|
||||
return accessor(object_);
|
||||
}
|
||||
|
||||
template <typename R = void, typename F>
|
||||
R access(F&& accessor)
|
||||
{
|
||||
std::lock_guard<MutexType> _{mutex_};
|
||||
return accessor(object_);
|
||||
}
|
||||
|
||||
template <typename R = void, typename F>
|
||||
R access_with_lock(F&& accessor) const
|
||||
{
|
||||
std::unique_lock<MutexType> lock{mutex_};
|
||||
return accessor(object_, lock);
|
||||
}
|
||||
|
||||
template <typename R = void, typename F>
|
||||
R access_with_lock(F&& accessor)
|
||||
{
|
||||
std::unique_lock<MutexType> lock{mutex_};
|
||||
return accessor(object_, lock);
|
||||
}
|
||||
|
||||
T& get_raw() { return object_; }
|
||||
const T& get_raw() const { return object_; }
|
||||
|
||||
private:
|
||||
mutable MutexType mutex_{};
|
||||
T object_{};
|
||||
};
|
||||
}
|
54
src/common/utils/finally.hpp
Normal file
54
src/common/utils/finally.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
#include <type_traits>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
/*
|
||||
* Copied from here: https://github.com/microsoft/GSL/blob/e0880931ae5885eb988d1a8a57acf8bc2b8dacda/include/gsl/util#L57
|
||||
*/
|
||||
|
||||
template <class F>
|
||||
class final_action
|
||||
{
|
||||
public:
|
||||
static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
|
||||
!std::is_volatile<F>::value,
|
||||
"Final_action should store its callable by value");
|
||||
|
||||
explicit final_action(F f) noexcept : f_(std::move(f))
|
||||
{
|
||||
}
|
||||
|
||||
final_action(final_action&& other) noexcept
|
||||
: f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
|
||||
{
|
||||
}
|
||||
|
||||
final_action(const final_action&) = delete;
|
||||
final_action& operator=(const final_action&) = delete;
|
||||
final_action& operator=(final_action&&) = delete;
|
||||
|
||||
~final_action() noexcept
|
||||
{
|
||||
if (invoke_) f_();
|
||||
}
|
||||
|
||||
// Added by momo5502
|
||||
void cancel()
|
||||
{
|
||||
invoke_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
F f_;
|
||||
bool invoke_{true};
|
||||
};
|
||||
|
||||
template <class F>
|
||||
final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
|
||||
finally(F&& f) noexcept
|
||||
{
|
||||
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
|
||||
std::forward<F>(f));
|
||||
}
|
||||
}
|
53
src/common/utils/flags.cpp
Normal file
53
src/common/utils/flags.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "flags.hpp"
|
||||
#include "string.hpp"
|
||||
#include "nt.hpp"
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
namespace utils::flags
|
||||
{
|
||||
void parse_flags(std::vector<std::string>& flags)
|
||||
{
|
||||
int num_args;
|
||||
auto* const argv = CommandLineToArgvW(GetCommandLineW(), &num_args);
|
||||
|
||||
flags.clear();
|
||||
|
||||
if (argv)
|
||||
{
|
||||
for (auto i = 0; i < num_args; ++i)
|
||||
{
|
||||
std::wstring wide_flag(argv[i]);
|
||||
if (wide_flag[0] == L'-')
|
||||
{
|
||||
wide_flag.erase(wide_flag.begin());
|
||||
flags.emplace_back(string::convert(wide_flag));
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree(argv);
|
||||
}
|
||||
}
|
||||
|
||||
bool has_flag(const std::string& flag)
|
||||
{
|
||||
static auto parsed = false;
|
||||
static std::vector<std::string> enabled_flags;
|
||||
|
||||
if (!parsed)
|
||||
{
|
||||
parse_flags(enabled_flags);
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
for (const auto& entry : enabled_flags)
|
||||
{
|
||||
if (string::to_lower(entry) == string::to_lower(flag))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
8
src/common/utils/flags.hpp
Normal file
8
src/common/utils/flags.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils::flags
|
||||
{
|
||||
bool has_flag(const std::string& flag);
|
||||
}
|
310
src/common/utils/hook.cpp
Normal file
310
src/common/utils/hook.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
#include "hook.hpp"
|
||||
#include "string.hpp"
|
||||
|
||||
#include <MinHook.h>
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
namespace
|
||||
{
|
||||
[[maybe_unused]] class _
|
||||
{
|
||||
public:
|
||||
_()
|
||||
{
|
||||
if (MH_Initialize() != MH_OK)
|
||||
{
|
||||
throw std::runtime_error("Failed to initialize MinHook");
|
||||
}
|
||||
}
|
||||
|
||||
~_()
|
||||
{
|
||||
MH_Uninitialize();
|
||||
}
|
||||
} __;
|
||||
}
|
||||
|
||||
void assembler::pushad64()
|
||||
{
|
||||
this->push(rax);
|
||||
this->push(rcx);
|
||||
this->push(rdx);
|
||||
this->push(rbx);
|
||||
this->push(rsp);
|
||||
this->push(rbp);
|
||||
this->push(rsi);
|
||||
this->push(rdi);
|
||||
|
||||
this->sub(rsp, 0x40);
|
||||
}
|
||||
|
||||
void assembler::popad64()
|
||||
{
|
||||
this->add(rsp, 0x40);
|
||||
|
||||
this->pop(rdi);
|
||||
this->pop(rsi);
|
||||
this->pop(rbp);
|
||||
this->pop(rsp);
|
||||
this->pop(rbx);
|
||||
this->pop(rdx);
|
||||
this->pop(rcx);
|
||||
this->pop(rax);
|
||||
}
|
||||
|
||||
void assembler::prepare_stack_for_call()
|
||||
{
|
||||
const auto reserve_callee_space = this->newLabel();
|
||||
const auto stack_unaligned = this->newLabel();
|
||||
|
||||
this->test(rsp, 0xF);
|
||||
this->jnz(stack_unaligned);
|
||||
|
||||
this->sub(rsp, 0x8);
|
||||
this->push(rsp);
|
||||
|
||||
this->push(rax);
|
||||
this->mov(rax, ptr(rsp, 8, 8));
|
||||
this->add(rax, 0x8);
|
||||
this->mov(ptr(rsp, 8, 8), rax);
|
||||
this->pop(rax);
|
||||
|
||||
this->jmp(reserve_callee_space);
|
||||
|
||||
this->bind(stack_unaligned);
|
||||
this->push(rsp);
|
||||
|
||||
this->bind(reserve_callee_space);
|
||||
this->sub(rsp, 0x40);
|
||||
}
|
||||
|
||||
void assembler::restore_stack_after_call()
|
||||
{
|
||||
this->lea(rsp, ptr(rsp, 0x40));
|
||||
this->pop(rsp);
|
||||
}
|
||||
|
||||
asmjit::Error assembler::call(void* target)
|
||||
{
|
||||
return Assembler::call(size_t(target));
|
||||
}
|
||||
|
||||
asmjit::Error assembler::jmp(void* target)
|
||||
{
|
||||
return Assembler::jmp(size_t(target));
|
||||
}
|
||||
|
||||
detour::detour(const size_t place, void* target) : detour(reinterpret_cast<void*>(place), target)
|
||||
{
|
||||
}
|
||||
|
||||
detour::detour(void* place, void* target)
|
||||
{
|
||||
this->create(place, target);
|
||||
}
|
||||
|
||||
detour::~detour()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void detour::enable() const
|
||||
{
|
||||
MH_EnableHook(this->place_);
|
||||
}
|
||||
|
||||
void detour::disable() const
|
||||
{
|
||||
MH_DisableHook(this->place_);
|
||||
}
|
||||
|
||||
void detour::create(void* place, void* target)
|
||||
{
|
||||
this->clear();
|
||||
this->place_ = place;
|
||||
|
||||
if (MH_CreateHook(this->place_, target, &this->original_) != MH_OK)
|
||||
{
|
||||
throw std::runtime_error(string::va("Unable to create hook at location: %p", this->place_));
|
||||
}
|
||||
|
||||
this->enable();
|
||||
}
|
||||
|
||||
void detour::create(const size_t place, void* target)
|
||||
{
|
||||
this->create(reinterpret_cast<void*>(place), target);
|
||||
}
|
||||
|
||||
void detour::clear()
|
||||
{
|
||||
if (this->place_)
|
||||
{
|
||||
MH_RemoveHook(this->place_);
|
||||
}
|
||||
|
||||
this->place_ = nullptr;
|
||||
this->original_ = nullptr;
|
||||
}
|
||||
|
||||
void* detour::get_original() const
|
||||
{
|
||||
return this->original_;
|
||||
}
|
||||
|
||||
bool iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub)
|
||||
{
|
||||
if (!library.is_valid()) return false;
|
||||
|
||||
auto* const ptr = library.get_iat_entry(target_library, process);
|
||||
if (!ptr) return false;
|
||||
|
||||
DWORD protect;
|
||||
VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect);
|
||||
|
||||
*ptr = stub;
|
||||
|
||||
VirtualProtect(ptr, sizeof(*ptr), protect, &protect);
|
||||
return true;
|
||||
}
|
||||
|
||||
void nop(void* place, const size_t length)
|
||||
{
|
||||
DWORD old_protect{};
|
||||
VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect);
|
||||
|
||||
std::memset(place, 0x90, length);
|
||||
|
||||
VirtualProtect(place, length, old_protect, &old_protect);
|
||||
FlushInstructionCache(GetCurrentProcess(), place, length);
|
||||
}
|
||||
|
||||
void nop(const size_t place, const size_t length)
|
||||
{
|
||||
nop(reinterpret_cast<void*>(place), length);
|
||||
}
|
||||
|
||||
void copy(void* place, const void* data, const size_t length)
|
||||
{
|
||||
DWORD old_protect{};
|
||||
VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect);
|
||||
|
||||
std::memmove(place, data, length);
|
||||
|
||||
VirtualProtect(place, length, old_protect, &old_protect);
|
||||
FlushInstructionCache(GetCurrentProcess(), place, length);
|
||||
}
|
||||
|
||||
void copy(const size_t place, const void* data, const size_t length)
|
||||
{
|
||||
copy(reinterpret_cast<void*>(place), data, length);
|
||||
}
|
||||
|
||||
bool is_relatively_far(const void* pointer, const void* data, const int offset)
|
||||
{
|
||||
const int64_t diff = size_t(data) - (size_t(pointer) + offset);
|
||||
const auto small_diff = int32_t(diff);
|
||||
return diff != int64_t(small_diff);
|
||||
}
|
||||
|
||||
void call(void* pointer, void* data)
|
||||
{
|
||||
if (is_relatively_far(pointer, data))
|
||||
{
|
||||
throw std::runtime_error("Too far away to create 32bit relative branch");
|
||||
}
|
||||
|
||||
auto* patch_pointer = PBYTE(pointer);
|
||||
set<uint8_t>(patch_pointer, 0xE8);
|
||||
set<int32_t>(patch_pointer + 1, int32_t(size_t(data) - (size_t(pointer) + 5)));
|
||||
}
|
||||
|
||||
void call(const size_t pointer, void* data)
|
||||
{
|
||||
return call(reinterpret_cast<void*>(pointer), data);
|
||||
}
|
||||
|
||||
void call(const size_t pointer, const size_t data)
|
||||
{
|
||||
return call(pointer, reinterpret_cast<void*>(data));
|
||||
}
|
||||
|
||||
void jump(void* pointer, void* data, const bool use_far)
|
||||
{
|
||||
static const unsigned char jump_data[] = {
|
||||
0x48, 0xb8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0xff, 0xe0
|
||||
};
|
||||
|
||||
if (!use_far && is_relatively_far(pointer, data))
|
||||
{
|
||||
throw std::runtime_error("Too far away to create 32bit relative branch");
|
||||
}
|
||||
|
||||
auto* patch_pointer = PBYTE(pointer);
|
||||
|
||||
if (use_far)
|
||||
{
|
||||
copy(patch_pointer, jump_data, sizeof(jump_data));
|
||||
copy(patch_pointer + 2, &data, sizeof(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
set<uint8_t>(patch_pointer, 0xE9);
|
||||
set<int32_t>(patch_pointer + 1, int32_t(size_t(data) - (size_t(pointer) + 5)));
|
||||
}
|
||||
}
|
||||
|
||||
void jump(const size_t pointer, void* data, const bool use_far)
|
||||
{
|
||||
return jump(reinterpret_cast<void*>(pointer), data, use_far);
|
||||
}
|
||||
|
||||
void jump(const size_t pointer, const size_t data, const bool use_far)
|
||||
{
|
||||
return jump(pointer, reinterpret_cast<void*>(data), use_far);
|
||||
}
|
||||
|
||||
void* assemble(const std::function<void(assembler&)>& asm_function)
|
||||
{
|
||||
static asmjit::JitRuntime runtime;
|
||||
|
||||
asmjit::CodeHolder code;
|
||||
code.init(runtime.environment());
|
||||
|
||||
assembler a(&code);
|
||||
|
||||
asm_function(a);
|
||||
|
||||
void* result = nullptr;
|
||||
runtime.add(&result, &code);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void inject(void* pointer, const void* data)
|
||||
{
|
||||
if (is_relatively_far(pointer, data, 4))
|
||||
{
|
||||
throw std::runtime_error("Too far away to create 32bit relative branch");
|
||||
}
|
||||
|
||||
set<int32_t>(pointer, int32_t(size_t(data) - (size_t(pointer) + 4)));
|
||||
}
|
||||
|
||||
void inject(const size_t pointer, const void* data)
|
||||
{
|
||||
return inject(reinterpret_cast<void*>(pointer), data);
|
||||
}
|
||||
|
||||
void* follow_branch(void* address)
|
||||
{
|
||||
auto* const data = static_cast<uint8_t*>(address);
|
||||
if (*data != 0xE8 && *data != 0xE9)
|
||||
{
|
||||
throw std::runtime_error("No branch instruction found");
|
||||
}
|
||||
|
||||
return extract<void*>(data + 1);
|
||||
}
|
||||
}
|
205
src/common/utils/hook.hpp
Normal file
205
src/common/utils/hook.hpp
Normal file
@ -0,0 +1,205 @@
|
||||
#pragma once
|
||||
#include "signature.hpp"
|
||||
|
||||
#include <asmjit/core/jitruntime.h>
|
||||
#include <asmjit/x86/x86assembler.h>
|
||||
|
||||
using namespace asmjit::x86;
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<size_t entries>
|
||||
std::vector<size_t(*)()> get_iota_functions()
|
||||
{
|
||||
if constexpr (entries == 0)
|
||||
{
|
||||
std::vector<size_t(*)()> functions;
|
||||
return functions;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto functions = get_iota_functions<entries - 1>();
|
||||
functions.emplace_back([]()
|
||||
{
|
||||
return entries - 1;
|
||||
});
|
||||
return functions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the pointer to the entry in the v-table.
|
||||
// It seems otherwise impossible to get this.
|
||||
// This is ugly as fuck and only safely works on x64
|
||||
// Example:
|
||||
// ID3D11Device* device = ...
|
||||
// auto entry = get_vtable_entry(device, &ID3D11Device::CreateTexture2D);
|
||||
template <size_t entries = 100, typename Class, typename T, typename... Args>
|
||||
void** get_vtable_entry(Class* obj, T (Class::* entry)(Args ...))
|
||||
{
|
||||
union
|
||||
{
|
||||
decltype(entry) func;
|
||||
void* pointer;
|
||||
};
|
||||
|
||||
func = entry;
|
||||
|
||||
auto iota_functions = detail::get_iota_functions<entries>();
|
||||
auto* object = iota_functions.data();
|
||||
|
||||
using FakeFunc = size_t(__thiscall*)(void* self);
|
||||
auto index = static_cast<FakeFunc>(pointer)(&object);
|
||||
|
||||
void** obj_v_table = *reinterpret_cast<void***>(obj);
|
||||
return &obj_v_table[index];
|
||||
}
|
||||
|
||||
class assembler : public Assembler
|
||||
{
|
||||
public:
|
||||
using Assembler::Assembler;
|
||||
using Assembler::call;
|
||||
using Assembler::jmp;
|
||||
|
||||
void pushad64();
|
||||
void popad64();
|
||||
|
||||
void prepare_stack_for_call();
|
||||
void restore_stack_after_call();
|
||||
|
||||
template <typename T>
|
||||
void call_aligned(T&& target)
|
||||
{
|
||||
this->prepare_stack_for_call();
|
||||
this->call(std::forward<T>(target));
|
||||
this->restore_stack_after_call();
|
||||
}
|
||||
|
||||
asmjit::Error call(void* target);
|
||||
asmjit::Error jmp(void* target);
|
||||
};
|
||||
|
||||
class detour
|
||||
{
|
||||
public:
|
||||
detour() = default;
|
||||
detour(void* place, void* target);
|
||||
detour(size_t place, void* target);
|
||||
~detour();
|
||||
|
||||
detour(detour&& other) noexcept
|
||||
{
|
||||
this->operator=(std::move(other));
|
||||
}
|
||||
|
||||
detour& operator=(detour&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
this->~detour();
|
||||
|
||||
this->place_ = other.place_;
|
||||
this->original_ = other.original_;
|
||||
|
||||
other.place_ = nullptr;
|
||||
other.original_ = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
detour(const detour&) = delete;
|
||||
detour& operator=(const detour&) = delete;
|
||||
|
||||
void enable() const;
|
||||
void disable() const;
|
||||
|
||||
void create(void* place, void* target);
|
||||
void create(size_t place, void* target);
|
||||
void clear();
|
||||
|
||||
template <typename T>
|
||||
T* get() const
|
||||
{
|
||||
return static_cast<T*>(this->get_original());
|
||||
}
|
||||
|
||||
template <typename T = void, typename... Args>
|
||||
T invoke(Args ... args)
|
||||
{
|
||||
return static_cast<T(*)(Args ...)>(this->get_original())(args...);
|
||||
}
|
||||
|
||||
[[nodiscard]] void* get_original() const;
|
||||
|
||||
private:
|
||||
void* place_{};
|
||||
void* original_{};
|
||||
};
|
||||
|
||||
bool iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub);
|
||||
|
||||
void nop(void* place, size_t length);
|
||||
void nop(size_t place, size_t length);
|
||||
|
||||
void copy(void* place, const void* data, size_t length);
|
||||
void copy(size_t place, const void* data, size_t length);
|
||||
|
||||
bool is_relatively_far(const void* pointer, const void* data, int offset = 5);
|
||||
|
||||
void call(void* pointer, void* data);
|
||||
void call(size_t pointer, void* data);
|
||||
void call(size_t pointer, size_t data);
|
||||
|
||||
void jump(void* pointer, void* data, bool use_far = false);
|
||||
void jump(size_t pointer, void* data, bool use_far = false);
|
||||
void jump(size_t pointer, size_t data, bool use_far = false);
|
||||
|
||||
void* assemble(const std::function<void(assembler&)>& asm_function);
|
||||
|
||||
void inject(void* pointer, const void* data);
|
||||
void inject(size_t pointer, const void* data);
|
||||
|
||||
template <typename T>
|
||||
T extract(void* address)
|
||||
{
|
||||
auto* const data = static_cast<uint8_t*>(address);
|
||||
const auto offset = *reinterpret_cast<int32_t*>(data);
|
||||
return reinterpret_cast<T>(data + offset + 4);
|
||||
}
|
||||
|
||||
void* follow_branch(void* address);
|
||||
|
||||
template <typename T>
|
||||
static void set(void* place, T value)
|
||||
{
|
||||
DWORD old_protect;
|
||||
VirtualProtect(place, sizeof(T), PAGE_EXECUTE_READWRITE, &old_protect);
|
||||
|
||||
*static_cast<T*>(place) = value;
|
||||
|
||||
VirtualProtect(place, sizeof(T), old_protect, &old_protect);
|
||||
FlushInstructionCache(GetCurrentProcess(), place, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void set(const size_t place, T value)
|
||||
{
|
||||
return set<T>(reinterpret_cast<void*>(place), value);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
static T invoke(size_t func, Args ... args)
|
||||
{
|
||||
return reinterpret_cast<T(*)(Args ...)>(func)(args...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
static T invoke(void* func, Args ... args)
|
||||
{
|
||||
return static_cast<T(*)(Args ...)>(func)(args...);
|
||||
}
|
||||
}
|
48
src/common/utils/http.cpp
Normal file
48
src/common/utils/http.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "http.hpp"
|
||||
#include "nt.hpp"
|
||||
#include <atlcomcli.h>
|
||||
|
||||
namespace utils::http
|
||||
{
|
||||
std::optional<std::string> get_data(const std::string& url)
|
||||
{
|
||||
CComPtr<IStream> stream;
|
||||
|
||||
if (FAILED(URLOpenBlockingStreamA(nullptr, url.data(), &stream, 0, nullptr)))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
char buffer[0x1000];
|
||||
std::string result;
|
||||
|
||||
HRESULT status{};
|
||||
|
||||
do
|
||||
{
|
||||
DWORD bytes_read = 0;
|
||||
status = stream->Read(buffer, sizeof(buffer), &bytes_read);
|
||||
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
result.append(buffer, bytes_read);
|
||||
}
|
||||
}
|
||||
while (SUCCEEDED(status) && status != S_FALSE);
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return {result};
|
||||
}
|
||||
|
||||
std::future<std::optional<std::string>> get_data_async(const std::string& url)
|
||||
{
|
||||
return std::async(std::launch::async, [url]()
|
||||
{
|
||||
return get_data(url);
|
||||
});
|
||||
}
|
||||
}
|
11
src/common/utils/http.hpp
Normal file
11
src/common/utils/http.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <future>
|
||||
|
||||
namespace utils::http
|
||||
{
|
||||
std::optional<std::string> get_data(const std::string& url);
|
||||
std::future<std::optional<std::string>> get_data_async(const std::string& url);
|
||||
}
|
65
src/common/utils/info_string.cpp
Normal file
65
src/common/utils/info_string.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include "info_string.hpp"
|
||||
#include "string.hpp"
|
||||
|
||||
namespace utils
|
||||
{
|
||||
info_string::info_string(const std::string& buffer)
|
||||
{
|
||||
this->parse(buffer);
|
||||
}
|
||||
|
||||
info_string::info_string(const std::string_view& buffer)
|
||||
: info_string(std::string{buffer})
|
||||
{
|
||||
}
|
||||
|
||||
void info_string::set(const std::string& key, const std::string& value)
|
||||
{
|
||||
this->key_value_pairs_[key] = value;
|
||||
}
|
||||
|
||||
std::string info_string::get(const std::string& key) const
|
||||
{
|
||||
const auto value = this->key_value_pairs_.find(key);
|
||||
if (value != this->key_value_pairs_.end())
|
||||
{
|
||||
return value->second;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void info_string::parse(std::string buffer)
|
||||
{
|
||||
if (buffer[0] == '\\')
|
||||
{
|
||||
buffer = buffer.substr(1);
|
||||
}
|
||||
|
||||
auto key_values = string::split(buffer, '\\');
|
||||
for (size_t i = 0; !key_values.empty() && i < (key_values.size() - 1); i += 2)
|
||||
{
|
||||
const auto& key = key_values[i];
|
||||
const auto& value = key_values[i + 1];
|
||||
this->key_value_pairs_[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
std::string info_string::build() const
|
||||
{
|
||||
//auto first = true;
|
||||
std::string info_string;
|
||||
for (auto i = this->key_value_pairs_.begin(); i != this->key_value_pairs_.end(); ++i)
|
||||
{
|
||||
//if (first) first = false;
|
||||
/*else*/
|
||||
info_string.append("\\");
|
||||
|
||||
info_string.append(i->first); // Key
|
||||
info_string.append("\\");
|
||||
info_string.append(i->second); // Value
|
||||
}
|
||||
|
||||
return info_string;
|
||||
}
|
||||
}
|
24
src/common/utils/info_string.hpp
Normal file
24
src/common/utils/info_string.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class info_string
|
||||
{
|
||||
public:
|
||||
info_string() = default;
|
||||
info_string(const std::string& buffer);
|
||||
info_string(const std::string_view& buffer);
|
||||
|
||||
void set(const std::string& key, const std::string& value);
|
||||
std::string get(const std::string& key) const;
|
||||
std::string build() const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::string> key_value_pairs_{};
|
||||
|
||||
void parse(std::string buffer);
|
||||
};
|
||||
}
|
125
src/common/utils/io.cpp
Normal file
125
src/common/utils/io.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include "io.hpp"
|
||||
#include "nt.hpp"
|
||||
#include <fstream>
|
||||
|
||||
namespace utils::io
|
||||
{
|
||||
bool remove_file(const std::string& file)
|
||||
{
|
||||
return DeleteFileA(file.data()) == TRUE;
|
||||
}
|
||||
|
||||
bool move_file(const std::string& src, const std::string& target)
|
||||
{
|
||||
return MoveFileA(src.data(), target.data()) == TRUE;
|
||||
}
|
||||
|
||||
bool file_exists(const std::string& file)
|
||||
{
|
||||
return std::ifstream(file).good();
|
||||
}
|
||||
|
||||
bool write_file(const std::string& file, const std::string& data, const bool append)
|
||||
{
|
||||
const auto pos = file.find_last_of("/\\");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
create_directory(file.substr(0, pos));
|
||||
}
|
||||
|
||||
std::ofstream stream(
|
||||
file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : 0));
|
||||
|
||||
if (stream.is_open())
|
||||
{
|
||||
stream.write(data.data(), data.size());
|
||||
stream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string read_file(const std::string& file)
|
||||
{
|
||||
std::string data;
|
||||
read_file(file, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
bool read_file(const std::string& file, std::string* data)
|
||||
{
|
||||
if (!data) return false;
|
||||
data->clear();
|
||||
|
||||
if (file_exists(file))
|
||||
{
|
||||
std::ifstream stream(file, std::ios::binary);
|
||||
if (!stream.is_open()) return false;
|
||||
|
||||
stream.seekg(0, std::ios::end);
|
||||
const std::streamsize size = stream.tellg();
|
||||
stream.seekg(0, std::ios::beg);
|
||||
|
||||
if (size > -1)
|
||||
{
|
||||
data->resize(static_cast<uint32_t>(size));
|
||||
stream.read(const_cast<char*>(data->data()), size);
|
||||
stream.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t file_size(const std::string& file)
|
||||
{
|
||||
if (file_exists(file))
|
||||
{
|
||||
std::ifstream stream(file, std::ios::binary);
|
||||
|
||||
if (stream.good())
|
||||
{
|
||||
stream.seekg(0, std::ios::end);
|
||||
return static_cast<size_t>(stream.tellg());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool create_directory(const std::string& directory)
|
||||
{
|
||||
return std::filesystem::create_directories(directory);
|
||||
}
|
||||
|
||||
bool directory_exists(const std::string& directory)
|
||||
{
|
||||
return std::filesystem::is_directory(directory);
|
||||
}
|
||||
|
||||
bool directory_is_empty(const std::string& directory)
|
||||
{
|
||||
return std::filesystem::is_empty(directory);
|
||||
}
|
||||
|
||||
std::vector<std::string> list_files(const std::string& directory)
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
|
||||
for (auto& file : std::filesystem::directory_iterator(directory))
|
||||
{
|
||||
files.push_back(file.path().generic_string());
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target)
|
||||
{
|
||||
std::filesystem::copy(src, target,
|
||||
std::filesystem::copy_options::overwrite_existing |
|
||||
std::filesystem::copy_options::recursive);
|
||||
}
|
||||
}
|
21
src/common/utils/io.hpp
Normal file
21
src/common/utils/io.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
namespace utils::io
|
||||
{
|
||||
bool remove_file(const std::string& file);
|
||||
bool move_file(const std::string& src, const std::string& target);
|
||||
bool file_exists(const std::string& file);
|
||||
bool write_file(const std::string& file, const std::string& data, bool append = false);
|
||||
bool read_file(const std::string& file, std::string* data);
|
||||
std::string read_file(const std::string& file);
|
||||
size_t file_size(const std::string& file);
|
||||
bool create_directory(const std::string& directory);
|
||||
bool directory_exists(const std::string& directory);
|
||||
bool directory_is_empty(const std::string& directory);
|
||||
std::vector<std::string> list_files(const std::string& directory);
|
||||
void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target);
|
||||
}
|
173
src/common/utils/memory.cpp
Normal file
173
src/common/utils/memory.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
#include "memory.hpp"
|
||||
#include "nt.hpp"
|
||||
|
||||
namespace utils
|
||||
{
|
||||
memory::allocator memory::mem_allocator_;
|
||||
|
||||
memory::allocator::~allocator()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void memory::allocator::clear()
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
for (auto& data : this->pool_)
|
||||
{
|
||||
memory::free(data);
|
||||
}
|
||||
|
||||
this->pool_.clear();
|
||||
}
|
||||
|
||||
void memory::allocator::free(void* data)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto j = std::find(this->pool_.begin(), this->pool_.end(), data);
|
||||
if (j != this->pool_.end())
|
||||
{
|
||||
memory::free(data);
|
||||
this->pool_.erase(j);
|
||||
}
|
||||
}
|
||||
|
||||
void memory::allocator::free(const void* data)
|
||||
{
|
||||
this->free(const_cast<void*>(data));
|
||||
}
|
||||
|
||||
void* memory::allocator::allocate(const size_t length)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto data = memory::allocate(length);
|
||||
this->pool_.push_back(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
bool memory::allocator::empty() const
|
||||
{
|
||||
return this->pool_.empty();
|
||||
}
|
||||
|
||||
char* memory::allocator::duplicate_string(const std::string& string)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto data = memory::duplicate_string(string);
|
||||
this->pool_.push_back(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
bool memory::allocator::find(const void* data)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto j = std::find(this->pool_.begin(), this->pool_.end(), data);
|
||||
return j != this->pool_.end();
|
||||
}
|
||||
|
||||
void* memory::allocate(const size_t length)
|
||||
{
|
||||
return calloc(length, 1);
|
||||
}
|
||||
|
||||
char* memory::duplicate_string(const std::string& string)
|
||||
{
|
||||
const auto new_string = allocate_array<char>(string.size() + 1);
|
||||
std::memcpy(new_string, string.data(), string.size());
|
||||
return new_string;
|
||||
}
|
||||
|
||||
void memory::free(void* data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
::free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void memory::free(const void* data)
|
||||
{
|
||||
free(const_cast<void*>(data));
|
||||
}
|
||||
|
||||
bool memory::is_set(const void* mem, const char chr, const size_t length)
|
||||
{
|
||||
const auto mem_arr = static_cast<const char*>(mem);
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if (mem_arr[i] != chr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool memory::is_bad_read_ptr(const void* ptr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi = {};
|
||||
if (VirtualQuery(ptr, &mbi, sizeof(mbi)))
|
||||
{
|
||||
const DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ |
|
||||
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
|
||||
auto b = !(mbi.Protect & mask);
|
||||
// check the page is not a guard page
|
||||
if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true;
|
||||
|
||||
return b;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool memory::is_bad_code_ptr(const void* ptr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi = {};
|
||||
if (VirtualQuery(ptr, &mbi, sizeof(mbi)))
|
||||
{
|
||||
const DWORD mask = (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
|
||||
auto b = !(mbi.Protect & mask);
|
||||
// check the page is not a guard page
|
||||
if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true;
|
||||
|
||||
return b;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool memory::is_rdata_ptr(void* pointer)
|
||||
{
|
||||
const std::string rdata = ".rdata";
|
||||
const auto pointer_lib = utils::nt::library::get_by_address(pointer);
|
||||
|
||||
for (const auto& section : pointer_lib.get_section_headers())
|
||||
{
|
||||
const auto size = sizeof(section->Name);
|
||||
char name[size + 1];
|
||||
name[size] = 0;
|
||||
std::memcpy(name, section->Name, size);
|
||||
|
||||
if (name == rdata)
|
||||
{
|
||||
const auto target = size_t(pointer);
|
||||
const size_t source_start = size_t(pointer_lib.get_ptr()) + section->PointerToRawData;
|
||||
const size_t source_end = source_start + section->SizeOfRawData;
|
||||
|
||||
return target >= source_start && target <= source_end;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
memory::allocator* memory::get_allocator()
|
||||
{
|
||||
return &memory::mem_allocator_;
|
||||
}
|
||||
}
|
77
src/common/utils/memory.hpp
Normal file
77
src/common/utils/memory.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class memory final
|
||||
{
|
||||
public:
|
||||
class allocator final
|
||||
{
|
||||
public:
|
||||
~allocator();
|
||||
|
||||
void clear();
|
||||
|
||||
void free(void* data);
|
||||
|
||||
void free(const void* data);
|
||||
|
||||
void* allocate(size_t length);
|
||||
|
||||
template <typename T>
|
||||
inline T* allocate()
|
||||
{
|
||||
return this->allocate_array<T>(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* allocate_array(const size_t count = 1)
|
||||
{
|
||||
return static_cast<T*>(this->allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
bool empty() const;
|
||||
|
||||
char* duplicate_string(const std::string& string);
|
||||
|
||||
bool find(const void* data);
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::vector<void*> pool_;
|
||||
};
|
||||
|
||||
static void* allocate(size_t length);
|
||||
|
||||
template <typename T>
|
||||
static inline T* allocate()
|
||||
{
|
||||
return allocate_array<T>(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T* allocate_array(const size_t count = 1)
|
||||
{
|
||||
return static_cast<T*>(allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
static char* duplicate_string(const std::string& string);
|
||||
|
||||
static void free(void* data);
|
||||
static void free(const void* data);
|
||||
|
||||
static bool is_set(const void* mem, char chr, size_t length);
|
||||
|
||||
static bool is_bad_read_ptr(const void* ptr);
|
||||
static bool is_bad_code_ptr(const void* ptr);
|
||||
static bool is_rdata_ptr(void* ptr);
|
||||
|
||||
static allocator* get_allocator();
|
||||
|
||||
private:
|
||||
static allocator mem_allocator_;
|
||||
};
|
||||
}
|
258
src/common/utils/nt.cpp
Normal file
258
src/common/utils/nt.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
#include "nt.hpp"
|
||||
|
||||
namespace utils::nt
|
||||
{
|
||||
library library::load(const std::string& name)
|
||||
{
|
||||
return library(LoadLibraryA(name.data()));
|
||||
}
|
||||
|
||||
library library::load(const std::filesystem::path& path)
|
||||
{
|
||||
return library::load(path.generic_string());
|
||||
}
|
||||
|
||||
library library::get_by_address(void* address)
|
||||
{
|
||||
HMODULE handle = nullptr;
|
||||
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, static_cast<LPCSTR>(address), &handle);
|
||||
return library(handle);
|
||||
}
|
||||
|
||||
library::library()
|
||||
{
|
||||
this->module_ = GetModuleHandleA(nullptr);
|
||||
}
|
||||
|
||||
library::library(const std::string& name)
|
||||
{
|
||||
this->module_ = GetModuleHandleA(name.data());
|
||||
}
|
||||
|
||||
library::library(const HMODULE handle)
|
||||
{
|
||||
this->module_ = handle;
|
||||
}
|
||||
|
||||
bool library::operator==(const library& obj) const
|
||||
{
|
||||
return this->module_ == obj.module_;
|
||||
}
|
||||
|
||||
library::operator bool() const
|
||||
{
|
||||
return this->is_valid();
|
||||
}
|
||||
|
||||
library::operator HMODULE() const
|
||||
{
|
||||
return this->get_handle();
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS library::get_nt_headers() const
|
||||
{
|
||||
if (!this->is_valid()) return nullptr;
|
||||
return reinterpret_cast<PIMAGE_NT_HEADERS>(this->get_ptr() + this->get_dos_header()->e_lfanew);
|
||||
}
|
||||
|
||||
PIMAGE_DOS_HEADER library::get_dos_header() const
|
||||
{
|
||||
return reinterpret_cast<PIMAGE_DOS_HEADER>(this->get_ptr());
|
||||
}
|
||||
|
||||
PIMAGE_OPTIONAL_HEADER library::get_optional_header() const
|
||||
{
|
||||
if (!this->is_valid()) return nullptr;
|
||||
return &this->get_nt_headers()->OptionalHeader;
|
||||
}
|
||||
|
||||
std::vector<PIMAGE_SECTION_HEADER> library::get_section_headers() const
|
||||
{
|
||||
std::vector<PIMAGE_SECTION_HEADER> headers;
|
||||
|
||||
auto nt_headers = this->get_nt_headers();
|
||||
auto section = IMAGE_FIRST_SECTION(nt_headers);
|
||||
|
||||
for (uint16_t i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i, ++section)
|
||||
{
|
||||
if (section) headers.push_back(section);
|
||||
else OutputDebugStringA("There was an invalid section :O");
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
std::uint8_t* library::get_ptr() const
|
||||
{
|
||||
return reinterpret_cast<std::uint8_t*>(this->module_);
|
||||
}
|
||||
|
||||
void library::unprotect() const
|
||||
{
|
||||
if (!this->is_valid()) return;
|
||||
|
||||
DWORD protection;
|
||||
VirtualProtect(this->get_ptr(), this->get_optional_header()->SizeOfImage, PAGE_EXECUTE_READWRITE,
|
||||
&protection);
|
||||
}
|
||||
|
||||
size_t library::get_relative_entry_point() const
|
||||
{
|
||||
if (!this->is_valid()) return 0;
|
||||
return this->get_nt_headers()->OptionalHeader.AddressOfEntryPoint;
|
||||
}
|
||||
|
||||
void* library::get_entry_point() const
|
||||
{
|
||||
if (!this->is_valid()) return nullptr;
|
||||
return this->get_ptr() + this->get_relative_entry_point();
|
||||
}
|
||||
|
||||
bool library::is_valid() const
|
||||
{
|
||||
return this->module_ != nullptr && this->get_dos_header()->e_magic == IMAGE_DOS_SIGNATURE;
|
||||
}
|
||||
|
||||
std::string library::get_name() const
|
||||
{
|
||||
if (!this->is_valid()) return "";
|
||||
|
||||
auto path = this->get_path();
|
||||
const auto pos = path.find_last_of("/\\");
|
||||
if (pos == std::string::npos) return path;
|
||||
|
||||
return path.substr(pos + 1);
|
||||
}
|
||||
|
||||
std::string library::get_path() const
|
||||
{
|
||||
if (!this->is_valid()) return "";
|
||||
|
||||
char name[MAX_PATH] = {0};
|
||||
GetModuleFileNameA(this->module_, name, sizeof name);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string library::get_folder() const
|
||||
{
|
||||
if (!this->is_valid()) return "";
|
||||
|
||||
const auto path = std::filesystem::path(this->get_path());
|
||||
return path.parent_path().generic_string();
|
||||
}
|
||||
|
||||
void library::free()
|
||||
{
|
||||
if (this->is_valid())
|
||||
{
|
||||
FreeLibrary(this->module_);
|
||||
this->module_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE library::get_handle() const
|
||||
{
|
||||
return this->module_;
|
||||
}
|
||||
|
||||
void** library::get_iat_entry(const std::string& module_name, const std::string& proc_name) const
|
||||
{
|
||||
if (!this->is_valid()) return nullptr;
|
||||
|
||||
const library other_module(module_name);
|
||||
if (!other_module.is_valid()) return nullptr;
|
||||
|
||||
auto* const target_function = other_module.get_proc<void*>(proc_name);
|
||||
if (!target_function) return nullptr;
|
||||
|
||||
auto* header = this->get_optional_header();
|
||||
if (!header) return nullptr;
|
||||
|
||||
auto* import_descriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(this->get_ptr() + header->DataDirectory
|
||||
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
|
||||
while (import_descriptor->Name)
|
||||
{
|
||||
if (!_stricmp(reinterpret_cast<char*>(this->get_ptr() + import_descriptor->Name), module_name.data()))
|
||||
{
|
||||
auto* original_thunk_data = reinterpret_cast<PIMAGE_THUNK_DATA>(import_descriptor->
|
||||
OriginalFirstThunk + this->get_ptr());
|
||||
auto* thunk_data = reinterpret_cast<PIMAGE_THUNK_DATA>(import_descriptor->FirstThunk + this->
|
||||
get_ptr());
|
||||
|
||||
while (original_thunk_data->u1.AddressOfData)
|
||||
{
|
||||
if(thunk_data->u1.Function == (uint64_t)target_function) {
|
||||
return reinterpret_cast<void**>(&thunk_data->u1.Function);
|
||||
}
|
||||
|
||||
const size_t ordinal_number = original_thunk_data->u1.AddressOfData & 0xFFFFFFF;
|
||||
|
||||
if (ordinal_number <= 0xFFFF) {
|
||||
if (GetProcAddress(other_module.module_, reinterpret_cast<char*>(ordinal_number)) ==
|
||||
target_function)
|
||||
{
|
||||
return reinterpret_cast<void**>(&thunk_data->u1.Function);
|
||||
}
|
||||
}
|
||||
|
||||
++original_thunk_data;
|
||||
++thunk_data;
|
||||
}
|
||||
|
||||
//break;
|
||||
}
|
||||
|
||||
++import_descriptor;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void raise_hard_exception()
|
||||
{
|
||||
int data = false;
|
||||
const library ntdll("ntdll.dll");
|
||||
ntdll.invoke_pascal<void>("RtlAdjustPrivilege", 19, true, false, &data);
|
||||
ntdll.invoke_pascal<void>("NtRaiseHardError", 0xC000007B, 0, nullptr, nullptr, 6, &data);
|
||||
}
|
||||
|
||||
std::string load_resource(const int id)
|
||||
{
|
||||
auto* const res = FindResource(library(), MAKEINTRESOURCE(id), RT_RCDATA);
|
||||
if (!res) return {};
|
||||
|
||||
auto* const handle = LoadResource(nullptr, res);
|
||||
if (!handle) return {};
|
||||
|
||||
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res));
|
||||
}
|
||||
|
||||
void relaunch_self()
|
||||
{
|
||||
const utils::nt::library self;
|
||||
|
||||
STARTUPINFOA startup_info;
|
||||
PROCESS_INFORMATION process_info;
|
||||
|
||||
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||
ZeroMemory(&process_info, sizeof(process_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
|
||||
char current_dir[MAX_PATH];
|
||||
GetCurrentDirectoryA(sizeof(current_dir), current_dir);
|
||||
auto* const command_line = GetCommandLineA();
|
||||
|
||||
CreateProcessA(self.get_path().data(), command_line, nullptr, nullptr, false, NULL, nullptr, current_dir,
|
||||
&startup_info, &process_info);
|
||||
|
||||
if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread);
|
||||
if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess);
|
||||
}
|
||||
|
||||
void terminate(const uint32_t code)
|
||||
{
|
||||
TerminateProcess(GetCurrentProcess(), code);
|
||||
}
|
||||
}
|
110
src/common/utils/nt.hpp
Normal file
110
src/common/utils/nt.hpp
Normal file
@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
// min and max is required by gdi, therefore NOMINMAX won't work
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <filesystem>
|
||||
|
||||
namespace utils::nt
|
||||
{
|
||||
class library final
|
||||
{
|
||||
public:
|
||||
static library load(const std::string& name);
|
||||
static library load(const std::filesystem::path& path);
|
||||
static library get_by_address(void* address);
|
||||
|
||||
library();
|
||||
explicit library(const std::string& name);
|
||||
explicit library(HMODULE handle);
|
||||
|
||||
library(const library& a) : module_(a.module_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator!=(const library& obj) const { return !(*this == obj); };
|
||||
bool operator==(const library& obj) const;
|
||||
|
||||
operator bool() const;
|
||||
operator HMODULE() const;
|
||||
|
||||
void unprotect() const;
|
||||
void* get_entry_point() const;
|
||||
size_t get_relative_entry_point() const;
|
||||
|
||||
bool is_valid() const;
|
||||
std::string get_name() const;
|
||||
std::string get_path() const;
|
||||
std::string get_folder() const;
|
||||
std::uint8_t* get_ptr() const;
|
||||
void free();
|
||||
|
||||
HMODULE get_handle() const;
|
||||
|
||||
template <typename T>
|
||||
T get_proc(const std::string& process) const
|
||||
{
|
||||
if (!this->is_valid()) T{};
|
||||
return reinterpret_cast<T>(GetProcAddress(this->module_, process.data()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::function<T> get(const std::string& process) const
|
||||
{
|
||||
if (!this->is_valid()) return std::function<T>();
|
||||
return static_cast<T*>(this->get_proc<void*>(process));
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T invoke(const std::string& process, Args ... args) const
|
||||
{
|
||||
auto method = this->get<T(__cdecl)(Args ...)>(process);
|
||||
if (method) return method(args...);
|
||||
return T();
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T invoke_pascal(const std::string& process, Args ... args) const
|
||||
{
|
||||
auto method = this->get<T(__stdcall)(Args ...)>(process);
|
||||
if (method) return method(args...);
|
||||
return T();
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T invoke_this(const std::string& process, void* this_ptr, Args ... args) const
|
||||
{
|
||||
auto method = this->get<T(__thiscall)(void*, Args ...)>(this_ptr, process);
|
||||
if (method) return method(args...);
|
||||
return T();
|
||||
}
|
||||
|
||||
std::vector<PIMAGE_SECTION_HEADER> get_section_headers() const;
|
||||
|
||||
PIMAGE_NT_HEADERS get_nt_headers() const;
|
||||
PIMAGE_DOS_HEADER get_dos_header() const;
|
||||
PIMAGE_OPTIONAL_HEADER get_optional_header() const;
|
||||
|
||||
void** get_iat_entry(const std::string& module_name, const std::string& proc_name) const;
|
||||
|
||||
private:
|
||||
HMODULE module_;
|
||||
};
|
||||
|
||||
__declspec(noreturn) void raise_hard_exception();
|
||||
std::string load_resource(int id);
|
||||
|
||||
void relaunch_self();
|
||||
__declspec(noreturn) void terminate(uint32_t code = 0);
|
||||
}
|
212
src/common/utils/signature.cpp
Normal file
212
src/common/utils/signature.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
#include "signature.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
void signature::load_pattern(const std::string& pattern)
|
||||
{
|
||||
this->mask_.clear();
|
||||
this->pattern_.clear();
|
||||
|
||||
uint8_t nibble = 0;
|
||||
auto has_nibble = false;
|
||||
|
||||
for (auto val : pattern)
|
||||
{
|
||||
if (val == ' ') continue;
|
||||
if (val == '?')
|
||||
{
|
||||
this->mask_.push_back(val);
|
||||
this->pattern_.push_back(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((val < '0' || val > '9') && (val < 'A' || val > 'F') && (val < 'a' || val > 'f'))
|
||||
{
|
||||
throw std::runtime_error("Invalid pattern");
|
||||
}
|
||||
|
||||
char str[] = {val, 0};
|
||||
const auto current_nibble = static_cast<uint8_t>(strtol(str, nullptr, 16));
|
||||
|
||||
if (!has_nibble)
|
||||
{
|
||||
has_nibble = true;
|
||||
nibble = current_nibble;
|
||||
}
|
||||
else
|
||||
{
|
||||
has_nibble = false;
|
||||
const uint8_t byte = current_nibble | (nibble << 4);
|
||||
|
||||
this->mask_.push_back('x');
|
||||
this->pattern_.push_back(byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!this->mask_.empty() && this->mask_.back() == '?')
|
||||
{
|
||||
this->mask_.pop_back();
|
||||
this->pattern_.pop_back();
|
||||
}
|
||||
|
||||
if (this->has_sse_support())
|
||||
{
|
||||
while (this->pattern_.size() < 16)
|
||||
{
|
||||
this->pattern_.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_nibble)
|
||||
{
|
||||
throw std::runtime_error("Invalid pattern");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<size_t> signature::process_range(uint8_t* start, const size_t length) const
|
||||
{
|
||||
if (this->has_sse_support()) return this->process_range_vectorized(start, length);
|
||||
return this->process_range_linear(start, length);
|
||||
}
|
||||
|
||||
std::vector<size_t> signature::process_range_linear(uint8_t* start, const size_t length) const
|
||||
{
|
||||
std::vector<size_t> result;
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
const auto address = start + i;
|
||||
|
||||
size_t j = 0;
|
||||
for (; j < this->mask_.size(); ++j)
|
||||
{
|
||||
if (this->mask_[j] != '?' && this->pattern_[j] != address[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == this->mask_.size())
|
||||
{
|
||||
result.push_back(size_t(address));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<size_t> signature::process_range_vectorized(uint8_t* start, const size_t length) const
|
||||
{
|
||||
std::vector<size_t> result;
|
||||
__declspec(align(16)) char desired_mask[16] = {0};
|
||||
|
||||
for (size_t i = 0; i < this->mask_.size(); i++)
|
||||
{
|
||||
desired_mask[i / 8] |= (this->mask_[i] == '?' ? 0 : 1) << i % 8;
|
||||
}
|
||||
|
||||
const auto mask = _mm_load_si128(reinterpret_cast<const __m128i*>(desired_mask));
|
||||
const auto comparand = _mm_loadu_si128(reinterpret_cast<const __m128i*>(this->pattern_.data()));
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
const auto address = start + i;
|
||||
const auto value = _mm_loadu_si128(reinterpret_cast<const __m128i*>(address));
|
||||
const auto comparison = _mm_cmpestrm(value, 16, comparand, static_cast<int>(this->mask_.size()),
|
||||
_SIDD_CMP_EQUAL_EACH);
|
||||
|
||||
const auto matches = _mm_and_si128(mask, comparison);
|
||||
const auto equivalence = _mm_xor_si128(mask, matches);
|
||||
|
||||
if (_mm_test_all_zeros(equivalence, equivalence))
|
||||
{
|
||||
result.push_back(size_t(address));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
signature::signature_result signature::process() const
|
||||
{
|
||||
const auto range = this->length_ - this->mask_.size();
|
||||
const auto cores = std::max(1u, std::thread::hardware_concurrency());
|
||||
|
||||
if (range <= cores * 10ull) return this->process_serial();
|
||||
return this->process_parallel();
|
||||
}
|
||||
|
||||
signature::signature_result signature::process_serial() const
|
||||
{
|
||||
const auto sub = this->has_sse_support() ? 16 : this->mask_.size();
|
||||
return {this->process_range(this->start_, this->length_ - sub)};
|
||||
}
|
||||
|
||||
signature::signature_result signature::process_parallel() const
|
||||
{
|
||||
const auto sub = this->has_sse_support() ? 16 : this->mask_.size();
|
||||
const auto range = this->length_ - sub;
|
||||
const auto cores = std::max(1u, std::thread::hardware_concurrency() / 2);
|
||||
// Only use half of the available cores
|
||||
const auto grid = range / cores;
|
||||
|
||||
std::mutex mutex;
|
||||
std::vector<size_t> result;
|
||||
std::vector<std::thread> threads;
|
||||
|
||||
for (auto i = 0u; i < cores; ++i)
|
||||
{
|
||||
const auto start = this->start_ + (grid * i);
|
||||
const auto length = (i + 1 == cores) ? (this->start_ + this->length_ - sub) - start : grid;
|
||||
threads.emplace_back([&, start, length]()
|
||||
{
|
||||
auto local_result = this->process_range(start, length);
|
||||
if (local_result.empty()) return;
|
||||
|
||||
std::lock_guard _(mutex);
|
||||
for (const auto& address : local_result)
|
||||
{
|
||||
result.push_back(address);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (auto& t : threads)
|
||||
{
|
||||
if (t.joinable())
|
||||
{
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(result.begin(), result.end());
|
||||
return {std::move(result)};
|
||||
}
|
||||
|
||||
bool signature::has_sse_support() const
|
||||
{
|
||||
if (this->mask_.size() <= 16)
|
||||
{
|
||||
int cpu_id[4];
|
||||
__cpuid(cpu_id, 0);
|
||||
|
||||
if (cpu_id[0] >= 1)
|
||||
{
|
||||
__cpuidex(cpu_id, 1, 0);
|
||||
return (cpu_id[2] & (1 << 20)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
utils::hook::signature::signature_result operator"" _sig(const char* str, const size_t len)
|
||||
{
|
||||
return utils::hook::signature(std::string(str, len)).process();
|
||||
}
|
73
src/common/utils/signature.hpp
Normal file
73
src/common/utils/signature.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
#include "nt.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
class signature final
|
||||
{
|
||||
public:
|
||||
class signature_result
|
||||
{
|
||||
public:
|
||||
signature_result(std::vector<size_t>&& matches) : matches_(std::move(matches))
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] uint8_t* get(const size_t index) const
|
||||
{
|
||||
if (index >= this->count())
|
||||
{
|
||||
throw std::runtime_error("Invalid index");
|
||||
}
|
||||
|
||||
return reinterpret_cast<uint8_t*>(this->matches_[index]);
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t count() const
|
||||
{
|
||||
return this->matches_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<size_t> matches_;
|
||||
};
|
||||
|
||||
explicit signature(const std::string& pattern, const nt::library library = {})
|
||||
: signature(pattern, library.get_ptr(), library.get_optional_header()->SizeOfImage)
|
||||
{
|
||||
}
|
||||
|
||||
signature(const std::string& pattern, void* start, void* end)
|
||||
: signature(pattern, start, size_t(end) - size_t(start))
|
||||
{
|
||||
}
|
||||
|
||||
signature(const std::string& pattern, void* start, const size_t length)
|
||||
: start_(static_cast<uint8_t*>(start)), length_(length)
|
||||
{
|
||||
this->load_pattern(pattern);
|
||||
}
|
||||
|
||||
signature_result process() const;
|
||||
|
||||
private:
|
||||
std::string mask_;
|
||||
std::basic_string<uint8_t> pattern_;
|
||||
|
||||
uint8_t* start_;
|
||||
size_t length_;
|
||||
|
||||
void load_pattern(const std::string& pattern);
|
||||
|
||||
signature_result process_parallel() const;
|
||||
signature_result process_serial() const;
|
||||
std::vector<size_t> process_range(uint8_t* start, size_t length) const;
|
||||
std::vector<size_t> process_range_linear(uint8_t* start, size_t length) const;
|
||||
std::vector<size_t> process_range_vectorized(uint8_t* start, size_t length) const;
|
||||
|
||||
bool has_sse_support() const;
|
||||
};
|
||||
}
|
||||
|
||||
utils::hook::signature::signature_result operator"" _sig(const char* str, size_t len);
|
94
src/common/utils/smbios.cpp
Normal file
94
src/common/utils/smbios.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "smbios.hpp"
|
||||
#include "memory.hpp"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <intrin.h>
|
||||
|
||||
namespace utils::smbios
|
||||
{
|
||||
namespace
|
||||
{
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
struct RawSMBIOSData
|
||||
{
|
||||
BYTE Used20CallingMethod;
|
||||
BYTE SMBIOSMajorVersion;
|
||||
BYTE SMBIOSMinorVersion;
|
||||
BYTE DmiRevision;
|
||||
DWORD Length;
|
||||
BYTE SMBIOSTableData[];
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE type;
|
||||
BYTE length;
|
||||
WORD handle;
|
||||
} dmi_header;
|
||||
#pragma warning(pop)
|
||||
|
||||
std::vector<uint8_t> get_smbios_data()
|
||||
{
|
||||
DWORD size = 0;
|
||||
std::vector<uint8_t> data{};
|
||||
|
||||
size = GetSystemFirmwareTable('RSMB', 0, nullptr, size);
|
||||
data.resize(size);
|
||||
GetSystemFirmwareTable('RSMB', 0, data.data(), size);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string parse_uuid(const uint8_t* data)
|
||||
{
|
||||
if (utils::memory::is_set(data, 0, 16) || utils::memory::is_set(data, -1, 16))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
char uuid[16] = {0};
|
||||
*reinterpret_cast<unsigned long*>(uuid + 0) =
|
||||
_byteswap_ulong(*reinterpret_cast<const unsigned long*>(data + 0));
|
||||
*reinterpret_cast<unsigned short*>(uuid + 4) =
|
||||
_byteswap_ushort(*reinterpret_cast<const unsigned short*>(data + 4));
|
||||
*reinterpret_cast<unsigned short*>(uuid + 6) =
|
||||
_byteswap_ushort(*reinterpret_cast<const unsigned short*>(data + 6));
|
||||
memcpy(uuid + 8, data + 8, 8);
|
||||
|
||||
return std::string(uuid, sizeof(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_uuid()
|
||||
{
|
||||
auto smbios_data = get_smbios_data();
|
||||
auto* raw_data = reinterpret_cast<RawSMBIOSData*>(smbios_data.data());
|
||||
|
||||
auto* data = raw_data->SMBIOSTableData;
|
||||
for (DWORD i = 0; i + sizeof(dmi_header) < raw_data->Length;)
|
||||
{
|
||||
auto* header = reinterpret_cast<dmi_header*>(data + i);
|
||||
if (header->length < 4)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (header->type == 0x01 && header->length >= 0x19)
|
||||
{
|
||||
return parse_uuid(data + i + 0x8);
|
||||
}
|
||||
|
||||
i += header->length;
|
||||
while ((i + 1) < raw_data->Length && *reinterpret_cast<uint16_t*>(data + i) != 0)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
i += 2;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
8
src/common/utils/smbios.hpp
Normal file
8
src/common/utils/smbios.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils::smbios
|
||||
{
|
||||
std::string get_uuid();
|
||||
}
|
179
src/common/utils/string.cpp
Normal file
179
src/common/utils/string.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#include "string.hpp"
|
||||
#include <sstream>
|
||||
#include <cstdarg>
|
||||
#include <algorithm>
|
||||
|
||||
#include "nt.hpp"
|
||||
|
||||
namespace utils::string
|
||||
{
|
||||
const char* va(const char* fmt, ...)
|
||||
{
|
||||
static thread_local va_provider<8, 256> provider;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
const char* result = provider.get(fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> split(const std::string& s, const char delim)
|
||||
{
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
std::vector<std::string> elems;
|
||||
|
||||
while (std::getline(ss, item, delim))
|
||||
{
|
||||
elems.push_back(item); // elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson)
|
||||
}
|
||||
|
||||
return elems;
|
||||
}
|
||||
|
||||
std::string to_lower(std::string text)
|
||||
{
|
||||
std::transform(text.begin(), text.end(), text.begin(), [](const char input)
|
||||
{
|
||||
return static_cast<char>(tolower(input));
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
std::string to_upper(std::string text)
|
||||
{
|
||||
std::transform(text.begin(), text.end(), text.begin(), [](const char input)
|
||||
{
|
||||
return static_cast<char>(toupper(input));
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
bool starts_with(const std::string& text, const std::string& substring)
|
||||
{
|
||||
return text.find(substring) == 0;
|
||||
}
|
||||
|
||||
bool ends_with(const std::string& text, const std::string& substring)
|
||||
{
|
||||
if (substring.size() > text.size()) return false;
|
||||
return std::equal(substring.rbegin(), substring.rend(), text.rbegin());
|
||||
}
|
||||
|
||||
std::string dump_hex(const std::string& data, const std::string& separator)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
for (unsigned int i = 0; i < data.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
result.append(separator);
|
||||
}
|
||||
|
||||
result.append(va("%02X", data[i] & 0xFF));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string get_clipboard_data()
|
||||
{
|
||||
if (OpenClipboard(nullptr))
|
||||
{
|
||||
std::string data;
|
||||
|
||||
auto* const clipboard_data = GetClipboardData(1u);
|
||||
if (clipboard_data)
|
||||
{
|
||||
auto* const cliptext = static_cast<char*>(GlobalLock(clipboard_data));
|
||||
if (cliptext)
|
||||
{
|
||||
data.append(cliptext);
|
||||
GlobalUnlock(clipboard_data);
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
|
||||
return data;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void strip(const char* in, char* out, int max)
|
||||
{
|
||||
if (!in || !out) return;
|
||||
|
||||
max--;
|
||||
auto current = 0;
|
||||
while (*in != 0 && current < max)
|
||||
{
|
||||
const auto color_index = (*(in + 1) - 48) >= 0xC ? 7 : (*(in + 1) - 48);
|
||||
|
||||
if (*in == '^' && (color_index != 7 || *(in + 1) == '7'))
|
||||
{
|
||||
++in;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out = *in;
|
||||
++out;
|
||||
++current;
|
||||
}
|
||||
|
||||
++in;
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4100)
|
||||
std::string convert(const std::wstring& wstr)
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(wstr.size());
|
||||
|
||||
for (const auto& chr : wstr)
|
||||
{
|
||||
result.push_back(static_cast<char>(chr));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring convert(const std::string& str)
|
||||
{
|
||||
std::wstring result;
|
||||
result.reserve(str.size());
|
||||
|
||||
for (const auto& chr : str)
|
||||
{
|
||||
result.push_back(static_cast<wchar_t>(chr));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
std::string replace(std::string str, const std::string& from, const std::string& to)
|
||||
{
|
||||
if (from.empty())
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length();
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
100
src/common/utils/string.hpp
Normal file
100
src/common/utils/string.hpp
Normal file
@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
#include "memory.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
template <class Type, size_t n>
|
||||
size_t ARRAYSIZE(Type (&)[n]) { return n; }
|
||||
#endif
|
||||
|
||||
namespace utils::string
|
||||
{
|
||||
template <size_t Buffers, size_t MinBufferSize>
|
||||
class va_provider final
|
||||
{
|
||||
public:
|
||||
static_assert(Buffers != 0 && MinBufferSize != 0, "Buffers and MinBufferSize mustn't be 0");
|
||||
|
||||
va_provider() : current_buffer_(0)
|
||||
{
|
||||
}
|
||||
|
||||
char* get(const char* format, const va_list ap)
|
||||
{
|
||||
++this->current_buffer_ %= ARRAYSIZE(this->string_pool_);
|
||||
auto entry = &this->string_pool_[this->current_buffer_];
|
||||
|
||||
if (!entry->size || !entry->buffer)
|
||||
{
|
||||
throw std::runtime_error("String pool not initialized");
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
const int res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap);
|
||||
if (res > 0) break; // Success
|
||||
if (res == 0) return nullptr; // Error
|
||||
|
||||
entry->double_size();
|
||||
}
|
||||
|
||||
return entry->buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
class entry final
|
||||
{
|
||||
public:
|
||||
explicit entry(const size_t _size = MinBufferSize) : size(_size), buffer(nullptr)
|
||||
{
|
||||
if (this->size < MinBufferSize) this->size = MinBufferSize;
|
||||
this->allocate();
|
||||
}
|
||||
|
||||
~entry()
|
||||
{
|
||||
if (this->buffer) memory::get_allocator()->free(this->buffer);
|
||||
this->size = 0;
|
||||
this->buffer = nullptr;
|
||||
}
|
||||
|
||||
void allocate()
|
||||
{
|
||||
if (this->buffer) memory::get_allocator()->free(this->buffer);
|
||||
this->buffer = memory::get_allocator()->allocate_array<char>(this->size + 1);
|
||||
}
|
||||
|
||||
void double_size()
|
||||
{
|
||||
this->size *= 2;
|
||||
this->allocate();
|
||||
}
|
||||
|
||||
size_t size;
|
||||
char* buffer;
|
||||
};
|
||||
|
||||
size_t current_buffer_;
|
||||
entry string_pool_[Buffers];
|
||||
};
|
||||
|
||||
const char* va(const char* fmt, ...);
|
||||
|
||||
std::vector<std::string> split(const std::string& s, char delim);
|
||||
|
||||
std::string to_lower(std::string text);
|
||||
std::string to_upper(std::string text);
|
||||
bool starts_with(const std::string& text, const std::string& substring);
|
||||
bool ends_with(const std::string& text, const std::string& substring);
|
||||
|
||||
std::string dump_hex(const std::string& data, const std::string& separator = " ");
|
||||
|
||||
std::string get_clipboard_data();
|
||||
|
||||
void strip(const char* in, char* out, int max);
|
||||
|
||||
std::string convert(const std::wstring& wstr);
|
||||
std::wstring convert(const std::string& str);
|
||||
|
||||
std::string replace(std::string str, const std::string& from, const std::string& to);
|
||||
}
|
127
src/common/utils/thread.cpp
Normal file
127
src/common/utils/thread.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
#include "thread.hpp"
|
||||
#include "string.hpp"
|
||||
#include "finally.hpp"
|
||||
|
||||
#include <TlHelp32.h>
|
||||
|
||||
namespace utils::thread
|
||||
{
|
||||
bool set_name(const HANDLE t, const std::string& name)
|
||||
{
|
||||
const nt::library kernel32("kernel32.dll");
|
||||
if (!kernel32)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto set_description = kernel32.get_proc<HRESULT(WINAPI *)(HANDLE, PCWSTR)>("SetThreadDescription");
|
||||
if (!set_description)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SUCCEEDED(set_description(t, string::convert(name).data()));
|
||||
}
|
||||
|
||||
bool set_name(const DWORD id, const std::string& name)
|
||||
{
|
||||
auto* const t = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, id);
|
||||
if (!t) return false;
|
||||
|
||||
const auto _ = utils::finally([t]()
|
||||
{
|
||||
CloseHandle(t);
|
||||
});
|
||||
|
||||
return set_name(t, name);
|
||||
}
|
||||
|
||||
bool set_name(std::thread& t, const std::string& name)
|
||||
{
|
||||
return set_name(t.native_handle(), name);
|
||||
}
|
||||
|
||||
bool set_name(const std::string& name)
|
||||
{
|
||||
return set_name(GetCurrentThread(), name);
|
||||
}
|
||||
|
||||
std::vector<DWORD> get_thread_ids()
|
||||
{
|
||||
auto* const h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto _ = utils::finally([h]()
|
||||
{
|
||||
CloseHandle(h);
|
||||
});
|
||||
|
||||
THREADENTRY32 entry{};
|
||||
entry.dwSize = sizeof(entry);
|
||||
if (!Thread32First(h, &entry))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<DWORD> ids{};
|
||||
|
||||
do
|
||||
{
|
||||
const auto check_size = entry.dwSize < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID)
|
||||
+ sizeof(entry.th32OwnerProcessID);
|
||||
entry.dwSize = sizeof(entry);
|
||||
|
||||
if (check_size && entry.th32OwnerProcessID == GetCurrentProcessId())
|
||||
{
|
||||
ids.emplace_back(entry.th32ThreadID);
|
||||
}
|
||||
}
|
||||
while (Thread32Next(h, &entry));
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
void for_each_thread(const std::function<void(HANDLE)>& callback)
|
||||
{
|
||||
const auto ids = get_thread_ids();
|
||||
|
||||
for (const auto& id : ids)
|
||||
{
|
||||
auto* const thread = OpenThread(THREAD_ALL_ACCESS, FALSE, id);
|
||||
if (thread != nullptr)
|
||||
{
|
||||
const auto _ = utils::finally([thread]()
|
||||
{
|
||||
CloseHandle(thread);
|
||||
});
|
||||
|
||||
callback(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void suspend_other_threads()
|
||||
{
|
||||
for_each_thread([](const HANDLE thread)
|
||||
{
|
||||
if (GetThreadId(thread) != GetCurrentThreadId())
|
||||
{
|
||||
SuspendThread(thread);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void resume_other_threads()
|
||||
{
|
||||
for_each_thread([](const HANDLE thread)
|
||||
{
|
||||
if (GetThreadId(thread) != GetCurrentThreadId())
|
||||
{
|
||||
ResumeThread(thread);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
25
src/common/utils/thread.hpp
Normal file
25
src/common/utils/thread.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include "nt.hpp"
|
||||
|
||||
namespace utils::thread
|
||||
{
|
||||
bool set_name(HANDLE t, const std::string& name);
|
||||
bool set_name(DWORD id, const std::string& name);
|
||||
bool set_name(std::thread& t, const std::string& name);
|
||||
bool set_name(const std::string& name);
|
||||
|
||||
template <typename ...Args>
|
||||
std::thread create_named_thread(const std::string& name, Args&&... args)
|
||||
{
|
||||
auto t = std::thread(std::forward<Args>(args)...);
|
||||
set_name(t, name);
|
||||
return t;
|
||||
}
|
||||
|
||||
std::vector<DWORD> get_thread_ids();
|
||||
void for_each_thread(const std::function<void(HANDLE)>& callback);
|
||||
|
||||
void suspend_other_threads();
|
||||
void resume_other_threads();
|
||||
}
|
BIN
tools/premake5.exe
Normal file
BIN
tools/premake5.exe
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user