Compare commits

..

No commits in common. "main" and "v0.0.4" have entirely different histories.
main ... v0.0.4

58 changed files with 1555 additions and 2495 deletions

View File

@ -58,7 +58,6 @@ jobs:
name: ${{matrix.configuration}} binaries name: ${{matrix.configuration}} binaries
path: | path: |
build/bin/${{matrix.configuration}}/t4sp-server-plugin.dll build/bin/${{matrix.configuration}}/t4sp-server-plugin.dll
build/bin/${{matrix.configuration}}/t4sp-server-plugin.pdb
deploy: deploy:
name: Deploy release name: Deploy release
@ -83,4 +82,3 @@ jobs:
draft: true draft: true
files: | files: |
t4sp-server-plugin.dll t4sp-server-plugin.dll
t4sp-server-plugin.pdb

3
.gitmodules vendored
View File

@ -29,6 +29,3 @@
[submodule "deps/SQLiteCpp"] [submodule "deps/SQLiteCpp"]
path = deps/SQLiteCpp path = deps/SQLiteCpp
url = https://github.com/SRombauts/SQLiteCpp url = https://github.com/SRombauts/SQLiteCpp
[submodule "deps/plutonium-sdk"]
path = deps/plutonium-sdk
url = https://github.com/plutoniummod/plutonium-sdk.git

109
README.md
View File

@ -3,112 +3,11 @@ A plugin that has code that hopefully compiles and the game will load it to do t
Requires Git (https://git-scm.com/), Premake5 (https://premake.github.io/), and MSVC 2022 (https://visualstudio.microsoft.com/vs/features/cplusplus/) to build. Requires Git (https://git-scm.com/), Premake5 (https://premake.github.io/), and MSVC 2022 (https://visualstudio.microsoft.com/vs/features/cplusplus/) to build.
# What does it do?
Nothing really right now, just detours and reimplements the entire GSC VM, for research purposes.
# Installation # Installation
Move the `t4sp-server-plugin.dll` to `%LOCALAPPDATA%\Plutonium\plugins\`, the plugin will be loaded when you start up a dedicated server for Plutonium T4SP. Move the `t4sp-server-plugin.dll` to `%LOCALAPPDATA%\Plutonium\storage\t4\plugins\`, the plugin will be loaded when you start up a dedicated server for Plutonium T4SP.
# Features
Detours and reimplements the entire GSC VM + compiler.
Adds custom GSC functions.
## FileIO
This plugin provides FileIO interface to GSC for reading and writing files, this is exact to [CoD4x's](https://github.com/callofduty4x/CoD4x_Server/blob/master/scriptdocumentation/script_functions_reference.md#file-operations) interface.
However, all reads and writes will take place strictly and only in the `scriptdata` folder, no up directory traversal allowed.
All files will be closed upon GSC restart (map_restart or fast_restart or missionfailed, etc), only a maximum of 10 files may be opened at once.
* `<bool> FS_TestFile(<filename string>)` Returns `true` if the file exists, `false` otherwise.
* `<bool> FS_Remove(<filename string>, <(optional) use_global bool>)` Deletes the file, return `true` if successful, `false` otherwise. `use_global` will use non mod specific folder.
```gsc
// test to see if "scriptdata/test.txt" file exists
if (FS_TestFile("test.txt")) // not a typo, all file io will take place inside the "scriptdata" folder
{
PrintConsole("Found test.txt!");
// delete it!
if (FS_Remove("test.txt"))
{
PrintConsole("test.txt was deleted!");
}
}
```
* `FS_FCloseAll()` Closes every full file.
```gsc
// open some files
FS_FCloseAll(); // close them all
```
* `<int> FS_FOpen(<filename string>, <mode string>, <(optional) use_global bool>)` Tries to open the file, mode must be one of `read`, `write` (clears the file), `append` (appends to the file), returns the filehandle. Will return `0` if failed to open. `use_global` will use non mod specific folder (only applies to `write` mode).
* `FS_FClose(<filehandle int>)` Closes the file pointed by the filehandle given, which was returned from `FS_FOpen`.
```gsc
// opens "scriptdata/test.txt", all io will take place inside the "scriptdata" folder
f = FS_FOpen("test.txt", "read"); // can be "read" "write", or "append"
if (!f)
{
PrintConsole("test.txt failed to be opened for reading!");
}
else
{
// do stuff with the file
FS_FClose(f); // make sure to close it
}
```
* `<string> FS_ReadLine(<filehandle int>)` Reads a line from the file pointed by the filehandle, removes the newline char. Returns `undefined` when nothing is left to read. Will not read more than 65536 characters at once. Filehandle must be opened for reading.
* `<string> FS_Read(<filehandle int>, <bytes int>(optional))` Reads number of bytes from the file. If bytes is `undefined`, reads the entire file. No more than 65536 characters will be read at once. Returns `undefined` if there are nothing left to read.
```gsc
// open the file for reading
line = FS_ReadLine(f);
while (isDefined(line))
{
// do something with line
line = FS_ReadLine(f);
}
// entire file is read
// close the file
```
* `<bool> FS_WriteLine(<filehandle int>, <contents string>)` Writes to the file pointed by the filehandle. Appends a newline character. Returns `true` if successful, `false` otherwise. Filehandle must be opened for writing.
* `<bool> FS_Write(<filehandle int>, <contents string>)` Same as above, does not add a newline character.
```gsc
// open the file for writing
FS_WriteLine(f, "writing some text with newline added");
FS_Write(f, "no newline here");
FS_Write(f, "i manually add a newline\n");
// close the file
```
* `<array of strings> FS_ListFiles(<folder string>)` Returns a list of files inside of the folder given.
```gsc
folder = "testfolder/";
files = FS_ListFiles(folder);
for (i = 0; i < files.size; i++)
{
filename = files[i];
// do something with the filename
filepath = folder + filename;
}
```
* `<int> FS_Length(<filehandle int>)` Returns the length in bytes of the open'd file.
* `<int> FS_GetSeek(<filehandle int>)` Returns the seek of the open'd file (only for reading).
* `<int> FS_Seek(<filehandle int>, <seek int>)` Sets the seek of the open'd file (only for reading).
# Credits # Credits
- momo5502 (https://github.com/momo5502) - momo5502 (https://github.com/momo5502)

2
deps/GSL vendored

@ -1 +1 @@
Subproject commit e64c97fc2cfc11992098bb38eda932de275e3f4d Subproject commit 43d60c5e3891dab6491a76d0bac554a4a89d57f6

2
deps/asmjit vendored

@ -1 +1 @@
Subproject commit 416f7356967c1f66784dc1580fe157f9406d8bff Subproject commit f1ea8a46c3f2bce5c51f290050c9d194668206bf

2
deps/curl vendored

@ -1 +1 @@
Subproject commit 78a1814b331c3535a785aa1c501203ad5a947838 Subproject commit 4528690cd51e5445df74aef8f83470a602683797

2
deps/json vendored

@ -1 +1 @@
Subproject commit a259ecc51e1951e12f757ce17db958e9881e9c6c Subproject commit 546370c9e778d99e7176641123e5cc1d0b62acab

2
deps/libtomcrypt vendored

@ -1 +1 @@
Subproject commit 7e863d21429f94ed6a720e24499a12a3f852bb31 Subproject commit b96e96cf8b22a931e8e91098ac37bc72f9e2f033

2
deps/libtommath vendored

@ -1 +1 @@
Subproject commit 8314bde5e5c8e5d9331460130a9d1066e324f091 Subproject commit 7f96509df1a6b44867bbda56bbf2cb92524be8ef

2
deps/minhook vendored

@ -1 +1 @@
Subproject commit f5485b8454544c2f034c78f8f127c1d03dea3636 Subproject commit 49d03ad118cf7f6768c79a8f187e14b8f2a07f94

1
deps/plutonium-sdk vendored

@ -1 +0,0 @@
Subproject commit 17e9a0a4d5e1133b50f879e3db07e97d1bf92e10

View File

@ -1,34 +1,34 @@
SQLiteCpp = { SQLiteCpp = {
source = path.join(dependencies.basePath, "SQLiteCpp"), source = path.join(dependencies.basePath, "SQLiteCpp"),
} }
function SQLiteCpp.import() function SQLiteCpp.import()
links { "SQLiteCpp" } links { "SQLiteCpp" }
SQLiteCpp.includes() SQLiteCpp.includes()
end end
function SQLiteCpp.includes() function SQLiteCpp.includes()
includedirs { includedirs {
path.join(SQLiteCpp.source, "include"), path.join(SQLiteCpp.source, "include"),
path.join(SQLiteCpp.source, "sqlite3") path.join(SQLiteCpp.source, "sqlite3")
} }
end end
function SQLiteCpp.project() function SQLiteCpp.project()
project "SQLiteCpp" project "SQLiteCpp"
language "C" language "C"
SQLiteCpp.includes() SQLiteCpp.includes()
files { files {
path.join(path.join(SQLiteCpp.source, "src"), "**.cpp"), path.join(path.join(SQLiteCpp.source, "src"), "**.cpp"),
path.join(path.join(SQLiteCpp.source, "include"), "**.h"), path.join(path.join(SQLiteCpp.source, "include"), "**.h"),
path.join(path.join(SQLiteCpp.source, "sqlite3"), "**.c"), path.join(path.join(SQLiteCpp.source, "sqlite3"), "**.c"),
path.join(path.join(SQLiteCpp.source, "sqlite3"), "**.h") path.join(path.join(SQLiteCpp.source, "sqlite3"), "**.h")
} }
warnings "Off" warnings "Off"
kind "StaticLib" kind "StaticLib"
end end
table.insert(dependencies, SQLiteCpp) table.insert(dependencies, SQLiteCpp)

View File

@ -1,16 +1,16 @@
csv_parser = { csv_parser = {
source = path.join(dependencies.basePath, "csv-parser"), source = path.join(dependencies.basePath, "csv-parser"),
} }
function csv_parser.import() function csv_parser.import()
dependson "csv-parser" dependson "csv-parser"
csv_parser.includes() csv_parser.includes()
end end
function csv_parser.includes() function csv_parser.includes()
includedirs { includedirs {
csv_parser.source csv_parser.source
} }
end end
function csv_parser.project() function csv_parser.project()

View File

@ -1,18 +0,0 @@
plutonium_sdk = {
source = path.join(dependencies.basePath, "plutonium-sdk"),
}
function plutonium_sdk.import()
plutonium_sdk.includes()
end
function plutonium_sdk.includes()
includedirs {
plutonium_sdk.source,
}
end
function plutonium_sdk.project()
end
table.insert(dependencies, plutonium_sdk)

2
deps/zlib vendored

@ -1 +1 @@
Subproject commit 643e17b7498d12ab8d15565662880579692f769d Subproject commit 04f42ceca40f73e2978b50e93806c2a18c1281fc

View File

@ -108,13 +108,13 @@ workspace "t4sp-server-plugin"
else else
filter "configurations:Release" filter "configurations:Release"
postbuildcommands { postbuildcommands {
"if \"%COMPUTERNAME%\" == \"\" ( copy /y \"$(TargetPath)\" \"$(LOCALAPPDATA)\\Plutonium\\plugins\\\" )" "if \"%COMPUTERNAME%\" == \"NEW-BUILT\" ( copy /y \"$(TargetPath)\" \"$(CODWAW_PATH)\\t4\\plugins\\\" )"
} }
filter {} filter {}
filter "configurations:Debug" filter "configurations:Debug"
postbuildcommands { postbuildcommands {
"if \"%COMPUTERNAME%\" == \"\" ( copy /y \"$(TargetPath)\" \"$(LOCALAPPDATA)\\Plutonium-staging\\plugins\\\" )" "if \"%COMPUTERNAME%\" == \"NEW-BUILT\" ( copy /y \"$(TargetPath)\" \"$(CODWAW_PATH)\\t4staging\\plugins\\\" )"
} }
filter {} filter {}
end end

View File

@ -2011,6 +2011,14 @@ LABEL_17:
} }
// our addition
auto f = gsc::function::get(pName, type);
if (f != nullptr)
{
return f;
}
//
// pluto // pluto
if (game::plutonium::scr_get_function_hook != nullptr) if (game::plutonium::scr_get_function_hook != nullptr)
{ {
@ -2146,6 +2154,14 @@ LABEL_17:
} }
} }
// our addition
auto f = gsc::method::get(pName, type);
if (f != nullptr)
{
return f;
}
//
// pluto // pluto
if (game::plutonium::scr_get_method_hook != nullptr) if (game::plutonium::scr_get_method_hook != nullptr)
{ {

View File

@ -304,6 +304,7 @@ namespace codsrc
{ {
game::plutonium::script_preprocess(sourceBuffer, inst, &parseData); // the pluto hook will call ScriptParse, so we dont have to game::plutonium::script_preprocess(sourceBuffer, inst, &parseData); // the pluto hook will call ScriptParse, so we dont have to
} }
// //
else else
{ {

View File

@ -723,20 +723,19 @@ namespace codsrc
{ {
if (game::Scr_IsInOpcodeMemory(scriptInstance, codepos - 1)) if (game::Scr_IsInOpcodeMemory(scriptInstance, codepos - 1))
{ {
const char* s;
// pluto // pluto
const char* s;
if (game::plutonium::at_codepose_va != nullptr) if (game::plutonium::at_codepose_va != nullptr)
{ {
s = game::plutonium::at_codepose_va(scriptInstance, codepos - game::gScrVarPub[scriptInstance].programBuffer); s = game::plutonium::at_codepose_va(scriptInstance, codepos - game::gScrVarPub[scriptInstance].programBuffer);
} }
//
else else
{ {
s = game::va("@ %d\n", codepos - game::gScrVarPub[scriptInstance].programBuffer); s = game::va("@ %d\n", codepos - game::gScrVarPub[scriptInstance].programBuffer);
} }
game::Com_PrintMessage(channel, s, 0); game::Com_PrintMessage(channel, s, 0);
//
return; return;
} }
} }

View File

@ -67,18 +67,11 @@ namespace codsrc
{ {
int len; int len;
if (!refString->u.s.byteLen) for ( len = refString->u.s.byteLen - 1;
refString->str[len];
len += 256 )
{ {
len = 256 - 1; //Bugfix for 256 % 256 = 0 or 512 % 256 = 0 or... Just promote it to 256 ;
}
else
{
len = refString->u.s.byteLen - 1;
}
while (refString->str[len])
{
len += 256;
} }
return len; return len;

View File

@ -1,6 +1,5 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "clientscript_public.hpp" #include "clientscript_public.hpp"
#include <component/scheduler.hpp>
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4244) #pragma warning(disable: 4244)
@ -4882,24 +4881,20 @@ namespace codsrc
return result; return result;
} }
result = value->u.anim; result.u.linkPointer = (const char*)value->u.intValue;
if ( !animTreeInputForValidation ) if ( !animTreeInputForValidation )
{ {
return result; return result;
} }
assert(animTreeInputForValidation); animTreeAnimPtr = animTreeInputForValidation->anims;
animTreeAnimPtr = animTreeInputForValidation->anims; // XAnimGetAnims(inst, animTreeInputForValidation); animPtr = game::gScrAnimPub[inst].xanim_lookup[user][(unsigned int)result.u.linkPointer >> 16].anims;
assert(result.u.s.tree > 0 && result.u.s.tree < game::gScrAnimPub[inst].xanim_num[user]);
animPtr = game::gScrAnimPub[inst].xanim_lookup[user][result.u.s.tree].anims; // Scr_GetAnims(inst, user, result.u.s.tree);
if ( animPtr == animTreeAnimPtr ) if ( animPtr == animTreeAnimPtr )
{ {
return result; return result;
} }
debugMsg = game::XAnimGetAnimDebugName(result.u.s.index, animPtr); debugMsg = game::XAnimGetAnimDebugName(value->u.intValue, animPtr);
game::gScrVarPub[inst].error_message = (char*)game::va("anim '%s' in animtree '%s' does not belong to the entity's animtree '%s'", debugMsg, animTreeAnimPtr->debugName, animTreeAnimPtr->debugName); game::gScrVarPub[inst].error_message = (char*)game::va("anim '%s' in animtree '%s' does not belong to the entity's animtree '%s'", debugMsg, animTreeAnimPtr->debugName, animTreeAnimPtr->debugName);
game::RemoveRefToValueInternal(game::SCRIPTINSTANCE_SERVER, value->type, value->u); game::RemoveRefToValueInternal(game::SCRIPTINSTANCE_SERVER, value->type, value->u);
value->type = game::VAR_UNDEFINED; value->type = game::VAR_UNDEFINED;
@ -5735,11 +5730,5 @@ namespace codsrc
{ {
game::Scr_NotifyNum_Internal(game::SCRIPTINSTANCE_SERVER, entnum, classnum, stringValue, paramcount); game::Scr_NotifyNum_Internal(game::SCRIPTINSTANCE_SERVER, entnum, classnum, stringValue, paramcount);
} }
// Restored
unsigned int Scr_GetNumParam(game::scriptInstance_t inst)
{
return game::gScrVmPub[inst].outparamcount;
}
} }
#pragma warning(pop) #pragma warning(pop)

View File

@ -116,5 +116,4 @@ namespace codsrc
unsigned int GetInternalVariableIndex(game::scriptInstance_t inst, unsigned int unsignedValue); unsigned int GetInternalVariableIndex(game::scriptInstance_t inst, unsigned int unsignedValue);
const char* Scr_ReadData(game::scriptInstance_t inst, const char** pos, unsigned int count); const char* Scr_ReadData(game::scriptInstance_t inst, const char** pos, unsigned int count);
void Scr_NotifyNum(int entnum, game::classNum_e classnum, unsigned int stringValue, unsigned int paramcount); void Scr_NotifyNum(int entnum, game::classNum_e classnum, unsigned int stringValue, unsigned int paramcount);
unsigned int Scr_GetNumParam(game::scriptInstance_t inst);
} }

View File

@ -1,5 +1,4 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include <utils/flags.hpp>
#include "clientscript_public.hpp" #include "clientscript_public.hpp"
#pragma warning(push) #pragma warning(push)
@ -2054,13 +2053,6 @@ namespace codsrc
game::yyparse(); game::yyparse();
*parseData = *game::yaccResult; *parseData = *game::yaccResult;
// our addition
if (utils::flags::has_flag("dump_asts"))
{
print_ast(inst, *parseData);
}
//
} }
} }
#pragma warning(pop) #pragma warning(pop)

View File

@ -3,7 +3,7 @@
#include "utils/hook.hpp" #include "utils/hook.hpp"
//#include "codsrc/clientscript/cscr_animtree.hpp" //#include "codsrc/clientscript/cscr_animtree.hpp"
#ifndef DISABLE_RE_CSCR_ANIMTREE #ifndef DISABLE_RE_CSCR_YACC
namespace re_cscr_animtree namespace re_cscr_animtree
{ {
utils::hook::detour AnimTreeCompileError_hook; utils::hook::detour AnimTreeCompileError_hook;
@ -353,29 +353,24 @@ namespace re_cscr_animtree
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; AnimTreeCompileError_hook.create(game::AnimTreeCompileError.get(), AnimTreeCompileError_stub);
#ifdef RE_CSCR_ANIMTREE_USE_WRAPPERS GetAnimTreeParseProperties_hook.create(game::GetAnimTreeParseProperties.get(), GetAnimTreeParseProperties_stub);
quick = false; Scr_EmitAnimationInternal_hook.create(game::Scr_EmitAnimationInternal_ADDR(), Scr_EmitAnimationInternal_stub);
#endif AnimTreeParseInternal_hook.create(game::AnimTreeParseInternal.get(), AnimTreeParseInternal_stub);
Scr_AnimTreeParse_hook.create(game::Scr_AnimTreeParse_ADDR(), Scr_AnimTreeParse_stub);
AnimTreeCompileError_hook.create(game::AnimTreeCompileError.get(), AnimTreeCompileError_stub, quick); Scr_GetAnimTreeSize_hook.create(game::Scr_GetAnimTreeSize.get(), Scr_GetAnimTreeSize_stub);
GetAnimTreeParseProperties_hook.create(game::GetAnimTreeParseProperties.get(), GetAnimTreeParseProperties_stub, quick); ConnectScriptToAnim_hook.create(game::ConnectScriptToAnim_ADDR(), ConnectScriptToAnim_stub);
Scr_EmitAnimationInternal_hook.create(game::Scr_EmitAnimationInternal_ADDR(), Scr_EmitAnimationInternal_stub, quick); Scr_GetAnimsIndex_hook.create(game::Scr_GetAnimsIndex_ADDR(), Scr_GetAnimsIndex_stub);
AnimTreeParseInternal_hook.create(game::AnimTreeParseInternal.get(), AnimTreeParseInternal_stub, quick); Scr_CreateAnimationTree_hook.create(game::Scr_CreateAnimationTree.get(), Scr_CreateAnimationTree_stub);
Scr_AnimTreeParse_hook.create(game::Scr_AnimTreeParse_ADDR(), Scr_AnimTreeParse_stub, quick); Scr_CheckAnimsDefined_hook.create(game::Scr_CheckAnimsDefined_ADDR(), Scr_CheckAnimsDefined_stub);
Scr_GetAnimTreeSize_hook.create(game::Scr_GetAnimTreeSize.get(), Scr_GetAnimTreeSize_stub, quick); Scr_PrecacheAnimationTree_hook.create(game::Scr_PrecacheAnimationTree.get(), Scr_PrecacheAnimationTree_stub);
ConnectScriptToAnim_hook.create(game::ConnectScriptToAnim_ADDR(), ConnectScriptToAnim_stub, quick); Scr_UsingTreeInternal_hook.create(game::Scr_UsingTreeInternal_ADDR(), Scr_UsingTreeInternal_stub);
Scr_GetAnimsIndex_hook.create(game::Scr_GetAnimsIndex_ADDR(), Scr_GetAnimsIndex_stub, quick); Scr_UsingTree_hook.create(game::Scr_UsingTree_ADDR(), Scr_UsingTree_stub);
Scr_CreateAnimationTree_hook.create(game::Scr_CreateAnimationTree.get(), Scr_CreateAnimationTree_stub, quick); Scr_SetAnimTreeConfigstring_hook.create(game::Scr_SetAnimTreeConfigstring.get(), Scr_SetAnimTreeConfigstring_stub);
Scr_CheckAnimsDefined_hook.create(game::Scr_CheckAnimsDefined_ADDR(), Scr_CheckAnimsDefined_stub, quick); Scr_LoadAnimTreeInternal_hook.create(game::Scr_LoadAnimTreeInternal_ADDR(), Scr_LoadAnimTreeInternal_stub);
Scr_PrecacheAnimationTree_hook.create(game::Scr_PrecacheAnimationTree.get(), Scr_PrecacheAnimationTree_stub, quick); Scr_LoadAnimTreeAtIndex_hook.create(game::Scr_LoadAnimTreeAtIndex_ADDR(), Scr_LoadAnimTreeAtIndex_stub);
Scr_UsingTreeInternal_hook.create(game::Scr_UsingTreeInternal_ADDR(), Scr_UsingTreeInternal_stub, quick); Scr_FindAnimTree_hook.create(game::Scr_FindAnimTree_ADDR(), Scr_FindAnimTree_stub);
Scr_UsingTree_hook.create(game::Scr_UsingTree_ADDR(), Scr_UsingTree_stub, quick); Scr_FindAnim_hook.create(game::Scr_FindAnim_ADDR(), Scr_FindAnim_stub);
Scr_SetAnimTreeConfigstring_hook.create(game::Scr_SetAnimTreeConfigstring.get(), Scr_SetAnimTreeConfigstring_stub, quick);
Scr_LoadAnimTreeInternal_hook.create(game::Scr_LoadAnimTreeInternal_ADDR(), Scr_LoadAnimTreeInternal_stub, quick);
Scr_LoadAnimTreeAtIndex_hook.create(game::Scr_LoadAnimTreeAtIndex_ADDR(), Scr_LoadAnimTreeAtIndex_stub, quick);
Scr_FindAnimTree_hook.create(game::Scr_FindAnimTree_ADDR(), Scr_FindAnimTree_stub, quick);
Scr_FindAnim_hook.create(game::Scr_FindAnim_ADDR(), Scr_FindAnim_stub, quick);
//Original hook function addresses //Original hook function addresses
AnimTreeCompileError_original = AnimTreeCompileError_hook.get_original(); AnimTreeCompileError_original = AnimTreeCompileError_hook.get_original();

View File

@ -3018,161 +3018,156 @@ namespace re_cscr_compiler
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; RemoveRefToValue_hook.create(game::RemoveRefToValue.get(), RemoveRefToValue_stub);
#ifdef RE_CSCR_COMPILER_USE_WRAPPERS Scr_CompileRemoveRefToString_hook.create(game::Scr_CompileRemoveRefToString_ADDR(), Scr_CompileRemoveRefToString_stub);
quick = false; EmitCanonicalString_hook.create(game::EmitCanonicalString_ADDR(), EmitCanonicalString_stub);
#endif CompileTransferRefToString_hook.create(game::CompileTransferRefToString_ADDR(), CompileTransferRefToString_stub);
EmitOpcode_hook.create(game::EmitOpcode.get(), EmitOpcode_stub);
RemoveRefToValue_hook.create(game::RemoveRefToValue.get(), RemoveRefToValue_stub, quick); EmitEnd_hook.create(game::EmitEnd_ADDR(), EmitEnd_stub);
Scr_CompileRemoveRefToString_hook.create(game::Scr_CompileRemoveRefToString_ADDR(), Scr_CompileRemoveRefToString_stub, quick); EmitReturn_hook.create(game::EmitReturn_ADDR(), EmitReturn_stub);
EmitCanonicalString_hook.create(game::EmitCanonicalString_ADDR(), EmitCanonicalString_stub, quick); EmitCodepos_hook.create(game::EmitCodepos_ADDR(), EmitCodepos_stub);
CompileTransferRefToString_hook.create(game::CompileTransferRefToString_ADDR(), CompileTransferRefToString_stub, quick); EmitShort_hook.create(game::EmitShort_ADDR(), EmitShort_stub);
EmitOpcode_hook.create(game::EmitOpcode.get(), EmitOpcode_stub, quick); EmitByte_hook.create(game::EmitByte_ADDR(), EmitByte_stub);
EmitEnd_hook.create(game::EmitEnd_ADDR(), EmitEnd_stub, quick); EmitGetInteger_hook.create(game::EmitGetInteger_ADDR(), EmitGetInteger_stub);
EmitReturn_hook.create(game::EmitReturn_ADDR(), EmitReturn_stub, quick); EmitGetFloat_hook.create(game::EmitGetFloat_ADDR(), EmitGetFloat_stub);
EmitCodepos_hook.create(game::EmitCodepos_ADDR(), EmitCodepos_stub, quick); EmitAnimTree_hook.create(game::EmitAnimTree_ADDR(), EmitAnimTree_stub);
EmitShort_hook.create(game::EmitShort_ADDR(), EmitShort_stub, quick); Scr_FindLocalVarIndex_hook.create(game::Scr_FindLocalVarIndex.get(), Scr_FindLocalVarIndex_stub);
EmitByte_hook.create(game::EmitByte_ADDR(), EmitByte_stub, quick); EmitCreateLocalVars_hook.create(game::EmitCreateLocalVars.get(), EmitCreateLocalVars_stub);
EmitGetInteger_hook.create(game::EmitGetInteger_ADDR(), EmitGetInteger_stub, quick); EmitRemoveLocalVars_hook.create(game::EmitRemoveLocalVars_ADDR(), EmitRemoveLocalVars_stub);
EmitGetFloat_hook.create(game::EmitGetFloat_ADDR(), EmitGetFloat_stub, quick); EmitNOP2_hook.create(game::EmitNOP2_ADDR(), EmitNOP2_stub);
EmitAnimTree_hook.create(game::EmitAnimTree_ADDR(), EmitAnimTree_stub, quick); Scr_InitFromChildBlocks_hook.create(game::Scr_InitFromChildBlocks.get(), Scr_InitFromChildBlocks_stub);
Scr_FindLocalVarIndex_hook.create(game::Scr_FindLocalVarIndex.get(), Scr_FindLocalVarIndex_stub, quick); Scr_AppendChildBlocks_hook.create(game::Scr_AppendChildBlocks_ADDR(), Scr_AppendChildBlocks_stub);
EmitCreateLocalVars_hook.create(game::EmitCreateLocalVars.get(), EmitCreateLocalVars_stub, quick); Scr_MergeChildBlocks_hook.create(game::Scr_MergeChildBlocks.get(), Scr_MergeChildBlocks_stub);
EmitRemoveLocalVars_hook.create(game::EmitRemoveLocalVars_ADDR(), EmitRemoveLocalVars_stub, quick); Scr_TransferBlock_hook.create(game::Scr_TransferBlock_ADDR(), Scr_TransferBlock_stub);
EmitNOP2_hook.create(game::EmitNOP2_ADDR(), EmitNOP2_stub, quick); EmitSafeSetVariableField_hook.create(game::EmitSafeSetVariableField_ADDR(), EmitSafeSetVariableField_stub);
Scr_InitFromChildBlocks_hook.create(game::Scr_InitFromChildBlocks.get(), Scr_InitFromChildBlocks_stub, quick); EmitSafeSetWaittillVariableField_hook.create(game::EmitSafeSetWaittillVariableField_ADDR(), EmitSafeSetWaittillVariableField_stub);
Scr_AppendChildBlocks_hook.create(game::Scr_AppendChildBlocks_ADDR(), Scr_AppendChildBlocks_stub, quick); EmitGetString_hook.create(game::EmitGetString_ADDR(), EmitGetString_stub);
Scr_MergeChildBlocks_hook.create(game::Scr_MergeChildBlocks.get(), Scr_MergeChildBlocks_stub, quick); EmitGetIString_hook.create(game::EmitGetIString_ADDR(), EmitGetIString_stub);
Scr_TransferBlock_hook.create(game::Scr_TransferBlock_ADDR(), Scr_TransferBlock_stub, quick); EmitGetVector_hook.create(game::EmitGetVector_ADDR(), EmitGetVector_stub);
EmitSafeSetVariableField_hook.create(game::EmitSafeSetVariableField_ADDR(), EmitSafeSetVariableField_stub, quick); EmitValue_hook.create(game::EmitValue.get(), EmitValue_stub);
EmitSafeSetWaittillVariableField_hook.create(game::EmitSafeSetWaittillVariableField_ADDR(), EmitSafeSetWaittillVariableField_stub, quick); Scr_PushValue_hook.create(game::Scr_PushValue_ADDR(), Scr_PushValue_stub);
EmitGetString_hook.create(game::EmitGetString_ADDR(), EmitGetString_stub, quick); EmitCastBool_hook.create(game::EmitCastBool_ADDR(), EmitCastBool_stub);
EmitGetIString_hook.create(game::EmitGetIString_ADDR(), EmitGetIString_stub, quick); EmitBoolNot_hook.create(game::EmitBoolNot_ADDR(), EmitBoolNot_stub);
EmitGetVector_hook.create(game::EmitGetVector_ADDR(), EmitGetVector_stub, quick); EmitBoolComplement_hook.create(game::EmitBoolComplement_ADDR(), EmitBoolComplement_stub);
EmitValue_hook.create(game::EmitValue.get(), EmitValue_stub, quick); EmitSize_hook.create(game::EmitSize_ADDR(), EmitSize_stub);
Scr_PushValue_hook.create(game::Scr_PushValue_ADDR(), Scr_PushValue_stub, quick); EmitSelf_hook.create(game::EmitSelf_ADDR(), EmitSelf_stub);
EmitCastBool_hook.create(game::EmitCastBool_ADDR(), EmitCastBool_stub, quick); EmitLevel_hook.create(game::EmitLevel_ADDR(), EmitLevel_stub);
EmitBoolNot_hook.create(game::EmitBoolNot_ADDR(), EmitBoolNot_stub, quick); EmitGame_hook.create(game::EmitGame_ADDR(), EmitGame_stub);
EmitBoolComplement_hook.create(game::EmitBoolComplement_ADDR(), EmitBoolComplement_stub, quick); EmitAnim_hook.create(game::EmitAnim_ADDR(), EmitAnim_stub);
EmitSize_hook.create(game::EmitSize_ADDR(), EmitSize_stub, quick); EmitSelfObject_hook.create(game::EmitSelfObject_ADDR(), EmitSelfObject_stub);
EmitSelf_hook.create(game::EmitSelf_ADDR(), EmitSelf_stub, quick); EmitLevelObject_hook.create(game::EmitLevelObject_ADDR(), EmitLevelObject_stub);
EmitLevel_hook.create(game::EmitLevel_ADDR(), EmitLevel_stub, quick); EmitAnimObject_hook.create(game::EmitAnimObject_ADDR(), EmitAnimObject_stub);
EmitGame_hook.create(game::EmitGame_ADDR(), EmitGame_stub, quick); EmitLocalVariable_hook.create(game::EmitLocalVariable_ADDR(), EmitLocalVariable_stub);
EmitAnim_hook.create(game::EmitAnim_ADDR(), EmitAnim_stub, quick); EmitLocalVariableRef_hook.create(game::EmitLocalVariableRef_ADDR(), EmitLocalVariableRef_stub);
EmitSelfObject_hook.create(game::EmitSelfObject_ADDR(), EmitSelfObject_stub, quick); Scr_RegisterLocalVar_hook.create(game::Scr_RegisterLocalVar.get(), Scr_RegisterLocalVar_stub);
EmitLevelObject_hook.create(game::EmitLevelObject_ADDR(), EmitLevelObject_stub, quick); EmitGameRef_hook.create(game::EmitGameRef_ADDR(), EmitGameRef_stub);
EmitAnimObject_hook.create(game::EmitAnimObject_ADDR(), EmitAnimObject_stub, quick); EmitClearArray_hook.create(game::EmitClearArray_ADDR(), EmitClearArray_stub);
EmitLocalVariable_hook.create(game::EmitLocalVariable_ADDR(), EmitLocalVariable_stub, quick); EmitEmptyArray_hook.create(game::EmitEmptyArray_ADDR(), EmitEmptyArray_stub);
EmitLocalVariableRef_hook.create(game::EmitLocalVariableRef_ADDR(), EmitLocalVariableRef_stub, quick); EmitAnimation_hook.create(game::EmitAnimation_ADDR(), EmitAnimation_stub);
Scr_RegisterLocalVar_hook.create(game::Scr_RegisterLocalVar.get(), Scr_RegisterLocalVar_stub, quick); EmitFieldVariable_hook.create(game::EmitFieldVariable_ADDR(), EmitFieldVariable_stub);
EmitGameRef_hook.create(game::EmitGameRef_ADDR(), EmitGameRef_stub, quick); EmitClearFieldVariable_hook.create(game::EmitClearFieldVariable_ADDR(), EmitClearFieldVariable_stub);
EmitClearArray_hook.create(game::EmitClearArray_ADDR(), EmitClearArray_stub, quick); EmitObject_hook.create(game::EmitObject_ADDR(), EmitObject_stub);
EmitEmptyArray_hook.create(game::EmitEmptyArray_ADDR(), EmitEmptyArray_stub, quick); EmitDecTop_hook.create(game::EmitDecTop_ADDR(), EmitDecTop_stub);
EmitAnimation_hook.create(game::EmitAnimation_ADDR(), EmitAnimation_stub, quick); EmitCastFieldObject_hook.create(game::EmitCastFieldObject.get(), EmitCastFieldObject_stub);
EmitFieldVariable_hook.create(game::EmitFieldVariable_ADDR(), EmitFieldVariable_stub, quick); EmitArrayVariable_hook.create(game::EmitArrayVariable_ADDR(), EmitArrayVariable_stub);
EmitClearFieldVariable_hook.create(game::EmitClearFieldVariable_ADDR(), EmitClearFieldVariable_stub, quick); EmitArrayVariableRef_hook.create(game::EmitArrayVariableRef_ADDR(), EmitArrayVariableRef_stub);
EmitObject_hook.create(game::EmitObject_ADDR(), EmitObject_stub, quick); EmitClearArrayVariable_hook.create(game::EmitClearArrayVariable_ADDR(), EmitClearArrayVariable_stub);
EmitDecTop_hook.create(game::EmitDecTop_ADDR(), EmitDecTop_stub, quick); EmitVariableExpression_hook.create(game::EmitVariableExpression.get(), EmitVariableExpression_stub);
EmitCastFieldObject_hook.create(game::EmitCastFieldObject.get(), EmitCastFieldObject_stub, quick); EmitExpressionList_hook.create(game::EmitExpressionList.get(), EmitExpressionList_stub);
EmitArrayVariable_hook.create(game::EmitArrayVariable_ADDR(), EmitArrayVariable_stub, quick); AddExpressionListOpcodePos_hook.create(game::AddExpressionListOpcodePos_ADDR(), AddExpressionListOpcodePos_stub);
EmitArrayVariableRef_hook.create(game::EmitArrayVariableRef_ADDR(), EmitArrayVariableRef_stub, quick); AddFilePrecache_hook.create(game::AddFilePrecache_ADDR(), AddFilePrecache_stub);
EmitClearArrayVariable_hook.create(game::EmitClearArrayVariable_ADDR(), EmitClearArrayVariable_stub, quick); EmitFunction_hook.create(game::EmitFunction_ADDR(), EmitFunction_stub);
EmitVariableExpression_hook.create(game::EmitVariableExpression.get(), EmitVariableExpression_stub, quick); EmitGetFunction_hook.create(game::EmitGetFunction_ADDR(), EmitGetFunction_stub);
EmitExpressionList_hook.create(game::EmitExpressionList.get(), EmitExpressionList_stub, quick); AddFunction_hook.create(game::AddFunction.get(), AddFunction_stub);
AddExpressionListOpcodePos_hook.create(game::AddExpressionListOpcodePos_ADDR(), AddExpressionListOpcodePos_stub, quick); EmitPostScriptFunction_hook.create(game::EmitPostScriptFunction.get(), EmitPostScriptFunction_stub);
AddFilePrecache_hook.create(game::AddFilePrecache_ADDR(), AddFilePrecache_stub, quick); EmitPostScriptFunctionPointer_hook.create(game::EmitPostScriptFunctionPointer_ADDR(), EmitPostScriptFunctionPointer_stub);
EmitFunction_hook.create(game::EmitFunction_ADDR(), EmitFunction_stub, quick); EmitPostScriptThread_hook.create(game::EmitPostScriptThread_ADDR(), EmitPostScriptThread_stub);
EmitGetFunction_hook.create(game::EmitGetFunction_ADDR(), EmitGetFunction_stub, quick); EmitPostScriptThreadPointer_hook.create(game::EmitPostScriptThreadPointer_ADDR(), EmitPostScriptThreadPointer_stub);
AddFunction_hook.create(game::AddFunction.get(), AddFunction_stub, quick); EmitPostScriptFunctionCall_hook.create(game::EmitPostScriptFunctionCall_ADDR(), EmitPostScriptFunctionCall_stub);
EmitPostScriptFunction_hook.create(game::EmitPostScriptFunction.get(), EmitPostScriptFunction_stub, quick); EmitPostScriptThreadCall_hook.create(game::EmitPostScriptThreadCall_ADDR(), EmitPostScriptThreadCall_stub);
EmitPostScriptFunctionPointer_hook.create(game::EmitPostScriptFunctionPointer_ADDR(), EmitPostScriptFunctionPointer_stub, quick); EmitPreFunctionCall_hook.create(game::EmitPreFunctionCall_ADDR(), EmitPreFunctionCall_stub);
EmitPostScriptThread_hook.create(game::EmitPostScriptThread_ADDR(), EmitPostScriptThread_stub, quick); EmitPostFunctionCall_hook.create(game::EmitPostFunctionCall_ADDR(), EmitPostFunctionCall_stub);
EmitPostScriptThreadPointer_hook.create(game::EmitPostScriptThreadPointer_ADDR(), EmitPostScriptThreadPointer_stub, quick); Scr_BeginDevScript_hook.create(game::Scr_BeginDevScript_ADDR(), Scr_BeginDevScript_stub);
EmitPostScriptFunctionCall_hook.create(game::EmitPostScriptFunctionCall_ADDR(), EmitPostScriptFunctionCall_stub, quick); Scr_EndDevScript_hook.create(game::Scr_EndDevScript_ADDR(), Scr_EndDevScript_stub);
EmitPostScriptThreadCall_hook.create(game::EmitPostScriptThreadCall_ADDR(), EmitPostScriptThreadCall_stub, quick); EmitCallBuiltinOpcode_hook.create(game::EmitCallBuiltinOpcode_ADDR(), EmitCallBuiltinOpcode_stub);
EmitPreFunctionCall_hook.create(game::EmitPreFunctionCall_ADDR(), EmitPreFunctionCall_stub, quick); EmitCallBuiltinMethodOpcode_hook.create(game::EmitCallBuiltinMethodOpcode_ADDR(), EmitCallBuiltinMethodOpcode_stub);
EmitPostFunctionCall_hook.create(game::EmitPostFunctionCall_ADDR(), EmitPostFunctionCall_stub, quick); EmitCall_hook.create(game::EmitCall_ADDR(), EmitCall_stub);
Scr_BeginDevScript_hook.create(game::Scr_BeginDevScript_ADDR(), Scr_BeginDevScript_stub, quick); EmitMethod_hook.create(game::EmitMethod.get(), EmitMethod_stub);
Scr_EndDevScript_hook.create(game::Scr_EndDevScript_ADDR(), Scr_EndDevScript_stub, quick); LinkThread_hook.create(game::LinkThread_ADDR(), LinkThread_stub);
EmitCallBuiltinOpcode_hook.create(game::EmitCallBuiltinOpcode_ADDR(), EmitCallBuiltinOpcode_stub, quick); LinkFile_hook.create(game::LinkFile_ADDR(), LinkFile_stub);
EmitCallBuiltinMethodOpcode_hook.create(game::EmitCallBuiltinMethodOpcode_ADDR(), EmitCallBuiltinMethodOpcode_stub, quick); CheckThreadPosition_hook.create(game::CheckThreadPosition.get(), CheckThreadPosition_stub);
EmitCall_hook.create(game::EmitCall_ADDR(), EmitCall_stub, quick); EmitCallExpression_hook.create(game::EmitCallExpression_ADDR(), EmitCallExpression_stub);
EmitMethod_hook.create(game::EmitMethod.get(), EmitMethod_stub, quick); EmitCallExpressionFieldObject_hook.create(game::EmitCallExpressionFieldObject_ADDR(), EmitCallExpressionFieldObject_stub);
LinkThread_hook.create(game::LinkThread_ADDR(), LinkThread_stub, quick); Scr_CreateVector_hook.create(game::Scr_CreateVector_ADDR(), Scr_CreateVector_stub);
LinkFile_hook.create(game::LinkFile_ADDR(), LinkFile_stub, quick); EvalPrimitiveExpressionList_hook.create(game::EvalPrimitiveExpressionList.get(), EvalPrimitiveExpressionList_stub);
CheckThreadPosition_hook.create(game::CheckThreadPosition.get(), CheckThreadPosition_stub, quick); EmitOrEvalPrimitiveExpressionList_hook.create(game::EmitOrEvalPrimitiveExpressionList_ADDR(), EmitOrEvalPrimitiveExpressionList_stub);
EmitCallExpression_hook.create(game::EmitCallExpression_ADDR(), EmitCallExpression_stub, quick); EmitExpressionListFieldObject_hook.create(game::EmitExpressionListFieldObject_ADDR(), EmitExpressionListFieldObject_stub);
EmitCallExpressionFieldObject_hook.create(game::EmitCallExpressionFieldObject_ADDR(), EmitCallExpressionFieldObject_stub, quick); EvalPrimitiveExpression_hook.create(game::EvalPrimitiveExpression.get(), EvalPrimitiveExpression_stub);
Scr_CreateVector_hook.create(game::Scr_CreateVector_ADDR(), Scr_CreateVector_stub, quick); EmitOrEvalPrimitiveExpression_hook.create(game::EmitOrEvalPrimitiveExpression.get(), EmitOrEvalPrimitiveExpression_stub);
EvalPrimitiveExpressionList_hook.create(game::EvalPrimitiveExpressionList.get(), EvalPrimitiveExpressionList_stub, quick); EmitBoolOrExpression_hook.create(game::EmitBoolOrExpression_ADDR(), EmitBoolOrExpression_stub);
EmitOrEvalPrimitiveExpressionList_hook.create(game::EmitOrEvalPrimitiveExpressionList_ADDR(), EmitOrEvalPrimitiveExpressionList_stub, quick); EmitBoolAndExpression_hook.create(game::EmitBoolAndExpression_ADDR(), EmitBoolAndExpression_stub);
EmitExpressionListFieldObject_hook.create(game::EmitExpressionListFieldObject_ADDR(), EmitExpressionListFieldObject_stub, quick); EvalBinaryOperatorExpression_hook.create(game::EvalBinaryOperatorExpression.get(), EvalBinaryOperatorExpression_stub);
EvalPrimitiveExpression_hook.create(game::EvalPrimitiveExpression.get(), EvalPrimitiveExpression_stub, quick); EmitOrEvalBinaryOperatorExpression_hook.create(game::EmitOrEvalBinaryOperatorExpression_ADDR(), EmitOrEvalBinaryOperatorExpression_stub);
EmitOrEvalPrimitiveExpression_hook.create(game::EmitOrEvalPrimitiveExpression.get(), EmitOrEvalPrimitiveExpression_stub, quick); EmitBinaryEqualsOperatorExpression_hook.create(game::EmitBinaryEqualsOperatorExpression_ADDR(), EmitBinaryEqualsOperatorExpression_stub);
EmitBoolOrExpression_hook.create(game::EmitBoolOrExpression_ADDR(), EmitBoolOrExpression_stub, quick); Scr_CalcLocalVarsVariableExpressionRef_hook.create(game::Scr_CalcLocalVarsVariableExpressionRef_ADDR(), Scr_CalcLocalVarsVariableExpressionRef_stub);
EmitBoolAndExpression_hook.create(game::EmitBoolAndExpression_ADDR(), EmitBoolAndExpression_stub, quick); EvalExpression_hook.create(game::EvalExpression_ADDR(), EvalExpression_stub);
EvalBinaryOperatorExpression_hook.create(game::EvalBinaryOperatorExpression.get(), EvalBinaryOperatorExpression_stub, quick); EmitOrEvalExpression_hook.create(game::EmitOrEvalExpression.get(), EmitOrEvalExpression_stub);
EmitOrEvalBinaryOperatorExpression_hook.create(game::EmitOrEvalBinaryOperatorExpression_ADDR(), EmitOrEvalBinaryOperatorExpression_stub, quick); EmitExpression_hook.create(game::EmitExpression.get(), EmitExpression_stub);
EmitBinaryEqualsOperatorExpression_hook.create(game::EmitBinaryEqualsOperatorExpression_ADDR(), EmitBinaryEqualsOperatorExpression_stub, quick); EmitVariableExpressionRef_hook.create(game::EmitVariableExpressionRef.get(), EmitVariableExpressionRef_stub);
Scr_CalcLocalVarsVariableExpressionRef_hook.create(game::Scr_CalcLocalVarsVariableExpressionRef_ADDR(), Scr_CalcLocalVarsVariableExpressionRef_stub, quick); EmitArrayPrimitiveExpressionRef_hook.create(game::EmitArrayPrimitiveExpressionRef_ADDR(), EmitArrayPrimitiveExpressionRef_stub);
EvalExpression_hook.create(game::EvalExpression_ADDR(), EvalExpression_stub, quick); Scr_CalcLocalVarsArrayVariableRef_hook.create(game::Scr_CalcLocalVarsArrayVariableRef.get(), Scr_CalcLocalVarsArrayVariableRef_stub);
EmitOrEvalExpression_hook.create(game::EmitOrEvalExpression.get(), EmitOrEvalExpression_stub, quick); EmitPrimitiveExpressionFieldObject_hook.create(game::EmitPrimitiveExpressionFieldObject.get(), EmitPrimitiveExpressionFieldObject_stub);
EmitExpression_hook.create(game::EmitExpression.get(), EmitExpression_stub, quick); ConnectBreakStatements_hook.create(game::ConnectBreakStatements_ADDR(), ConnectBreakStatements_stub);
EmitVariableExpressionRef_hook.create(game::EmitVariableExpressionRef.get(), EmitVariableExpressionRef_stub, quick); ConnectContinueStatements_hook.create(game::ConnectContinueStatements_ADDR(), ConnectContinueStatements_stub);
EmitArrayPrimitiveExpressionRef_hook.create(game::EmitArrayPrimitiveExpressionRef_ADDR(), EmitArrayPrimitiveExpressionRef_stub, quick); EmitClearVariableExpression_hook.create(game::EmitClearVariableExpression_ADDR(), EmitClearVariableExpression_stub);
Scr_CalcLocalVarsArrayVariableRef_hook.create(game::Scr_CalcLocalVarsArrayVariableRef.get(), Scr_CalcLocalVarsArrayVariableRef_stub, quick); EmitAssignmentStatement_hook.create(game::EmitAssignmentStatement_ADDR(), EmitAssignmentStatement_stub);
EmitPrimitiveExpressionFieldObject_hook.create(game::EmitPrimitiveExpressionFieldObject.get(), EmitPrimitiveExpressionFieldObject_stub, quick); EmitCallExpressionStatement_hook.create(game::EmitCallExpressionStatement_ADDR(), EmitCallExpressionStatement_stub);
ConnectBreakStatements_hook.create(game::ConnectBreakStatements_ADDR(), ConnectBreakStatements_stub, quick); EmitReturnStatement_hook.create(game::EmitReturnStatement_ADDR(), EmitReturnStatement_stub);
ConnectContinueStatements_hook.create(game::ConnectContinueStatements_ADDR(), ConnectContinueStatements_stub, quick); EmitWaitStatement_hook.create(game::EmitWaitStatement_ADDR(), EmitWaitStatement_stub);
EmitClearVariableExpression_hook.create(game::EmitClearVariableExpression_ADDR(), EmitClearVariableExpression_stub, quick); EmitWaittillFrameEnd_hook.create(game::EmitWaittillFrameEnd_ADDR(), EmitWaittillFrameEnd_stub);
EmitAssignmentStatement_hook.create(game::EmitAssignmentStatement_ADDR(), EmitAssignmentStatement_stub, quick); EmitIfStatement_hook.create(game::EmitIfStatement_ADDR(), EmitIfStatement_stub);
EmitCallExpressionStatement_hook.create(game::EmitCallExpressionStatement_ADDR(), EmitCallExpressionStatement_stub, quick); Scr_CalcLocalVarsIfStatement_hook.create(game::Scr_CalcLocalVarsIfStatement.get(), Scr_CalcLocalVarsIfStatement_stub);
EmitReturnStatement_hook.create(game::EmitReturnStatement_ADDR(), EmitReturnStatement_stub, quick); EmitIfElseStatement_hook.create(game::EmitIfElseStatement.get(), EmitIfElseStatement_stub);
EmitWaitStatement_hook.create(game::EmitWaitStatement_ADDR(), EmitWaitStatement_stub, quick); Scr_CalcLocalVarsIfElseStatement_hook.create(game::Scr_CalcLocalVarsIfElseStatement.get(), Scr_CalcLocalVarsIfElseStatement_stub);
EmitWaittillFrameEnd_hook.create(game::EmitWaittillFrameEnd_ADDR(), EmitWaittillFrameEnd_stub, quick); Scr_AddBreakBlock_hook.create(game::Scr_AddBreakBlock_ADDR(), Scr_AddBreakBlock_stub);
EmitIfStatement_hook.create(game::EmitIfStatement_ADDR(), EmitIfStatement_stub, quick); Scr_AddContinueBlock_hook.create(game::Scr_AddContinueBlock_ADDR(), Scr_AddContinueBlock_stub);
Scr_CalcLocalVarsIfStatement_hook.create(game::Scr_CalcLocalVarsIfStatement.get(), Scr_CalcLocalVarsIfStatement_stub, quick); EmitWhileStatement_hook.create(game::EmitWhileStatement.get(), EmitWhileStatement_stub);
EmitIfElseStatement_hook.create(game::EmitIfElseStatement.get(), EmitIfElseStatement_stub, quick); Scr_CalcLocalVarsWhileStatement_hook.create(game::Scr_CalcLocalVarsWhileStatement.get(), Scr_CalcLocalVarsWhileStatement_stub);
Scr_CalcLocalVarsIfElseStatement_hook.create(game::Scr_CalcLocalVarsIfElseStatement.get(), Scr_CalcLocalVarsIfElseStatement_stub, quick); EmitForStatement_hook.create(game::EmitForStatement.get(), EmitForStatement_stub);
Scr_AddBreakBlock_hook.create(game::Scr_AddBreakBlock_ADDR(), Scr_AddBreakBlock_stub, quick); Scr_CalcLocalVarsForStatement_hook.create(game::Scr_CalcLocalVarsForStatement.get(), Scr_CalcLocalVarsForStatement_stub);
Scr_AddContinueBlock_hook.create(game::Scr_AddContinueBlock_ADDR(), Scr_AddContinueBlock_stub, quick); EmitIncStatement_hook.create(game::EmitIncStatement_ADDR(), EmitIncStatement_stub);
EmitWhileStatement_hook.create(game::EmitWhileStatement.get(), EmitWhileStatement_stub, quick); EmitDecStatement_hook.create(game::EmitDecStatement_ADDR(), EmitDecStatement_stub);
Scr_CalcLocalVarsWhileStatement_hook.create(game::Scr_CalcLocalVarsWhileStatement.get(), Scr_CalcLocalVarsWhileStatement_stub, quick); Scr_CalcLocalVarsFormalParameterListInternal_hook.create(game::Scr_CalcLocalVarsFormalParameterListInternal_ADDR(), Scr_CalcLocalVarsFormalParameterListInternal_stub);
EmitForStatement_hook.create(game::EmitForStatement.get(), EmitForStatement_stub, quick); EmitWaittillStatement_hook.create(game::EmitWaittillStatement_ADDR(), EmitWaittillStatement_stub);
Scr_CalcLocalVarsForStatement_hook.create(game::Scr_CalcLocalVarsForStatement.get(), Scr_CalcLocalVarsForStatement_stub, quick); EmitWaittillmatchStatement_hook.create(game::EmitWaittillmatchStatement_ADDR(), EmitWaittillmatchStatement_stub);
EmitIncStatement_hook.create(game::EmitIncStatement_ADDR(), EmitIncStatement_stub, quick); EmitNotifyStatement_hook.create(game::EmitNotifyStatement_ADDR(), EmitNotifyStatement_stub);
EmitDecStatement_hook.create(game::EmitDecStatement_ADDR(), EmitDecStatement_stub, quick); EmitEndOnStatement_hook.create(game::EmitEndOnStatement_ADDR(), EmitEndOnStatement_stub);
Scr_CalcLocalVarsFormalParameterListInternal_hook.create(game::Scr_CalcLocalVarsFormalParameterListInternal_ADDR(), Scr_CalcLocalVarsFormalParameterListInternal_stub, quick); CompareCaseInfo_hook.create(game::CompareCaseInfo.get(), CompareCaseInfo_stub);
EmitWaittillStatement_hook.create(game::EmitWaittillStatement_ADDR(), EmitWaittillStatement_stub, quick); EmitCaseStatement_hook.create(game::EmitCaseStatement_ADDR(), EmitCaseStatement_stub);
EmitWaittillmatchStatement_hook.create(game::EmitWaittillmatchStatement_ADDR(), EmitWaittillmatchStatement_stub, quick); EmitSwitchStatementList_hook.create(game::EmitSwitchStatementList.get(), EmitSwitchStatementList_stub);
EmitNotifyStatement_hook.create(game::EmitNotifyStatement_ADDR(), EmitNotifyStatement_stub, quick); Scr_CalcLocalVarsSwitchStatement_hook.create(game::Scr_CalcLocalVarsSwitchStatement.get(), Scr_CalcLocalVarsSwitchStatement_stub);
EmitEndOnStatement_hook.create(game::EmitEndOnStatement_ADDR(), EmitEndOnStatement_stub, quick); EmitSwitchStatement_hook.create(game::EmitSwitchStatement.get(), EmitSwitchStatement_stub);
CompareCaseInfo_hook.create(game::CompareCaseInfo.get(), CompareCaseInfo_stub, quick); EmitCaseStatementInfo_hook.create(game::EmitCaseStatementInfo_ADDR(), EmitCaseStatementInfo_stub);
EmitCaseStatement_hook.create(game::EmitCaseStatement_ADDR(), EmitCaseStatement_stub, quick); EmitBreakStatement_hook.create(game::EmitBreakStatement_ADDR(), EmitBreakStatement_stub);
EmitSwitchStatementList_hook.create(game::EmitSwitchStatementList.get(), EmitSwitchStatementList_stub, quick); EmitContinueStatement_hook.create(game::EmitContinueStatement_ADDR(), EmitContinueStatement_stub);
Scr_CalcLocalVarsSwitchStatement_hook.create(game::Scr_CalcLocalVarsSwitchStatement.get(), Scr_CalcLocalVarsSwitchStatement_stub, quick); EmitProfStatement_hook.create(game::EmitProfStatement_ADDR(), EmitProfStatement_stub);
EmitSwitchStatement_hook.create(game::EmitSwitchStatement.get(), EmitSwitchStatement_stub, quick); EmitStatement_hook.create(game::EmitStatement.get(), EmitStatement_stub);
EmitCaseStatementInfo_hook.create(game::EmitCaseStatementInfo_ADDR(), EmitCaseStatementInfo_stub, quick); Scr_CalcLocalVarsStatement_hook.create(game::Scr_CalcLocalVarsStatement.get(), Scr_CalcLocalVarsStatement_stub);
EmitBreakStatement_hook.create(game::EmitBreakStatement_ADDR(), EmitBreakStatement_stub, quick); EmitStatementList_hook.create(game::EmitStatementList.get(), EmitStatementList_stub);
EmitContinueStatement_hook.create(game::EmitContinueStatement_ADDR(), EmitContinueStatement_stub, quick); Scr_CalcLocalVarsStatementList_hook.create(game::Scr_CalcLocalVarsStatementList_ADDR(), Scr_CalcLocalVarsStatementList_stub);
EmitProfStatement_hook.create(game::EmitProfStatement_ADDR(), EmitProfStatement_stub, quick); Scr_CalcLocalVarsDeveloperStatementList_hook.create(game::Scr_CalcLocalVarsDeveloperStatementList.get(), Scr_CalcLocalVarsDeveloperStatementList_stub);
EmitStatement_hook.create(game::EmitStatement.get(), EmitStatement_stub, quick); EmitDeveloperStatementList_hook.create(game::EmitDeveloperStatementList.get(), EmitDeveloperStatementList_stub);
Scr_CalcLocalVarsStatement_hook.create(game::Scr_CalcLocalVarsStatement.get(), Scr_CalcLocalVarsStatement_stub, quick); EmitFormalParameterList_hook.create(game::EmitFormalParameterList_ADDR(), EmitFormalParameterList_stub);
EmitStatementList_hook.create(game::EmitStatementList.get(), EmitStatementList_stub, quick); SpecifyThread_hook.create(game::SpecifyThread_ADDR(), SpecifyThread_stub);
Scr_CalcLocalVarsStatementList_hook.create(game::Scr_CalcLocalVarsStatementList_ADDR(), Scr_CalcLocalVarsStatementList_stub, quick); EmitThreadInternal_hook.create(game::EmitThreadInternal_ADDR(), EmitThreadInternal_stub);
Scr_CalcLocalVarsDeveloperStatementList_hook.create(game::Scr_CalcLocalVarsDeveloperStatementList.get(), Scr_CalcLocalVarsDeveloperStatementList_stub, quick); Scr_CalcLocalVarsThread_hook.create(game::Scr_CalcLocalVarsThread_ADDR(), Scr_CalcLocalVarsThread_stub);
EmitDeveloperStatementList_hook.create(game::EmitDeveloperStatementList.get(), EmitDeveloperStatementList_stub, quick); InitThread_hook.create(game::InitThread_ADDR(), InitThread_stub);
EmitFormalParameterList_hook.create(game::EmitFormalParameterList_ADDR(), EmitFormalParameterList_stub, quick); EmitNormalThread_hook.create(game::EmitNormalThread_ADDR(), EmitNormalThread_stub);
SpecifyThread_hook.create(game::SpecifyThread_ADDR(), SpecifyThread_stub, quick); EmitDeveloperThread_hook.create(game::EmitDeveloperThread_ADDR(), EmitDeveloperThread_stub);
EmitThreadInternal_hook.create(game::EmitThreadInternal_ADDR(), EmitThreadInternal_stub, quick); EmitThread_hook.create(game::EmitThread_ADDR(), EmitThread_stub);
Scr_CalcLocalVarsThread_hook.create(game::Scr_CalcLocalVarsThread_ADDR(), Scr_CalcLocalVarsThread_stub, quick); EmitThreadList_hook.create(game::EmitThreadList.get(), EmitThreadList_stub);
InitThread_hook.create(game::InitThread_ADDR(), InitThread_stub, quick); EmitInclude_hook.create(game::EmitInclude_ADDR(), EmitInclude_stub);
EmitNormalThread_hook.create(game::EmitNormalThread_ADDR(), EmitNormalThread_stub, quick); ScriptCompile_hook.create(game::ScriptCompile_ADDR(), ScriptCompile_stub);
EmitDeveloperThread_hook.create(game::EmitDeveloperThread_ADDR(), EmitDeveloperThread_stub, quick);
EmitThread_hook.create(game::EmitThread_ADDR(), EmitThread_stub, quick);
EmitThreadList_hook.create(game::EmitThreadList.get(), EmitThreadList_stub, quick);
EmitInclude_hook.create(game::EmitInclude_ADDR(), EmitInclude_stub, quick);
ScriptCompile_hook.create(game::ScriptCompile_ADDR(), ScriptCompile_stub, quick);
//Original hook function addresses //Original hook function addresses
RemoveRefToValue_original = RemoveRefToValue_hook.get_original(); RemoveRefToValue_original = RemoveRefToValue_hook.get_original();

View File

@ -272,24 +272,19 @@ namespace re_cscr_main
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; Scr_IsIdentifier_hook.create(game::Scr_IsIdentifier_ADDR(), Scr_IsIdentifier_stub);
#ifdef RE_CSCR_MAIN_USE_WRAPPERS Scr_GetFunctionHandle_hook.create(game::Scr_GetFunctionHandle_ADDR(), Scr_GetFunctionHandle_stub);
quick = false; SL_TransferToCanonicalString_hook.create(game::SL_TransferToCanonicalString_ADDR(), SL_TransferToCanonicalString_stub);
#endif SL_GetCanonicalString_hook.create(game::SL_GetCanonicalString_ADDR(), SL_GetCanonicalString_stub);
Scr_BeginLoadScripts_hook.create(game::Scr_BeginLoadScripts_ADDR(), Scr_BeginLoadScripts_stub);
Scr_IsIdentifier_hook.create(game::Scr_IsIdentifier_ADDR(), Scr_IsIdentifier_stub, quick); Scr_BeginLoadAnimTrees_hook.create(game::Scr_BeginLoadAnimTrees_ADDR(), Scr_BeginLoadAnimTrees_stub);
Scr_GetFunctionHandle_hook.create(game::Scr_GetFunctionHandle_ADDR(), Scr_GetFunctionHandle_stub, quick); Scr_ScanFile_hook.create(game::Scr_ScanFile_ADDR(), Scr_ScanFile_stub);
SL_TransferToCanonicalString_hook.create(game::SL_TransferToCanonicalString_ADDR(), SL_TransferToCanonicalString_stub, quick); Scr_LoadScriptInternal_hook.create(game::Scr_LoadScriptInternal.get(), Scr_LoadScriptInternal_stub);
SL_GetCanonicalString_hook.create(game::SL_GetCanonicalString_ADDR(), SL_GetCanonicalString_stub, quick); Scr_LoadScript_hook.create(game::Scr_LoadScript_ADDR(), Scr_LoadScript_stub);
Scr_BeginLoadScripts_hook.create(game::Scr_BeginLoadScripts_ADDR(), Scr_BeginLoadScripts_stub, quick); Scr_EndLoadScripts_hook.create(game::Scr_EndLoadScripts.get(), Scr_EndLoadScripts_stub);
Scr_BeginLoadAnimTrees_hook.create(game::Scr_BeginLoadAnimTrees_ADDR(), Scr_BeginLoadAnimTrees_stub, quick); Scr_PrecacheAnimTrees_hook.create(game::Scr_PrecacheAnimTrees.get(), Scr_PrecacheAnimTrees_stub);
Scr_ScanFile_hook.create(game::Scr_ScanFile_ADDR(), Scr_ScanFile_stub, quick); Scr_EndLoadAnimTrees_hook.create(game::Scr_EndLoadAnimTrees.get(), Scr_EndLoadAnimTrees_stub);
Scr_LoadScriptInternal_hook.create(game::Scr_LoadScriptInternal.get(), Scr_LoadScriptInternal_stub, quick); Scr_FreeScripts_hook.create(game::Scr_FreeScripts_ADDR(), Scr_FreeScripts_stub);
Scr_LoadScript_hook.create(game::Scr_LoadScript_ADDR(), Scr_LoadScript_stub, quick);
Scr_EndLoadScripts_hook.create(game::Scr_EndLoadScripts.get(), Scr_EndLoadScripts_stub, quick);
Scr_PrecacheAnimTrees_hook.create(game::Scr_PrecacheAnimTrees.get(), Scr_PrecacheAnimTrees_stub, quick);
Scr_EndLoadAnimTrees_hook.create(game::Scr_EndLoadAnimTrees.get(), Scr_EndLoadAnimTrees_stub, quick);
Scr_FreeScripts_hook.create(game::Scr_FreeScripts_ADDR(), Scr_FreeScripts_stub, quick);
//Original hook function addresses //Original hook function addresses
Scr_IsIdentifier_original = Scr_IsIdentifier_hook.get_original(); Scr_IsIdentifier_original = Scr_IsIdentifier_hook.get_original();

View File

@ -269,25 +269,20 @@ namespace re_cscr_memorytree
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; MT_GetSubTreeSize_hook.create(game::MT_GetSubTreeSize.get(), MT_GetSubTreeSize_stub);
#ifdef RE_CSCR_MEMORYTREE_USE_WRAPPERS MT_DumpTree_hook.create(game::MT_DumpTree.get(), MT_DumpTree_stub);
quick = false; MT_InitBits_hook.create(game::MT_InitBits_ADDR(), MT_InitBits_stub);
#endif MT_GetScore_hook.create(game::MT_GetScore_ADDR(), MT_GetScore_stub);
MT_AddMemoryNode_hook.create(game::MT_AddMemoryNode.get(), MT_AddMemoryNode_stub);
MT_GetSubTreeSize_hook.create(game::MT_GetSubTreeSize.get(), MT_GetSubTreeSize_stub, quick); MT_RemoveMemoryNode_hook.create(game::MT_RemoveMemoryNode.get(), MT_RemoveMemoryNode_stub);
MT_DumpTree_hook.create(game::MT_DumpTree.get(), MT_DumpTree_stub, quick); MT_RemoveHeadMemoryNode_hook.create(game::MT_RemoveHeadMemoryNode.get(), MT_RemoveHeadMemoryNode_stub);
MT_InitBits_hook.create(game::MT_InitBits_ADDR(), MT_InitBits_stub, quick); MT_Init_hook.create(game::MT_Init_ADDR(), MT_Init_stub);
MT_GetScore_hook.create(game::MT_GetScore_ADDR(), MT_GetScore_stub, quick); MT_Error_hook.create(game::MT_Error_ADDR(), MT_Error_stub);
MT_AddMemoryNode_hook.create(game::MT_AddMemoryNode.get(), MT_AddMemoryNode_stub, quick); MT_GetSize_hook.create(game::MT_GetSize_ADDR(), MT_GetSize_stub);
MT_RemoveMemoryNode_hook.create(game::MT_RemoveMemoryNode.get(), MT_RemoveMemoryNode_stub, quick); MT_AllocIndex_hook.create(game::MT_AllocIndex_ADDR(), MT_AllocIndex_stub);
MT_RemoveHeadMemoryNode_hook.create(game::MT_RemoveHeadMemoryNode.get(), MT_RemoveHeadMemoryNode_stub, quick); MT_FreeIndex_hook.create(game::MT_FreeIndex_ADDR(), MT_FreeIndex_stub);
MT_Init_hook.create(game::MT_Init_ADDR(), MT_Init_stub, quick); MT_Alloc_hook.create(game::MT_Alloc_ADDR(), MT_Alloc_stub);
MT_Error_hook.create(game::MT_Error_ADDR(), MT_Error_stub, quick); MT_Free_hook.create(game::MT_Free.get(), MT_Free_stub);
MT_GetSize_hook.create(game::MT_GetSize_ADDR(), MT_GetSize_stub, quick);
MT_AllocIndex_hook.create(game::MT_AllocIndex_ADDR(), MT_AllocIndex_stub, quick);
MT_FreeIndex_hook.create(game::MT_FreeIndex_ADDR(), MT_FreeIndex_stub, quick);
MT_Alloc_hook.create(game::MT_Alloc_ADDR(), MT_Alloc_stub, quick);
MT_Free_hook.create(game::MT_Free.get(), MT_Free_stub, quick);
//Original hook function addresses //Original hook function addresses
MT_GetSubTreeSize_original = MT_GetSubTreeSize_hook.get_original(); MT_GetSubTreeSize_original = MT_GetSubTreeSize_hook.get_original();

View File

@ -533,34 +533,29 @@ namespace re_cscr_parser
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; Scr_InitOpcodeLookup_hook.create(game::Scr_InitOpcodeLookup_ADDR(), Scr_InitOpcodeLookup_stub);
#ifdef RE_CSCR_PARSER_USE_WRAPPERS Scr_ShutdownOpcodeLookup_hook.create(game::Scr_ShutdownOpcodeLookup_ADDR(), Scr_ShutdownOpcodeLookup_stub);
quick = false; AddOpcodePos_hook.create(game::AddOpcodePos_ADDR(), AddOpcodePos_stub);
#endif RemoveOpcodePos_hook.create(game::RemoveOpcodePos_ADDR(), RemoveOpcodePos_stub);
AddThreadStartOpcodePos_hook.create(game::AddThreadStartOpcodePos_ADDR(), AddThreadStartOpcodePos_stub);
Scr_InitOpcodeLookup_hook.create(game::Scr_InitOpcodeLookup_ADDR(), Scr_InitOpcodeLookup_stub, quick); Scr_GetSourceBuffer_hook.create(game::Scr_GetSourceBuffer_ADDR(), Scr_GetSourceBuffer_stub);
Scr_ShutdownOpcodeLookup_hook.create(game::Scr_ShutdownOpcodeLookup_ADDR(), Scr_ShutdownOpcodeLookup_stub, quick); Scr_GetLineNumInternal_hook.create(game::Scr_GetLineNumInternal_ADDR(), Scr_GetLineNumInternal_stub);
AddOpcodePos_hook.create(game::AddOpcodePos_ADDR(), AddOpcodePos_stub, quick); Scr_GetNewSourceBuffer_hook.create(game::Scr_GetNewSourceBuffer_ADDR(), Scr_GetNewSourceBuffer_stub);
RemoveOpcodePos_hook.create(game::RemoveOpcodePos_ADDR(), RemoveOpcodePos_stub, quick); Scr_AddSourceBufferInternal_hook.create(game::Scr_AddSourceBufferInternal_ADDR(), Scr_AddSourceBufferInternal_stub);
AddThreadStartOpcodePos_hook.create(game::AddThreadStartOpcodePos_ADDR(), AddThreadStartOpcodePos_stub, quick); Scr_ReadFile_FastFile_hook.create(game::Scr_ReadFile_FastFile.get(), Scr_ReadFile_FastFile_stub);
Scr_GetSourceBuffer_hook.create(game::Scr_GetSourceBuffer_ADDR(), Scr_GetSourceBuffer_stub, quick); Scr_ReadFile_LoadObj_hook.create(game::Scr_ReadFile_LoadObj.get(), Scr_ReadFile_LoadObj_stub);
Scr_GetLineNumInternal_hook.create(game::Scr_GetLineNumInternal_ADDR(), Scr_GetLineNumInternal_stub, quick); Scr_ReadFile_hook.create(game::Scr_ReadFile_ADDR(), Scr_ReadFile_stub);
Scr_GetNewSourceBuffer_hook.create(game::Scr_GetNewSourceBuffer_ADDR(), Scr_GetNewSourceBuffer_stub, quick); Scr_AddSourceBuffer_hook.create(game::Scr_AddSourceBuffer_ADDR(), Scr_AddSourceBuffer_stub);
Scr_AddSourceBufferInternal_hook.create(game::Scr_AddSourceBufferInternal_ADDR(), Scr_AddSourceBufferInternal_stub, quick); Scr_CopyFormattedLine_hook.create(game::Scr_CopyFormattedLine_ADDR(), Scr_CopyFormattedLine_stub);
Scr_ReadFile_FastFile_hook.create(game::Scr_ReadFile_FastFile.get(), Scr_ReadFile_FastFile_stub, quick); Scr_GetLineInfo_hook.create(game::Scr_GetLineInfo_ADDR(), Scr_GetLineInfo_stub);
Scr_ReadFile_LoadObj_hook.create(game::Scr_ReadFile_LoadObj.get(), Scr_ReadFile_LoadObj_stub, quick); Scr_PrintSourcePos_hook.create(game::Scr_PrintSourcePos_ADDR(), Scr_PrintSourcePos_stub);
Scr_ReadFile_hook.create(game::Scr_ReadFile_ADDR(), Scr_ReadFile_stub, quick); Scr_GetPrevSourcePosOpcodeLookup_hook.create(game::Scr_GetPrevSourcePosOpcodeLookup_ADDR(), Scr_GetPrevSourcePosOpcodeLookup_stub);
Scr_AddSourceBuffer_hook.create(game::Scr_AddSourceBuffer_ADDR(), Scr_AddSourceBuffer_stub, quick); Scr_GetTextSourcePos_hook.create(game::Scr_GetTextSourcePos_ADDR(), Scr_GetTextSourcePos_stub);
Scr_CopyFormattedLine_hook.create(game::Scr_CopyFormattedLine_ADDR(), Scr_CopyFormattedLine_stub, quick); Scr_PrintPrevCodePos_hook.create(game::Scr_PrintPrevCodePos_ADDR(), Scr_PrintPrevCodePos_stub);
Scr_GetLineInfo_hook.create(game::Scr_GetLineInfo_ADDR(), Scr_GetLineInfo_stub, quick); CompileError_hook.create(game::CompileError.get(), CompileError_stub);
Scr_PrintSourcePos_hook.create(game::Scr_PrintSourcePos_ADDR(), Scr_PrintSourcePos_stub, quick); CompileError2_hook.create(game::CompileError2_ADDR(), CompileError2_stub);
Scr_GetPrevSourcePosOpcodeLookup_hook.create(game::Scr_GetPrevSourcePosOpcodeLookup_ADDR(), Scr_GetPrevSourcePosOpcodeLookup_stub, quick); RuntimeErrorInternal_hook.create(game::RuntimeErrorInternal_ADDR(), RuntimeErrorInternal_stub);
Scr_GetTextSourcePos_hook.create(game::Scr_GetTextSourcePos_ADDR(), Scr_GetTextSourcePos_stub, quick); RuntimeError_hook.create(game::RuntimeError_ADDR(), RuntimeError_stub);
Scr_PrintPrevCodePos_hook.create(game::Scr_PrintPrevCodePos_ADDR(), Scr_PrintPrevCodePos_stub, quick);
CompileError_hook.create(game::CompileError.get(), CompileError_stub, quick);
CompileError2_hook.create(game::CompileError2_ADDR(), CompileError2_stub, quick);
RuntimeErrorInternal_hook.create(game::RuntimeErrorInternal_ADDR(), RuntimeErrorInternal_stub, quick);
RuntimeError_hook.create(game::RuntimeError_ADDR(), RuntimeError_stub, quick);
//Original hook function addresses //Original hook function addresses
Scr_InitOpcodeLookup_original = Scr_InitOpcodeLookup_hook.get_original(); Scr_InitOpcodeLookup_original = Scr_InitOpcodeLookup_hook.get_original();

View File

@ -160,24 +160,19 @@ namespace re_cscr_parsetree
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; Scr_InitAllocNode_hook.create(game::Scr_InitAllocNode.get(), Scr_InitAllocNode_stub);
#ifdef RE_CSCR_PARSETREE_USE_WRAPPERS node0_hook.create(game::node0.get(), node0_stub);
quick = false; node1_hook.create(game::node1.get(), node1_stub);
#endif node2_hook.create(game::node2.get(), node2_stub);
node3_hook.create(game::node3.get(), node3_stub);
Scr_InitAllocNode_hook.create(game::Scr_InitAllocNode.get(), Scr_InitAllocNode_stub, quick); node4_hook.create(game::node4.get(), node4_stub);
node0_hook.create(game::node0.get(), node0_stub, quick); node5_hook.create(game::node5.get(), node5_stub);
node1_hook.create(game::node1.get(), node1_stub, quick); node6_hook.create(game::node6.get(), node6_stub);
node2_hook.create(game::node2.get(), node2_stub, quick); node7_hook.create(game::node7.get(), node7_stub);
node3_hook.create(game::node3.get(), node3_stub, quick); node8_hook.create(game::node8.get(), node8_stub);
node4_hook.create(game::node4.get(), node4_stub, quick); linked_list_end_hook.create(game::linked_list_end.get(), linked_list_end_stub);
node5_hook.create(game::node5.get(), node5_stub, quick); prepend_node_hook.create(game::prepend_node.get(), prepend_node_stub);
node6_hook.create(game::node6.get(), node6_stub, quick); append_node_hook.create(game::append_node.get(), append_node_stub);
node7_hook.create(game::node7.get(), node7_stub, quick);
node8_hook.create(game::node8.get(), node8_stub, quick);
linked_list_end_hook.create(game::linked_list_end.get(), linked_list_end_stub, quick);
prepend_node_hook.create(game::prepend_node.get(), prepend_node_stub, quick);
append_node_hook.create(game::append_node.get(), append_node_stub, quick);
//Original hook function addresses //Original hook function addresses
Scr_InitAllocNode_original = Scr_InitAllocNode_hook.get_original(); Scr_InitAllocNode_original = Scr_InitAllocNode_hook.get_original();

View File

@ -64,13 +64,8 @@ namespace re_cscr_readwrite
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; FindVariableIndexInternal2_hook.create(game::FindVariableIndexInternal2_ADDR(), FindVariableIndexInternal2_stub);
#ifdef RE_CSCR_READWRITE_USE_WRAPPERS FindLastSibling_hook.create(game::FindLastSibling_ADDR(), FindLastSibling_stub);
quick = false;
#endif
FindVariableIndexInternal2_hook.create(game::FindVariableIndexInternal2_ADDR(), FindVariableIndexInternal2_stub, quick);
FindLastSibling_hook.create(game::FindLastSibling_ADDR(), FindLastSibling_stub, quick);
//Original hook function addresses //Original hook function addresses
FindVariableIndexInternal2_original = FindVariableIndexInternal2_hook.get_original(); FindVariableIndexInternal2_original = FindVariableIndexInternal2_hook.get_original();

View File

@ -585,39 +585,34 @@ namespace re_cscr_stringlist
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; SL_ConvertToString_hook.create(game::SL_ConvertToString_ADDR(), SL_ConvertToString_stub);
#ifdef RE_CSCR_STRINGLIST_USE_WRAPPERS SL_GetStringLen_hook.create(game::SL_GetStringLen_ADDR(), SL_GetStringLen_stub);
quick = false; GetHashCode_hook.create(game::GetHashCode_ADDR(), GetHashCode_stub);
#endif SL_Init_hook.create(game::SL_Init_ADDR(), SL_Init_stub);
SL_FindStringOfSize_hook.create(game::SL_FindStringOfSize_ADDR(), SL_FindStringOfSize_stub);
SL_ConvertToString_hook.create(game::SL_ConvertToString_ADDR(), SL_ConvertToString_stub, quick); SL_FindString_hook.create(game::SL_FindString_ADDR(), SL_FindString_stub);
SL_GetStringLen_hook.create(game::SL_GetStringLen_ADDR(), SL_GetStringLen_stub, quick); SL_FindLowercaseString_hook.create(game::SL_FindLowercaseString.get(), SL_FindLowercaseString_stub);
GetHashCode_hook.create(game::GetHashCode_ADDR(), GetHashCode_stub, quick); SL_AddUserInternal_hook.create(game::SL_AddUserInternal_ADDR(), SL_AddUserInternal_stub);
SL_Init_hook.create(game::SL_Init_ADDR(), SL_Init_stub, quick); Mark_ScriptStringCustom_hook.create(game::Mark_ScriptStringCustom_ADDR(), Mark_ScriptStringCustom_stub);
SL_FindStringOfSize_hook.create(game::SL_FindStringOfSize_ADDR(), SL_FindStringOfSize_stub, quick); SL_GetStringOfSize_hook.create(game::SL_GetStringOfSize.get(), SL_GetStringOfSize_stub);
SL_FindString_hook.create(game::SL_FindString_ADDR(), SL_FindString_stub, quick); SL_GetString__hook.create(game::SL_GetString__ADDR(), SL_GetString__stub);
SL_FindLowercaseString_hook.create(game::SL_FindLowercaseString.get(), SL_FindLowercaseString_stub, quick); SL_GetString__0_hook.create(game::SL_GetString__0_ADDR(), SL_GetString__0_stub);
SL_AddUserInternal_hook.create(game::SL_AddUserInternal_ADDR(), SL_AddUserInternal_stub, quick); SL_GetLowercaseStringOfLen_hook.create(game::SL_GetLowercaseStringOfLen.get(), SL_GetLowercaseStringOfLen_stub);
Mark_ScriptStringCustom_hook.create(game::Mark_ScriptStringCustom_ADDR(), Mark_ScriptStringCustom_stub, quick); SL_GetLowercaseString_hook.create(game::SL_GetLowercaseString_ADDR(), SL_GetLowercaseString_stub);
SL_GetStringOfSize_hook.create(game::SL_GetStringOfSize.get(), SL_GetStringOfSize_stub, quick); SL_ConvertToLowercase_hook.create(game::SL_ConvertToLowercase.get(), SL_ConvertToLowercase_stub);
SL_GetString__hook.create(game::SL_GetString__ADDR(), SL_GetString__stub, quick); SL_TransferRefToUser_hook.create(game::SL_TransferRefToUser_ADDR(), SL_TransferRefToUser_stub);
SL_GetString__0_hook.create(game::SL_GetString__0_ADDR(), SL_GetString__0_stub, quick); SL_FreeString_hook.create(game::SL_FreeString.get(), SL_FreeString_stub);
SL_GetLowercaseStringOfLen_hook.create(game::SL_GetLowercaseStringOfLen.get(), SL_GetLowercaseStringOfLen_stub, quick); SL_RemoveRefToString_hook.create(game::SL_RemoveRefToString_ADDR(), SL_RemoveRefToString_stub);
SL_GetLowercaseString_hook.create(game::SL_GetLowercaseString_ADDR(), SL_GetLowercaseString_stub, quick); Scr_SetString_hook.create(game::Scr_SetString_ADDR(), Scr_SetString_stub);
SL_ConvertToLowercase_hook.create(game::SL_ConvertToLowercase.get(), SL_ConvertToLowercase_stub, quick); Scr_SetStringFromCharString_hook.create(game::Scr_SetStringFromCharString_ADDR(), Scr_SetStringFromCharString_stub);
SL_TransferRefToUser_hook.create(game::SL_TransferRefToUser_ADDR(), SL_TransferRefToUser_stub, quick); GScr_AllocString_hook.create(game::GScr_AllocString_ADDR(), GScr_AllocString_stub);
SL_FreeString_hook.create(game::SL_FreeString.get(), SL_FreeString_stub, quick); SL_GetStringForFloat_hook.create(game::SL_GetStringForFloat_ADDR(), SL_GetStringForFloat_stub);
SL_RemoveRefToString_hook.create(game::SL_RemoveRefToString_ADDR(), SL_RemoveRefToString_stub, quick); SL_GetStringForInt_hook.create(game::SL_GetStringForInt_ADDR(), SL_GetStringForInt_stub);
Scr_SetString_hook.create(game::Scr_SetString_ADDR(), Scr_SetString_stub, quick); SL_GetStringForVector_hook.create(game::SL_GetStringForVector_ADDR(), SL_GetStringForVector_stub);
Scr_SetStringFromCharString_hook.create(game::Scr_SetStringFromCharString_ADDR(), Scr_SetStringFromCharString_stub, quick); SL_ShutdownSystem_hook.create(game::SL_ShutdownSystem_ADDR(), SL_ShutdownSystem_stub);
GScr_AllocString_hook.create(game::GScr_AllocString_ADDR(), GScr_AllocString_stub, quick); SL_TransferSystem_hook.create(game::SL_TransferSystem.get(), SL_TransferSystem_stub);
SL_GetStringForFloat_hook.create(game::SL_GetStringForFloat_ADDR(), SL_GetStringForFloat_stub, quick); SL_CreateCanonicalFilename_hook.create(game::SL_CreateCanonicalFilename_ADDR(), SL_CreateCanonicalFilename_stub);
SL_GetStringForInt_hook.create(game::SL_GetStringForInt_ADDR(), SL_GetStringForInt_stub, quick); Scr_CreateCanonicalFilename_hook.create(game::Scr_CreateCanonicalFilename.get(), Scr_CreateCanonicalFilename_stub);
SL_GetStringForVector_hook.create(game::SL_GetStringForVector_ADDR(), SL_GetStringForVector_stub, quick);
SL_ShutdownSystem_hook.create(game::SL_ShutdownSystem_ADDR(), SL_ShutdownSystem_stub, quick);
SL_TransferSystem_hook.create(game::SL_TransferSystem.get(), SL_TransferSystem_stub, quick);
SL_CreateCanonicalFilename_hook.create(game::SL_CreateCanonicalFilename_ADDR(), SL_CreateCanonicalFilename_stub, quick);
Scr_CreateCanonicalFilename_hook.create(game::Scr_CreateCanonicalFilename.get(), Scr_CreateCanonicalFilename_stub, quick);
//Original hook function addresses //Original hook function addresses
SL_ConvertToString_original = SL_ConvertToString_hook.get_original(); SL_ConvertToString_original = SL_ConvertToString_hook.get_original();

View File

@ -2288,116 +2288,111 @@ namespace re_cscr_variable
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; ThreadInfoCompare_hook.create(game::ThreadInfoCompare.get(), ThreadInfoCompare_stub);
#ifdef RE_CSCR_VARIABLE_USE_WRAPPERS Scr_DumpScriptThreads_hook.create(game::Scr_DumpScriptThreads.get(), Scr_DumpScriptThreads_stub);
quick = false; Scr_InitVariableRange_hook.create(game::Scr_InitVariableRange_ADDR(), Scr_InitVariableRange_stub);
#endif Scr_InitClassMap_hook.create(game::Scr_InitClassMap_ADDR(), Scr_InitClassMap_stub);
GetNewVariableIndexInternal3_hook.create(game::GetNewVariableIndexInternal3.get(), GetNewVariableIndexInternal3_stub);
ThreadInfoCompare_hook.create(game::ThreadInfoCompare.get(), ThreadInfoCompare_stub, quick); GetNewVariableIndexInternal2_hook.create(game::GetNewVariableIndexInternal2_ADDR(), GetNewVariableIndexInternal2_stub);
Scr_DumpScriptThreads_hook.create(game::Scr_DumpScriptThreads.get(), Scr_DumpScriptThreads_stub, quick); GetNewVariableIndexReverseInternal2_hook.create(game::GetNewVariableIndexReverseInternal2_ADDR(), GetNewVariableIndexReverseInternal2_stub);
Scr_InitVariableRange_hook.create(game::Scr_InitVariableRange_ADDR(), Scr_InitVariableRange_stub, quick); MakeVariableExternal_hook.create(game::MakeVariableExternal_ADDR(), MakeVariableExternal_stub);
Scr_InitClassMap_hook.create(game::Scr_InitClassMap_ADDR(), Scr_InitClassMap_stub, quick); FreeChildValue_hook.create(game::FreeChildValue_ADDR(), FreeChildValue_stub);
GetNewVariableIndexInternal3_hook.create(game::GetNewVariableIndexInternal3.get(), GetNewVariableIndexInternal3_stub, quick); ClearObjectInternal_hook.create(game::ClearObjectInternal.get(), ClearObjectInternal_stub);
GetNewVariableIndexInternal2_hook.create(game::GetNewVariableIndexInternal2_ADDR(), GetNewVariableIndexInternal2_stub, quick); ClearObject_hook.create(game::ClearObject_ADDR(), ClearObject_stub);
GetNewVariableIndexReverseInternal2_hook.create(game::GetNewVariableIndexReverseInternal2_ADDR(), GetNewVariableIndexReverseInternal2_stub, quick); Scr_StopThread_hook.create(game::Scr_StopThread_ADDR(), Scr_StopThread_stub);
MakeVariableExternal_hook.create(game::MakeVariableExternal_ADDR(), MakeVariableExternal_stub, quick); GetSafeParentLocalId_hook.create(game::GetSafeParentLocalId_ADDR(), GetSafeParentLocalId_stub);
FreeChildValue_hook.create(game::FreeChildValue_ADDR(), FreeChildValue_stub, quick); GetStartLocalId_hook.create(game::GetStartLocalId_ADDR(), GetStartLocalId_stub);
ClearObjectInternal_hook.create(game::ClearObjectInternal.get(), ClearObjectInternal_stub, quick); Scr_KillThread_hook.create(game::Scr_KillThread_ADDR(), Scr_KillThread_stub);
ClearObject_hook.create(game::ClearObject_ADDR(), ClearObject_stub, quick); AllocVariable_hook.create(game::AllocVariable_ADDR(), AllocVariable_stub);
Scr_StopThread_hook.create(game::Scr_StopThread_ADDR(), Scr_StopThread_stub, quick); FreeVariable_hook.create(game::FreeVariable_ADDR(), FreeVariable_stub);
GetSafeParentLocalId_hook.create(game::GetSafeParentLocalId_ADDR(), GetSafeParentLocalId_stub, quick); AllocValue_hook.create(game::AllocValue_ADDR(), AllocValue_stub);
GetStartLocalId_hook.create(game::GetStartLocalId_ADDR(), GetStartLocalId_stub, quick); AllocEntity_hook.create(game::AllocEntity_ADDR(), AllocEntity_stub);
Scr_KillThread_hook.create(game::Scr_KillThread_ADDR(), Scr_KillThread_stub, quick); Scr_AllocArray_hook.create(game::Scr_AllocArray_ADDR(), Scr_AllocArray_stub);
AllocVariable_hook.create(game::AllocVariable_ADDR(), AllocVariable_stub, quick); AllocChildThread_hook.create(game::AllocChildThread_ADDR(), AllocChildThread_stub);
FreeVariable_hook.create(game::FreeVariable_ADDR(), FreeVariable_stub, quick); FreeValue_hook.create(game::FreeValue_ADDR(), FreeValue_stub);
AllocValue_hook.create(game::AllocValue_ADDR(), AllocValue_stub, quick); RemoveRefToObject_hook.create(game::RemoveRefToObject_ADDR(), RemoveRefToObject_stub);
AllocEntity_hook.create(game::AllocEntity_ADDR(), AllocEntity_stub, quick); Scr_AllocVector_hook.create(game::Scr_AllocVector_ADDR(), Scr_AllocVector_stub);
Scr_AllocArray_hook.create(game::Scr_AllocArray_ADDR(), Scr_AllocArray_stub, quick); RemoveRefToVector_hook.create(game::RemoveRefToVector_ADDR(), RemoveRefToVector_stub);
AllocChildThread_hook.create(game::AllocChildThread_ADDR(), AllocChildThread_stub, quick); AddRefToValue_hook.create(game::AddRefToValue_ADDR(), AddRefToValue_stub);
FreeValue_hook.create(game::FreeValue_ADDR(), FreeValue_stub, quick); RemoveRefToValueInternal_hook.create(game::RemoveRefToValueInternal.get(), RemoveRefToValueInternal_stub);
RemoveRefToObject_hook.create(game::RemoveRefToObject_ADDR(), RemoveRefToObject_stub, quick); FindArrayVariable_hook.create(game::FindArrayVariable_ADDR(), FindArrayVariable_stub);
Scr_AllocVector_hook.create(game::Scr_AllocVector_ADDR(), Scr_AllocVector_stub, quick); FindVariable_hook.create(game::FindVariable_ADDR(), FindVariable_stub);
RemoveRefToVector_hook.create(game::RemoveRefToVector_ADDR(), RemoveRefToVector_stub, quick); GetArrayVariableIndex_hook.create(game::GetArrayVariableIndex_ADDR(), GetArrayVariableIndex_stub);
AddRefToValue_hook.create(game::AddRefToValue_ADDR(), AddRefToValue_stub, quick); Scr_GetVariableFieldIndex_hook.create(game::Scr_GetVariableFieldIndex_ADDR(), Scr_GetVariableFieldIndex_stub);
RemoveRefToValueInternal_hook.create(game::RemoveRefToValueInternal.get(), RemoveRefToValueInternal_stub, quick); Scr_FindVariableField_hook.create(game::Scr_FindVariableField_ADDR(), Scr_FindVariableField_stub);
FindArrayVariable_hook.create(game::FindArrayVariable_ADDR(), FindArrayVariable_stub, quick); ClearVariableField_hook.create(game::ClearVariableField_ADDR(), ClearVariableField_stub);
FindVariable_hook.create(game::FindVariable_ADDR(), FindVariable_stub, quick); GetVariable_hook.create(game::GetVariable_ADDR(), GetVariable_stub);
GetArrayVariableIndex_hook.create(game::GetArrayVariableIndex_ADDR(), GetArrayVariableIndex_stub, quick); GetNewVariable_hook.create(game::GetNewVariable_ADDR(), GetNewVariable_stub);
Scr_GetVariableFieldIndex_hook.create(game::Scr_GetVariableFieldIndex_ADDR(), Scr_GetVariableFieldIndex_stub, quick); GetObjectVariable_hook.create(game::GetObjectVariable_ADDR(), GetObjectVariable_stub);
Scr_FindVariableField_hook.create(game::Scr_FindVariableField_ADDR(), Scr_FindVariableField_stub, quick); GetNewObjectVariable_hook.create(game::GetNewObjectVariable_ADDR(), GetNewObjectVariable_stub);
ClearVariableField_hook.create(game::ClearVariableField_ADDR(), ClearVariableField_stub, quick); RemoveVariable_hook.create(game::RemoveVariable_ADDR(), RemoveVariable_stub);
GetVariable_hook.create(game::GetVariable_ADDR(), GetVariable_stub, quick); RemoveNextVariable_hook.create(game::RemoveNextVariable_ADDR(), RemoveNextVariable_stub);
GetNewVariable_hook.create(game::GetNewVariable_ADDR(), GetNewVariable_stub, quick); SafeRemoveVariable_hook.create(game::SafeRemoveVariable_ADDR(), SafeRemoveVariable_stub);
GetObjectVariable_hook.create(game::GetObjectVariable_ADDR(), GetObjectVariable_stub, quick); CopyArray_hook.create(game::CopyArray.get(), CopyArray_stub);
GetNewObjectVariable_hook.create(game::GetNewObjectVariable_ADDR(), GetNewObjectVariable_stub, quick); SetVariableValue_hook.create(game::SetVariableValue_ADDR(), SetVariableValue_stub);
RemoveVariable_hook.create(game::RemoveVariable_ADDR(), RemoveVariable_stub, quick); SetVariableEntityFieldValue_hook.create(game::SetVariableEntityFieldValue.get(), SetVariableEntityFieldValue_stub);
RemoveNextVariable_hook.create(game::RemoveNextVariable_ADDR(), RemoveNextVariable_stub, quick); Scr_EvalVariable_hook.create(game::Scr_EvalVariable_ADDR(), Scr_EvalVariable_stub);
SafeRemoveVariable_hook.create(game::SafeRemoveVariable_ADDR(), SafeRemoveVariable_stub, quick); Scr_EvalVariableObject_hook.create(game::Scr_EvalVariableObject_ADDR(), Scr_EvalVariableObject_stub);
CopyArray_hook.create(game::CopyArray.get(), CopyArray_stub, quick); Scr_EvalVariableEntityField_hook.create(game::Scr_EvalVariableEntityField_ADDR(), Scr_EvalVariableEntityField_stub);
SetVariableValue_hook.create(game::SetVariableValue_ADDR(), SetVariableValue_stub, quick); Scr_EvalVariableField_hook.create(game::Scr_EvalVariableField_ADDR(), Scr_EvalVariableField_stub);
SetVariableEntityFieldValue_hook.create(game::SetVariableEntityFieldValue.get(), SetVariableEntityFieldValue_stub, quick); Scr_EvalSizeValue_hook.create(game::Scr_EvalSizeValue_ADDR(), Scr_EvalSizeValue_stub);
Scr_EvalVariable_hook.create(game::Scr_EvalVariable_ADDR(), Scr_EvalVariable_stub, quick); GetObject_hook.create(game::GetObject_ADDR(), GetObject_stub);
Scr_EvalVariableObject_hook.create(game::Scr_EvalVariableObject_ADDR(), Scr_EvalVariableObject_stub, quick); GetArray_hook.create(game::GetArray_ADDR(), GetArray_stub);
Scr_EvalVariableEntityField_hook.create(game::Scr_EvalVariableEntityField_ADDR(), Scr_EvalVariableEntityField_stub, quick); Scr_EvalBoolComplement_hook.create(game::Scr_EvalBoolComplement_ADDR(), Scr_EvalBoolComplement_stub);
Scr_EvalVariableField_hook.create(game::Scr_EvalVariableField_ADDR(), Scr_EvalVariableField_stub, quick); Scr_CastBool_hook.create(game::Scr_CastBool_ADDR(), Scr_CastBool_stub);
Scr_EvalSizeValue_hook.create(game::Scr_EvalSizeValue_ADDR(), Scr_EvalSizeValue_stub, quick); Scr_CastString_hook.create(game::Scr_CastString_ADDR(), Scr_CastString_stub);
GetObject_hook.create(game::GetObject_ADDR(), GetObject_stub, quick); Scr_CastDebugString_hook.create(game::Scr_CastDebugString_ADDR(), Scr_CastDebugString_stub);
GetArray_hook.create(game::GetArray_ADDR(), GetArray_stub, quick); Scr_ClearVector_hook.create(game::Scr_ClearVector.get(), Scr_ClearVector_stub);
Scr_EvalBoolComplement_hook.create(game::Scr_EvalBoolComplement_ADDR(), Scr_EvalBoolComplement_stub, quick); Scr_CastVector_hook.create(game::Scr_CastVector_ADDR(), Scr_CastVector_stub);
Scr_CastBool_hook.create(game::Scr_CastBool_ADDR(), Scr_CastBool_stub, quick); Scr_EvalFieldObject_hook.create(game::Scr_EvalFieldObject_ADDR(), Scr_EvalFieldObject_stub);
Scr_CastString_hook.create(game::Scr_CastString_ADDR(), Scr_CastString_stub, quick); Scr_UnmatchingTypesError_hook.create(game::Scr_UnmatchingTypesError_ADDR(), Scr_UnmatchingTypesError_stub);
Scr_CastDebugString_hook.create(game::Scr_CastDebugString_ADDR(), Scr_CastDebugString_stub, quick); Scr_CastWeakerPair_hook.create(game::Scr_CastWeakerPair_ADDR(), Scr_CastWeakerPair_stub);
Scr_ClearVector_hook.create(game::Scr_ClearVector.get(), Scr_ClearVector_stub, quick); Scr_CastWeakerStringPair_hook.create(game::Scr_CastWeakerStringPair_ADDR(), Scr_CastWeakerStringPair_stub);
Scr_CastVector_hook.create(game::Scr_CastVector_ADDR(), Scr_CastVector_stub, quick); Scr_EvalOr_hook.create(game::Scr_EvalOr_ADDR(), Scr_EvalOr_stub);
Scr_EvalFieldObject_hook.create(game::Scr_EvalFieldObject_ADDR(), Scr_EvalFieldObject_stub, quick); Scr_EvalExOr_hook.create(game::Scr_EvalExOr_ADDR(), Scr_EvalExOr_stub);
Scr_UnmatchingTypesError_hook.create(game::Scr_UnmatchingTypesError_ADDR(), Scr_UnmatchingTypesError_stub, quick); Scr_EvalAnd_hook.create(game::Scr_EvalAnd_ADDR(), Scr_EvalAnd_stub);
Scr_CastWeakerPair_hook.create(game::Scr_CastWeakerPair_ADDR(), Scr_CastWeakerPair_stub, quick); Scr_EvalEquality_hook.create(game::Scr_EvalEquality_ADDR(), Scr_EvalEquality_stub);
Scr_CastWeakerStringPair_hook.create(game::Scr_CastWeakerStringPair_ADDR(), Scr_CastWeakerStringPair_stub, quick); Scr_EvalLess_hook.create(game::Scr_EvalLess_ADDR(), Scr_EvalLess_stub);
Scr_EvalOr_hook.create(game::Scr_EvalOr_ADDR(), Scr_EvalOr_stub, quick); Scr_EvalGreaterEqual_hook.create(game::Scr_EvalGreaterEqual_ADDR(), Scr_EvalGreaterEqual_stub);
Scr_EvalExOr_hook.create(game::Scr_EvalExOr_ADDR(), Scr_EvalExOr_stub, quick); Scr_EvalGreater_hook.create(game::Scr_EvalGreater_ADDR(), Scr_EvalGreater_stub);
Scr_EvalAnd_hook.create(game::Scr_EvalAnd_ADDR(), Scr_EvalAnd_stub, quick); Scr_EvalLessEqual_hook.create(game::Scr_EvalLessEqual_ADDR(), Scr_EvalLessEqual_stub);
Scr_EvalEquality_hook.create(game::Scr_EvalEquality_ADDR(), Scr_EvalEquality_stub, quick); Scr_EvalShiftLeft_hook.create(game::Scr_EvalShiftLeft_ADDR(), Scr_EvalShiftLeft_stub);
Scr_EvalLess_hook.create(game::Scr_EvalLess_ADDR(), Scr_EvalLess_stub, quick); Scr_EvalShiftRight_hook.create(game::Scr_EvalShiftRight_ADDR(), Scr_EvalShiftRight_stub);
Scr_EvalGreaterEqual_hook.create(game::Scr_EvalGreaterEqual_ADDR(), Scr_EvalGreaterEqual_stub, quick); Scr_EvalPlus_hook.create(game::Scr_EvalPlus_ADDR(), Scr_EvalPlus_stub);
Scr_EvalGreater_hook.create(game::Scr_EvalGreater_ADDR(), Scr_EvalGreater_stub, quick); Scr_EvalMinus_hook.create(game::Scr_EvalMinus_ADDR(), Scr_EvalMinus_stub);
Scr_EvalLessEqual_hook.create(game::Scr_EvalLessEqual_ADDR(), Scr_EvalLessEqual_stub, quick); Scr_EvalMultiply_hook.create(game::Scr_EvalMultiply_ADDR(), Scr_EvalMultiply_stub);
Scr_EvalShiftLeft_hook.create(game::Scr_EvalShiftLeft_ADDR(), Scr_EvalShiftLeft_stub, quick); Scr_EvalDivide_hook.create(game::Scr_EvalDivide_ADDR(), Scr_EvalDivide_stub);
Scr_EvalShiftRight_hook.create(game::Scr_EvalShiftRight_ADDR(), Scr_EvalShiftRight_stub, quick); Scr_EvalMod_hook.create(game::Scr_EvalMod_ADDR(), Scr_EvalMod_stub);
Scr_EvalPlus_hook.create(game::Scr_EvalPlus_ADDR(), Scr_EvalPlus_stub, quick); Scr_EvalBinaryOperator_hook.create(game::Scr_EvalBinaryOperator_ADDR(), Scr_EvalBinaryOperator_stub);
Scr_EvalMinus_hook.create(game::Scr_EvalMinus_ADDR(), Scr_EvalMinus_stub, quick); Scr_FreeEntityNum_hook.create(game::Scr_FreeEntityNum_ADDR(), Scr_FreeEntityNum_stub);
Scr_EvalMultiply_hook.create(game::Scr_EvalMultiply_ADDR(), Scr_EvalMultiply_stub, quick); Scr_FreeEntityList_hook.create(game::Scr_FreeEntityList.get(), Scr_FreeEntityList_stub);
Scr_EvalDivide_hook.create(game::Scr_EvalDivide_ADDR(), Scr_EvalDivide_stub, quick); Scr_FreeObjects_hook.create(game::Scr_FreeObjects.get(), Scr_FreeObjects_stub);
Scr_EvalMod_hook.create(game::Scr_EvalMod_ADDR(), Scr_EvalMod_stub, quick); Scr_SetClassMap_hook.create(game::Scr_SetClassMap_ADDR(), Scr_SetClassMap_stub);
Scr_EvalBinaryOperator_hook.create(game::Scr_EvalBinaryOperator_ADDR(), Scr_EvalBinaryOperator_stub, quick); Scr_RemoveClassMap_hook.create(game::Scr_RemoveClassMap_ADDR(), Scr_RemoveClassMap_stub);
Scr_FreeEntityNum_hook.create(game::Scr_FreeEntityNum_ADDR(), Scr_FreeEntityNum_stub, quick); Scr_AddClassField_hook.create(game::Scr_AddClassField_ADDR(), Scr_AddClassField_stub);
Scr_FreeEntityList_hook.create(game::Scr_FreeEntityList.get(), Scr_FreeEntityList_stub, quick); Scr_GetOffset_hook.create(game::Scr_GetOffset_ADDR(), Scr_GetOffset_stub);
Scr_FreeObjects_hook.create(game::Scr_FreeObjects.get(), Scr_FreeObjects_stub, quick); FindEntityId_hook.create(game::FindEntityId_ADDR(), FindEntityId_stub);
Scr_SetClassMap_hook.create(game::Scr_SetClassMap_ADDR(), Scr_SetClassMap_stub, quick); Scr_GetEntityId_hook.create(game::Scr_GetEntityId_ADDR(), Scr_GetEntityId_stub);
Scr_RemoveClassMap_hook.create(game::Scr_RemoveClassMap_ADDR(), Scr_RemoveClassMap_stub, quick); Scr_FindArrayIndex_hook.create(game::Scr_FindArrayIndex_ADDR(), Scr_FindArrayIndex_stub);
Scr_AddClassField_hook.create(game::Scr_AddClassField_ADDR(), Scr_AddClassField_stub, quick); Scr_EvalArray_hook.create(game::Scr_EvalArray_ADDR(), Scr_EvalArray_stub);
Scr_GetOffset_hook.create(game::Scr_GetOffset_ADDR(), Scr_GetOffset_stub, quick); Scr_EvalArrayRef_hook.create(game::Scr_EvalArrayRef_ADDR(), Scr_EvalArrayRef_stub);
FindEntityId_hook.create(game::FindEntityId_ADDR(), FindEntityId_stub, quick); ClearArray_hook.create(game::ClearArray_ADDR(), ClearArray_stub);
Scr_GetEntityId_hook.create(game::Scr_GetEntityId_ADDR(), Scr_GetEntityId_stub, quick); SetEmptyArray_hook.create(game::SetEmptyArray_ADDR(), SetEmptyArray_stub);
Scr_FindArrayIndex_hook.create(game::Scr_FindArrayIndex_ADDR(), Scr_FindArrayIndex_stub, quick); Scr_AddArrayKeys_hook.create(game::Scr_AddArrayKeys.get(), Scr_AddArrayKeys_stub);
Scr_EvalArray_hook.create(game::Scr_EvalArray_ADDR(), Scr_EvalArray_stub, quick); Scr_GetEntityIdRef_hook.create(game::Scr_GetEntityIdRef_ADDR(), Scr_GetEntityIdRef_stub);
Scr_EvalArrayRef_hook.create(game::Scr_EvalArrayRef_ADDR(), Scr_EvalArrayRef_stub, quick); CopyEntity_hook.create(game::CopyEntity_ADDR(), CopyEntity_stub);
ClearArray_hook.create(game::ClearArray_ADDR(), ClearArray_stub, quick); Scr_GetEndonUsage_hook.create(game::Scr_GetEndonUsage_ADDR(), Scr_GetEndonUsage_stub);
SetEmptyArray_hook.create(game::SetEmptyArray_ADDR(), SetEmptyArray_stub, quick); Scr_GetObjectUsage_hook.create(game::Scr_GetObjectUsage.get(), Scr_GetObjectUsage_stub);
Scr_AddArrayKeys_hook.create(game::Scr_AddArrayKeys.get(), Scr_AddArrayKeys_stub, quick); Scr_GetThreadUsage_hook.create(game::Scr_GetThreadUsage_ADDR(), Scr_GetThreadUsage_stub);
Scr_GetEntityIdRef_hook.create(game::Scr_GetEntityIdRef_ADDR(), Scr_GetEntityIdRef_stub, quick); Scr_FindField_hook.create(game::Scr_FindField_ADDR(), Scr_FindField_stub);
CopyEntity_hook.create(game::CopyEntity_ADDR(), CopyEntity_stub, quick); Scr_GetSourceFile_LoadObj_hook.create(game::Scr_GetSourceFile_LoadObj.get(), Scr_GetSourceFile_LoadObj_stub);
Scr_GetEndonUsage_hook.create(game::Scr_GetEndonUsage_ADDR(), Scr_GetEndonUsage_stub, quick); Scr_GetSourceFile_FastFile_hook.create(game::Scr_GetSourceFile_FastFile.get(), Scr_GetSourceFile_FastFile_stub);
Scr_GetObjectUsage_hook.create(game::Scr_GetObjectUsage.get(), Scr_GetObjectUsage_stub, quick); Scr_AddFieldsForFile_hook.create(game::Scr_AddFieldsForFile.get(), Scr_AddFieldsForFile_stub);
Scr_GetThreadUsage_hook.create(game::Scr_GetThreadUsage_ADDR(), Scr_GetThreadUsage_stub, quick); Scr_AddFields_LoadObj_hook.create(game::Scr_AddFields_LoadObj.get(), Scr_AddFields_LoadObj_stub);
Scr_FindField_hook.create(game::Scr_FindField_ADDR(), Scr_FindField_stub, quick); Scr_AddFields_FastFile_hook.create(game::Scr_AddFields_FastFile.get(), Scr_AddFields_FastFile_stub);
Scr_GetSourceFile_LoadObj_hook.create(game::Scr_GetSourceFile_LoadObj.get(), Scr_GetSourceFile_LoadObj_stub, quick); Scr_MakeValuePrimitive_hook.create(game::Scr_MakeValuePrimitive.get(), Scr_MakeValuePrimitive_stub);
Scr_GetSourceFile_FastFile_hook.create(game::Scr_GetSourceFile_FastFile.get(), Scr_GetSourceFile_FastFile_stub, quick); Scr_FreeGameVariable_hook.create(game::Scr_FreeGameVariable_ADDR(), Scr_FreeGameVariable_stub);
Scr_AddFieldsForFile_hook.create(game::Scr_AddFieldsForFile.get(), Scr_AddFieldsForFile_stub, quick); Scr_SLHasLowercaseString_hook.create(game::Scr_SLHasLowercaseString_ADDR(), Scr_SLHasLowercaseString_stub);
Scr_AddFields_LoadObj_hook.create(game::Scr_AddFields_LoadObj.get(), Scr_AddFields_LoadObj_stub, quick);
Scr_AddFields_FastFile_hook.create(game::Scr_AddFields_FastFile.get(), Scr_AddFields_FastFile_stub, quick);
Scr_MakeValuePrimitive_hook.create(game::Scr_MakeValuePrimitive.get(), Scr_MakeValuePrimitive_stub, quick);
Scr_FreeGameVariable_hook.create(game::Scr_FreeGameVariable_ADDR(), Scr_FreeGameVariable_stub, quick);
Scr_SLHasLowercaseString_hook.create(game::Scr_SLHasLowercaseString_ADDR(), Scr_SLHasLowercaseString_stub, quick);
//Original hook function addresses //Original hook function addresses
ThreadInfoCompare_original = ThreadInfoCompare_hook.get_original(); ThreadInfoCompare_original = ThreadInfoCompare_hook.get_original();

View File

@ -1524,83 +1524,78 @@ namespace re_cscr_vm
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; Scr_VM_Init_hook.create(game::Scr_VM_Init.get(), Scr_VM_Init_stub);
#ifdef RE_CSCR_VM_USE_WRAPPERS Scr_Init_hook.create(game::Scr_Init_ADDR(), Scr_Init_stub);
quick = false; Scr_Shutdown_hook.create(game::Scr_Shutdown_ADDR(), Scr_Shutdown_stub);
#endif Scr_ErrorInternal_hook.create(game::Scr_ErrorInternal_ADDR(), Scr_ErrorInternal_stub);
Scr_ClearOutParams_hook.create(game::Scr_ClearOutParams_ADDR(), Scr_ClearOutParams_stub);
Scr_VM_Init_hook.create(game::Scr_VM_Init.get(), Scr_VM_Init_stub, quick); GetDummyObject_hook.create(game::GetDummyObject_ADDR(), GetDummyObject_stub);
Scr_Init_hook.create(game::Scr_Init_ADDR(), Scr_Init_stub, quick); GetDummyFieldValue_hook.create(game::GetDummyFieldValue_ADDR(), GetDummyFieldValue_stub);
Scr_Shutdown_hook.create(game::Scr_Shutdown_ADDR(), Scr_Shutdown_stub, quick); VM_ExecuteInternal_hook.create(game::VM_ExecuteInternal.get(), VM_ExecuteInternal_stub);
Scr_ErrorInternal_hook.create(game::Scr_ErrorInternal_ADDR(), Scr_ErrorInternal_stub, quick); VM_CancelNotifyInternal_hook.create(game::VM_CancelNotifyInternal_ADDR(), VM_CancelNotifyInternal_stub);
Scr_ClearOutParams_hook.create(game::Scr_ClearOutParams_ADDR(), Scr_ClearOutParams_stub, quick); VM_CancelNotify_hook.create(game::VM_CancelNotify_ADDR(), VM_CancelNotify_stub);
GetDummyObject_hook.create(game::GetDummyObject_ADDR(), GetDummyObject_stub, quick); VM_ArchiveStack_hook.create(game::VM_ArchiveStack_ADDR(), VM_ArchiveStack_stub);
GetDummyFieldValue_hook.create(game::GetDummyFieldValue_ADDR(), GetDummyFieldValue_stub, quick); Scr_AddLocalVars_hook.create(game::Scr_AddLocalVars_ADDR(), Scr_AddLocalVars_stub);
VM_ExecuteInternal_hook.create(game::VM_ExecuteInternal.get(), VM_ExecuteInternal_stub, quick); VM_UnarchiveStack_hook.create(game::VM_UnarchiveStack.get(), VM_UnarchiveStack_stub);
VM_CancelNotifyInternal_hook.create(game::VM_CancelNotifyInternal_ADDR(), VM_CancelNotifyInternal_stub, quick); VM_TerminateStack_hook.create(game::VM_TerminateStack_ADDR(), VM_TerminateStack_stub);
VM_CancelNotify_hook.create(game::VM_CancelNotify_ADDR(), VM_CancelNotify_stub, quick); VM_TrimStack_hook.create(game::VM_TrimStack_ADDR(), VM_TrimStack_stub);
VM_ArchiveStack_hook.create(game::VM_ArchiveStack_ADDR(), VM_ArchiveStack_stub, quick); Scr_TerminateRunningThread_hook.create(game::Scr_TerminateRunningThread_ADDR(), Scr_TerminateRunningThread_stub);
Scr_AddLocalVars_hook.create(game::Scr_AddLocalVars_ADDR(), Scr_AddLocalVars_stub, quick); Scr_TerminateWaitThread_hook.create(game::Scr_TerminateWaitThread_ADDR(), Scr_TerminateWaitThread_stub);
VM_UnarchiveStack_hook.create(game::VM_UnarchiveStack.get(), VM_UnarchiveStack_stub, quick); Scr_CancelWaittill_hook.create(game::Scr_CancelWaittill_ADDR(), Scr_CancelWaittill_stub);
VM_TerminateStack_hook.create(game::VM_TerminateStack_ADDR(), VM_TerminateStack_stub, quick); Scr_TerminateWaittillThread_hook.create(game::Scr_TerminateWaittillThread_ADDR(), Scr_TerminateWaittillThread_stub);
VM_TrimStack_hook.create(game::VM_TrimStack_ADDR(), VM_TrimStack_stub, quick); Scr_TerminateThread_hook.create(game::Scr_TerminateThread_ADDR(), Scr_TerminateThread_stub);
Scr_TerminateRunningThread_hook.create(game::Scr_TerminateRunningThread_ADDR(), Scr_TerminateRunningThread_stub, quick); VM_Notify_hook.create(game::VM_Notify_ADDR(), VM_Notify_stub);
Scr_TerminateWaitThread_hook.create(game::Scr_TerminateWaitThread_ADDR(), Scr_TerminateWaitThread_stub, quick); Scr_NotifyNum_Internal_hook.create(game::Scr_NotifyNum_Internal_ADDR(), Scr_NotifyNum_Internal_stub);
Scr_CancelWaittill_hook.create(game::Scr_CancelWaittill_ADDR(), Scr_CancelWaittill_stub, quick); Scr_CancelNotifyList_hook.create(game::Scr_CancelNotifyList_ADDR(), Scr_CancelNotifyList_stub);
Scr_TerminateWaittillThread_hook.create(game::Scr_TerminateWaittillThread_ADDR(), Scr_TerminateWaittillThread_stub, quick); VM_TerminateTime_hook.create(game::VM_TerminateTime_ADDR(), VM_TerminateTime_stub);
Scr_TerminateThread_hook.create(game::Scr_TerminateThread_ADDR(), Scr_TerminateThread_stub, quick); VM_Resume_hook.create(game::VM_Resume_ADDR(), VM_Resume_stub);
VM_Notify_hook.create(game::VM_Notify_ADDR(), VM_Notify_stub, quick); VM_Execute_hook.create(game::VM_Execute.get(), VM_Execute_stub);
Scr_NotifyNum_Internal_hook.create(game::Scr_NotifyNum_Internal_ADDR(), Scr_NotifyNum_Internal_stub, quick); Scr_ExecThread_hook.create(game::Scr_ExecThread_ADDR(), Scr_ExecThread_stub);
Scr_CancelNotifyList_hook.create(game::Scr_CancelNotifyList_ADDR(), Scr_CancelNotifyList_stub, quick); Scr_ExecEntThread_hook.create(game::Scr_ExecEntThread_ADDR(), Scr_ExecEntThread_stub);
VM_TerminateTime_hook.create(game::VM_TerminateTime_ADDR(), VM_TerminateTime_stub, quick); Scr_AddExecThread_hook.create(game::Scr_AddExecThread_ADDR(), Scr_AddExecThread_stub);
VM_Resume_hook.create(game::VM_Resume_ADDR(), VM_Resume_stub, quick); VM_SetTime_hook.create(game::VM_SetTime_ADDR(), VM_SetTime_stub);
VM_Execute_hook.create(game::VM_Execute.get(), VM_Execute_stub, quick); Scr_InitSystem_hook.create(game::Scr_InitSystem_ADDR(), Scr_InitSystem_stub);
Scr_ExecThread_hook.create(game::Scr_ExecThread_ADDR(), Scr_ExecThread_stub, quick); Scr_ShutdownSystem_hook.create(game::Scr_ShutdownSystem.get(), Scr_ShutdownSystem_stub);
Scr_ExecEntThread_hook.create(game::Scr_ExecEntThread_ADDR(), Scr_ExecEntThread_stub, quick); Scr_IsSystemActive_hook.create(game::Scr_IsSystemActive.get(), Scr_IsSystemActive_stub);
Scr_AddExecThread_hook.create(game::Scr_AddExecThread_ADDR(), Scr_AddExecThread_stub, quick); Scr_GetInt_hook.create(game::Scr_GetInt_ADDR(), Scr_GetInt_stub);
VM_SetTime_hook.create(game::VM_SetTime_ADDR(), VM_SetTime_stub, quick); Scr_GetAnim_hook.create(game::Scr_GetAnim_ADDR(), Scr_GetAnim_stub);
Scr_InitSystem_hook.create(game::Scr_InitSystem_ADDR(), Scr_InitSystem_stub, quick); Scr_GetAnimTree_hook.create(game::Scr_GetAnimTree.get(), Scr_GetAnimTree_stub);
Scr_ShutdownSystem_hook.create(game::Scr_ShutdownSystem.get(), Scr_ShutdownSystem_stub, quick); Scr_GetFloat_hook.create(game::Scr_GetFloat_ADDR(), Scr_GetFloat_stub);
Scr_IsSystemActive_hook.create(game::Scr_IsSystemActive.get(), Scr_IsSystemActive_stub, quick); Scr_GetConstString_hook.create(game::Scr_GetConstString_ADDR(), Scr_GetConstString_stub);
Scr_GetInt_hook.create(game::Scr_GetInt_ADDR(), Scr_GetInt_stub, quick); Scr_GetConstLowercaseString_hook.create(game::Scr_GetConstLowercaseString_ADDR(), Scr_GetConstLowercaseString_stub);
Scr_GetAnim_hook.create(game::Scr_GetAnim_ADDR(), Scr_GetAnim_stub, quick); Scr_GetString_hook.create(game::Scr_GetString_ADDR(), Scr_GetString_stub);
Scr_GetAnimTree_hook.create(game::Scr_GetAnimTree.get(), Scr_GetAnimTree_stub, quick); Scr_GetConstStringIncludeNull_hook.create(game::Scr_GetConstStringIncludeNull_ADDR(), Scr_GetConstStringIncludeNull_stub);
Scr_GetFloat_hook.create(game::Scr_GetFloat_ADDR(), Scr_GetFloat_stub, quick); Scr_GetDebugString_hook.create(game::Scr_GetDebugString_ADDR(), Scr_GetDebugString_stub);
Scr_GetConstString_hook.create(game::Scr_GetConstString_ADDR(), Scr_GetConstString_stub, quick); Scr_GetConstIString_hook.create(game::Scr_GetConstIString_ADDR(), Scr_GetConstIString_stub);
Scr_GetConstLowercaseString_hook.create(game::Scr_GetConstLowercaseString_ADDR(), Scr_GetConstLowercaseString_stub, quick); Scr_GetVector_hook.create(game::Scr_GetVector_ADDR(), Scr_GetVector_stub);
Scr_GetString_hook.create(game::Scr_GetString_ADDR(), Scr_GetString_stub, quick); Scr_GetFunc_hook.create(game::Scr_GetFunc.get(), Scr_GetFunc_stub);
Scr_GetConstStringIncludeNull_hook.create(game::Scr_GetConstStringIncludeNull_ADDR(), Scr_GetConstStringIncludeNull_stub, quick); Scr_GetEntityRef_hook.create(game::Scr_GetEntityRef_ADDR(), Scr_GetEntityRef_stub);
Scr_GetDebugString_hook.create(game::Scr_GetDebugString_ADDR(), Scr_GetDebugString_stub, quick); Scr_GetObject_hook.create(game::Scr_GetObject_ADDR(), Scr_GetObject_stub);
Scr_GetConstIString_hook.create(game::Scr_GetConstIString_ADDR(), Scr_GetConstIString_stub, quick); Scr_GetType_hook.create(game::Scr_GetType_ADDR(), Scr_GetType_stub);
Scr_GetVector_hook.create(game::Scr_GetVector_ADDR(), Scr_GetVector_stub, quick); Scr_GetTypeName_hook.create(game::Scr_GetTypeName_ADDR(), Scr_GetTypeName_stub);
Scr_GetFunc_hook.create(game::Scr_GetFunc.get(), Scr_GetFunc_stub, quick); Scr_GetPointerType_hook.create(game::Scr_GetPointerType_ADDR(), Scr_GetPointerType_stub);
Scr_GetEntityRef_hook.create(game::Scr_GetEntityRef_ADDR(), Scr_GetEntityRef_stub, quick); Scr_AddInt_hook.create(game::Scr_AddInt_ADDR(), Scr_AddInt_stub);
Scr_GetObject_hook.create(game::Scr_GetObject_ADDR(), Scr_GetObject_stub, quick); Scr_AddFloat_hook.create(game::Scr_AddFloat_ADDR(), Scr_AddFloat_stub);
Scr_GetType_hook.create(game::Scr_GetType_ADDR(), Scr_GetType_stub, quick); Scr_AddAnim_hook.create(game::Scr_AddAnim.get(), Scr_AddAnim_stub);
Scr_GetTypeName_hook.create(game::Scr_GetTypeName_ADDR(), Scr_GetTypeName_stub, quick); Scr_AddUndefined_hook.create(game::Scr_AddUndefined_ADDR(), Scr_AddUndefined_stub);
Scr_GetPointerType_hook.create(game::Scr_GetPointerType_ADDR(), Scr_GetPointerType_stub, quick); Scr_AddObject_hook.create(game::Scr_AddObject_ADDR(), Scr_AddObject_stub);
Scr_AddInt_hook.create(game::Scr_AddInt_ADDR(), Scr_AddInt_stub, quick); Scr_AddString_hook.create(game::Scr_AddString_ADDR(), Scr_AddString_stub);
Scr_AddFloat_hook.create(game::Scr_AddFloat_ADDR(), Scr_AddFloat_stub, quick); Scr_AddIString_hook.create(game::Scr_AddIString_ADDR(), Scr_AddIString_stub);
Scr_AddAnim_hook.create(game::Scr_AddAnim.get(), Scr_AddAnim_stub, quick); Scr_AddConstString_hook.create(game::Scr_AddConstString_ADDR(), Scr_AddConstString_stub);
Scr_AddUndefined_hook.create(game::Scr_AddUndefined_ADDR(), Scr_AddUndefined_stub, quick); Scr_AddVector_hook.create(game::Scr_AddVector_ADDR(), Scr_AddVector_stub);
Scr_AddObject_hook.create(game::Scr_AddObject_ADDR(), Scr_AddObject_stub, quick); Scr_MakeArray_hook.create(game::Scr_MakeArray_ADDR(), Scr_MakeArray_stub);
Scr_AddString_hook.create(game::Scr_AddString_ADDR(), Scr_AddString_stub, quick); Scr_AddArray_hook.create(game::Scr_AddArray.get(), Scr_AddArray_stub);
Scr_AddIString_hook.create(game::Scr_AddIString_ADDR(), Scr_AddIString_stub, quick); Scr_AddArrayStringIndexed_hook.create(game::Scr_AddArrayStringIndexed_ADDR(), Scr_AddArrayStringIndexed_stub);
Scr_AddConstString_hook.create(game::Scr_AddConstString_ADDR(), Scr_AddConstString_stub, quick); Scr_Error_hook.create(game::Scr_Error_ADDR(), Scr_Error_stub);
Scr_AddVector_hook.create(game::Scr_AddVector_ADDR(), Scr_AddVector_stub, quick); Scr_TerminalError_hook.create(game::Scr_TerminalError_ADDR(), Scr_TerminalError_stub);
Scr_MakeArray_hook.create(game::Scr_MakeArray_ADDR(), Scr_MakeArray_stub, quick); Scr_ParamError_hook.create(game::Scr_ParamError_ADDR(), Scr_ParamError_stub);
Scr_AddArray_hook.create(game::Scr_AddArray.get(), Scr_AddArray_stub, quick); Scr_ObjectError_hook.create(game::Scr_ObjectError_ADDR(), Scr_ObjectError_stub);
Scr_AddArrayStringIndexed_hook.create(game::Scr_AddArrayStringIndexed_ADDR(), Scr_AddArrayStringIndexed_stub, quick); SetEntityFieldValue_hook.create(game::SetEntityFieldValue_ADDR(), SetEntityFieldValue_stub);
Scr_Error_hook.create(game::Scr_Error_ADDR(), Scr_Error_stub, quick); GetEntityFieldValue_hook.create(game::GetEntityFieldValue_ADDR(), GetEntityFieldValue_stub);
Scr_TerminalError_hook.create(game::Scr_TerminalError_ADDR(), Scr_TerminalError_stub, quick); Scr_SetStructField_hook.create(game::Scr_SetStructField_ADDR(), Scr_SetStructField_stub);
Scr_ParamError_hook.create(game::Scr_ParamError_ADDR(), Scr_ParamError_stub, quick); Scr_IncTime_hook.create(game::Scr_IncTime_ADDR(), Scr_IncTime_stub);
Scr_ObjectError_hook.create(game::Scr_ObjectError_ADDR(), Scr_ObjectError_stub, quick); Scr_RunCurrentThreads_hook.create(game::Scr_RunCurrentThreads_ADDR(), Scr_RunCurrentThreads_stub);
SetEntityFieldValue_hook.create(game::SetEntityFieldValue_ADDR(), SetEntityFieldValue_stub, quick); Scr_ResetTimeout_hook.create(game::Scr_ResetTimeout_ADDR(), Scr_ResetTimeout_stub);
GetEntityFieldValue_hook.create(game::GetEntityFieldValue_ADDR(), GetEntityFieldValue_stub, quick);
Scr_SetStructField_hook.create(game::Scr_SetStructField_ADDR(), Scr_SetStructField_stub, quick);
Scr_IncTime_hook.create(game::Scr_IncTime_ADDR(), Scr_IncTime_stub, quick);
Scr_RunCurrentThreads_hook.create(game::Scr_RunCurrentThreads_ADDR(), Scr_RunCurrentThreads_stub, quick);
Scr_ResetTimeout_hook.create(game::Scr_ResetTimeout_ADDR(), Scr_ResetTimeout_stub, quick);
//Original hook function addresses //Original hook function addresses
Scr_VM_Init_original = Scr_VM_Init_hook.get_original(); Scr_VM_Init_original = Scr_VM_Init_hook.get_original();

View File

@ -199,22 +199,17 @@ namespace re_cscr_yacc
public: public:
void post_unpack() override void post_unpack() override
{ {
bool quick = true; LowerCase_hook.create(game::LowerCase(), LowerCase_stub);
#ifdef RE_CSCR_YACC_USE_WRAPPERS yyparse_hook.create(game::yyparse.get(), yyparse_stub);
quick = false; StringValue_hook.create(game::StringValue(), StringValue_stub);
#endif yylex_hook.create(game::yylex.get(), yylex_stub);
yy_get_next_buffer_hook.create(game::yy_get_next_buffer.get(), yy_get_next_buffer_stub);
LowerCase_hook.create(game::LowerCase_ADDR(), LowerCase_stub, quick); yy_get_previous_state_hook.create(game::yy_get_previous_state.get(), yy_get_previous_state_stub);
yyparse_hook.create(game::yyparse.get(), yyparse_stub, quick); yy_try_NUL_trans_hook.create(game::yy_try_NUL_trans(), yy_try_NUL_trans_stub);
StringValue_hook.create(game::StringValue_ADDR(), StringValue_stub, quick); yyrestart_hook.create(game::yyrestart.get(), yyrestart_stub);
yylex_hook.create(game::yylex.get(), yylex_stub, quick); yy_create_buffer_hook.create(game::yy_create_buffer.get(), yy_create_buffer_stub);
yy_get_next_buffer_hook.create(game::yy_get_next_buffer.get(), yy_get_next_buffer_stub, quick); yy_flush_buffer_hook.create(game::yy_flush_buffer(), yy_flush_buffer_stub);
yy_get_previous_state_hook.create(game::yy_get_previous_state.get(), yy_get_previous_state_stub, quick); ScriptParse_hook.create(game::ScriptParse(), ScriptParse_stub);
yy_try_NUL_trans_hook.create(game::yy_try_NUL_trans_ADDR(), yy_try_NUL_trans_stub, quick);
yyrestart_hook.create(game::yyrestart.get(), yyrestart_stub, quick);
yy_create_buffer_hook.create(game::yy_create_buffer.get(), yy_create_buffer_stub, quick);
yy_flush_buffer_hook.create(game::yy_flush_buffer_ADDR(), yy_flush_buffer_stub, quick);
ScriptParse_hook.create(game::ScriptParse_ADDR(), ScriptParse_stub, quick);
//Original hook function addresses //Original hook function addresses
LowerCase_original = LowerCase_hook.get_original(); LowerCase_original = LowerCase_hook.get_original();

View File

@ -1,467 +0,0 @@
#include <stdinc.hpp>
#include "loader/component_loader.hpp"
#include "gsc.hpp"
#include "scheduler.hpp"
#include <utils/memory.hpp>
#include <utils/string.hpp>
namespace fileio
{
namespace
{
static constexpr size_t max_fhs = 10;
static constexpr size_t max_gsc_string = 0x10000 - 1;
enum class scr_fh_type_e
{
UNUSED,
READ,
WRITE,
APPEND
};
struct scr_fh_t
{
scr_fh_type_e type;
std::unique_ptr<char[]> file_buff;
int file_length;
int seek;
std::filesystem::path full_path;
std::string base_path;
};
std::array<scr_fh_t, max_fhs> scr_fhs = {};
bool validate_scr_path(const std::string& fpath)
{
auto toks = utils::string::split(fpath, '/');
for (const auto& tok : toks)
{
if (tok == "." || tok == "..")
{
return false;
}
if (tok.find(":") != std::string::npos)
{
return false;
}
}
return true;
}
std::string build_base_path(const std::string& path_)
{
auto path = path_;
std::replace(path.begin(), path.end(), '\\', '/');
if (!validate_scr_path(path))
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, utils::string::va("Invalid path: %s", path_.c_str()));
}
// its sandboxed, but what about symlinks?
return path.starts_with("scriptdata/") ? path : "scriptdata/" + path;
}
std::filesystem::path build_full_path(const std::string& path, bool use_global)
{
static game::dvar_s* fs_localAppData = nullptr;
static game::dvar_s* fs_gamedir = nullptr;
if (!fs_localAppData)
{
fs_localAppData = game::Dvar_FindVar("fs_localAppData");
}
if (!fs_gamedir)
{
fs_gamedir = game::Dvar_FindVar("fs_game");
}
return std::filesystem::path(fs_localAppData->current.string) / (!use_global && *fs_gamedir->current.string ? fs_gamedir->current.string : "raw") / path;
}
void free_scr_fh(scr_fh_t& scr_fh)
{
#ifdef DEBUG
plugin::get()->get_interface()->logging()->info(utils::string::va("free_scr_fh: closing %s\n", scr_fh.base_path.c_str()));
#endif
scr_fh = {};
scr_fh.type = scr_fh_type_e::UNUSED;
}
void close_all_scr_fh()
{
for (auto& fh : scr_fhs)
{
if (fh.type == scr_fh_type_e::UNUSED)
{
continue;
}
free_scr_fh(fh);
}
}
int scr_get_fh()
{
auto fh = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0) - 1;
if (fh < 0 || fh >= max_fhs)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "fs_fwrite: invalid filehandle");
}
return fh;
}
void fwrite_to_file(bool append_newline)
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type != scr_fh_type_e::WRITE && scr_fhs[fh].type != scr_fh_type_e::APPEND)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for writing");
}
std::string to_write = game::Scr_GetString(1, game::SCRIPTINSTANCE_SERVER);
if (append_newline)
{
to_write += '\n';
}
if (!utils::io::write_file(scr_fhs[fh].full_path.string(), to_write, true))
{
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Failed to write file: %s\n", scr_fhs[fh].base_path.c_str());
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 0);
return;
}
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
}
void add_file_io()
{
scheduler::on_scr_execute([]()
{
close_all_scr_fh();
});
gsc::function::add("fs_testfile", []()
{
auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER));
auto fd = 0;
auto file_length = game::FS_FOpenFileRead(fpath.c_str(), &fd);
if (!fd || file_length < 0)
{
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 0);
return;
}
game::FS_FCloseFile(fd);
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
});
gsc::function::add("fs_fopen", []()
{
auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER));
// check for dupes
for (const auto& scr_fd : scr_fhs)
{
if (scr_fd.type != scr_fh_type_e::UNUSED && scr_fd.base_path == fpath)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File already opened");
}
}
// check for avail slot
auto i = 0;
for (; i < max_fhs; i++)
{
if (scr_fhs[i].type == scr_fh_type_e::UNUSED)
{
break;
}
}
if (i >= max_fhs)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "Too many files opened");
}
// check mode
auto mode = game::Scr_GetString(1, game::SCRIPTINSTANCE_SERVER);
if (mode == "read"s)
{
auto fd = 0;
auto file_length = game::FS_FOpenFileRead(fpath.c_str(), &fd);
if (!fd || file_length < 0)
{
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Failed to open file for reading: %s\n", fpath.c_str());
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 0);
return;
}
scr_fhs[i].file_buff = std::make_unique<char[]>(file_length + 1);
auto bytes_read = game::FS_Read(scr_fhs[i].file_buff.get(), file_length, fd);
scr_fhs[i].file_buff[file_length] = '\0';
game::FS_FCloseFile(fd);
assert(bytes_read == file_length);
if (bytes_read < 0)
{
scr_fhs[i].file_buff = {};
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Failed to read file: %s\n", fpath.c_str());
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 0);
return;
}
scr_fhs[i].type = scr_fh_type_e::READ;
scr_fhs[i].file_length = bytes_read;
scr_fhs[i].seek = 0;
scr_fhs[i].base_path = fpath;
}
else if (mode == "write"s || mode == "append"s)
{
auto full_path = build_full_path(fpath, game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 3 && game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 2) == game::VAR_INTEGER && game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 2));
if (!utils::io::write_file(full_path.string(), "", (mode == "append"s)))
{
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Failed to open file for writing: %s\n", fpath.c_str());
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 0);
return;
}
scr_fhs[i].type = scr_fh_type_e::WRITE;
scr_fhs[i].base_path = fpath;
scr_fhs[i].full_path = full_path;
}
else
{
game::Scr_ParamError(1, game::SCRIPTINSTANCE_SERVER, utils::string::va("Invalid mode: %s", mode));
}
#ifdef DEBUG
plugin::get()->get_interface()->logging()->info(utils::string::va("gscr_fs_fopen: opening %s, mode %s\n", fpath.c_str(), mode));
#endif
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, i + 1);
});
gsc::function::add("fs_write", []()
{
fwrite_to_file(false);
});
gsc::function::add("fs_writeline", []()
{
fwrite_to_file(true);
});
gsc::function::add("fs_readline", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type != scr_fh_type_e::READ)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
}
// file is completed being read
if (scr_fhs[fh].seek >= scr_fhs[fh].file_length)
{
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
return;
}
// count how many bytes until the newline
auto bytes_to_read = 0;
auto found_nl = false;
for (auto i = scr_fhs[fh].seek; i < scr_fhs[fh].file_length; bytes_to_read++, i++)
{
if (scr_fhs[fh].file_buff[i] == '\n')
{
bytes_to_read++;
found_nl = true;
break;
}
}
if (bytes_to_read > max_gsc_string)
{
found_nl = false;
bytes_to_read = max_gsc_string;
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Line was too long in file %s, truncating\n", scr_fhs[fh].base_path.c_str());
}
auto scr_str = std::string(&scr_fhs[fh].file_buff[scr_fhs[fh].seek], bytes_to_read);
scr_fhs[fh].seek += bytes_to_read;
// remove all '\r'
scr_str.erase(std::remove(scr_str.begin(), scr_str.end(), '\r'), scr_str.end());
// chop the newline char off
if (found_nl)
{
scr_str.pop_back();
}
game::Scr_AddString(game::SCRIPTINSTANCE_SERVER, scr_str.c_str());
});
gsc::function::add("fs_read", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type != scr_fh_type_e::READ)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
}
// file is completed being read
if (scr_fhs[fh].seek >= scr_fhs[fh].file_length)
{
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
return;
}
auto bytes_to_read = scr_fhs[fh].file_length - scr_fhs[fh].seek;
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 2)
{
bytes_to_read = std::clamp(game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 1), 0, bytes_to_read);
if (bytes_to_read <= 0)
{
game::Scr_ParamError(1, game::SCRIPTINSTANCE_SERVER, "Trying to read <1 bytes");
}
}
if (bytes_to_read > max_gsc_string)
{
bytes_to_read = max_gsc_string;
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Line was too long in file %s, truncating\n", scr_fhs[fh].base_path.c_str());
}
auto scr_str = std::string(&scr_fhs[fh].file_buff[scr_fhs[fh].seek], bytes_to_read);
scr_fhs[fh].seek += bytes_to_read;
game::Scr_AddString(game::SCRIPTINSTANCE_SERVER, scr_str.c_str());
});
gsc::function::add("fs_fcloseall", []()
{
close_all_scr_fh();
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
});
gsc::function::add("fs_fclose", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type == scr_fh_type_e::UNUSED)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened");
}
free_scr_fh(scr_fhs[fh]);
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
});
gsc::function::add("fs_length", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type == scr_fh_type_e::UNUSED)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened");
}
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, scr_fhs[fh].file_length);
});
gsc::function::add("fs_getseek", []()
{
auto fh = scr_get_fh();
// write seek would require completely redoing how we write files...
if (scr_fhs[fh].type != scr_fh_type_e::READ)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
}
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, scr_fhs[fh].seek);
});
gsc::function::add("fs_seek", []()
{
auto fh = scr_get_fh();
if (scr_fhs[fh].type != scr_fh_type_e::READ)
{
game::Scr_ParamError(0, game::SCRIPTINSTANCE_SERVER, "File not opened for reading");
}
scr_fhs[fh].seek = std::clamp(game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 1), 0, scr_fhs[fh].file_length);
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
});
gsc::function::add("fs_remove", []()
{
auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER));
auto full_path = build_full_path(fpath, game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 2 && game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 1) == game::VAR_INTEGER && game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 1));
if (!utils::io::remove_file(full_path.string()))
{
game::Com_PrintWarning(game::CON_CHANNEL_SCRIPT, "Failed to delete file: %s\n", fpath.c_str());
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 0);
return;
}
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, 1);
});
gsc::function::add("fs_listfiles", []()
{
auto fpath = build_base_path(game::Scr_GetString(0, game::SCRIPTINSTANCE_SERVER));
int numfiles;
auto* files = game::FS_ListFiles(fpath.c_str(), "", game::FS_LIST_ALL, &numfiles);
game::Scr_MakeArray(game::SCRIPTINSTANCE_SERVER);
for (int i = 0; i < numfiles; i++)
{
game::Scr_AddString(game::SCRIPTINSTANCE_SERVER, files[i]);
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
}
game::FS_FreeFileList(files);
});
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
add_file_io();
}
private:
};
}
REGISTER_COMPONENT(fileio::component)

View File

@ -1,14 +1,125 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "loader/component_loader.hpp"
#include "gsc.hpp" #include "gsc.hpp"
#include "scheduler.hpp"
#include <json.hpp>
#include <utils/io.hpp>
#include <utils/hook.hpp>
#include <utils/string.hpp>
namespace gsc namespace gsc
{ {
std::unordered_map<std::string, game::BuiltinFunction> functions;
std::unordered_map<std::string, game::BuiltinMethod> methods;
utils::hook::detour scr_getmethod_hook;
void* scr_getfunction_stub_ret_loc;
namespace
{
game::BuiltinFunction scr_getfunction_call(const char** pName, int* pType)
{
auto itr = functions.find(*pName);
if (itr == functions.end())
{
return nullptr;
}
*pType = 0;
return itr->second;
}
game::BuiltinFunction NAKED scr_getfunction_stub()
{
__asm
{
push eax;
pushad;
lea eax, [esp + 0x24 + 0x2C - 0x1C];
push eax;
push edx;
call scr_getfunction_call;
add esp, 8;
mov [esp + 0x20], eax;
popad;
pop eax;
test eax, eax;
jnz just_ret;
// go do original code
push scr_getfunction_stub_ret_loc;
ret;
just_ret:
add esp, 4;
push 0x682DC8;
ret;
}
}
game::BuiltinMethod scr_getmethod_call(const char** pName, int* pType)
{
auto itr = methods.find(*pName);
if (itr == methods.end())
{
// call og
const auto og_addr = scr_getmethod_hook.get_original();
game::BuiltinMethod answer;
__asm
{
mov edi, pType;
mov esi, pName;
call og_addr;
mov answer, eax;
}
return answer;
}
*pType = 0;
return itr->second;
}
game::BuiltinMethod NAKED scr_getmethod_stub()
{
__asm
{
push edi;
push esi;
call scr_getmethod_call;
add esp, 8;
ret;
}
}
}
namespace function namespace function
{ {
void add(const std::string& name, const game::BuiltinFunction function) void add(const std::string& name, const game::BuiltinFunction function)
{ {
plugin::get()->get_interface()->gsc()->register_function(name, function); functions.insert_or_assign(name, function);
}
game::BuiltinFunction get(const char** name, int* type)
{
auto got = functions.find(*name);
if (got == functions.end())
{
return nullptr;
}
*type = 0;
return got->second;
} }
} }
@ -16,8 +127,46 @@ namespace gsc
{ {
void add(const std::string& name, const game::BuiltinMethod method) void add(const std::string& name, const game::BuiltinMethod method)
{ {
plugin::get()->get_interface()->gsc()->register_method(name, (plutonium::sdk::v1::interfaces::gsc::method_callback)method); methods.insert_or_assign(name, method);
}
game::BuiltinMethod get(const char** name, int* type)
{
auto got = methods.find(*name);
if (got == methods.end())
{
return nullptr;
}
*type = 0;
return got->second;
} }
} }
class component final : public component_interface
{
public:
void post_unpack() override
{
// for when we dont use the decomp
// custom gsc methods
if (game::plutonium::scr_get_method_stub != nullptr)
{
scr_getmethod_hook.create(game::plutonium::scr_get_method_stub.get(), scr_getmethod_stub);
}
// custom gsc funcs
if (game::plutonium::scr_get_function_stub != nullptr)
{
scr_getfunction_stub_ret_loc = game::plutonium::scr_get_function_stub.get();
utils::hook::jump(SELECT(0x0, 0x682D99), scr_getfunction_stub);
}
}
private:
};
} }
REGISTER_COMPONENT(gsc::component)

View File

@ -5,10 +5,12 @@ namespace gsc
namespace function namespace function
{ {
void add(const std::string& name, const game::BuiltinFunction function); void add(const std::string& name, const game::BuiltinFunction function);
game::BuiltinFunction get(const char** name, int* type);
} }
namespace method namespace method
{ {
void add(const std::string& name, const game::BuiltinMethod method); void add(const std::string& name, const game::BuiltinMethod method);
game::BuiltinMethod get(const char** name, int* type);
} }
} }

View File

@ -1,11 +1,195 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "loader/component_loader.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include <utils/concurrency.hpp>
#include <utils/hook.hpp>
namespace scheduler namespace scheduler
{ {
void on_scr_execute(void(*callback)()) namespace
{ {
plugin::get()->get_interface()->callbacks()->on_scripts_execute(callback); 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 = {};
});
});
}
};
std::thread thread;
task_pipeline pipelines[pipeline::count];
void execute(const pipeline type)
{
assert(type >= 0 && type < pipeline::count);
pipelines[type].execute();
}
void execute_server()
{
execute(pipeline::server);
}
void execute_main()
{
execute(pipeline::main);
}
utils::hook::detour com_init_hook;
utils::hook::detour gscr_postloadscripts_hook;
std::vector<std::function<void()>> post_init_funcs;
bool com_inited = false;
void on_post_init_hook()
{
if (com_inited)
{
return;
}
com_inited = true;
for (const auto& func : post_init_funcs)
{
func();
}
post_init_funcs.clear();
}
void com_init_stub()
{
com_init_hook.invoke<void>();
on_post_init_hook();
}
} }
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);
}
void on_init(const std::function<void()>& callback)
{
if (com_inited)
{
once(callback, pipeline::main);
}
else
{
post_init_funcs.push_back(callback);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
thread = std::thread([]()
{
while (true)
{
execute(pipeline::async);
std::this_thread::sleep_for(10ms);
}
});
com_init_hook.create(SELECT(0x0, 0x59D710), com_init_stub);
utils::hook::call(SELECT(0x0, 0x503B5D), execute_server);
utils::hook::call(SELECT(0x0, 0x59DCFD), execute_main);
}
};
} }
REGISTER_COMPONENT(scheduler::component)

View File

@ -2,5 +2,23 @@
namespace scheduler namespace scheduler
{ {
void on_scr_execute(void(*callback)()); enum pipeline
{
server,
async,
main,
count,
};
static const bool cond_continue = false;
static const bool cond_end = true;
void schedule(const std::function<bool()>& callback, pipeline type = pipeline::main,
std::chrono::milliseconds delay = 0ms);
void loop(const std::function<void()>& callback, pipeline type = pipeline::main,
std::chrono::milliseconds delay = 0ms);
void once(const std::function<void()>& callback, pipeline type = pipeline::main,
std::chrono::milliseconds delay = 0ms);
void on_init(const std::function<void()>& callback);
} }

View File

@ -9,32 +9,174 @@
namespace signatures namespace signatures
{ {
bool addr_is_in_image_space_of_pluto(size_t wheree) std::string read_sigs_file()
{
return utils::compression::zlib::decompress(utils::cryptography::des::decrypt(utils::io::read_file("t4sp-server-plugin/sigs")));
}
bool write_sigs_file(const std::string& f)
{
return utils::io::write_file("t4sp-server-plugin/sigs", utils::cryptography::des::encrypt(utils::compression::zlib::compress(f)));
}
const char* get_current_version()
{
return *reinterpret_cast<const char**>(0x4FF72D + 4);
}
std::unordered_map<std::string, std::string> get_cache_info_for_our_version()
{
std::unordered_map<std::string, std::string> answer;
auto* version = get_current_version();
nlohmann::json cache_json = nlohmann::json::parse(read_sigs_file(), nullptr, false, true);
if (!cache_json.is_discarded() && cache_json.is_object())
{
for (const auto& [key, value] : cache_json.items())
{
if (key != version)
{
continue;
}
if (!value.is_object())
{
continue;
}
answer = value.get<std::unordered_map<std::string, std::string>>();
break;
}
}
return answer;
}
bool save_cache_info_for_our_version(const std::unordered_map<std::string, std::string>& cache_info)
{
auto* version = get_current_version();
nlohmann::json cache_json = nlohmann::json::parse(read_sigs_file(), nullptr, false, true);
if (cache_json.is_discarded() || !cache_json.is_object())
{
cache_json = nlohmann::json::parse("{}", nullptr, false, true);
if (cache_json.is_discarded() || !cache_json.is_object())
{
return false; // can't happen?
}
}
cache_json[version] = cache_info;
return write_sigs_file(cache_json.dump());
}
size_t load_image_size()
{ {
MODULEINFO info{}; MODULEINFO info{};
GetModuleInformation(GetCurrentProcess(), GetModuleInformation(GetCurrentProcess(),
GetModuleHandle("plutonium-bootstrapper-win32.exe"), &info, sizeof(MODULEINFO)); GetModuleHandle("plutonium-bootstrapper-win32.exe"), &info, sizeof(MODULEINFO));
return info.SizeOfImage;
}
static const auto image_base = reinterpret_cast<size_t>(GetModuleHandle("plutonium-bootstrapper-win32.exe")); size_t get_image_size()
{
static const auto image_size = load_image_size();
return image_size;
}
return wheree >= image_base && wheree < image_base + info.SizeOfImage; size_t load_iamge_base()
{
return reinterpret_cast<size_t>(GetModuleHandle("plutonium-bootstrapper-win32.exe"));
}
size_t get_image_base()
{
static const auto image_base = load_iamge_base();
return image_base;
}
bool addr_is_in_image_space(size_t wheree)
{
static const auto image_base = load_iamge_base();
return wheree >= image_base && wheree < image_base + get_image_size();
}
size_t find_string_ptr(const std::string& string)
{
const char* string_ptr = nullptr;
std::string mask(string.size(), 'x');
const auto base = get_image_base();
utils::hook::signature signature(base, get_image_size() - base);
signature.add({
string,
mask,
[&](char* address)
{
string_ptr = address;
}
});
signature.process();
return reinterpret_cast<size_t>(string_ptr);
}
size_t find_string_ref(const std::string& string)
{
char bytes[4] = {0};
const auto string_ptr = find_string_ptr(string);
if (!string_ptr)
{
return 0;
}
std::memcpy(bytes, &string_ptr, sizeof(bytes));
return find_string_ptr({bytes, 4});
} }
std::string err_reason; std::string err_reason;
const std::string& get_err_reason() const std::string& get_err_reason()
{ {
return err_reason; return err_reason;
} }
bool process_printf(std::unordered_map<std::string, std::string> &cache_info)
{
if (cache_info.contains("printf"))
{
game::plutonium::printf.set(std::atoi(cache_info.at("printf").c_str()));
return true;
}
const auto string_ref = find_string_ref("A critical exception occured!\n");
if (!string_ref)
{
err_reason = "printf";
return false;
}
const auto offset = *reinterpret_cast<size_t*>(string_ref + 5);
game::plutonium::printf.set(string_ref + 4 + 5 + offset);
cache_info.insert_or_assign("printf", std::to_string(string_ref + 4 + 5 + offset));
return true;
}
#define SAFE_SET_PLUTO_SYMBOL_DOUBLE(name, addr, off) \ #define SAFE_SET_PLUTO_SYMBOL_DOUBLE(name, addr, off) \
addr2 = reinterpret_cast<size_t>(utils::hook::get_displacement_addr(addr)); \ addr2 = reinterpret_cast<size_t>(utils::hook::get_displacement_addr(addr)); \
if (!addr_is_in_image_space_of_pluto(addr2)) \ if (!addr_is_in_image_space(addr2)) \
{ \ { \
err_reason = #name " 1"; \ err_reason = #name " 1"; \
return false; \ return false; \
} \ } \
addr1 = reinterpret_cast<size_t>(utils::hook::get_displacement_addr(addr2 + off)); \ addr1 = reinterpret_cast<size_t>(utils::hook::get_displacement_addr(addr2 + off)); \
if (!addr_is_in_image_space_of_pluto(addr1)) \ if (!addr_is_in_image_space(addr1)) \
{ \ { \
err_reason = #name " 2"; \ err_reason = #name " 2"; \
return false; \ return false; \
@ -44,7 +186,7 @@ namespace signatures
#define SAFE_SET_PLUTO_SYMBOL(name, addr) \ #define SAFE_SET_PLUTO_SYMBOL(name, addr) \
addr1 = reinterpret_cast<size_t>(utils::hook::get_displacement_addr(addr)); \ addr1 = reinterpret_cast<size_t>(utils::hook::get_displacement_addr(addr)); \
if (!addr_is_in_image_space_of_pluto(addr1)) \ if (!addr_is_in_image_space(addr1)) \
{ \ { \
err_reason = #name; \ err_reason = #name; \
return false; \ return false; \
@ -56,6 +198,12 @@ namespace signatures
{ {
size_t addr1; size_t addr1;
size_t addr2; size_t addr2;
auto cache_info = get_cache_info_for_our_version();
if (!process_printf(cache_info))
{
return false;
}
SAFE_SET_PLUTO_SYMBOL_DOUBLE(load_custom_script_func, 0x689C80, 0x6); SAFE_SET_PLUTO_SYMBOL_DOUBLE(load_custom_script_func, 0x689C80, 0x6);
SAFE_SET_PLUTO_SYMBOL_DOUBLE(script_preprocess, 0x689BCF, 0x2); SAFE_SET_PLUTO_SYMBOL_DOUBLE(script_preprocess, 0x689BCF, 0x2);
@ -68,15 +216,21 @@ namespace signatures
SAFE_SET_PLUTO_SYMBOL_DOUBLE(store_func_codepos, 0x688909, 0x3); SAFE_SET_PLUTO_SYMBOL_DOUBLE(store_func_codepos, 0x688909, 0x3);
SAFE_SET_PLUTO_SYMBOL(cscr_get_function_hook, 0x682DC0); SAFE_SET_PLUTO_SYMBOL(cscr_get_function_hook, 0x682DC0);
SAFE_SET_PLUTO_SYMBOL(scr_get_function_stub, 0x682D99);
SAFE_SET_PLUTO_SYMBOL(scr_get_method_stub, 0x683043);
SAFE_SET_PLUTO_SYMBOL(cscr_get_method_hook, 0x68305C); SAFE_SET_PLUTO_SYMBOL(cscr_get_method_hook, 0x68305C);
SAFE_SET_PLUTO_SYMBOL_DOUBLE(scr_get_method_hook, 0x683043, 0x4); SAFE_SET_PLUTO_SYMBOL_DOUBLE(scr_get_method_hook, 0x683043, 0x4);
SAFE_SET_PLUTO_SYMBOL_DOUBLE(scr_get_function_hook, 0x682D99, 0x8); SAFE_SET_PLUTO_SYMBOL_DOUBLE(scr_get_function_hook, 0x682D99, 0x8);
save_cache_info_for_our_version(cache_info);
return true; return true;
} }
bool process() bool process()
{ {
utils::cryptography::des::set_key("694201337");
return handle_funcs(); return handle_funcs();
} }
} }

View File

@ -1,11 +1,40 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "loader/component_loader.hpp"
#include "component/signatures.hpp"
PLUTONIUM_API plutonium::sdk::plugin* PLUTONIUM_CALLBACK on_initialize() #include <utils/hook.hpp>
{
return plugin::get();
}
BOOL APIENTRY DllMain(HMODULE /*module_*/, DWORD /*ul_reason_for_call*/, LPVOID /*reserved_*/) BOOL APIENTRY DllMain(HMODULE /*module_*/, DWORD ul_reason_for_call, LPVOID /*reserved_*/)
{ {
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
if (game::environment::t4sp())
{
if (!signatures::process())
{
MessageBoxA(NULL,
std::format("This version of t4sp-server-plugin is outdated.\n" \
"Download the latest dll from here: https://github.com/JezuzLizard/T4SP-Server-Plugin/releases\n" \
"'{}' failed", signatures::get_err_reason()).c_str(),
"ERROR", MB_ICONERROR);
return FALSE;
}
if (game::plutonium::printf.get() != nullptr)
{
utils::hook::jump(reinterpret_cast<uintptr_t>(&printf), game::plutonium::printf);
}
component_loader::post_unpack();
}
else
{
MessageBoxA(nullptr, "Unsupported game executable. (t4sp is only supported)", "ERROR, BRO!", 0);
return FALSE;
}
}
return TRUE; return TRUE;
} }

View File

@ -384,44 +384,6 @@ namespace game
VAR_ENDON_LIST = 0x18, VAR_ENDON_LIST = 0x18,
}; };
enum scr_builtin_type_t
{
BUILTIN_ANY = 0x0,
BUILTIN_DEVELOPER_ONLY = 0x1,
};
enum Scr_SourceType_t
{
SOURCE_TYPE_NONE = 0x0,
SOURCE_TYPE_BREAKPOINT = 0x1,
SOURCE_TYPE_CALL = 0x2,
};
enum scr_abort_t
{
SCR_ABORT_NONE = 0x0,
SCR_ABORT_CONTINUE = 0x1,
SCR_ABORT_BREAK = 0x2,
SCR_ABORT_RETURN = 0x3,
SCR_ABORT_MAX = 0x3,
};
enum scr_call_type_t
{
CALL_NONE = 0x0,
CALL_BUILTIN = 0x1,
CALL_THREAD = 0x2,
CALL_FUNCTION = 0x3,
};
enum sl_user_type_e
{
SL_USER_GAME = 0x1,
SL_USER_TEMP = 0x2,
SL_USER_XZONE = 0x4,
SL_USER_XZONE_TEMP = 0x8,
};
#pragma endregion #pragma endregion
#pragma region "structs" #pragma region "structs"

View File

@ -178,5 +178,4 @@ namespace game
void Scr_EvalBoolNot(scriptInstance_t inst, VariableValue* value); void Scr_EvalBoolNot(scriptInstance_t inst, VariableValue* value);
unsigned int GetInternalVariableIndex(scriptInstance_t inst, unsigned int unsignedValue); unsigned int GetInternalVariableIndex(scriptInstance_t inst, unsigned int unsignedValue);
const char* Scr_ReadData(scriptInstance_t inst, const char** pos, unsigned int count); const char* Scr_ReadData(scriptInstance_t inst, const char** pos, unsigned int count);
unsigned int Scr_GetNumParam(game::scriptInstance_t inst);
} }

View File

@ -981,9 +981,4 @@ namespace game
{ {
return codsrc::Scr_ReadData(inst, pos, count); return codsrc::Scr_ReadData(inst, pos, count);
} }
unsigned int Scr_GetNumParam(game::scriptInstance_t inst)
{
return codsrc::Scr_GetNumParam(inst);
}
} }

View File

@ -9,16 +9,16 @@ namespace game
WEAK symbol<void()>yyrestart{ 0x0, 0x69D5C0 }; WEAK symbol<void()>yyrestart{ 0x0, 0x69D5C0 };
WEAK symbol<yy_buffer_state* ()>yy_create_buffer{ 0x0, 0x69D620 }; WEAK symbol<yy_buffer_state* ()>yy_create_buffer{ 0x0, 0x69D620 };
inline void* LowerCase_ADDR() { return CALL_ADDR(0x0, 0x69AEA0); } inline void* LowerCase() { return CALL_ADDR(0x0, 0x69AEA0); }
unsigned int LowerCase(unsigned int strVal, void* call_addr = LowerCase_ADDR()); unsigned int LowerCase(unsigned int strVal, void* call_addr = LowerCase());
inline void* StringValue_ADDR() { return CALL_ADDR(0x0, 0x69BFF0); } inline void* StringValue() { return CALL_ADDR(0x0, 0x69BFF0); }
int StringValue(int len, const char* str_, void* call_addr = StringValue_ADDR()); int StringValue(int len, const char* str_, void* call_addr = StringValue());
inline void* yy_try_NUL_trans_ADDR() { return CALL_ADDR(0x0, 0x69D520); } inline void* yy_try_NUL_trans() { return CALL_ADDR(0x0, 0x69D520); }
int yy_try_NUL_trans(int yy_current_state, void* call_addr = yy_try_NUL_trans_ADDR()); int yy_try_NUL_trans(int yy_current_state, void* call_addr = yy_try_NUL_trans());
inline void* yy_flush_buffer_ADDR() { return CALL_ADDR(0x0, 0x69D690); } inline void* yy_flush_buffer() { return CALL_ADDR(0x0, 0x69D690); }
void yy_flush_buffer(yy_buffer_state* result, void* call_addr = yy_flush_buffer_ADDR()); void yy_flush_buffer(yy_buffer_state* result, void* call_addr = yy_flush_buffer());
inline void* ScriptParse_ADDR() { return CALL_ADDR(0x0, 0x69D710); } inline void* ScriptParse() { return CALL_ADDR(0x0, 0x69D710); }
void ScriptParse(scriptInstance_t a1, sval_u* parseData, void* call_addr = ScriptParse_ADDR()); void ScriptParse(scriptInstance_t a1, sval_u* parseData, void* call_addr = ScriptParse());
FILE* yy_load_buffer_state(); FILE* yy_load_buffer_state();
void yy_fatal_error(const char* err); void yy_fatal_error(const char* err);

View File

@ -3763,9 +3763,6 @@ namespace game
CRITSECT_SCRIPT_STRING = 0xB, CRITSECT_SCRIPT_STRING = 0xB,
CRITSECT_MEMORY_TREE = 0xC, CRITSECT_MEMORY_TREE = 0xC,
CRITSECT_SYS_EVENT_QUEUE = 0xE, CRITSECT_SYS_EVENT_QUEUE = 0xE,
CRITSECT_DXDEVICE = 0x11,
CRITSECT_DXDEVICE_GLOB = 0x12,
CRITSECT_MISSING_ASSET = 0x13,
CRITSECT_PHYSICS_UPDATE = 0x15, CRITSECT_PHYSICS_UPDATE = 0x15,
CRITSECT_CINEMATIC = 0x19, CRITSECT_CINEMATIC = 0x19,
CRITSECT_CINEMATIC_TARGET_CHANGE = 0x1A, CRITSECT_CINEMATIC_TARGET_CHANGE = 0x1A,
@ -3900,6 +3897,15 @@ namespace game
HUDELEM_UPDATE_ARCHIVAL_AND_CURRENT = 0x3, HUDELEM_UPDATE_ARCHIVAL_AND_CURRENT = 0x3,
}; };
enum sourceType_e
{
SOURCE_TYPE_BREAKPOINT = 0x1,
SOURCE_TYPE_CALL = 0x2,
SOURCE_TYPE_THREAD_START = 0x4,
SOURCE_TYPE_BUILTIN_CALL = 0x8,
SOURCE_TYPE_NOTIFY = 0x10,
};
enum animBodyPart_t enum animBodyPart_t
{ {
ANIM_BP_UNUSED = 0x0, ANIM_BP_UNUSED = 0x0,
@ -3909,51 +3915,6 @@ namespace game
NUM_ANIM_BODYPARTS = 0x4, NUM_ANIM_BODYPARTS = 0x4,
}; };
enum zone_flags_e
{
ZONE_FLAG_none = 0x0,
DB_ZONE_COMMON_LOC = 0x1,
DB_ZONE_LEVEL_LOC = 0x2,
DB_ZONE_CODE = 0x4,
DB_ZONE_COMMON = 0x8,
DB_ZONE_LEVEL = 0x10,
DB_ZONE_LOAD = 0x20,
DB_ZONE_MYCHANGES = 0x40,
ZONE_FLAG_unk3 = 0x80,
DB_ZONE_LEVELOVERLAY = 0x100, // patch, not 'so'
DB_ZONE_PATCH = 0x200,
ZONE_FLAG_unk5 = 0x400,
DB_ZONE_MOD = 0x800,
};
enum xfile_block_type_e
{
XFILE_BLOCK_TEMP = 0x0,
XFILE_BLOCK_RUNTIME = 0x1,
XFILE_BLOCK_RUNTIME_BEGIN = 0x1,
XFILE_BLOCK_LARGE_RUNTIME = 0x2,
XFILE_BLOCK_PHYSICAL_RUNTIME = 0x3,
XFILE_BLOCK_VIRTUAL = 0x4,
XFILE_BLOCK_RUNTIME_END = 0x4,
XFILE_BLOCK_LARGE = 0x5,
XFILE_BLOCK_PHYSICAL = 0x6,
MAX_XFILE_COUNT = 0x7,
};
enum dm_memory_tyep_e
{
DM_MEMORY_TEMP = 0x0,
DM_MEMORY_VIRTUAL = 0x1,
DM_MEMORY_PHYSICAL = 0x2,
};
enum phys_alloc_type_e
{
PHYS_ALLOC_LOW = 0x0,
PHYS_ALLOC_HIGH = 0x1,
PHYS_ALLOC_COUNT = 0x2,
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -231,21 +231,6 @@ namespace game
*cmd_functions = newCmd; *cmd_functions = newCmd;
} }
// restored
const char** FS_ListFiles(const char* path, const char* extension, FsListBehavior_e behavior, int* numfiles)
{
return FS_ListFilteredFiles(*fs_searchpaths, path, extension, nullptr, behavior, numfiles);
}
// restored
void FS_FreeFileList(const char** list)
{
if ( list )
{
Hunk_UserDestroy((HunkUser*)*(list - 1));
}
}
// restored // restored
void Sys_EnterCriticalSection(CriticalSection critSect) void Sys_EnterCriticalSection(CriticalSection critSect)
{ {

View File

@ -41,7 +41,6 @@
//#define DISABLE_RE_CSCR_PARSETREE //#define DISABLE_RE_CSCR_PARSETREE
//#define DISABLE_RE_CSCR_READWRITE //#define DISABLE_RE_CSCR_READWRITE
//#define DISABLE_RE_CSCR_STRINGLIST //#define DISABLE_RE_CSCR_STRINGLIST
//#define DISABLE_RE_CSCR_VARIABLE
//#define DISABLE_RE_CSCR_VM //#define DISABLE_RE_CSCR_VM
//#define DISABLE_RE_CSCR_YACC //#define DISABLE_RE_CSCR_YACC

View File

@ -3604,6 +3604,17 @@ namespace game
ASSERT_STRUCT_OFFSET(TLSData_t, field_38, 0x38); ASSERT_STRUCT_OFFSET(TLSData_t, field_38, 0x38);
ASSERT_STRUCT_OFFSET(TLSData_t, field_3C, 0x3C); ASSERT_STRUCT_OFFSET(TLSData_t, field_3C, 0x3C);
struct XZoneInfo
{
char * name; //OFS: 0x0 SIZE: 0x4
int allocFlags; //OFS: 0x4 SIZE: 0x4
int freeFlags; //OFS: 0x8 SIZE: 0x4
};
ASSERT_STRUCT_SIZE(XZoneInfo, 0xC);
ASSERT_STRUCT_OFFSET(XZoneInfo, name, 0x0);
ASSERT_STRUCT_OFFSET(XZoneInfo, allocFlags, 0x4);
ASSERT_STRUCT_OFFSET(XZoneInfo, freeFlags, 0x8);
union DvarValue union DvarValue
{ {
bool enabled; //OFS: 0x0 SIZE: 0x1 bool enabled; //OFS: 0x0 SIZE: 0x1
@ -11396,6 +11407,17 @@ namespace game
ASSERT_STRUCT_OFFSET(LargeLocal, startPos, 0x0); ASSERT_STRUCT_OFFSET(LargeLocal, startPos, 0x0);
ASSERT_STRUCT_OFFSET(LargeLocal, size, 0x4); ASSERT_STRUCT_OFFSET(LargeLocal, size, 0x4);
struct XFile
{
unsigned int size; //OFS: 0x0 SIZE: 0x4
unsigned int externalSize; //OFS: 0x4 SIZE: 0x4
unsigned int blockSize[8]; //OFS: 0x8 SIZE: 0x20
};
ASSERT_STRUCT_SIZE(XFile, 0x28);
ASSERT_STRUCT_OFFSET(XFile, size, 0x0);
ASSERT_STRUCT_OFFSET(XFile, externalSize, 0x4);
ASSERT_STRUCT_OFFSET(XFile, blockSize, 0x8);
union pointtrace_or_moveclip_u union pointtrace_or_moveclip_u
{ {
pointtrace_t point; //OFS: 0x0 SIZE: 0x40 pointtrace_t point; //OFS: 0x0 SIZE: 0x40
@ -12755,6 +12777,21 @@ namespace game
ASSERT_STRUCT_OFFSET(GfxCmdStretchPicRotateXY, color, 0x28); ASSERT_STRUCT_OFFSET(GfxCmdStretchPicRotateXY, color, 0x28);
ASSERT_STRUCT_OFFSET(GfxCmdStretchPicRotateXY, rotation, 0x2C); ASSERT_STRUCT_OFFSET(GfxCmdStretchPicRotateXY, rotation, 0x2C);
struct XZoneMemory
{
XBlock blocks[9]; //OFS: 0x0 SIZE: 0x48
char * lockedVertexData; //OFS: 0x48 SIZE: 0x4
char * lockedIndexData; //OFS: 0x4C SIZE: 0x4
void * vertexBuffer; //OFS: 0x50 SIZE: 0x4
void * indexBuffer; //OFS: 0x54 SIZE: 0x4
};
ASSERT_STRUCT_SIZE(XZoneMemory, 0x58);
ASSERT_STRUCT_OFFSET(XZoneMemory, blocks, 0x0);
ASSERT_STRUCT_OFFSET(XZoneMemory, lockedVertexData, 0x48);
ASSERT_STRUCT_OFFSET(XZoneMemory, lockedIndexData, 0x4C);
ASSERT_STRUCT_OFFSET(XZoneMemory, vertexBuffer, 0x50);
ASSERT_STRUCT_OFFSET(XZoneMemory, indexBuffer, 0x54);
struct SaveMemoryGlob struct SaveMemoryGlob
{ {
SaveGame * committedGameSave; //OFS: 0x0 SIZE: 0x4 SaveGame * committedGameSave; //OFS: 0x0 SIZE: 0x4
@ -13287,64 +13324,7 @@ namespace game
ASSERT_STRUCT_OFFSET(DynEnt_FadeData, id, 0x0); ASSERT_STRUCT_OFFSET(DynEnt_FadeData, id, 0x0);
ASSERT_STRUCT_OFFSET(DynEnt_FadeData, startTime, 0x4); ASSERT_STRUCT_OFFSET(DynEnt_FadeData, startTime, 0x4);
struct __declspec(align(2)) GfxMetrics
{
unsigned __int16 cubemapShotRes;
unsigned __int16 cubemapShotPixelBorder;
bool hasAnisotropicMinFilter;
bool hasAnisotropicMagFilter;
int maxAnisotropy;
int maxClipPlanes;
unsigned __int8 shadowmapSamplerState;
bool slopeScaleDepthBias;
bool canMipCubemaps;
};
// cCurve
struct CommonFastFileLoad
{
int code_post_gfx_flags;
int patch_flags;
int ui_flags;
int common_flags;
int flags5;
int localized_common_flags;
const char *code_post_gfx;
const char *patch;
const char *ui;
const char *common;
int filename4;
const char *localized_common;
const char *mod;
};
struct GfxWindowParms
{
HWND__ *hwnd;
int hz;
bool fullscreen;
int x;
int y;
int sceneWidth;
int sceneHeight;
int displayWidth;
int displayHeight;
int aaSamples;
};
struct stream_source_info_t
{
char Stream;
char Offset;
char Type;
};
struct stream_dest_info_t
{
char Usage;
char UsageIndex;
};
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -78,9 +78,6 @@ namespace game
void Sys_EnterCriticalSection(CriticalSection critSect); void Sys_EnterCriticalSection(CriticalSection critSect);
void Sys_LeaveCriticalSection(CriticalSection critSect); void Sys_LeaveCriticalSection(CriticalSection critSect);
const char** FS_ListFiles(const char* path, const char* extension, FsListBehavior_e behavior, int* numfiles);
void FS_FreeFileList(const char** list);
// Variables // Variables
WEAK symbol<CRITICAL_SECTION> s_criticalSection{ 0x0, 0x2298D08 }; WEAK symbol<CRITICAL_SECTION> s_criticalSection{ 0x0, 0x2298D08 };
WEAK symbol<HunkUser*> g_DebugHunkUser{ 0x0, 0x212B2EC }; WEAK symbol<HunkUser*> g_DebugHunkUser{ 0x0, 0x212B2EC };
@ -96,6 +93,8 @@ namespace game
namespace plutonium namespace plutonium
{ {
WEAK symbol<int(const char* fmt, ...)> printf{0x0, 0x0};
WEAK symbol<void(scriptInstance_t)> load_custom_script_func{0x0, 0x0}; WEAK symbol<void(scriptInstance_t)> load_custom_script_func{0x0, 0x0};
WEAK symbol<void(char*, game::scriptInstance_t, sval_u*)> script_preprocess{0x0, 0x0}; WEAK symbol<void(char*, game::scriptInstance_t, sval_u*)> script_preprocess{0x0, 0x0};
WEAK symbol<void(game::scriptInstance_t)> vm_execute_update_codepos{0x0, 0x0}; WEAK symbol<void(game::scriptInstance_t)> vm_execute_update_codepos{0x0, 0x0};
@ -105,6 +104,9 @@ namespace game
WEAK symbol<const char*(game::scriptInstance_t, unsigned int)> at_codepose_va{ 0x0, 0x0 }; WEAK symbol<const char*(game::scriptInstance_t, unsigned int)> at_codepose_va{ 0x0, 0x0 };
WEAK symbol<void()> scr_get_method_stub{ 0x0, 0x0 };
WEAK symbol<void()> scr_get_function_stub{ 0x0, 0x0 };
WEAK symbol<game::BuiltinMethod(const char** name, int* type)> scr_get_method_hook{ 0x0, 0x0 }; WEAK symbol<game::BuiltinMethod(const char** name, int* type)> scr_get_method_hook{ 0x0, 0x0 };
WEAK symbol<game::BuiltinFunction(const char** name, int* type)> scr_get_function_hook{ 0x0, 0x0 }; WEAK symbol<game::BuiltinFunction(const char** name, int* type)> scr_get_function_hook{ 0x0, 0x0 };
WEAK symbol<game::BuiltinMethod(const char** name, int* type)> cscr_get_method_hook{ 0x0, 0x0 }; WEAK symbol<game::BuiltinMethod(const char** name, int* type)> cscr_get_method_hook{ 0x0, 0x0 };

View File

@ -5318,8 +5318,7 @@ namespace game
RawFile* rawfile; //OFS: 0x1A SIZE: 0x4 RawFile* rawfile; //OFS: 0x1A SIZE: 0x4
StringTable* stringTable; //OFS: 0x1B SIZE: 0x4 StringTable* stringTable; //OFS: 0x1B SIZE: 0x4
PackIndex* packIndex; //OFS: 0x1C SIZE: 0x4 PackIndex* packIndex; //OFS: 0x1C SIZE: 0x4
snd_alias_list_t* sound; //OFS: 0x1D SIZE: 0x4 void* data; //OFS: 0x1D SIZE: 0x4
void* data; //OFS: 0x1E SIZE: 0x4
}; };
struct XAsset struct XAsset
@ -5418,28 +5417,6 @@ namespace game
ASSERT_STRUCT_OFFSET(XZone, allocType, 0x8); ASSERT_STRUCT_OFFSET(XZone, allocType, 0x8);
ASSERT_STRUCT_OFFSET(XZone, blocks, 0xC); ASSERT_STRUCT_OFFSET(XZone, blocks, 0xC);
struct XFile
{
unsigned int size; //OFS: 0x0 SIZE: 0x4
unsigned int externalSize; //OFS: 0x4 SIZE: 0x4
unsigned int blockSize[7]; //OFS: 0x8 SIZE: 0x1C
};
ASSERT_STRUCT_SIZE(XFile, 0x24);
ASSERT_STRUCT_OFFSET(XFile, size, 0x0);
ASSERT_STRUCT_OFFSET(XFile, externalSize, 0x4);
ASSERT_STRUCT_OFFSET(XFile, blockSize, 0x8);
struct XZoneInfo
{
char * name; //OFS: 0x0 SIZE: 0x4
int allocFlags; //OFS: 0x4 SIZE: 0x4
int freeFlags; //OFS: 0x8 SIZE: 0x4
};
ASSERT_STRUCT_SIZE(XZoneInfo, 0xC);
ASSERT_STRUCT_OFFSET(XZoneInfo, name, 0x0);
ASSERT_STRUCT_OFFSET(XZoneInfo, allocFlags, 0x4);
ASSERT_STRUCT_OFFSET(XZoneInfo, freeFlags, 0x8);
#ifdef __cplusplus #ifdef __cplusplus
WEAK symbol<XAssetHeader(XAssetType type, const char* name, bool errorIfMissing, int waitTime)>DB_FindXAssetHeader{ 0x0, 0x48DA30 }; WEAK symbol<XAssetHeader(XAssetType type, const char* name, bool errorIfMissing, int waitTime)>DB_FindXAssetHeader{ 0x0, 0x48DA30 };
} }

View File

@ -1,68 +0,0 @@
#include <stdinc.hpp>
#include "component/signatures.hpp"
#include <utils/hook.hpp>
#include "loader/component_loader.hpp"
namespace plugin
{
std::uint32_t plugin::plugin_version()
{
return 1;
}
const char* plugin::plugin_name()
{
return "t4sp-server-plugin";
}
bool plugin::is_game_supported(plutonium::sdk::game game)
{
return game == plutonium::sdk::game::t4;
}
void plugin::on_startup(plutonium::sdk::iinterface* interface_ptr, plutonium::sdk::game game)
{
this->interface_ = interface_ptr;
this->game_ = game;
if (!game::environment::t4sp())
{
MessageBoxA(nullptr, "Unsupported game executable. (t4sp is only supported)", "ERROR, BRO!", 0);
return;
}
if (!signatures::process())
{
MessageBoxA(NULL,
std::format("This version of t4sp-server-plugin is outdated.\n" \
"Download the latest dll from here: https://github.com/JezuzLizard/T4SP-Server-Plugin/releases\n" \
"'{}' failed", signatures::get_err_reason()).c_str(),
"ERROR", MB_ICONERROR);
return;
}
component_loader::post_unpack();
}
void plugin::on_shutdown()
{
}
plutonium::sdk::iinterface* plugin::get_interface()
{
return this->interface_;
}
plutonium::sdk::game plugin::get_game()
{
return this->game_;
}
plugin* get()
{
static plugin instance;
return &instance;
}
}

View File

@ -1,30 +0,0 @@
#pragma once
#include <plutonium_sdk.hpp>
namespace plugin
{
class plugin : public plutonium::sdk::plugin
{
public:
~plugin() = default;
std::uint32_t plugin_version() override;
const char* plugin_name() override;
bool is_game_supported(plutonium::sdk::game game) override;
void on_startup(plutonium::sdk::iinterface* interface_ptr, plutonium::sdk::game game) override;
void on_shutdown() override;
plutonium::sdk::iinterface* get_interface();
plutonium::sdk::game get_game();
private:
plutonium::sdk::iinterface* interface_{};
plutonium::sdk::game game_{};
};
plugin* get();
}

View File

@ -1 +1,418 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "codsrc/clientscript/clientscript_public.hpp"
#include <dbghelp.h>
namespace game
{
#define QUICK_TO_JSON_FIELD(j, v, membername) j[#membername] = v.membername
#define QUICK_TO_JSON_FIELD_SAFE_CSTR(j, v, membername) \
if (v.membername) \
j[#membername] = v.membername; \
else \
j[#membername] = "(NULL)"
#define QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, membername) j[#membername] = reinterpret_cast<size_t>(&v.membername)
#define QUICK_TO_JSON_FIELD_ARRAY(j, v, membername) \
for (auto i = 0; i < ARRAY_COUNT(v.membername); i++) \
{ \
j[#membername][i] = v.membername[i]; \
}
#define QUICK_TO_JSON_FIELD_SL_STRING(j, v, membername) j[#membername "Str"] = SL_ConvertToStringSafe(v.membername, *gInst)
void to_json(nlohmann::json& j, const scrVarPub_t& v)
{
QUICK_TO_JSON_FIELD_SAFE_CSTR(j, v, fieldBuffer);
QUICK_TO_JSON_FIELD(j, v, canonicalStrCount);
QUICK_TO_JSON_FIELD(j, v, developer);
QUICK_TO_JSON_FIELD(j, v, developer_script);
QUICK_TO_JSON_FIELD(j, v, evaluate);
QUICK_TO_JSON_FIELD_SAFE_CSTR(j, v, error_message);
QUICK_TO_JSON_FIELD(j, v, error_index);
QUICK_TO_JSON_FIELD(j, v, time);
QUICK_TO_JSON_FIELD(j, v, timeArrayId);
QUICK_TO_JSON_FIELD(j, v, pauseArrayId);
QUICK_TO_JSON_FIELD(j, v, levelId);
QUICK_TO_JSON_FIELD(j, v, gameId);
QUICK_TO_JSON_FIELD(j, v, animId);
QUICK_TO_JSON_FIELD(j, v, freeEntList);
QUICK_TO_JSON_FIELD(j, v, tempVariable);
QUICK_TO_JSON_FIELD(j, v, bInited);
QUICK_TO_JSON_FIELD(j, v, savecount);
QUICK_TO_JSON_FIELD(j, v, checksum);
QUICK_TO_JSON_FIELD(j, v, entId);
QUICK_TO_JSON_FIELD(j, v, entFieldName);
QUICK_TO_JSON_FIELD_SL_STRING(j, v, entFieldName);
QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, programHunkUser);
QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, programBuffer);
QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, endScriptBuffer);
QUICK_TO_JSON_FIELD_ARRAY(j, v, saveIdMap);
QUICK_TO_JSON_FIELD_ARRAY(j, v, saveIdMapRev);
}
}
// https://stackoverflow.com/questions/5693192/win32-backtrace-from-c-code
std::string build_code_stack()
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
std::string answer{};
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
answer += std::format("{}: {} - 0x{:06x}\n", frames - i - 1, symbol->Name, symbol->Address);
}
free( symbol );
return answer;
}
int op_idx[game::SCRIPT_INSTANCE_MAX] = { 0, 0 };
bool op_idx_rolled_over[game::SCRIPT_INSTANCE_MAX] = { false, false };
game::OpcodeVM op_history[game::SCRIPT_INSTANCE_MAX][128] = {};
int builtin_idx[game::SCRIPT_INSTANCE_MAX] = { 0, 0 };
bool builtin_idx_rolled_over[game::SCRIPT_INSTANCE_MAX] = { false, false };
int builtin_history[game::SCRIPT_INSTANCE_MAX][128] = {};
int codepos_idx[game::SCRIPT_INSTANCE_MAX] = { 0, 0 };
bool codepos_idx_rolled_over[game::SCRIPT_INSTANCE_MAX] = { false, false };
const char* codepos_history[game::SCRIPT_INSTANCE_MAX][128] = {};
std::string build_builtin_history(game::scriptInstance_t inst)
{
std::string answer{};
int count = builtin_idx_rolled_over[inst] ? ARRAY_COUNT(builtin_history[inst]) : builtin_idx[inst];
for (auto i = 0; i < count; i++)
{
auto idx = builtin_idx[inst] - 1 - i;
if (idx < 0)
{
idx += ARRAY_COUNT(builtin_history[inst]);
}
// todo, convert to builtin name
answer += std::format("{}\n", builtin_history[inst][idx]);
}
return answer;
}
std::string build_codepos_history(game::scriptInstance_t inst)
{
std::string answer{};
int bufferIndex;
int prevSourcePos;
int col;
char line[1024];
int lineNum;
const char* fileName;
int count = codepos_idx_rolled_over[inst] ? ARRAY_COUNT(codepos_history[inst]) : codepos_idx[inst];
for (auto i = 0; i < count; i++)
{
auto idx = codepos_idx[inst] - 1 - i;
if (idx < 0)
{
idx += ARRAY_COUNT(codepos_history[inst]);
}
bufferIndex = game::Scr_GetSourceBuffer(inst, codepos_history[inst][idx]);
prevSourcePos = game::Scr_GetPrevSourcePos(inst, codepos_history[inst][idx], 0);
lineNum = game::Scr_GetLineInfo(&col, game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].sourceBuf, prevSourcePos, line);
fileName = game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].buf;
answer += std::format("{}({}, {}): '{}'\n", fileName, lineNum, col, line);
}
return answer;
}
std::string build_op_history(game::scriptInstance_t inst)
{
static const char* OpcodeVMToString[] = {
"OP_End",
"OP_Return",
"OP_GetUndefined",
"OP_GetZero",
"OP_GetByte",
"OP_GetNegByte",
"OP_GetUnsignedShort",
"OP_GetNegUnsignedShort",
"OP_GetInteger",
"OP_GetFloat",
"OP_GetString",
"OP_GetIString",
"OP_GetVector",
"OP_GetLevelObject",
"OP_GetAnimObject",
"OP_GetSelf",
"OP_GetLevel",
"OP_GetGame",
"OP_GetAnim",
"OP_GetAnimation",
"OP_GetGameRef",
"OP_GetFunction",
"OP_CreateLocalVariable",
"OP_RemoveLocalVariables",
"OP_EvalLocalVariableCached0",
"OP_EvalLocalVariableCached1",
"OP_EvalLocalVariableCached2",
"OP_EvalLocalVariableCached3",
"OP_EvalLocalVariableCached4",
"OP_EvalLocalVariableCached5",
"OP_EvalLocalVariableCached",
"OP_EvalLocalArrayCached",
"OP_EvalArray",
"OP_EvalLocalArrayRefCached0",
"OP_EvalLocalArrayRefCached",
"OP_EvalArrayRef",
"OP_ClearArray",
"OP_EmptyArray",
"OP_GetSelfObject",
"OP_EvalLevelFieldVariable",
"OP_EvalAnimFieldVariable",
"OP_EvalSelfFieldVariable",
"OP_EvalFieldVariable",
"OP_EvalLevelFieldVariableRef",
"OP_EvalAnimFieldVariableRef",
"OP_EvalSelfFieldVariableRef",
"OP_EvalFieldVariableRef",
"OP_ClearFieldVariable",
"OP_SafeCreateVariableFieldCached",
"OP_SafeSetVariableFieldCached0",
"OP_SafeSetVariableFieldCached",
"OP_SafeSetWaittillVariableFieldCached",
"OP_clearparams",
"OP_checkclearparams",
"OP_EvalLocalVariableRefCached0",
"OP_EvalLocalVariableRefCached",
"OP_SetLevelFieldVariableField",
"OP_SetVariableField",
"OP_SetAnimFieldVariableField",
"OP_SetSelfFieldVariableField",
"OP_SetLocalVariableFieldCached0",
"OP_SetLocalVariableFieldCached",
"OP_CallBuiltin0",
"OP_CallBuiltin1",
"OP_CallBuiltin2",
"OP_CallBuiltin3",
"OP_CallBuiltin4",
"OP_CallBuiltin5",
"OP_CallBuiltin",
"OP_CallBuiltinMethod0",
"OP_CallBuiltinMethod1",
"OP_CallBuiltinMethod2",
"OP_CallBuiltinMethod3",
"OP_CallBuiltinMethod4",
"OP_CallBuiltinMethod5",
"OP_CallBuiltinMethod",
"OP_wait",
"OP_waittillFrameEnd",
"OP_PreScriptCall",
"OP_ScriptFunctionCall2",
"OP_ScriptFunctionCall",
"OP_ScriptFunctionCallPointer",
"OP_ScriptMethodCall",
"OP_ScriptMethodCallPointer",
"OP_ScriptThreadCall",
"OP_ScriptThreadCallPointer",
"OP_ScriptMethodThreadCall",
"OP_ScriptMethodThreadCallPointer",
"OP_DecTop",
"OP_CastFieldObject",
"OP_EvalLocalVariableObjectCached",
"OP_CastBool",
"OP_BoolNot",
"OP_BoolComplement",
"OP_JumpOnFalse",
"OP_JumpOnTrue",
"OP_JumpOnFalseExpr",
"OP_JumpOnTrueExpr",
"OP_jump",
"OP_jumpback",
"OP_inc",
"OP_dec",
"OP_bit_or",
"OP_bit_ex_or",
"OP_bit_and",
"OP_equality",
"OP_inequality",
"OP_less",
"OP_greater",
"OP_less_equal",
"OP_greater_equal",
"OP_shift_left",
"OP_shift_right",
"OP_plus",
"OP_minus",
"OP_multiply",
"OP_divide",
"OP_mod",
"OP_size",
"OP_waittillmatch",
"OP_waittill",
"OP_notify",
"OP_endon",
"OP_voidCodepos",
"OP_switch",
"OP_endswitch",
"OP_vector",
"OP_NOP",
"OP_abort",
"OP_object",
"OP_thread_object",
"OP_EvalLocalVariable",
"OP_EvalLocalVariableRef",
"OP_prof_begin",
"OP_prof_end",
"OP_breakpoint",
"OP_assignmentBreakpoint",
"OP_manualAndAssignmentBreakpoint",
"OP_count"
};
std::string answer{};
int count = op_idx_rolled_over[inst] ? ARRAY_COUNT(op_history[inst]) : op_idx[inst];
for (auto i = 0; i < count; i++)
{
auto idx = op_idx[inst] - 1 - i;
if (idx < 0)
{
idx += ARRAY_COUNT(op_history[inst]);
}
if ((int)op_history[inst][idx] >= 0 && op_history[inst][idx] < game::OP_count)
{
answer += std::format("{}\n", OpcodeVMToString[op_history[inst][idx]]);
}
else
{
answer += std::format("0x{:02x}\n", (int)op_history[inst][idx]);
}
}
return answer;
}
std::string build_gsc_stack(game::scriptInstance_t inst)
{
std::string answer{};
int bufferIndex;
int prevSourcePos;
int col;
char line[1024];
int lineNum;
const char* fileName;
if (!game::gFs[inst].pos || !game::Scr_IsInOpcodeMemory(inst, game::gFs[inst].pos))
{
return answer;
}
for (auto frame = game::gScrVmPub[inst].function_frame_start;; frame++)
{
if (!frame->fs.pos || !game::Scr_IsInOpcodeMemory(inst, frame->fs.pos))
{
break;
}
bufferIndex = game::Scr_GetSourceBuffer(inst, frame->fs.pos - 1);
prevSourcePos = game::Scr_GetPrevSourcePos(inst, frame->fs.pos - 1, 0);
lineNum = game::Scr_GetLineInfo(&col, game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].sourceBuf, prevSourcePos, line);
fileName = game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].buf;
answer += std::format("{}({}, {}): '{}'\n", fileName, lineNum, col, line);
if (frame == game::gScrVmPub[inst].function_frame)
{
break;
}
}
return answer;
}
std::string build_gsc_dump(game::scriptInstance_t inst)
{
nlohmann::json answer{};
auto t = *game::gInst;
*game::gInst = inst;
answer["inst"] = inst;
answer["gScrVarPub"] = game::gScrVarPub[inst];
answer["codeCallStack"] = build_code_stack();
answer["gscCallStack"] = build_gsc_stack(inst);
answer["opHistory"] = build_op_history(inst);
answer["builtinHistory"] = build_builtin_history(inst);
answer["codeposHistory"] = build_codepos_history(inst);
*game::gInst = t;
return answer.dump(2);
}
void push_opcode_history(game::scriptInstance_t inst, game::OpcodeVM op)
{
assert(inst == 0 || inst == 1);
//assert((int)op >= 0 && op < game::OP_count);
op_history[inst][op_idx[inst]++] = op;
if (op_idx[inst] >= ARRAY_COUNT(op_history[inst]))
{
op_idx_rolled_over[inst] = true;
op_idx[inst] = 0;
}
}
void push_builtin_history(game::scriptInstance_t inst, int idx)
{
assert(inst == 0 || inst == 1);
assert(idx >= 0 && idx < 1024);
builtin_history[inst][builtin_idx[inst]++] = idx;
if (builtin_idx[inst] >= ARRAY_COUNT(builtin_history[inst]))
{
builtin_idx_rolled_over[inst] = true;
builtin_idx[inst] = 0;
}
}
void push_codepos_history(game::scriptInstance_t inst, const char* pos)
{
assert(inst == 0 || inst == 1);
assert(game::Scr_IsInOpcodeMemory(inst, pos));
codepos_history[inst][codepos_idx[inst]++] = pos;
if (codepos_idx[inst] >= ARRAY_COUNT(codepos_history[inst]))
{
codepos_idx_rolled_over[inst] = true;
codepos_idx[inst] = 0;
}
}

View File

@ -10,7 +10,6 @@
#pragma warning(disable: 4324) #pragma warning(disable: 4324)
#pragma warning(disable: 4459) #pragma warning(disable: 4459)
#pragma warning(disable: 4611) #pragma warning(disable: 4611)
#pragma warning(disable: 4359)
#pragma warning(error: 4409) #pragma warning(error: 4409)
#define DLL_EXPORT extern "C" __declspec(dllexport) #define DLL_EXPORT extern "C" __declspec(dllexport)
@ -71,12 +70,9 @@
#include "game/structs.hpp" #include "game/structs.hpp"
#include "game/symbols.hpp" #include "game/symbols.hpp"
#include "plugin.hpp"
std::string build_gsc_dump(game::scriptInstance_t inst); std::string build_gsc_dump(game::scriptInstance_t inst);
void push_opcode_history(game::scriptInstance_t inst, game::OpcodeVM op); void push_opcode_history(game::scriptInstance_t inst, game::OpcodeVM op);
void push_builtin_history(game::scriptInstance_t inst, int idx); void push_builtin_history(game::scriptInstance_t inst, int idx);
void push_codepos_history(game::scriptInstance_t inst, const char* pos); void push_codepos_history(game::scriptInstance_t inst, const char* pos);
void print_ast(game::scriptInstance_t inst, game::sval_u node);
using namespace std::literals; using namespace std::literals;

View File

@ -97,15 +97,8 @@ namespace utils::hook
MH_DisableHook(this->place_); MH_DisableHook(this->place_);
} }
void detour::create(void* place, void* target, bool quick) void detour::create(void* place, void* target)
{ {
// each detour is ~30ms to install, quick is for instances where we will NEVER need to invoke the original
if (quick)
{
jump(reinterpret_cast<std::uintptr_t>(place), target);
return;
}
this->clear(); this->clear();
this->place_ = place; this->place_ = place;
@ -117,9 +110,9 @@ namespace utils::hook
this->enable(); this->enable();
} }
void detour::create(const size_t place, void* target, bool quick) void detour::create(const size_t place, void* target)
{ {
this->create(reinterpret_cast<void*>(place), target, quick); this->create(reinterpret_cast<void*>(place), target);
} }
void detour::clear() void detour::clear()

View File

@ -86,8 +86,8 @@ namespace utils::hook
void enable() const; void enable() const;
void disable() const; void disable() const;
void create(void* place, void* target, bool quick = false); void create(void* place, void* target);
void create(size_t place, void* target, bool quick = false); void create(size_t place, void* target);
void clear(); void clear();
template <typename T> template <typename T>

View File

@ -1,986 +0,0 @@
#include <stdinc.hpp>
#include "codsrc/clientscript/clientscript_public.hpp"
#include <dbghelp.h>
#define QUICK_TO_JSON_FIELD(j, v, membername) j[#membername] = v.membername
#define QUICK_TO_JSON_FIELD_SAFE_CSTR(j, v, membername) \
if (v.membername) \
j[#membername] = v.membername; \
else \
j[#membername] = "(NULL)"
#define QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, membername) j[#membername] = reinterpret_cast<size_t>(&v.membername)
#define QUICK_TO_JSON_FIELD_ARRAY(j, v, membername) \
for (auto i = 0; i < ARRAY_COUNT(v.membername); i++) \
{ \
j[#membername][i] = v.membername[i]; \
}
#define QUICK_TO_JSON_FIELD_SL_STRING(j, v, membername) j[#membername "Str"] = SL_ConvertToStringSafe(v.membername, *gInst)
namespace game
{
void to_json(nlohmann::json& j, const scrVarPub_t& v)
{
QUICK_TO_JSON_FIELD_SAFE_CSTR(j, v, fieldBuffer);
QUICK_TO_JSON_FIELD(j, v, canonicalStrCount);
QUICK_TO_JSON_FIELD(j, v, developer);
QUICK_TO_JSON_FIELD(j, v, developer_script);
QUICK_TO_JSON_FIELD(j, v, evaluate);
QUICK_TO_JSON_FIELD_SAFE_CSTR(j, v, error_message);
QUICK_TO_JSON_FIELD(j, v, error_index);
QUICK_TO_JSON_FIELD(j, v, time);
QUICK_TO_JSON_FIELD(j, v, timeArrayId);
QUICK_TO_JSON_FIELD(j, v, pauseArrayId);
QUICK_TO_JSON_FIELD(j, v, levelId);
QUICK_TO_JSON_FIELD(j, v, gameId);
QUICK_TO_JSON_FIELD(j, v, animId);
QUICK_TO_JSON_FIELD(j, v, freeEntList);
QUICK_TO_JSON_FIELD(j, v, tempVariable);
QUICK_TO_JSON_FIELD(j, v, bInited);
QUICK_TO_JSON_FIELD(j, v, savecount);
QUICK_TO_JSON_FIELD(j, v, checksum);
QUICK_TO_JSON_FIELD(j, v, entId);
QUICK_TO_JSON_FIELD(j, v, entFieldName);
QUICK_TO_JSON_FIELD_SL_STRING(j, v, entFieldName);
QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, programHunkUser);
QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, programBuffer);
QUICK_TO_JSON_FIELD_PTR_ADDR(j, v, endScriptBuffer);
QUICK_TO_JSON_FIELD_ARRAY(j, v, saveIdMap);
QUICK_TO_JSON_FIELD_ARRAY(j, v, saveIdMapRev);
}
}
int op_idx[game::SCRIPT_INSTANCE_MAX] = { 0, 0 };
bool op_idx_rolled_over[game::SCRIPT_INSTANCE_MAX] = { false, false };
game::OpcodeVM op_history[game::SCRIPT_INSTANCE_MAX][128] = {};
int builtin_idx[game::SCRIPT_INSTANCE_MAX] = { 0, 0 };
bool builtin_idx_rolled_over[game::SCRIPT_INSTANCE_MAX] = { false, false };
int builtin_history[game::SCRIPT_INSTANCE_MAX][128] = {};
int codepos_idx[game::SCRIPT_INSTANCE_MAX] = { 0, 0 };
bool codepos_idx_rolled_over[game::SCRIPT_INSTANCE_MAX] = { false, false };
const char* codepos_history[game::SCRIPT_INSTANCE_MAX][128] = {};
const char* scr_enum_t_to_string[] =
{
"ENUM_NOP",
"ENUM_program",
"ENUM_assignment",
"ENUM_unknown_variable",
"ENUM_duplicate_variable",
"ENUM_local_variable",
"ENUM_local_variable_frozen",
"ENUM_duplicate_expression",
"ENUM_primitive_expression",
"ENUM_integer",
"ENUM_float",
"ENUM_minus_integer",
"ENUM_minus_float",
"ENUM_string",
"ENUM_istring",
"ENUM_array_variable",
"ENUM_unknown_field",
"ENUM_field_variable",
"ENUM_field_variable_frozen",
"ENUM_variable",
"ENUM_function",
"ENUM_call_expression",
"ENUM_local_function",
"ENUM_far_function",
"ENUM_function_pointer",
"ENUM_call",
"ENUM_method",
"ENUM_call_expression_statement",
"ENUM_script_call",
"ENUM_return",
"ENUM_return2",
"ENUM_wait",
"ENUM_script_thread_call",
"ENUM_undefined",
"ENUM_self",
"ENUM_self_frozen",
"ENUM_level",
"ENUM_game",
"ENUM_anim",
"ENUM_if",
"ENUM_if_else",
"ENUM_while",
"ENUM_for",
"ENUM_inc",
"ENUM_dec",
"ENUM_binary_equals",
"ENUM_statement_list",
"ENUM_developer_statement_list",
"ENUM_expression_list",
"ENUM_bool_or",
"ENUM_bool_and",
"ENUM_binary",
"ENUM_bool_not",
"ENUM_bool_complement",
"ENUM_size_field",
"ENUM_self_field",
"ENUM_precachetree",
"ENUM_waittill",
"ENUM_waittillmatch",
"ENUM_waittillFrameEnd",
"ENUM_notify",
"ENUM_endon",
"ENUM_switch",
"ENUM_case",
"ENUM_default",
"ENUM_break",
"ENUM_continue",
"ENUM_expression",
"ENUM_empty_array",
"ENUM_animation",
"ENUM_thread",
"ENUM_begin_developer_thread",
"ENUM_end_developer_thread",
"ENUM_usingtree",
"ENUM_false",
"ENUM_true",
"ENUM_animtree",
"ENUM_breakon",
"ENUM_breakpoint",
"ENUM_prof_begin",
"ENUM_prof_end",
"ENUM_vector",
"ENUM_object",
"ENUM_thread_object",
"ENUM_local",
"ENUM_statement",
"ENUM_bad_expression",
"ENUM_bad_statement",
"ENUM_include",
"ENUM_argument"
};
const char* OpcodeVMToString[] = {
"OP_End",
"OP_Return",
"OP_GetUndefined",
"OP_GetZero",
"OP_GetByte",
"OP_GetNegByte",
"OP_GetUnsignedShort",
"OP_GetNegUnsignedShort",
"OP_GetInteger",
"OP_GetFloat",
"OP_GetString",
"OP_GetIString",
"OP_GetVector",
"OP_GetLevelObject",
"OP_GetAnimObject",
"OP_GetSelf",
"OP_GetLevel",
"OP_GetGame",
"OP_GetAnim",
"OP_GetAnimation",
"OP_GetGameRef",
"OP_GetFunction",
"OP_CreateLocalVariable",
"OP_RemoveLocalVariables",
"OP_EvalLocalVariableCached0",
"OP_EvalLocalVariableCached1",
"OP_EvalLocalVariableCached2",
"OP_EvalLocalVariableCached3",
"OP_EvalLocalVariableCached4",
"OP_EvalLocalVariableCached5",
"OP_EvalLocalVariableCached",
"OP_EvalLocalArrayCached",
"OP_EvalArray",
"OP_EvalLocalArrayRefCached0",
"OP_EvalLocalArrayRefCached",
"OP_EvalArrayRef",
"OP_ClearArray",
"OP_EmptyArray",
"OP_GetSelfObject",
"OP_EvalLevelFieldVariable",
"OP_EvalAnimFieldVariable",
"OP_EvalSelfFieldVariable",
"OP_EvalFieldVariable",
"OP_EvalLevelFieldVariableRef",
"OP_EvalAnimFieldVariableRef",
"OP_EvalSelfFieldVariableRef",
"OP_EvalFieldVariableRef",
"OP_ClearFieldVariable",
"OP_SafeCreateVariableFieldCached",
"OP_SafeSetVariableFieldCached0",
"OP_SafeSetVariableFieldCached",
"OP_SafeSetWaittillVariableFieldCached",
"OP_clearparams",
"OP_checkclearparams",
"OP_EvalLocalVariableRefCached0",
"OP_EvalLocalVariableRefCached",
"OP_SetLevelFieldVariableField",
"OP_SetVariableField",
"OP_SetAnimFieldVariableField",
"OP_SetSelfFieldVariableField",
"OP_SetLocalVariableFieldCached0",
"OP_SetLocalVariableFieldCached",
"OP_CallBuiltin0",
"OP_CallBuiltin1",
"OP_CallBuiltin2",
"OP_CallBuiltin3",
"OP_CallBuiltin4",
"OP_CallBuiltin5",
"OP_CallBuiltin",
"OP_CallBuiltinMethod0",
"OP_CallBuiltinMethod1",
"OP_CallBuiltinMethod2",
"OP_CallBuiltinMethod3",
"OP_CallBuiltinMethod4",
"OP_CallBuiltinMethod5",
"OP_CallBuiltinMethod",
"OP_wait",
"OP_waittillFrameEnd",
"OP_PreScriptCall",
"OP_ScriptFunctionCall2",
"OP_ScriptFunctionCall",
"OP_ScriptFunctionCallPointer",
"OP_ScriptMethodCall",
"OP_ScriptMethodCallPointer",
"OP_ScriptThreadCall",
"OP_ScriptThreadCallPointer",
"OP_ScriptMethodThreadCall",
"OP_ScriptMethodThreadCallPointer",
"OP_DecTop",
"OP_CastFieldObject",
"OP_EvalLocalVariableObjectCached",
"OP_CastBool",
"OP_BoolNot",
"OP_BoolComplement",
"OP_JumpOnFalse",
"OP_JumpOnTrue",
"OP_JumpOnFalseExpr",
"OP_JumpOnTrueExpr",
"OP_jump",
"OP_jumpback",
"OP_inc",
"OP_dec",
"OP_bit_or",
"OP_bit_ex_or",
"OP_bit_and",
"OP_equality",
"OP_inequality",
"OP_less",
"OP_greater",
"OP_less_equal",
"OP_greater_equal",
"OP_shift_left",
"OP_shift_right",
"OP_plus",
"OP_minus",
"OP_multiply",
"OP_divide",
"OP_mod",
"OP_size",
"OP_waittillmatch",
"OP_waittill",
"OP_notify",
"OP_endon",
"OP_voidCodepos",
"OP_switch",
"OP_endswitch",
"OP_vector",
"OP_NOP",
"OP_abort",
"OP_object",
"OP_thread_object",
"OP_EvalLocalVariable",
"OP_EvalLocalVariableRef",
"OP_prof_begin",
"OP_prof_end",
"OP_breakpoint",
"OP_assignmentBreakpoint",
"OP_manualAndAssignmentBreakpoint",
"OP_count"
};
nlohmann::json print_statement_ast(game::scriptInstance_t inst, game::sval_u val)
{
nlohmann::json answer{};
game::sval_u *node;
game::sval_u *start_node;
int i;
answer["type"] = scr_enum_t_to_string[val.node[0].type];
switch (val.node[0].type)
{
case game::ENUM_array_variable:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["index"] = print_statement_ast(inst, val.node[2]);
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["indexSourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_field_variable:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["field"] = game::SL_ConvertToString(val.node[2].stringValue, inst);
answer["sourcePos"] = val.node[3].sourcePosValue;
break;
case game::ENUM_assignment:
answer["lhs"] = print_statement_ast(inst, val.node[1]);
answer["rhs"] = print_statement_ast(inst, val.node[2]);
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["rhsSourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_far_function:
answer["filename"] = game::SL_ConvertToString(val.node[1].stringValue, inst);
answer["threadName"] = game::SL_ConvertToString(val.node[2].stringValue, inst);
answer["sourcePos"] = val.node[3].sourcePosValue;
break;
case game::ENUM_local_function:
answer["threadName"] = game::SL_ConvertToString(val.node[1].stringValue, inst);
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_function:
case game::ENUM_function_pointer:
answer["func"] = print_statement_ast(inst, val.node[1]);
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_script_call:
answer["func_name"] = print_statement_ast(inst, val.node[1]);
answer["nameSourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_script_thread_call:
answer["func_name"] = print_statement_ast(inst, val.node[1]);
answer["sourcePos"] = val.node[2].sourcePosValue;
answer["nameSourcePos"] = val.node[3].sourcePosValue;
break;
case game::ENUM_call:
answer["func_name"] = print_statement_ast(inst, val.node[1]);
answer["params"] = nlohmann::json::array();
for (i = 0, node = val.node[2].node[0].node;
node;
node = node[1].node, i++)
{
answer["params"][i] = print_statement_ast(inst, node->node[0]);
}
answer["sourcePos"] = val.node[3].sourcePosValue;
break;
case game::ENUM_method:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["func_name"] = print_statement_ast(inst, val.node[2]);
answer["params"] = nlohmann::json::array();
for (i = 0, node = val.node[3].node[0].node;
node;
node = node[1].node, i++)
{
answer["params"][i] = print_statement_ast(inst, node->node[0]);
}
answer["sourcePos"] = val.node[4].sourcePosValue;
answer["methodSourcePos"] = val.node[5].sourcePosValue;
break;
case game::ENUM_integer:
case game::ENUM_minus_integer:
answer["value"] = val.node[1].intValue;
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_float:
case game::ENUM_minus_float:
answer["value"] = val.node[1].floatValue;
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_string:
case game::ENUM_istring:
answer["value"] = game::SL_ConvertToString(val.node[1].stringValue, inst);
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_expression_list:
answer["exprlist"] = nlohmann::json::array();
for (i = 0, node = val.node[1].node->node;
node;
node = node[1].node, i++)
{
answer["exprlist"][i] = print_statement_ast(inst, *node->node);
}
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_thread:
answer["threadName"] = game::SL_ConvertToString(val.node[1].stringValue, inst);
answer["formalParams"] = nlohmann::json::array();
for (i = 0, node = val.node[2].node->node[1].node;
node;
node = node[1].node, i++)
{
answer["formalParams"][i]["expr_name"] = game::SL_ConvertToString(node->node[0].stringValue, inst);
answer["formalParams"][i]["sourcePos"] = node->node[1].sourcePosValue;
}
answer["statements"] = nlohmann::json::array();
for (i = 0, node = val.node[3].node->node[1].node;
node;
node = node[1].node, i++)
{
answer["statements"][i] = print_statement_ast(inst, *node);
}
answer["sourcePos"] = val.node[4].sourcePosValue;
answer["endSourcePos"] = val.node[5].sourcePosValue;
{
auto stmtblock = &val.node[6].block;
stmtblock = stmtblock;
}
break;
case game::ENUM_usingtree:
answer["string"] = game::SL_ConvertToString(val.node[1].stringValue, inst);
answer["sourcePos"] = val.node[2].sourcePosValue;
answer["sourcePos2"] = val.node[3].sourcePosValue;
break;
case game::ENUM_wait:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["sourcePos"] = val.node[2].sourcePosValue;
answer["waitSourcePos"] = val.node[3].sourcePosValue;
break;
case game::ENUM_developer_statement_list:
answer["list"] = nlohmann::json::array();
for (i = 0, node = val.node[1].node->node[1].node;
node;
node = node[1].node, i++)
{
answer["list"][i] = print_statement_ast(inst, *node);
}
answer["sourcePos"] = val.node[2].sourcePosValue;
{
auto devStatBlock = val.node[3].block;
devStatBlock = devStatBlock;
}
break;
case game::ENUM_statement_list:
answer["list"] = nlohmann::json::array();
for (i = 0, node = val.node[1].node->node[1].node;
node;
node = node[1].node, i++)
{
answer["list"][i] = print_statement_ast(inst, *node);
}
answer["sourcePos"] = val.node[2].sourcePosValue;
answer["sourcePos2"] = val.node[3].sourcePosValue;
break;
case game::ENUM_if:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["stmt"] = print_statement_ast(inst, val.node[2]);
answer["sourcePos"] = val.node[3].sourcePosValue;
{
auto ifStatBlock = val.node[4].block;
ifStatBlock = ifStatBlock;
}
break;
case game::ENUM_if_else:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["stmt1"] = print_statement_ast(inst, val.node[2]);
answer["stmt2"] = print_statement_ast(inst, val.node[3]);
answer["sourcePos"] = val.node[4].sourcePosValue;
answer["elseSourcePos"] = val.node[5].sourcePosValue;
{
auto ifBlock = val.node[6].block;
auto elseBlock = val.node[7].block;
ifBlock = ifBlock;
elseBlock = elseBlock;
}
break;
case game::ENUM_while:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["stmt"] = print_statement_ast(inst, val.node[2]);
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["whileSourcePos"] = val.node[4].sourcePosValue;
{
auto whileStatBlock = val.node[5].block;
whileStatBlock = whileStatBlock;
}
break;
case game::ENUM_for:
answer["stmt1"] = print_statement_ast(inst, val.node[1]);
answer["expr"] = print_statement_ast(inst, val.node[2]);
answer["stmt2"] = print_statement_ast(inst, val.node[3]);
answer["stmt"] = print_statement_ast(inst, val.node[4]);
answer["sourcePos"] = val.node[5].sourcePosValue;
answer["forSourcePos"] = val.node[6].sourcePosValue;
{
auto forStatBlock = val.node[7].block;
auto forStatPostBlock = val.node[8].block;
forStatBlock = forStatBlock;
forStatPostBlock = forStatPostBlock;
}
break;
case game::ENUM_bool_or:
case game::ENUM_bool_and:
answer["expr1"] = print_statement_ast(inst, val.node[1]);
answer["expr2"] = print_statement_ast(inst, val.node[2]);
answer["expr1SourcePos"] = val.node[3].sourcePosValue;
answer["expr2SourcePos"] = val.node[4].sourcePosValue;
answer["sourcePos"] = val.node[5].sourcePosValue;
break;
case game::ENUM_binary:
{
auto expr1 = val.node[1];
auto expr2 = val.node[2];
auto opcode = val.node[3].type;
auto sourcePos = val.node[4].sourcePosValue;
answer["opcode"] = OpcodeVMToString[opcode];
answer["sourcePos"] = sourcePos;
answer["expr1"] = print_statement_ast(inst, expr1);
answer["expr2"] = print_statement_ast(inst, expr2);
break;
}
case game::ENUM_binary_equals:
answer["lhs"] = print_statement_ast(inst, val.node[1]);
answer["rhs"] = print_statement_ast(inst, val.node[2]);
answer["opcode"] = OpcodeVMToString[val.node[3].type];
answer["sourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_endon:
answer["obj"] = print_statement_ast(inst, val.node[1]);
answer["expr"] = print_statement_ast(inst, val.node[2]);
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["exprSourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_notify:
answer["obj"] = print_statement_ast(inst, val.node[1]);
answer["exprlist"] = nlohmann::json::array();
start_node = nullptr;
for (i = 0, node = val.node[2].node->node;
node;
node = node[1].node, i++)
{
start_node = node;
answer["exprlist"][i] = print_statement_ast(inst, *node->node);
}
answer["startNodeSourcePos"] = start_node->node[1].sourcePosValue;
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["notifySourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_waittill:
answer["obj"] = print_statement_ast(inst, val.node[1]);
node = val.node[2].node->node[1].node;
answer["expr"]["expr"] = print_statement_ast(inst, *node->node);
answer["expr"]["sourcePos"] = node->node[1].sourcePosValue;
answer["exprlist"] = nlohmann::json::array();
for (i = 0, node = node[1].node;
node;
node = node[1].node, i++)
{
answer["exprlist"][i]["expr"] = game::SL_ConvertToString(node[0].node->stringValue, inst);
answer["exprlist"][i]["sourcePos"] = node->node[1].sourcePosValue;
}
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["waitSourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_switch:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["stmtlist"] = nlohmann::json::array();
for (i = 0, node = val.node[2].node->node[1].node;
node;
node = node[1].node, i++)
{
answer["stmtlist"][i] = print_statement_ast(inst, *node);
}
answer["sourcePos"] = val.node[3].sourcePosValue;
break;
case game::ENUM_default:
answer["sourcePos"] = val.node[1].sourcePosValue;
{
auto breakBlock = val.node[2].block;
breakBlock = breakBlock;
}
break;
case game::ENUM_case:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["sourcePos"] = val.node[2].sourcePosValue;
{
auto caseBlock = val.node[3].block;
caseBlock = caseBlock;
}
break;
case game::ENUM_waittillmatch:
answer["obj"] = print_statement_ast(inst, val.node[1]);
answer["exprlist"] = nlohmann::json::array();
for (i = 0, node = val.node[2].node->node[1].node;
node;
node = node[1].node, i++)
{
answer["exprlist"][i]["expr"] = print_statement_ast(inst, *node->node);
answer["exprlist"][i]["sourcePos"] = node->node[1].sourcePosValue;
}
answer["sourcePos"] = val.node[3].sourcePosValue;
answer["waitSourcePos"] = val.node[4].sourcePosValue;
break;
case game::ENUM_local_variable:
case game::ENUM_prof_begin:
case game::ENUM_prof_end:
case game::ENUM_animation:
answer["name"] = game::SL_ConvertToString(val.node[1].stringValue, inst);
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_begin_developer_thread:
case game::ENUM_end_developer_thread:
case game::ENUM_undefined:
case game::ENUM_false:
case game::ENUM_true:
case game::ENUM_return2:
case game::ENUM_self:
case game::ENUM_level:
case game::ENUM_game:
case game::ENUM_anim:
case game::ENUM_empty_array:
case game::ENUM_waittillFrameEnd:
case game::ENUM_break:
case game::ENUM_continue:
case game::ENUM_animtree:
case game::ENUM_breakpoint:
answer["sourcePos"] = val.node[1].sourcePosValue;
break;
case game::ENUM_duplicate_variable:
case game::ENUM_duplicate_expression:
case game::ENUM_call_expression:
case game::ENUM_call_expression_statement:
case game::ENUM_expression:
case game::ENUM_statement:
answer["expr"] = print_statement_ast(inst, val.node[1]);
break;
case game::ENUM_variable:
case game::ENUM_primitive_expression:
case game::ENUM_return:
case game::ENUM_inc:
case game::ENUM_dec:
case game::ENUM_bool_not:
case game::ENUM_bool_complement:
case game::ENUM_size_field:
answer["expr"] = print_statement_ast(inst, val.node[1]);
answer["sourcePos"] = val.node[2].sourcePosValue;
break;
case game::ENUM_NOP:
case game::ENUM_program: // unk
case game::ENUM_unknown_variable: // unk
case game::ENUM_local_variable_frozen: // unk, debugger?
case game::ENUM_unknown_field: // unk
case game::ENUM_field_variable_frozen: // unk, debugger?
case game::ENUM_self_frozen: // unk, debugger?
case game::ENUM_include: // handled
case game::ENUM_self_field: // debugger
case game::ENUM_object: // debugger
case game::ENUM_precachetree: // unk
case game::ENUM_local: // unk
case game::ENUM_bad_expression: // unk
case game::ENUM_bad_statement: // unk
case game::ENUM_argument: // unk
case game::ENUM_thread_object: // unk
case game::ENUM_vector: // unk
case game::ENUM_breakon: // debugger unk 2 vals 1 pos
default:
break;
}
return answer;
}
void print_ast(game::scriptInstance_t inst, game::sval_u val)
{
nlohmann::json answer{};
game::sval_u* node;
int i;
answer["filename"] = game::gScrParserPub[inst].scriptfilename;
// this is the include list
answer["includes"] = nlohmann::json::array();
for ( i = 0, node = val.node[0].node->node[1].node;
node;
node = node[1].node, i++ )
{
answer["includes"][i]["type"] = scr_enum_t_to_string[node->node[0].type];
answer["includes"][i]["filename"] = game::SL_ConvertToString(node->node[1].stringValue, inst);
answer["includes"][i]["sourcePos"] = node->node[2].sourcePosValue;
}
// this is the thread list
answer["threads"] = nlohmann::json::array();
for ( i = 0, node = val.node[1].node->node[1].node;
node;
node = node[1].node, i++ )
{
answer["threads"][i] = print_statement_ast(inst, *node);
}
utils::io::write_file(std::format("t4sp-server-plugin/ast-{}.json", game::gScrParserPub[inst].scriptfilename), answer.dump(2));
}
// https://stackoverflow.com/questions/5693192/win32-backtrace-from-c-code
std::string build_code_stack()
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
std::string answer{};
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
answer += std::format("{}: {} - 0x{:06x}\n", frames - i - 1, symbol->Name, symbol->Address);
}
free( symbol );
return answer;
}
std::string build_builtin_history(game::scriptInstance_t inst)
{
std::string answer{};
int count = builtin_idx_rolled_over[inst] ? ARRAY_COUNT(builtin_history[inst]) : builtin_idx[inst];
for (auto i = 0; i < count; i++)
{
auto idx = builtin_idx[inst] - 1 - i;
if (idx < 0)
{
idx += ARRAY_COUNT(builtin_history[inst]);
}
// todo, convert to builtin name
answer += std::format("{}\n", builtin_history[inst][idx]);
}
return answer;
}
std::string build_codepos_history(game::scriptInstance_t inst)
{
std::string answer{};
int bufferIndex;
int prevSourcePos;
int col;
char line[1024];
int lineNum;
const char* fileName;
int count = codepos_idx_rolled_over[inst] ? ARRAY_COUNT(codepos_history[inst]) : codepos_idx[inst];
for (auto i = 0; i < count; i++)
{
auto idx = codepos_idx[inst] - 1 - i;
if (idx < 0)
{
idx += ARRAY_COUNT(codepos_history[inst]);
}
bufferIndex = game::Scr_GetSourceBuffer(inst, codepos_history[inst][idx]);
prevSourcePos = game::Scr_GetPrevSourcePos(inst, codepos_history[inst][idx], 0);
lineNum = game::Scr_GetLineInfo(&col, game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].sourceBuf, prevSourcePos, line);
fileName = game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].buf;
answer += std::format("{}({}, {}): '{}'\n", fileName, lineNum, col, line);
}
return answer;
}
std::string build_op_history(game::scriptInstance_t inst)
{
std::string answer{};
int count = op_idx_rolled_over[inst] ? ARRAY_COUNT(op_history[inst]) : op_idx[inst];
for (auto i = 0; i < count; i++)
{
auto idx = op_idx[inst] - 1 - i;
if (idx < 0)
{
idx += ARRAY_COUNT(op_history[inst]);
}
if ((int)op_history[inst][idx] >= 0 && op_history[inst][idx] < game::OP_count)
{
answer += std::format("{}\n", OpcodeVMToString[op_history[inst][idx]]);
}
else
{
answer += std::format("0x{:02x}\n", (int)op_history[inst][idx]);
}
}
return answer;
}
std::string build_gsc_stack(game::scriptInstance_t inst)
{
std::string answer{};
int bufferIndex;
int prevSourcePos;
int col;
char line[1024];
int lineNum;
const char* fileName;
if (!game::gFs[inst].pos || !game::Scr_IsInOpcodeMemory(inst, game::gFs[inst].pos))
{
return answer;
}
for (auto frame = game::gScrVmPub[inst].function_frame_start;; frame++)
{
if (!frame->fs.pos || !game::Scr_IsInOpcodeMemory(inst, frame->fs.pos))
{
break;
}
bufferIndex = game::Scr_GetSourceBuffer(inst, frame->fs.pos - 1);
prevSourcePos = game::Scr_GetPrevSourcePos(inst, frame->fs.pos - 1, 0);
lineNum = game::Scr_GetLineInfo(&col, game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].sourceBuf, prevSourcePos, line);
fileName = game::gScrParserPub[inst].sourceBufferLookup[bufferIndex].buf;
answer += std::format("{}({}, {}): '{}'\n", fileName, lineNum, col, line);
if (frame == game::gScrVmPub[inst].function_frame)
{
break;
}
}
return answer;
}
std::string build_gsc_dump(game::scriptInstance_t inst)
{
nlohmann::json answer{};
auto t = *game::gInst;
*game::gInst = inst;
answer["inst"] = inst;
answer["gScrVarPub"] = game::gScrVarPub[inst];
answer["codeCallStack"] = build_code_stack();
answer["gscCallStack"] = build_gsc_stack(inst);
answer["opHistory"] = build_op_history(inst);
answer["builtinHistory"] = build_builtin_history(inst);
answer["codeposHistory"] = build_codepos_history(inst);
*game::gInst = t;
return answer.dump(2);
}
void push_opcode_history(game::scriptInstance_t inst, game::OpcodeVM op)
{
assert(inst == 0 || inst == 1);
//assert((int)op >= 0 && op < game::OP_count);
op_history[inst][op_idx[inst]++] = op;
if (op_idx[inst] >= ARRAY_COUNT(op_history[inst]))
{
op_idx_rolled_over[inst] = true;
op_idx[inst] = 0;
}
}
void push_builtin_history(game::scriptInstance_t inst, int idx)
{
assert(inst == 0 || inst == 1);
assert(idx >= 0 && idx < 1024);
builtin_history[inst][builtin_idx[inst]++] = idx;
if (builtin_idx[inst] >= ARRAY_COUNT(builtin_history[inst]))
{
builtin_idx_rolled_over[inst] = true;
builtin_idx[inst] = 0;
}
}
void push_codepos_history(game::scriptInstance_t inst, const char* pos)
{
assert(inst == 0 || inst == 1);
assert(game::Scr_IsInOpcodeMemory(inst, pos));
codepos_history[inst][codepos_idx[inst]++] = pos;
if (codepos_idx[inst] >= ARRAY_COUNT(codepos_history[inst]))
{
codepos_idx_rolled_over[inst] = true;
codepos_idx[inst] = 0;
}
}