Compare commits

...

17 commits

Author SHA1 Message Date
Allusive
9ddf557948
Default compile constants to 0 if not defined (#932)
Some checks failed
CI / format-check (push) Failing after 3s
CI / nix-build (push) Failing after 3s
CI / format-check-cmake-files (push) Failing after 2s
Merge Conflict Auto Label / triage (push) Failing after 1s
CI / build (map[cc:cl name:MSVC]) (push) Has been cancelled
CI / build (map[cc:clang-cl name:LLVM]) (push) Has been cancelled
* default ifdef constants to 0

---------

Co-authored-by: Will <39478251+sonny-tel@users.noreply.github.com> 
Co-authored-by: Will <39478251+VITALISED@users.noreply.github.com>
2026-08-20 22:33:16 -04:00
cat_or_not
2c16ed3605
Hardcode cardinals of all exports in wsock32 (#931)
* fix version eval in flake

* Move `core/convar/` to `tier1/` 2 (#928)

* just hard code everything in wsock32 def
2026-08-12 22:30:00 -04:00
cat_or_not
0d0cf3e79f
fix version eval in flake (#929) 2026-08-12 22:09:18 -04:00
cat_or_not
e85910e9ac
Move core/convar/ to tier1/ 2 (#928) 2026-08-08 04:26:00 -04:00
cat_or_not
edbd89f636
Patch idlekick (#927)
* patch idlekick

* remove empty header
2026-08-06 03:18:04 -04:00
pg9182
4df8857814
Fix remove_server (#894)
* Fix remove_server

* me lazy
2026-08-04 23:49:49 -04:00
LightBlueCube
329e8f667f
-noshaderapi and -nowindow (#926)
* -noshaderapi

* fmt

---------

Co-authored-by: catornot <41955154+catornot@users.noreply.github.com>
2026-08-04 23:38:03 -04:00
HuiZhiYin
48f3560077
Add callback for client chat messages (#920) 2026-07-02 21:24:10 -04:00
Allusive
9430cef240
Allows for custom gamemode text for ffa rui (#924)
* add the ability to replace the ffa text in for custom gamemodes

* fmt

* maybe make it work for clang

* fmt

* forgot this

* more stuff

* Delete clang-format.exe

* give vars good names
2026-06-02 16:31:38 -04:00
Jack
f05943806f
Fix weapon_reparse not invalidating compiled weapon files (#922)
* fix weapon_reparse not invalidating compiled weapon files

* remove unused include
2026-06-02 18:48:19 +01:00
cat_or_not
47f0fa43b6
Cache nix builds on main (#921)
* cache nix artifacts to cache server instead of uploading them

* Revert "cache nix artifacts to cache server instead of uploading them"

This reverts commit d9ffaeda92.

* Revert "Revert "cache nix artifacts to cache server instead of uploading them""

This reverts commit 707b416535.

* only run on main

the motivation for this is to not completly fill my cache server instantly (which only has 15gb)

* push the store path instead of the result path
2026-06-01 19:18:06 -04:00
Rémy Raes
0075d671d1 build(ci): use actions/checkout@v4 in release workflow 2026-05-23 15:29:38 +02:00
FourthVolt
fad19af919
Various materialsystem things (#919)
* various materialsystem things

* Update nscustomdxbuffer.cpp

formatter maybe

* Update nscustomdxbuffer.cpp

Buy minecraft

* move comment

move comment

* Update nscustomdxbuffer.cpp

* more slots slots go brrrt

more slots slots go brrrt
2026-05-18 20:17:06 +01:00
Allusive
39d5570c76
Make pakLoadApi global (#918)
* make pakLoadApi global

* fmt

---------

Co-authored-by: catornot <41955154+catornot@users.noreply.github.com>
2026-05-09 20:30:55 -04:00
Jack
64a7735c57
Don't include the various libcurl test build targets (#916)
* Don't add all of the libcurl testing build targets
2026-05-07 00:07:50 +02:00
cat_or_not
8d19272b65
Pin clang version to 16 for formatting in the flake (#911)
* Add older nixpkgs for clang-format-16
2026-05-06 22:59:04 +02:00
HuiZhiYin
0d746273a7
Block empty chat messages (#915)
* Block empty chat messages
2026-05-06 22:00:44 +02:00
65 changed files with 1120 additions and 248 deletions

View file

@ -96,17 +96,12 @@ jobs:
- name: Build
run: nix build
- name: Extract Short Commit Hash
id: extract
shell: bash
run: echo commit=$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
- name: Upload Build Artifact
uses: actions/upload-artifact@v4
with:
name: NorthstarLauncher-NIX-${{ steps.extract.outputs.commit }}
path: |
result/
- name: Cache this Build
continue-on-error: true
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run: |
nix run nixpkgs#attic-client -- login northstar https://attic.catornot.net ${{ secrets.ATTIC_CACHE_TOKEN }}
nix run nixpkgs#attic-client -- push northstar $(nix build --print-out-paths)
format-check-cmake-files:
runs-on: ubuntu-latest

View file

@ -15,7 +15,7 @@ jobs:
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Setup msvc

View file

@ -9,7 +9,14 @@
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ]
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": [
{
"name": "BUILD_TESTING",
"value": "False",
"type": "BOOL"
}
]
},
{
"name": "x64-RelWithDebInfo",
@ -20,7 +27,14 @@
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": ""
"ctestCommandArgs": "",
"variables": [
{
"name": "BUILD_TESTING",
"value": "False",
"type": "BOOL"
}
]
},
{
"name": "x64-Debug",
@ -32,7 +46,13 @@
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": []
"variables": [
{
"name": "BUILD_TESTING",
"value": "False",
"type": "BOOL"
}
]
}
]
}
}

17
flake.lock generated
View file

@ -34,6 +34,22 @@
"type": "github"
}
},
"nixpkgs-24-11": {
"locked": {
"lastModified": 1731603435,
"narHash": "sha256-CqCX4JG7UiHvkrBTpYC3wcEurvbtTADLbo3Ns2CEoL8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8b27c1239e5c421a2bbc2c65d52e4a6fbf2ff296",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1770107345,
@ -54,6 +70,7 @@
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"nixpkgs-24-11": "nixpkgs-24-11",
"treefmt-nix": "treefmt-nix"
}
},

View file

@ -4,6 +4,8 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-24-11.url = "github:NixOS/nixpkgs/24.11"; # needed for clang-format-16
flake-utils.url = "github:numtide/flake-utils";
treefmt-nix.url = "github:numtide/treefmt-nix";
@ -15,6 +17,7 @@
{
self,
nixpkgs,
nixpkgs-24-11,
flake-utils,
treefmt-nix,
}:
@ -135,14 +138,20 @@
# settings
settings.formatter.clang-format = {
args = [
package = nixpkgs-24-11.legacyPackages.${system}.llvmPackages_16.clang-tools;
command = "${nixpkgs-24-11.legacyPackages.${system}.llvmPackages_16.clang-tools}/bin/clang-format";
options = [
"-i"
"--style=file"
];
excludes = [
"primedev/include/**"
"primedev/*.cpp"
"primedev/*.h"
"primedev/thirdparty/**"
"primedev/wsockproxy/**"
"primedev/dllmain.cpp"
"primedev/ns_version.h"
"primedev/pch.h"
"primedev/resource1.h"
];
};
}
@ -203,7 +212,7 @@
versionQuadruplet = "${versionAt 0},${versionAt 1},${versionAt 2},${
if isDev then
"1"
else if builtins.length > 3 then
else if builtins.length versionSeq > 3 then
versionAt 3
else
"0"

View file

@ -28,12 +28,12 @@ add_library(
"client/rejectconnectionfixes.cpp"
"config/profile.cpp"
"config/profile.h"
"core/convar/concommand.cpp"
"core/convar/concommand.h"
"core/convar/convar.cpp"
"core/convar/convar.h"
"core/convar/cvar.cpp"
"core/convar/cvar.h"
"tier1/cmd.cpp"
"tier1/cmd.h"
"tier1/convar.cpp"
"tier1/convar.h"
"tier1/cvar.cpp"
"tier1/cvar.h"
"core/filesystem/filesystem.cpp"
"core/filesystem/filesystem.h"
"core/filesystem/rpakfilesystem.cpp"
@ -139,6 +139,7 @@ add_library(
"server/servernethooks.cpp"
"server/serverpresence.cpp"
"server/serverpresence.h"
"server/idlekick.cpp"
"shared/exploit_fixes/exploitfixes.cpp"
"shared/exploit_fixes/exploitfixes_lzss.cpp"
"shared/exploit_fixes/exploitfixes_utf8parser.cpp"
@ -152,6 +153,7 @@ add_library(
"shared/misccommands.h"
"shared/playlist.cpp"
"shared/playlist.h"
"shared/weapon_reparse.cpp"
"squirrel/squirrel.cpp"
"squirrel/squirrel.h"
"squirrel/squirrelautobind.cpp"
@ -159,6 +161,8 @@ add_library(
"squirrel/squirrelclasstypes.h"
"rtech/pakfile.h"
"rtech/pakfile.cpp"
"rtech/rui.h"
"rtech/rui.cpp"
"util/printcommands.cpp"
"util/printcommands.h"
"util/printmaps.cpp"

View file

@ -1,6 +1,6 @@
#include "audio.h"
#include "dedicated/dedicated.h"
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "rapidjson/error/en.h"
#include <fstream>

View file

@ -1,21 +1,42 @@
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
#include "localchatwriter.h"
#include "squirrel/squirrel.h"
// note: isIngameChat is an int64 because the whole register the arg is stored in needs to be 0'd out to work
// if isIngameChat is false, we use network chat instead
void(__fastcall* ClientSayText)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat);
static void(__fastcall* o_ClientSayText)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat) = nullptr;
static void __fastcall h_ClientSayText(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat)
{
SQRESULT result = g_pSquirrel[ScriptContext::CLIENT]->Call("NS_PreSendMessage", message, (bool)isIngameChat, (bool)isTeamChat);
if (result == SQRESULT_ERROR)
{
o_ClientSayText(a1, message, isIngameChat, isTeamChat);
}
}
ADD_SQFUNC("void", NSSendMessage, "string message, bool isIngame, bool isTeam", "", ScriptContext::CLIENT)
{
const char* message = g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 1);
bool isIngame = g_pSquirrel[ScriptContext::CLIENT]->getbool(sqvm, 2);
bool isTeam = g_pSquirrel[ScriptContext::CLIENT]->getbool(sqvm, 3);
o_ClientSayText(nullptr, message, isIngame, isTeam);
return SQRESULT_NULL;
}
void ConCommand_say(const CCommand& args)
{
if (args.ArgC() >= 2)
ClientSayText(nullptr, args.ArgS(), true, false);
o_ClientSayText(nullptr, args.ArgS(), true, false);
}
void ConCommand_say_team(const CCommand& args)
{
if (args.ArgC() >= 2)
ClientSayText(nullptr, args.ArgS(), true, true);
o_ClientSayText(nullptr, args.ArgS(), true, true);
}
void ConCommand_log(const CCommand& args)
@ -28,8 +49,9 @@ void ConCommand_log(const CCommand& args)
ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientChatCommand, ConCommand, (CModule module))
{
ClientSayText =
o_ClientSayText =
module.Offset(0x54780).RCast<void(__fastcall*)(void* a1, const char* message, uint64_t isIngameChat, bool isTeamChat)>();
HookAttach(&(PVOID&)o_ClientSayText, (PVOID)h_ClientSayText);
RegisterConCommand("say", ConCommand_say, "Enters a message in public chat", FCVAR_CLIENTDLL);
RegisterConCommand("say_team", ConCommand_say_team, "Enters a message in team chat", FCVAR_CLIENTDLL);
RegisterConCommand("log", ConCommand_log, "Log a message to the local chat window", FCVAR_CLIENTDLL);

View file

@ -1,5 +1,5 @@
#include "masterserver/masterserver.h"
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "client/r2client.h"
#include "core/vanilla.h"

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
ConVar* Cvar_rui_drawEnable;

View file

@ -1,7 +1,7 @@
#include "debugoverlay.h"
#include "dedicated/dedicated.h"
#include "core/convar/cvar.h"
#include "tier1/cvar.h"
#include "core/math/vector.h"
#include "server/ai_helper.h"

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
ON_DLL_LOAD_CLIENT("engine.dll", EngineDemoFixes, (CModule module))
{

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
ConVar* Cvar_r_latencyflex;

View file

@ -5,47 +5,6 @@
#include "util/utils.h"
#include "rtech/pakfile.h"
#pragma pack(push, 1)
struct PakLoadFuncs
{
void (*InitRpakSystem)();
void (*AddAssetLoaderWithJobDetails)(/*assetTypeHeader*/ void*, uint32_t, int);
void (*AddAssetLoader)(/*assetTypeHeader*/ void*);
PakHandle (*LoadRpakFileAsync)(const char* pPath, void* allocator, int flags);
void (*LoadRpakFile)(const char*, __int64(__fastcall*)(), __int64, void(__cdecl*)());
__int64 qword28;
void (*UnloadPak)(PakHandle iPakHandle, void* callback);
__int64 qword38;
__int64 qword40;
__int64 qword48;
__int64 qword50;
FARPROC (*GetDllCallback)(__int16 a1, const CHAR* a2);
__int64 (*GetAssetByHash)(__int64 hash);
__int64 (*GetAssetByName)(const char* a1);
__int64 qword70;
__int64 qword78;
__int64 qword80;
__int64 qword88;
__int64 qword90;
__int64 qword98;
__int64 qwordA0;
__int64 qwordA8;
__int64 qwordB0;
__int64 qwordBB;
void* (*OpenFile)(const char* pPath);
__int64 CloseFile;
__int64 qwordD0;
__int64 FileReadAsync;
__int64 ComplexFileReadAsync;
__int64 GetReadJobState;
__int64 WaitForFileReadJobComplete;
__int64 CancelFileReadJob;
__int64 CancelFileReadJobAsync;
__int64 qword108;
};
static_assert(sizeof(PakLoadFuncs) == 0x110);
#pragma pack(pop)
PakLoadFuncs* g_pakLoadApi;
PakLoadManager* g_pPakLoadManager;

View file

@ -3,6 +3,49 @@
#include <regex>
#include "rtech/pakfile.h"
#pragma pack(push, 1)
struct PakLoadFuncs
{
void (*InitRpakSystem)();
void (*AddAssetLoaderWithJobDetails)(/*assetTypeHeader*/ void*, uint32_t, int);
void (*AddAssetLoader)(/*assetTypeHeader*/ void*);
PakHandle (*LoadRpakFileAsync)(const char* pPath, void* allocator, int flags);
void (*LoadRpakFile)(const char*, __int64(__fastcall*)(), __int64, void(__cdecl*)());
__int64 qword28;
void (*UnloadPak)(PakHandle iPakHandle, void* callback);
__int64 qword38;
__int64 qword40;
__int64 qword48;
__int64 qword50;
FARPROC (*GetDllCallback)(__int16 a1, const CHAR* a2);
__int64 (*GetAssetByHash)(__int64 hash);
__int64 (*GetAssetByName)(const char* a1);
__int64 qword70;
__int64 qword78;
__int64 qword80;
__int64 qword88;
__int64 qword90;
__int64 qword98;
__int64 qwordA0;
__int64 qwordA8;
__int64 qwordB0;
__int64 qwordBB;
void* (*OpenFile)(const char* pPath);
__int64 CloseFile;
__int64 qwordD0;
__int64 FileReadAsync;
__int64 ComplexFileReadAsync;
__int64 GetReadJobState;
__int64 WaitForFileReadJobComplete;
__int64 CancelFileReadJob;
__int64 CancelFileReadJobAsync;
__int64 qword108;
};
static_assert(sizeof(PakLoadFuncs) == 0x110);
#pragma pack(pop)
extern PakLoadFuncs* g_pakLoadApi;
struct ModPak_t
{
std::string m_modName;

View file

@ -150,6 +150,28 @@ ON_DLL_LOAD_DEDI_RELIESON("engine.dll", DedicatedServer, ServerPresence, (CModul
// nop the call to it
module.Offset(0x156A63).NOP(5);
if (CommandLine()->CheckParm("-noshaderapi"))
{
// Likely CL_ClearState: clears the client map/model state.
// Preserve all software-side cleanup, but skip the render-context reset and release because the null MaterialSystem has no context.
module.Offset(0x72B9A).NOP(9);
module.Offset(0x72BCE).NOP(6);
module.Offset(0x72BDC).Patch("C3 90 90 90");
// Called by Mod_LoadCubemapSamples to select the map cubemap or engine/defaultcubemap.
// Keep the texture reference and BSP model metadata, but skip BindLocalCubemap and the context release because the context is null.
module.Offset(0xC8404).NOP(9);
module.Offset(0xC8414).NOP(6);
module.Offset(0xC842E).Patch("C3 90 90 90");
}
if (CommandLine()->CheckParm("-nowindow"))
{
// CVideoMode_Common::CreateGameWindow: skip creating and binding the Win32 window and skip IMaterialSystem::SetMode.
// Resume at the software-side datatable and LCD screen effect RPak type registrations, then return success.
module.Offset(0x1CD0ED).Patch("E9 70 00 00 00");
}
// runframeserver
// nop some access violations
module.Offset(0x159819).NOP(17);

View file

@ -1,6 +1,6 @@
#pragma once
#include "logging/logging.h"
#include "core/convar/convar.h"
#include "tier1/convar.h"
class CBaseClient;

View file

@ -41,6 +41,85 @@ ON_DLL_LOAD_DEDI("materialsystem_dx11.dll", DedicatedServerMaterialSystem, (CMod
o_pD3D11CreateDevice = module.Offset(0xD9A0E).RCast<decltype(o_pD3D11CreateDevice)>();
HookAttach(&(PVOID&)o_pD3D11CreateDevice, (PVOID)h_D3D11CreateDevice);
if (CommandLine()->CheckParm("-noshaderapi"))
{
// Initializes the texture/sampler cache, default bindings, and HBAO context.
// Keep the software-side resource tables, but skip their D3D-backed initialization.
module.Offset(0x29590).Patch("C3 90 90 90 90");
// Initializes the transient vertex/index streaming-buffer pools.
// Keep the surrounding ShaderAPI state initialization, but do not allocate or map D3D buffers.
module.Offset(0x19BE0).Patch("C3 90 90 90 90");
// Initializes GPU query pools and renderer-owned scratch textures/buffers.
// These resources have no software consumers on a dedicated server and require a D3D device.
module.Offset(0x2C000).Patch("C3 90 90 90 90");
// Initializes the shader-set global constant buffers and sampler-state table.
// Shader-set RPak registration remains active; only its global D3D resources are omitted.
module.Offset(0x505D0).Patch("C3 90 90 90 90");
// RPak "txtr" asset load callback.
// Parse and register the texture metadata, then skip D3D texture and shader-resource-view creation.
module.Offset(0x2B28).Patch("E9 5A 02 00 00");
// RPak "matl" asset constructor callback.
// Construct and register the CMaterialGlue asset without its D3D constant buffer.
module.Offset(0x50AD4).Patch("EB 48");
// RPak "shdr" asset load callback for pixel, vertex, geometry, and compute shaders.
// Keep the shader assets registered without creating their D3D shader objects.
module.Offset(0x2850).Patch("C3 90 90 90 90");
// These three functions create blend, depth-stencil, and rasterizer states respectively.
// Preserve the shader-set state caches while returning null D3D handles for these GPU-only objects.
module.Offset(0x33350).Patch("33 C0 C3 90 90 90 90 90 90");
module.Offset(0x33430).Patch("33 C0 C3 90");
module.Offset(0x33520).Patch("33 C0 C3 90");
// Decompresses dynamic .vcs bytecode and creates the requested D3D shader variants.
// Treat the bytecode as loaded successfully because no caller on the dedicated server consumes the D3D objects.
module.Offset(0x30D00).Patch("B8 01 00 00 00 C3 90");
// Maps and updates the two global shader-set constant buffers.
// Skip these uploads because the shader-set resource initializer deliberately leaves both buffers uncreated.
module.Offset(0x50BF0).Patch("C3 90 90");
// These three functions are the 1D, 2D, and 3D runtime texture hardware constructors.
// Keep the caller-created texture IDs and metadata without creating D3D textures or views.
module.Offset(0x274C0).Patch("C3 90 90 90 90");
module.Offset(0x277C0).Patch("C3 90 90 90 90");
module.Offset(0x28020).Patch("C3 90 90");
// Rebuilds and binds the GPU buffer containing lightmap-page data.
// Preserve the CPU lightmap tables maintained by its caller, but skip creation and binding of this GPU-only buffer.
module.Offset(0x22150).Patch("C3 90 90 90 90");
// Tests the active device feature level against D3D_FEATURE_LEVEL_10_0.
// Report the low-capability path without querying the null D3D device.
module.Offset(0x11E80).Patch("B0 01 C3 90");
// Likely the ShaderAPI/ShaderDevice SetMode path from Source SDK.
// Keep window/mode bookkeeping and interface setup, but skip swap-chain and device-resource initialization.
module.Offset(0x16CC5).Patch("E9 0C 01 00 00 90 90 90 90 90 90");
// Likely InitClientRenderTargets: creates the water, camera, shadow, and frame render targets.
// Dedicated servers do not need the named render-target set or its render-context bindings.
module.Offset(0x95EF0).Patch("C3 90 90 90 90");
// Likely CMaterialSystem::CreateStandardTextures: creates black, white, flat-normal, and debug textures.
// Leave this standard/debug texture set uninitialized on a null device; do not set its initialized flag or run shutdown releases.
module.Offset(0x594B0).Patch("C3 90 90");
// Likely the ShaderAPI state-cache shutdown/reset path.
// Skip its three hardware-state unbinds on the null ShaderAPI interface, then retain all CPU cache clearing and guarded releases.
module.Offset(0x33C3A).Patch("EB 3D 90 90 90 90 90");
// Shuts down the transient vertex/index streaming-buffer pools omitted above.
// None of its GPU resources or backing containers were constructed, so its unguarded releases must also be omitted.
module.Offset(0x1A1B0).Patch("C3 90 90 90 90");
}
// CMaterialSystem::FindMaterial
// make the game always use the error material
module.Offset(0x5F0F1).Patch("E9 34 03 00");

View file

@ -19,26 +19,46 @@ static void __fastcall h_CC_mat_crosshair_printmaterial_f(const CCommand& args)
if (!pGlue)
{
spdlog::info("|-- {} is NULL", szName);
spdlog::info("├ No reference material for {}", szName);
return;
}
spdlog::info("|-- Name: {}", szName);
spdlog::info("|-- GUID: {:#x}", pGlue->m_GUID);
spdlog::info("|-- Name: {}", pGlue->m_pszName);
spdlog::info("|-- Width : {}", pGlue->m_iWidth);
spdlog::info("|-- Height: {}", pGlue->m_iHeight);
spdlog::info("├ {}", szName);
spdlog::info("│├── GUID: {:#x}", pGlue->material.guid);
spdlog::info("│└── Name: {}", pGlue->material.name);
};
spdlog::info("|- GUID: {:#x}", pMat->m_GUID);
spdlog::info("|- Name: {}", pMat->m_pszName);
spdlog::info("|- Width : {}", pMat->m_iWidth);
spdlog::info("|- Height: {}", pMat->m_iHeight);
spdlog::info("────────────────────────────────────────────────────────────");
spdlog::info("┌ Name: {}", pMat->material.name);
spdlog::info("├ GUID: {:#x}", pMat->material.guid);
spdlog::info("├ Width : {}", pMat->material.width);
spdlog::info("├ Height: {}", pMat->material.height);
spdlog::info("├ Shaderset: {}", pMat->material.shaderSet->inner.name);
fnPrintGlue(pMat->m_pDepthShadow, "DepthShadow");
fnPrintGlue(pMat->m_pDepthPrepass, "DepthPrepass");
fnPrintGlue(pMat->m_pDepthVSM, "DepthVSM");
fnPrintGlue(pMat->m_pColPass, "ColPass");
fnPrintGlue(pMat->material.DepthShadow_ref, "DepthShadow");
fnPrintGlue(pMat->material.DepthPrepass_ref, "DepthPrepass");
fnPrintGlue(pMat->material.DepthVSM_ref, "DepthVSM");
fnPrintGlue(pMat->material.Colpass_ref, "Colpass");
if (pMat && pMat->material.shaderSet && pMat->material.shaderSet->inner.textureInputCount >= 1 && pMat->material.textureHandles)
{
spdlog::info("├ Textures");
for (size_t slot = 0; slot < pMat->material.shaderSet->inner.textureInputCount + 1; ++slot)
{
RpakTextureHeader* currentTexture = pMat->material.textureHandles[slot];
if (currentTexture && currentTexture->name)
{
if (slot == pMat->material.shaderSet->inner.textureInputCount)
spdlog::info("│└[{}][{:#x}]{}", slot, currentTexture->guid, currentTexture->name);
else
spdlog::info("│├[{}][{:#x}]{}", slot, currentTexture->guid, currentTexture->name);
}
}
}
spdlog::info("├ Glueflags: {:#x}", pMat->material.flags);
spdlog::info("└ Glueflags2: {:#x}", pMat->material.flags2);
spdlog::info("────────────────────────────────────────────────────────────");
}
ON_DLL_LOAD("engine.dll", GlMatSysIFace, (CModule module))

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "mods/modmanager.h"
#include "util/printcommands.h"
#include "util/printmaps.h"

View file

@ -1,6 +1,6 @@
#include "logging.h"
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
#include "config/profile.h"
#include "core/tier0.h"
#include "util/version.h"

View file

@ -1,7 +1,7 @@
#include "logging.h"
#include "loghooks.h"
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
#include "core/math/bitbuf.h"
#include "config/profile.h"
#include "core/tier0.h"

View file

@ -1,7 +1,7 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "sourceconsole.h"
#include "core/tier1.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
#include "util/printcommands.h"
CGameConsole* g_pGameConsole;

View file

@ -1,5 +1,5 @@
#include "masterserver/masterserver.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
#include "shared/playlist.h"
#include "server/auth/serverauthentication.h"
#include "core/tier0.h"
@ -1062,11 +1062,14 @@ void MasterServerPresenceReporter::DestroyPresence(const ServerPresence* pServer
return;
}
auto url =
fmt::format("{}/server/remove_server?id={}", Cvar_ns_masterserver_hostname->GetString(), g_pMasterServerManager->m_sOwnServerId);
// Not bothering with better thread safety in this case since DestroyPresence() is called when the game is shutting down.
*g_pMasterServerManager->m_sOwnServerId = 0;
std::thread requestThread(
[this]
[this, url]
{
CURL* curl = curl_easy_init();
SetCommonHttpClientOptions(curl);
@ -1075,12 +1078,7 @@ void MasterServerPresenceReporter::DestroyPresence(const ServerPresence* pServer
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteToStringBufferCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(
curl,
CURLOPT_URL,
fmt::format(
"{}/server/remove_server?id={}", Cvar_ns_masterserver_hostname->GetString(), g_pMasterServerManager->m_sOwnServerId)
.c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
CURLcode result = curl_easy_perform(curl);
curl_easy_cleanup(curl);

View file

@ -1,6 +1,6 @@
#pragma once
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "server/serverpresence.h"
#include <winsock2.h>
#include <string>

View file

@ -1,47 +1,124 @@
#pragma once
#include "materialsystem/cshaderglue.h"
#include <d3d11.h>
class RpakTextureHeader // Expected size: 0x130
{
public:
uint64_t guid;
const char* name;
uint16_t width;
uint16_t height;
int16_t depth;
uint16_t dxgiFormat;
uint32_t dataSize;
uint8_t compressionType;
uint8_t optStreamedMipCount;
uint8_t arraySize;
uint8_t layerCount;
uint8_t mipFlags;
uint8_t permanentMipCount;
uint8_t streamedMipCount;
uint8_t unk[13];
int64_t numPixels;
uint16_t unknownWord38;
uint8_t unknownByte3A;
uint8_t unknownByte3B;
uint32_t unknownDword3C;
uint32_t unknownDword40;
uint32_t unknownDword44;
float transform[16];
uint64_t unknownQword88;
uint64_t unknownQword90;
uint32_t unknownArray98[16];
uint32_t unknownArrayD8[16];
ID3D11Resource* d3d11Resource;
ID3D11ShaderResourceView* shaderResourceView;
uint8_t unknownByte128;
uint8_t padding[7];
};
struct CBufUberStatic // sizeof = 0xE0
{
float c_uv1RotScaleX[2]; // 0x00
float c_uv1RotScaleY[2]; // 0x08
float c_uv1Translate[2]; // 0x10
float c_uv2RotScaleX[2]; // 0x18
float c_uv2RotScaleY[2]; // 0x20
float c_uv2Translate[2]; // 0x28
float c_uv3RotScaleX[2]; // 0x30
float c_uv3RotScaleY[2]; // 0x38
float c_uv3Translate[2]; // 0x40
float c_uvDistortionIntensity[2]; // 0x48
float c_uvDistortion2Intensity[2]; // 0x50
float c_fogColorFactor; // 0x58
float c_layerBlendRamp; // 0x5C
float c_albedoTint[3]; // 0x60
float c_opacity; // 0x6C
float c_useAlphaModulateSpecular; // 0x70
float c_alphaEdgeFadeExponent; // 0x74
float c_alphaEdgeFadeInner; // 0x78
float c_alphaEdgeFadeOuter; // 0x7C
float c_useAlphaModulateEmissive; // 0x80
float c_emissiveEdgeFadeExponent; // 0x84
float c_emissiveEdgeFadeInner; // 0x88
float c_emissiveEdgeFadeOuter; // 0x8C
float c_alphaDistanceFadeScale; // 0x90
float c_alphaDistanceFadeBias; // 0x94
float c_alphaTestReference; // 0x98
float c_aspectRatioMulV; // 0x9C
float c_emissiveTint[3]; // 0xA0
float c_shadowBias; // 0xAC
float c_tsaaDepthAlphaThreshold; // 0xB0
float c_tsaaMotionAlphaThreshold; // 0xB4
float c_tsaaMotionAlphaRamp; // 0xB8
uint32_t c_tsaaResponsiveFlag; // 0xBC
float c_dofOpacityLuminanceScale; // 0xC0
float c_glitchStrength; // 0xC4
float c_padding[2]; // 0xC8
float c_perfGloss; // 0xD0
float c_perfSpecColor[3]; // 0xD4
};
class CMaterialGlue;
class CMaterialGlue_short
{
public:
uint64_t guid;
const char* name;
uint64_t* surfaceProps[2];
CMaterialGlue* DepthShadow_ref;
CMaterialGlue* DepthPrepass_ref;
CMaterialGlue* DepthVSM_ref;
CMaterialGlue* Colpass_ref;
uint8_t gap_50[64];
ShaderGlue* shaderSet;
RpakTextureHeader** textureHandles;
RpakTextureHeader** streamingTextures;
int16_t streamingTextureCount;
uint8_t samplersIndices[4];
int16_t unknown;
uint8_t gap_B0[12];
uint16_t unknownWord[2];
uint32_t flags;
uint32_t flags2;
uint16_t width;
uint16_t height;
uint8_t gap_CC[2];
uint16_t word_CE;
void** pointer_D0;
CBufUberStatic* cbufUberStatic;
ID3D11Buffer* buffer;
uint32_t* atlasBufferIndices;
uint32_t dword_F0;
uint8_t gap_F4[12];
};
class CMaterialGlue
{
public:
void* m_pVFTable;
char m_unk[8];
uint64_t m_GUID;
const char* m_pszName;
const char* m_pszSurfaceProp;
const char* m_pszSurfaceProp2;
CMaterialGlue* m_pDepthShadow;
CMaterialGlue* m_pDepthPrepass;
CMaterialGlue* m_pDepthVSM;
CMaterialGlue* m_pColPass;
char gap_50[64];
CShaderGlue* m_pShaderGlue;
void** m_pTextureHandles;
void** m_pStreamingTextures;
int16_t m_iStreamingTextureCount;
uint8_t m_iSamplersIndices[4];
int16_t m_iUnknown0;
char gap_B0[12];
int16_t aword_BC[2];
int32_t flags2;
int32_t flags3;
int16_t m_iWidth;
int16_t m_iHeight;
int16_t m_iUnknown1;
int16_t m_iUnknown2;
void** m_pUnkD3D11Ptr;
void* m_pD3D11Buffer;
void* qword_E0;
void* pointer_E8;
int32_t dword_F0;
char gap_F4[12];
CMaterialGlue_short material;
};

View file

@ -5,3 +5,28 @@ class CShaderGlue
public:
void* vftable;
};
struct ShaderGlue_inner
{
const char* name;
uint64_t flagsMaybe;
uint16_t resourceBindingSlot;
uint16_t textureInputCount;
int16_t shadowSamplerCount;
uint16_t unkBindingSlot;
uint16_t unkBindingCount;
uint8_t bytes_22[6];
uint64_t unk3[4];
void* vertexShader;
void* pixelShader;
};
struct ShaderGlue
{
void* vtable;
ShaderGlue_inner inner;
};

View file

@ -6,6 +6,8 @@
#include <cctype>
#include <string>
#include <cstdint>
#include "core/filesystem/rpakfilesystem.h"
#include "cmaterialglue.h"
static ID3D11DeviceContext** DeviceContext;
static ID3D11Device** D3D11Device_14E8DD0;
@ -15,6 +17,12 @@ struct Ns_Constant_Buffer
float data[320];
};
struct MaterialTextureMappings
{
std::array<uint64_t, 60> slots;
};
AUTOHOOK_INIT()
static Ns_Constant_Buffer NSCustomDXBuffer;
@ -22,15 +30,48 @@ static std::mutex NSCustomDXBufferMutex;
// map to later on associate guid > buffer
static std::map<uint64_t, Ns_Constant_Buffer> NSCustomBuffersPerMaterial = {};
static std::map<uint64_t, MaterialTextureMappings> NSMaterialTextureSlotBindings = {};
static std::unordered_set<uint64_t> NSRegisteredCustomBufferMaterials = {};
static std::unordered_set<uint64_t> NSRegisteredTextureOverrides = {};
AUTOHOOK(SUB_511D0, materialsystem_dx11.dll + 0x511D0, __int64, __fastcall, (__int64 a1, __int64 a2, __int64 a3, __int64 a4))
AUTOHOOK(SUB_511D0, materialsystem_dx11.dll + 0x511D0, __int64, __fastcall, (__int64 a1, __int64 a2, __int64 a3, CMaterialGlue_short* a4))
{
int64_t subResult = SUB_511D0(a1, a2, a3, a4);
CMaterialGlue_short* internal_logic_material = a4;
uint32_t glueFlags = *(uint32_t*)((uint8_t*)a4 + 176);
int64_t subResult = SUB_511D0(a1, a2, a3, internal_logic_material);
if (!DeviceContext || !D3D11Device_14E8DD0 || !*DeviceContext || !*D3D11Device_14E8DD0)
return subResult;
// bind textures to slots if existing
if (NSMaterialTextureSlotBindings.contains(internal_logic_material->guid))
{
auto& mappings = NSMaterialTextureSlotBindings[internal_logic_material->guid];
for (size_t slot = 0; slot < mappings.slots.size(); ++slot)
{
uint64_t textureGUID = mappings.slots[slot];
if (textureGUID == 0)
continue;
__int64 texturePointer = g_pakLoadApi->GetAssetByHash(textureGUID);
if (!texturePointer)
continue;
RpakTextureHeader* TextureHeader = (RpakTextureHeader*)texturePointer;
ID3D11ShaderResourceView* TextureSRV = TextureHeader->shaderResourceView;
if (!TextureSRV)
continue;
(*DeviceContext)->PSSetShaderResources(slot, 1, &TextureSRV);
}
}
// bind custom buffer when flag is 0x04089901 in rpak mat
if ((glueFlags & 0x04089901) == 0x04089901)
if (NSRegisteredCustomBufferMaterials.contains(internal_logic_material->guid))
{
D3D11_BUFFER_DESC desc {};
@ -62,7 +103,7 @@ AUTOHOOK(SUB_511D0, materialsystem_dx11.dll + 0x511D0, __int64, __fastcall, (__i
std::lock_guard<std::mutex> lock(NSCustomDXBufferMutex);
memcpy(pData, &NSCustomBuffersPerMaterial[*(uint64_t*)a4], sizeof(Ns_Constant_Buffer));
memcpy(pData, &NSCustomBuffersPerMaterial[internal_logic_material->guid], sizeof(Ns_Constant_Buffer));
(*DeviceContext)->Unmap(resource, 0);
(*DeviceContext)->PSSetConstantBuffers(4, 1, &resource);
@ -86,7 +127,73 @@ bool isValidMaterialGUID(const std::string& str)
return true;
}
template <ScriptContext context> SQRESULT NSSetCustomDXBuffer(HSQUIRRELVM sqvm)
SQRESULT NSRegisterCustomDXBufferForGUID(HSQUIRRELVM sqvm)
{
auto rPakMaterialGUIDString = (g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 1));
uint64_t rPakMaterialGUID = std::stoull(rPakMaterialGUIDString, nullptr, 16);
__int64 AssetFromGUID = g_pakLoadApi->GetAssetByHash(rPakMaterialGUID);
if (!AssetFromGUID)
{
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(
sqvm, fmt::format("Asset with GUID {} Doesnt Exist", rPakMaterialGUIDString).c_str());
return SQRESULT_ERROR;
}
// we need to add 16 to the pointer, matglueshort is matglue without the first 16 bytes. GetAssetByHash returns a pointer to the full
auto* base = reinterpret_cast<uint8_t*>(AssetFromGUID);
auto* GUIDMaterialGlue_short = reinterpret_cast<CMaterialGlue_short*>(base + 16);
if (!NSRegisteredCustomBufferMaterials.contains(GUIDMaterialGlue_short->guid))
{
NS::log::SCRIPT_CL->info("Registered GUID: {} to use the NSCustomDXBuffer system", GUIDMaterialGlue_short->guid);
NSRegisteredCustomBufferMaterials.insert(GUIDMaterialGlue_short->guid);
}
else
{
NS::log::SCRIPT_CL->warn(
"Attempted to register GUID: {} to the NSCustomDXBuffer system, GUID was already registered", GUIDMaterialGlue_short->guid);
}
return SQRESULT_NULL;
}
SQRESULT NSDeregisterCustomDXBufferForGUID(HSQUIRRELVM sqvm)
{
auto rPakMaterialGUIDString = (g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 1));
uint64_t rPakMaterialGUID = std::stoull(rPakMaterialGUIDString, nullptr, 16);
__int64 AssetFromGUID = g_pakLoadApi->GetAssetByHash(rPakMaterialGUID);
if (!AssetFromGUID)
{
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(
sqvm, fmt::format("Asset with GUID {} Doesnt Exist", rPakMaterialGUIDString).c_str());
return SQRESULT_ERROR;
}
// we need to add 16 to the pointer, matglueshort is matglue without the first 16 bytes. GetAssetByHash returns a pointer to the full
auto* base = reinterpret_cast<uint8_t*>(AssetFromGUID);
auto* GUIDMaterialGlue_short = reinterpret_cast<CMaterialGlue_short*>(base + 16);
if (NSRegisteredCustomBufferMaterials.contains(GUIDMaterialGlue_short->guid))
{
NS::log::SCRIPT_CL->info("Deregistered GUID: {} from the NSCustomDXBuffer system", GUIDMaterialGlue_short->guid);
NSRegisteredCustomBufferMaterials.erase(GUIDMaterialGlue_short->guid);
}
else
{
NS::log::SCRIPT_CL->warn(
"Attempted to deregister GUID: {} from the NSCustomDXBuffer system, GUID was not registered", GUIDMaterialGlue_short->guid);
}
return SQRESULT_NULL;
}
SQRESULT NSUpdateCustomDXBufferForGUID(HSQUIRRELVM sqvm)
{
// get the guid as a string to later conv
@ -107,7 +214,7 @@ template <ScriptContext context> SQRESULT NSSetCustomDXBuffer(HSQUIRRELVM sqvm)
if (!isValidMaterialGUID(guidString))
{
g_pSquirrel[ScriptContext::SERVER]->raiseerror(
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(
sqvm, fmt::format("Malformed Material GUID", (NSCustomBufferDataArray->_usedSlots) * 4, sizeof(Ns_Constant_Buffer)).c_str());
return SQRESULT_ERROR;
}
@ -118,7 +225,7 @@ template <ScriptContext context> SQRESULT NSSetCustomDXBuffer(HSQUIRRELVM sqvm)
if ((NSCustomBufferDataArray->_usedSlots) * 4 > sizeof(Ns_Constant_Buffer))
{
g_pSquirrel[ScriptContext::SERVER]->raiseerror(
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(
sqvm,
fmt::format(
"Size of Squirrel array exceeds NSCustomDXBuffer size\n\nSquirrel "
@ -136,16 +243,75 @@ template <ScriptContext context> SQRESULT NSSetCustomDXBuffer(HSQUIRRELVM sqvm)
return SQRESULT_NULL;
}
SQRESULT NSBindTextureToMaterial(HSQUIRRELVM sqvm)
{
auto rPakMaterialGUIDString = (g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 1));
auto rPakTextureGUIDString = (g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 2));
auto rPakShaderSlotBindingInt = (g_pSquirrel[ScriptContext::CLIENT]->getinteger(sqvm, 3));
uint64_t rPakMaterialGUID = std::stoull(rPakMaterialGUIDString, nullptr, 16);
__int64 MatAssetFromGUID = g_pakLoadApi->GetAssetByHash(rPakMaterialGUID);
if (rPakShaderSlotBindingInt > 60)
{
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(sqvm, fmt::format("TextureOverrides only support 30 custom bindings").c_str());
return SQRESULT_ERROR;
}
if (!MatAssetFromGUID)
{
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(
sqvm, fmt::format("Material with GUID {} Doesnt Exist", rPakMaterialGUIDString).c_str());
return SQRESULT_ERROR;
}
auto* base = reinterpret_cast<uint8_t*>(MatAssetFromGUID);
auto* GUIDMaterialGlue_short = reinterpret_cast<CMaterialGlue_short*>(base + 16);
if (!rPakTextureGUIDString == 0)
{
uint64_t rPakTextureGUID = std::stoull(rPakTextureGUIDString, nullptr, 16);
__int64 TexAssetFromGUID = g_pakLoadApi->GetAssetByHash(rPakTextureGUID);
if (!TexAssetFromGUID)
{
g_pSquirrel[ScriptContext::CLIENT]->raiseerror(
sqvm, fmt::format("Texture with GUID {} Doesnt Exist", rPakTextureGUIDString).c_str());
return SQRESULT_ERROR;
}
NSMaterialTextureSlotBindings[GUIDMaterialGlue_short->guid].slots[rPakShaderSlotBindingInt] = rPakTextureGUID;
}
else
NSMaterialTextureSlotBindings[GUIDMaterialGlue_short->guid].slots[rPakShaderSlotBindingInt] = 0;
return SQRESULT_NULL;
}
ON_DLL_LOAD_CLIENT("materialsystem_dx11.dll", SUB_511D0, (CModule module))
{
AUTOHOOK_DISPATCH_MODULE(materialsystem_dx11.dll)
DeviceContext = module.Offset(0x14E8DD8).RCast<ID3D11DeviceContext**>();
D3D11Device_14E8DD0 = module.Offset(0x14E8DD0).RCast<ID3D11Device**>();
g_pSquirrel[ScriptContext::CLIENT]->AddFuncRegistration(
"void",
"NSSetCustomDXBuffer",
"NSUpdateCustomDXBufferForGUID",
"string rPakMaterialGUID array NSCustomBufferPerMaterialData",
"",
NSSetCustomDXBuffer<ScriptContext::CLIENT>);
NSUpdateCustomDXBufferForGUID);
g_pSquirrel[ScriptContext::CLIENT]->AddFuncRegistration(
"void", "NSRegisterCustomDXBufferForGUID", "string rPakMaterialGUID", "", NSRegisterCustomDXBufferForGUID);
g_pSquirrel[ScriptContext::CLIENT]->AddFuncRegistration(
"void", "NSDeregisterCustomDXBufferForGUID", "string rPakMaterialGUID", "", NSDeregisterCustomDXBufferForGUID);
g_pSquirrel[ScriptContext::CLIENT]->AddFuncRegistration(
"void",
"NSBindTextureToMaterial",
"string rPakMaterialGUID string rPakTextureGUID int shaderBindingSlot",
"",
NSBindTextureToMaterial);
}

View file

@ -1,6 +1,6 @@
#include "modmanager.h"
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
#include "client/audio.h"
#include "masterserver/masterserver.h"
#include "core/filesystem/filesystem.h"

View file

@ -1,5 +1,5 @@
#pragma once
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "core/memalloc.h"
#include "squirrel/squirrel.h"

View file

@ -4,7 +4,7 @@
#include <ranges>
#include "plugins.h"
#include "config/profile.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
namespace fs = std::filesystem;

View file

@ -364,14 +364,28 @@ int main(int argc, char* argv[])
bool noOriginStartup = false;
bool dedicated = false;
bool nostubs = false;
bool noWindow = false;
bool noShaderApi = false;
for (int i = 0; i < argc; i++)
{
if (!strcmp(argv[i], "-noOriginStartup"))
noOriginStartup = true;
else if (!strcmp(argv[i], "-dedicated")) // also checked by Northstar.dll
dedicated = true;
else if (!strcmp(argv[i], "-nostubs"))
nostubs = true;
else if (!strcmp(argv[i], "-nowindow"))
noWindow = true;
else if (!strcmp(argv[i], "-noshaderapi"))
noShaderApi = true;
}
if (noWindow && (!dedicated || !noShaderApi))
{
std::cerr << "[*] ERROR: -nowindow requires -dedicated and -noshaderapi" << std::endl;
return 1;
}
if (!noOriginStartup && !dedicated)
{

175
primedev/rtech/rui.cpp Normal file
View file

@ -0,0 +1,175 @@
#include "rui.h"
struct gamestate_info_ffa_struct
{
BYTE gap0[68];
float endTime;
const char* statusText;
float leftTeamScore;
float rightTeamScore;
DWORD maxTeamScore;
const char* factionImage;
const char* friendlyPlayerCardImage;
const char* enemyPlayerCardImage;
BYTE gap78[64];
DWORD whiteAssetHandle;
DWORD playerCardImageAssetHandle;
// struct needs to be 8 byte aligned for these
uint64_t owordC0[2];
uint64_t owordD0[2];
uint64_t topColor[2];
uint64_t bottomColor[2];
const char* formattedTimeString;
const char* gameModeName;
DWORD otherPlayerCardAssetHandle;
DWORD leftFillAsset;
DWORD rightFillAsset;
float leftTeamScoreDiff;
float otherTeamScoreDiff;
DWORD factionImageHandle;
const char* scoreString;
const char* rightTeamScoreString;
};
using gamestate_info_ffa_t = void(__fastcall*)(RuiFunctions_t*, RuiGlobals*, RuiInstance*, gamestate_info_ffa_struct*);
gamestate_info_ffa_t o_gamestate_info_ffa = nullptr;
void h_gamestate_info_ffa(RuiFunctions_t* funcs, RuiGlobals* globals, RuiInstance* inst, gamestate_info_ffa_struct* data)
{
static __m128 xmmword_D3C20 = {25.866, 25.866f, 40.000f, 40.000f};
static __m128 xmmword_D3C40 = {128.000f, 128.000f, 40.000f, 40.f};
static __m128 xmmword_D3C50 = {200.000f, 200.000f, 40.000f, 40.000f};
static __m128 xmmword_D4A00 = {1920.000f, 1920.000f, 1080.000f, 1080.000f};
static __m128 xmmword_D40E0 = {2.000f, 2.000f, 84.000f, 84.000f};
static __m128 xmmword_D3CE0 = {48.000f, 48.000f, 48.000f, 48.000f};
static __m128 enemyColor = {1.000f, 0.188f, 0.014f, 1.f};
static __m128 friendlyColor = {0.095f, 0.309f, 0.708f, 1.f};
float endTime = data->endTime;
float timeLeft = endTime - globals->currentTime;
char* buffer = (char*)alloca(2048);
strcpy_s(buffer, 2048, data->statusText);
if (strcmp(buffer, "") == 0)
{
strcpy_s(buffer, 2048, "#PL_ffa");
}
if (timeLeft < 0.0f || endTime == -1.0e30f)
{
data->formattedTimeString = "--:--";
}
else if (timeLeft > 30.0f)
{
data->formattedTimeString = funcs->printf(inst, "%i:%02i", (unsigned int)((int)timeLeft / 60), (unsigned int)((int)timeLeft % 60));
}
else
{
data->formattedTimeString = funcs->printf(inst, "%05.2f", timeLeft);
}
data->rightFillAsset = funcs->LoadAsset(inst, "rui/hud/gamestate/score_fill_right");
assetHandle v9 = funcs->LoadAsset(inst, "rui/hud/gamestate/score_fill_right");
bool teamScoreDiff = data->leftTeamScore < data->rightTeamScore;
data->leftFillAsset = v9;
__m128 topColor, bottomColor;
const char* scoreString;
const char* v23;
float otherScore;
if (teamScoreDiff)
{
assetHandle enemyPlayerCardImage_1 = funcs->LoadAsset(inst, data->enemyPlayerCardImage);
const char* friendlyPlayerCardImage = data->friendlyPlayerCardImage;
data->playerCardImageAssetHandle = enemyPlayerCardImage_1;
assetHandle v26 = funcs->LoadAsset(inst, friendlyPlayerCardImage);
data->otherPlayerCardAssetHandle = v26;
float v28 = static_cast<float>(data->maxTeamScore);
if (v28 == 0.0f)
{
return (funcs->SetErrorWithReason)(inst, "content\\r2\\ui\\hud\\gamemode_ffa.rui (83,46): divide by zero.\n");
}
float rightTeamScore = data->rightTeamScore;
data->leftTeamScoreDiff = rightTeamScore / v28;
topColor = enemyColor;
bottomColor = friendlyColor;
float v30 = data->leftTeamScore / v28;
*(__m128*)data->topColor = topColor;
*(__m128*)data->bottomColor = bottomColor;
data->otherTeamScoreDiff = v30;
scoreString = funcs->printf(inst, "%.8g", rightTeamScore);
otherScore = data->leftTeamScore;
v23 = "%.8g";
}
else
{
assetHandle v11 = funcs->LoadAsset(inst, data->friendlyPlayerCardImage);
const char* enemyPlayerCardImage = data->enemyPlayerCardImage;
data->playerCardImageAssetHandle = v11;
assetHandle enemyPlayerCardImageAssetHandle_2 = funcs->LoadAsset(inst, enemyPlayerCardImage);
data->otherPlayerCardAssetHandle = enemyPlayerCardImageAssetHandle_2;
float maxTeamScore_1 = static_cast<float>(data->maxTeamScore);
if (maxTeamScore_1 == 0.0f)
{
return (funcs->SetErrorWithReason)(inst, "content\\r2\\ui\\hud\\gamemode_ffa.rui (83,46): divide by zero.\n");
}
float leftTeamScore_1 = data->leftTeamScore;
data->leftTeamScoreDiff = leftTeamScore_1 / maxTeamScore_1;
topColor = friendlyColor;
bottomColor = enemyColor;
float v20 = data->rightTeamScore / maxTeamScore_1;
*(__m128*)data->topColor = topColor;
*(__m128*)data->bottomColor = bottomColor;
data->otherTeamScoreDiff = v20;
scoreString = funcs->printf(inst, "%.8g", leftTeamScore_1);
otherScore = data->rightTeamScore;
v23 = "%.8g";
}
data->scoreString = scoreString;
const char* v31 = funcs->printf(inst, v23, otherScore);
*(__m128*)data->owordD0 = bottomColor;
*(__m128*)data->owordC0 = topColor;
data->rightTeamScoreString = v31;
data->whiteAssetHandle = funcs->LoadAsset(inst, "white");
const char* factionImage = data->factionImage;
data->gameModeName = funcs->localize(inst, buffer);
data->factionImageHandle = funcs->LoadAsset(inst, factionImage);
__m128* transformSizes = funcs->GetTransformSize(inst);
transformSizes[3] = (__m128)xmmword_D3C50;
funcs->executeTransform(inst, 1);
transformSizes[4] = (__m128)xmmword_D3C50;
funcs->executeTransform(inst, 2);
transformSizes[5] = (__m128)xmmword_D4A00;
transformSizes[6] = (__m128)xmmword_D40E0;
__m128 v35;
v35 = _mm_set_ps(40.0f, 40.0f, 0.0f, 0.0f);
transformSizes[7] = (__m128)xmmword_D4A00;
transformSizes[9] = (__m128)xmmword_D3C20;
transformSizes[8] = (__m128)xmmword_D3C40;
transformSizes[10] = (__m128)xmmword_D3C20;
v35 = (funcs->unknown_5)(inst, 3LL, 4LL);
transformSizes[11] = v35;
v35 = (funcs->unknown_5)(inst, 4LL, 5LL);
transformSizes[12] = v35;
transformSizes[13] = (funcs->GetTextSize)(inst, 42LL);
transformSizes[14] = (funcs->GetTextSize)(inst, 60LL);
transformSizes[15] = (funcs->GetTextSize)(inst, 78LL);
transformSizes[16] = (funcs->GetTextSize)(inst, 348LL);
transformSizes[17] = (funcs->GetTextSize)(inst, 366LL);
transformSizes[18] = xmmword_D3CE0;
return (funcs->executeTransform)(inst, 0x9ELL);
}
ON_DLL_LOAD("ui(11).dll", Rui, (CModule module))
{
o_gamestate_info_ffa = module.Offset(0x3E8E0).RCast<gamestate_info_ffa_t>();
HookAttach(&(PVOID&)o_gamestate_info_ffa, (PVOID)h_gamestate_info_ffa);
}

77
primedev/rtech/rui.h Normal file
View file

@ -0,0 +1,77 @@
#pragma once
#include <intrin.h>
#include <cstddef>
#include <stdint.h>
#include <cmath>
typedef unsigned int assetHandle;
struct RuiGlobals
{
BYTE gap_0[60];
float localPlayerPos[3];
BYTE gap_48[72];
uint64_t qword_90;
float currentTime;
BYTE gap_9C[4];
int dword_A0;
int isConsole;
int dword_A8;
int dword_AC;
int dword_B0;
int dword_B4;
float float_B8;
float float_BC;
float float_C0;
int dword_C4;
float float_C8;
float float_CC;
DWORD dword_D0;
DWORD dword_D4;
DWORD dword_D8;
DWORD dword_DC;
float float_E0;
DWORD dword_E4;
};
struct RuiInstance
{
void* header; // original type RuiHeader
float canvasWidth;
float canvasHeight;
float canvasWidthRatio;
float canvasHeightRatio;
void* v1; // original type struct_v1
__int64 createTimeStamp;
BYTE byte_28;
BYTE error;
BYTE gap_2A[14];
void* pvoid_38; // original type ruiUnknown2
char dataValues[1];
};
struct RuiFunctions_t
{
void(__fastcall* setNoRender)(RuiInstance* a1);
void(__fastcall* setError)(RuiInstance* a1);
void(__fastcall* SetErrorWithReason)(RuiInstance* a1, const char* a2);
__m128*(__fastcall* GetTransformSize)(RuiInstance* a1);
__m128(__fastcall* GetTextSize)(RuiInstance* a1, unsigned int a2);
__m128(__fastcall* unknown_5)(RuiInstance* a1, int a2, int a3);
void(__fastcall* executeTransform)(RuiInstance* a1, int a2);
const char* (*printf)(RuiInstance* a1, const char* format, ...);
const char* (*localize)(RuiInstance* a1, const char* format, ...);
const char*(__fastcall* toUpper)(RuiInstance* a1, const char* a2);
__m128(__fastcall* unknown_10)(__m128* a1);
__m128(__fastcall* unknown_11)(float a1);
float(__fastcall* randomFloat)(RuiInstance* a1);
__int64(__fastcall* unknown_13)(__int64 a1, __int64 a2, __m128* a3);
__m128(__fastcall* unknown_14)(__int64 a1);
int(__fastcall* LoadAsset)(RuiInstance* a1, const char* assetPath);
const char*(__fastcall* unknown_16)(RuiInstance* a1, int a2);
float(__fastcall* unknown_17)(RuiInstance* a1, __int64 a2, float a3);
__m128(__fastcall* unknown_18)(__int64 a1, __int64 a2, float a3);
__m128(__fastcall* unknown_19)(__int64 a1, __int64 a2, __int64 a3);
__m128(__fastcall* unknown_20)(__int64 a1, __int64 a2, __int64 a3);
};

View file

@ -5,6 +5,7 @@
#include "client/localchatwriter.h"
#include <rapidjson/document.h>
#include <cctype>
static void(__fastcall* o_pCHudChat__AddGameLine)(void* self, const char* message, int inboxId, bool isTeam, bool isDead) = nullptr;
static void __fastcall h_CHudChat__AddGameLine(void* self, const char* message, int inboxId, bool isTeam, bool isDead)
@ -12,6 +13,8 @@ static void __fastcall h_CHudChat__AddGameLine(void* self, const char* message,
// This hook is called for each HUD, but we only want our logic to run once.
if (self != *CHudChat::allHuds)
return;
if (message == nullptr || message[0] == '\0')
return;
int senderId = inboxId & CUSTOM_MESSAGE_INDEX_MASK;
bool isAnonymous = senderId == 0;
@ -28,6 +31,14 @@ static void __fastcall h_CHudChat__AddGameLine(void* self, const char* message,
RemoveAsciiControlSequences(const_cast<char*>(message), true);
{
const char* p = isCustom ? payload : message;
while (isspace((unsigned char)*p))
p++;
if (*p == '\0')
return;
}
SQRESULT result = g_pSquirrel[ScriptContext::CLIENT]->Call(
"CHudChat_ProcessMessageStartThread", static_cast<int>(senderId) - 1, payload, isTeam, isDead, type);
if (result == SQRESULT_ERROR)

View file

@ -1,6 +1,6 @@
#include "squirrel/squirrel.h"
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
void ConCommand_ns_script_servertoclientstringcommand(const CCommand& arg)
{

View file

@ -1,6 +1,6 @@
#include "squirrel/squirrel.h"
#include "core/filesystem/rpakfilesystem.h"
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "dedicated/dedicated.h"
#include "core/filesystem/filesystem.h"
#include "core/math/vector.h"

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "engine/r2engine.h"
size_t __fastcall ShouldAllowAlltalk()

View file

@ -1,6 +1,6 @@
#include "bansystem.h"
#include "serverauthentication.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
#include "server/r2server.h"
#include "engine/r2engine.h"
#include "client/r2client.h"

View file

@ -1,12 +1,12 @@
#include "serverauthentication.h"
#include "shared/exploit_fixes/ns_limits.h"
#include "core/convar/cvar.h"
#include "core/convar/convar.h"
#include "tier1/cvar.h"
#include "tier1/convar.h"
#include "masterserver/masterserver.h"
#include "server/serverpresence.h"
#include "engine/hoststate.h"
#include "bansystem.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
#include "dedicated/dedicated.h"
#include "config/profile.h"
#include "core/tier0.h"

View file

@ -1,5 +1,5 @@
#pragma once
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "engine/r2engine.h"
#include <unordered_map>
#include <string>

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "engine/hoststate.h"
#include "engine/r2engine.h"

View file

@ -0,0 +1,39 @@
#include "tier1/convar.h"
#include "dedicated/dedicated.h"
#include "silver-bun/module.h"
ConVar* Cvar_idleKickLocal_enable;
ON_DLL_LOAD("server.dll", IdleKick, (CModule module))
{
// Jump over the check for match_useMatchmaking in the function that handles idling
module.Offset(0x157e68).Patch("EB 17 90 90 90 90 90 90 90 90");
// Skip the first player (local player) in the idle kick function
if (!IsDedicatedServer())
CModule("server.dll").Offset(0x157ea6).Patch("BF 02");
Cvar_idleKickLocal_enable = new ConVar(
"idleKickLocal_enable",
"0",
FCVAR_GAMEDLL,
"Enables/disables whether the local player would get kicked or not; doesn't work on dedicated servers",
false,
0,
false,
0,
[](ConVar* cvar, const char* pOldValue, float flOldValue)
{
NOTE_UNUSED(cvar);
NOTE_UNUSED(pOldValue);
NOTE_UNUSED(flOldValue);
if (IsDedicatedServer())
return;
// Toggles if the first player would get skipped in the idle kick function
if (Cvar_idleKickLocal_enable->GetBool())
CModule("server.dll").Offset(0x157ea6).Patch("BF 01");
else
CModule("server.dll").Offset(0x157ea6).Patch("BF 02");
});
}

View file

@ -7,6 +7,7 @@
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <cctype>
class CServerGameDLL;
@ -36,8 +37,18 @@ static void(__fastcall* o_pCServerGameDLL__OnReceivedSayTextMessage)(
static void __fastcall h_CServerGameDLL__OnReceivedSayTextMessage(
CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam)
{
if (text == nullptr)
return;
RemoveAsciiControlSequences(const_cast<char*>(text), true);
if (text[0] == '\0')
return;
const char* p = text;
while (isspace((unsigned char)*p))
p++;
if (*p == '\0')
return;
// MiniHook doesn't allow calling the base function outside of anywhere but the hook function.
// To allow bypassing the hook, isSkippingHook can be set.
if (bShouldCallSayTextHook)

View file

@ -1,4 +1,4 @@
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include "engine/r2engine.h"
#include "shared/exploit_fixes/ns_limits.h"
#include "masterserver/masterserver.h"

View file

@ -1,7 +1,7 @@
#include "serverpresence.h"
#include "shared/playlist.h"
#include "core/tier0.h"
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include <regex>

View file

@ -1,5 +1,5 @@
#pragma once
#include "core/convar/convar.h"
#include "tier1/convar.h"
struct ServerPresence
{

View file

@ -1,4 +1,4 @@
#include "core/convar/cvar.h"
#include "tier1/cvar.h"
#include "ns_limits.h"
#include "dedicated/dedicated.h"
#include "core/tier0.h"

View file

@ -1,6 +1,6 @@
#pragma once
#include "engine/r2engine.h"
#include "core/convar/convar.h"
#include "tier1/convar.h"
#include <unordered_map>
struct PlayerLimitData

View file

@ -1,5 +1,5 @@
#include "misccommands.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
#include "shared/playlist.h"
#include "engine/r2engine.h"
#include "client/r2client.h"

View file

@ -1,6 +1,6 @@
#include "playlist.h"
#include "core/convar/concommand.h"
#include "core/convar/convar.h"
#include "tier1/cmd.h"
#include "tier1/convar.h"
#include "core/vanilla.h"
#include "squirrel/squirrel.h"
#include "engine/hoststate.h"

View file

@ -0,0 +1,37 @@
#include "mods/modmanager.h"
#include <string>
#include <algorithm>
static void RemoveCompiledWeaponScripts()
{
// avoid clearing literally everything, just weapons
auto& files = g_pModManager->m_CompiledFiles;
std::erase_if(
files, [](const std::string& val) { return val.starts_with("scripts/weapons/") || val.starts_with("scripts\\weapons\\"); });
}
static void(__fastcall* o_pConCommand_weapon_reparse_server)(const CCommand& arg) = nullptr;
static void __fastcall h_ConCommand_weapon_reparse_server(const CCommand& arg)
{
RemoveCompiledWeaponScripts();
o_pConCommand_weapon_reparse_server(arg);
}
static void(__fastcall* o_pConCommand_weapon_reparse)(const CCommand& arg) = nullptr;
static void __fastcall h_ConCommand_weapon_reparse(const CCommand& arg)
{
RemoveCompiledWeaponScripts();
o_pConCommand_weapon_reparse(arg);
}
ON_DLL_LOAD("server.dll", WeaponReparse_Server, (CModule module))
{
o_pConCommand_weapon_reparse_server = module.Offset(0x6D2B70).RCast<decltype(o_pConCommand_weapon_reparse_server)>();
HookAttach(&(PVOID&)o_pConCommand_weapon_reparse_server, (PVOID)h_ConCommand_weapon_reparse_server);
}
ON_DLL_LOAD("client.dll", WeaponReparse_Client, (CModule module))
{
o_pConCommand_weapon_reparse = module.Offset(0x3D4930).RCast<decltype(o_pConCommand_weapon_reparse)>();
HookAttach(&(PVOID&)o_pConCommand_weapon_reparse, (PVOID)h_ConCommand_weapon_reparse);
}

View file

@ -1,7 +1,7 @@
#include "squirrel.h"
#include "mods/modsavefiles.h"
#include "logging/logging.h"
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
#include "mods/modmanager.h"
#include "dedicated/dedicated.h"
#include "engine/r2engine.h"
@ -20,7 +20,7 @@
AUTOHOOK_INIT()
SquirrelManagerManager g_pSquirrel;
thread_local SQCompiler* pIfDirectiveCompiler;
std::shared_ptr<ColoredLogger> getSquirrelLoggerByContext(ScriptContext context)
{
switch (context)
@ -326,9 +326,43 @@ bool IsUIVM(ScriptContext context, HSQUIRRELVM pSqvm)
return ScriptContext(pSqvm->sharedState->cSquirrelVM->vmContext) == ScriptContext::UI;
}
template <ScriptContext context> std::int64_t (*SQCompiler_ParseDirective)(SQCompiler* pCompiler);
template <ScriptContext context> std::int64_t __fastcall SQCompiler_ParseDirectiveHook(SQCompiler* pCompiler)
{
SQCompiler* pPreviousCompiler = pIfDirectiveCompiler;
pIfDirectiveCompiler = pCompiler;
const std::int64_t result = SQCompiler_ParseDirective<context>(pCompiler);
pIfDirectiveCompiler = pPreviousCompiler;
return result;
}
template <ScriptContext context>
bool (*SQCompiler_ResolveLocalOrConstant)(void* pFunctionState, SQObject* pIdentifier, SQObject* pValue, std::uintptr_t* pType);
template <ScriptContext context>
bool __fastcall SQCompiler_ResolveLocalOrConstantHook(void* pFunctionState, SQObject* pIdentifier, SQObject* pValue, std::uintptr_t* pType)
{
if (SQCompiler_ResolveLocalOrConstant<context>(pFunctionState, pIdentifier, pValue, pType))
return true;
// if we're not in a preprocessor directive, we don't want to resolve the identifier as a constant
if (!pIfDirectiveCompiler || pIfDirectiveCompiler->preprocessorDepth <= 0)
return false;
// evaluate to 0 if we're doing directives because #if with a compile error is stupid
pValue->_Type = OT_INTEGER;
pValue->structNumber = 0;
pValue->_VAL.as64Integer = 0;
constexpr std::uint32_t typeHashMagic = 0x9E3779B9u - 0x61C88647u;
constexpr std::uint32_t typeHash = typeHashMagic * static_cast<std::uint32_t>(OT_INTEGER);
constexpr std::size_t typeIndex = (typeHash / 0xF499u) & 0x3FFFu;
SQSharedState* pSharedState = pIfDirectiveCompiler->pSQVM->sharedState;
*pType = reinterpret_cast<std::uintptr_t>(&pSharedState->compilerTypeDescriptors[typeIndex]);
return true;
}
template <ScriptContext context> void* (*sq_compiler_create)(HSQUIRRELVM sqvm, void* a2, void* a3, SQBool bShouldThrowError);
template <ScriptContext context> void* __fastcall sq_compiler_createHook(HSQUIRRELVM sqvm, void* a2, void* a3, SQBool bShouldThrowError)
{
pIfDirectiveCompiler = nullptr;
// store whether errors generated from this compile should be fatal
if (IsUIVM(context, sqvm))
g_pSquirrel[ScriptContext::UI]->m_bFatalCompilationErrors = bShouldThrowError;
@ -789,6 +823,13 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module))
MAKEHOOK(module.Offset(0x8AD0), &sq_compiler_createHook<ScriptContext::CLIENT>, &sq_compiler_create<ScriptContext::CLIENT>);
MAKEHOOK(
module.Offset(0x58590), &SQCompiler_ParseDirectiveHook<ScriptContext::CLIENT>, &SQCompiler_ParseDirective<ScriptContext::CLIENT>);
MAKEHOOK(
module.Offset(0x65CB0),
&SQCompiler_ResolveLocalOrConstantHook<ScriptContext::CLIENT>,
&SQCompiler_ResolveLocalOrConstant<ScriptContext::CLIENT>);
MAKEHOOK(module.Offset(0x12B00), &SQPrintHook<ScriptContext::CLIENT>, &SQPrint<ScriptContext::CLIENT>);
MAKEHOOK(module.Offset(0x12BA0), &SQPrintHook<ScriptContext::UI>, &SQPrint<ScriptContext::UI>);
@ -868,6 +909,13 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module))
MAKEHOOK(module.Offset(0x8AA0), &sq_compiler_createHook<ScriptContext::SERVER>, &sq_compiler_create<ScriptContext::SERVER>);
MAKEHOOK(
module.Offset(0x58530), &SQCompiler_ParseDirectiveHook<ScriptContext::SERVER>, &SQCompiler_ParseDirective<ScriptContext::SERVER>);
MAKEHOOK(
module.Offset(0x65C50),
&SQCompiler_ResolveLocalOrConstantHook<ScriptContext::SERVER>,
&SQCompiler_ResolveLocalOrConstant<ScriptContext::SERVER>);
MAKEHOOK(module.Offset(0x1FE90), &SQPrintHook<ScriptContext::SERVER>, &SQPrint<ScriptContext::SERVER>);
MAKEHOOK(module.Offset(0x260E0), &CreateNewVMHook<ScriptContext::SERVER>, &CreateNewVM<ScriptContext::SERVER>);
MAKEHOOK(module.Offset(0x26E20), &DestroyVMHook<ScriptContext::SERVER>, &DestroyVM<ScriptContext::SERVER>);

View file

@ -1,4 +1,4 @@
#include "concommand.h"
#include "cmd.h"
#include "shared/misccommands.h"
#include "engine/r2engine.h"

View file

@ -1,7 +1,7 @@
#pragma once
#include "core/math/color.h"
#include "cvar.h"
#include "concommand.h"
#include "cmd.h"
// taken directly from iconvar.h

View file

@ -1,6 +1,6 @@
#include "cvar.h"
#include "convar.h"
#include "concommand.h"
#include "cmd.h"
//-----------------------------------------------------------------------------
// Purpose: returns all ConVars

View file

@ -1,7 +1,7 @@
#include "printcommands.h"
#include "core/convar/cvar.h"
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/cvar.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name)
{

View file

@ -1,5 +1,5 @@
#pragma once
#include "core/convar/concommand.h"
#include "tier1/cmd.h"
void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name);
void TryPrintCvarHelpForCommand(const char* pCommand);

View file

@ -1,6 +1,6 @@
#include "printmaps.h"
#include "core/convar/convar.h"
#include "core/convar/concommand.h"
#include "tier1/convar.h"
#include "tier1/cmd.h"
#include "mods/modmanager.h"
#include "core/tier0.h"
#include "engine/r2engine.h"

View file

@ -14,7 +14,9 @@ struct SQCompiler
int64_t qword98;
BYTE gapA0[280];
bool bFatalError;
BYTE gap1B9[143];
BYTE gap1B9[11];
int preprocessorDepth;
BYTE gap1C8[128];
int64_t qword248;
int64_t qword250;
int64_t qword258;

View file

@ -58,7 +58,9 @@ struct SQSharedState
SQTable* _entityTypesMaybe;
SQObjectType unknownTable2Type;
SQTable* unknownTable2;
unsigned char gap_41D8[64];
unsigned char gap_41D8[16];
SQObject* compilerTypeDescriptors;
unsigned char gap_41F0[40];
SQCompiler* pCompiler;
SQObjectType _compilerKeywordsType;
SQTable* _compilerKeywords;

View file

@ -1,77 +1,77 @@
LIBRARY wsock32
EXPORTS
AcceptEx=mswsock.AcceptEx
EnumProtocolsA=PROXY_EnumProtocolsA
EnumProtocolsW=PROXY_EnumProtocolsW
GetAcceptExSockaddrs=mswsock.GetAcceptExSockaddrs
GetAddressByNameA=PROXY_GetAddressByNameA
GetAddressByNameW=PROXY_GetAddressByNameW
GetNameByTypeA=ws2_32.GetNameByTypeA
GetNameByTypeW=ws2_32.GetNameByTypeW
GetServiceA=ws2_32.GetServiceA
GetServiceW=ws2_32.GetServiceW
GetTypeByNameA=ws2_32.GetTypeByNameA
GetTypeByNameW=ws2_32.GetTypeByNameW
MigrateWinsockConfiguration=ws2_32.MigrateWinsockConfiguration
NPLoadNameSpaces=ws2_32.NPLoadNameSpaces
SetServiceA=ws2_32.SetServiceA
SetServiceW=ws2_32.SetServiceW
TransmitFile=mswsock.TransmitFile
WEP=PROXY_WEP
WSAAsyncGetHostByAddr=ws2_32.WSAAsyncGetHostByAddr
WSAAsyncGetHostByName=ws2_32.WSAAsyncGetHostByName
WSAAsyncGetProtoByName=ws2_32.WSAAsyncGetProtoByName
WSAAsyncGetProtoByNumber=ws2_32.WSAAsyncGetProtoByNumber
WSAAsyncGetServByName=ws2_32.WSAAsyncGetServByName
WSAAsyncGetServByPort=ws2_32.WSAAsyncGetServByPort
WSAAsyncSelect=ws2_32.WSAAsyncSelect
WSACancelAsyncRequest=ws2_32.WSACancelAsyncRequest
WSACancelBlockingCall=ws2_32.WSACancelBlockingCall
WSACleanup=ws2_32.WSACleanup @116
WSAGetLastError=ws2_32.WSAGetLastError @111
WSAIsBlocking=ws2_32.WSAIsBlocking
WSARecvEx=PROXY_WSARecvEx
WSASetBlockingHook=ws2_32.WSASetBlockingHook
WSASetLastError=ws2_32.WSASetLastError @112
WSAStartup=ws2_32.WSAStartup @115
WSAUnhookBlockingHook=ws2_32.WSAUnhookBlockingHook
WSApSetPostRoutine=ws2_32.WSApSetPostRoutine
__WSAFDIsSet=PROXY___WSAFDIsSet @151
accept=ws2_32.accept @1
bind=ws2_32.bind @2
closesocket=ws2_32.closesocket @3
connect=ws2_32.connect @4
dn_expand=ws2_32.dn_expand @1106
gethostbyaddr=ws2_32.gethostbyaddr
gethostbyname=ws2_32.gethostbyname @52
gethostname=ws2_32.gethostname @57
getnetbyname=PROXY_getnetbyname @ 1101
getpeername=ws2_32.getpeername @5
getprotobyname=ws2_32.getprotobyname
getprotobynumber=ws2_32.getprotobynumber
getservbyname=ws2_32.getservbyname
getservbyport=ws2_32.getservbyport
getsockname=ws2_32.getsockname @6
getsockopt=PROXY_getsockopt @7
htonl=ws2_32.htonl
AcceptEx=mswsock.AcceptEx @8
htons=ws2_32.htons @9
inet_addr=ws2_32.inet_addr
inet_network=PROXY_inet_network
inet_ntoa=ws2_32.inet_ntoa
EnumProtocolsA=PROXY_EnumProtocolsA @10
EnumProtocolsW=PROXY_EnumProtocolsW @11
ioctlsocket=ws2_32.ioctlsocket @12
listen=ws2_32.listen @13
ntohl=ws2_32.ntohl
GetAcceptExSockaddrs=mswsock.GetAcceptExSockaddrs @14
ntohs=ws2_32.ntohs @15
rcmd=ws2_32.rcmd
recv=ws2_32.recv @16
recvfrom=ws2_32.recvfrom @17
rexec=ws2_32.rexec
rresvport=ws2_32.rresvport
s_perror=PROXY_s_perror
select=ws2_32.select @18
send=ws2_32.send @19
sendto=ws2_32.sendto @20
sethostname=ws2_32.sethostname
setsockopt=PROXY_setsockopt @21
shutdown=ws2_32.shutdown @22
socket=ws2_32.socket @23
GetAddressByNameA=PROXY_GetAddressByNameA @24
GetAddressByNameW=PROXY_GetAddressByNameW @25
GetNameByTypeA=ws2_32.GetNameByTypeA @26
GetNameByTypeW=ws2_32.GetNameByTypeW @27
GetServiceA=ws2_32.GetServiceA @28
GetServiceW=ws2_32.GetServiceW @29
GetTypeByNameA=ws2_32.GetTypeByNameA @30
GetTypeByNameW=ws2_32.GetTypeByNameW @31
MigrateWinsockConfiguration=ws2_32.MigrateWinsockConfiguration @32
NPLoadNameSpaces=ws2_32.NPLoadNameSpaces @33
SetServiceA=ws2_32.SetServiceA @34
SetServiceW=ws2_32.SetServiceW @35
TransmitFile=mswsock.TransmitFile @36
WEP=PROXY_WEP @37
WSAAsyncGetHostByAddr=ws2_32.WSAAsyncGetHostByAddr @38
WSAAsyncGetHostByName=ws2_32.WSAAsyncGetHostByName @39
WSAAsyncGetProtoByName=ws2_32.WSAAsyncGetProtoByName @40
WSAAsyncGetProtoByNumber=ws2_32.WSAAsyncGetProtoByNumber @41
WSAAsyncGetServByName=ws2_32.WSAAsyncGetServByName @42
WSAAsyncGetServByPort=ws2_32.WSAAsyncGetServByPort @43
WSAAsyncSelect=ws2_32.WSAAsyncSelect @44
WSACancelAsyncRequest=ws2_32.WSACancelAsyncRequest @45
WSACancelBlockingCall=ws2_32.WSACancelBlockingCall @46
WSAIsBlocking=ws2_32.WSAIsBlocking @47
WSARecvEx=PROXY_WSARecvEx @48
WSASetBlockingHook=ws2_32.WSASetBlockingHook @49
WSAUnhookBlockingHook=ws2_32.WSAUnhookBlockingHook @50
WSApSetPostRoutine=ws2_32.WSApSetPostRoutine @51
gethostbyname=ws2_32.gethostbyname @52
gethostbyaddr=ws2_32.gethostbyaddr @53
getprotobyname=ws2_32.getprotobyname @54
getprotobynumber=ws2_32.getprotobynumber @55
getservbyname=ws2_32.getservbyname @56
gethostname=ws2_32.gethostname @57
getservbyport=ws2_32.getservbyport @58
htonl=ws2_32.htonl @59
inet_addr=ws2_32.inet_addr @60
inet_network=PROXY_inet_network @61
inet_ntoa=ws2_32.inet_ntoa @62
ntohl=ws2_32.ntohl @63
rcmd=ws2_32.rcmd @64
rexec=ws2_32.rexec @65
rresvport=ws2_32.rresvport @66
s_perror=PROXY_s_perror @67
sethostname=ws2_32.sethostname @68
WSAGetLastError=ws2_32.WSAGetLastError @111
WSASetLastError=ws2_32.WSASetLastError @112
WSAStartup=ws2_32.WSAStartup @115
WSACleanup=ws2_32.WSACleanup @116
__WSAFDIsSet=PROXY___WSAFDIsSet @151
getnetbyname=PROXY_getnetbyname @1101
dn_expand=ws2_32.dn_expand @1106