Merge pull request #216 from diamante0018/scr-method-function
[Script] Do GSC functions & methods properly
This commit is contained in:
commit
51278faab0
@ -110,7 +110,7 @@ namespace Components
|
|||||||
|
|
||||||
void Bots::AddMethods()
|
void Bots::AddMethods()
|
||||||
{
|
{
|
||||||
Script::AddFunction("SetPing", [](Game::scr_entref_t entref) // gsc: self SetPing(<int>)
|
Script::AddMethod("SetPing", [](Game::scr_entref_t entref) // gsc: self SetPing(<int>)
|
||||||
{
|
{
|
||||||
auto ping = Game::Scr_GetInt(0);
|
auto ping = Game::Scr_GetInt(0);
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ namespace Components
|
|||||||
client->ping = static_cast<int16_t>(ping);
|
client->ping = static_cast<int16_t>(ping);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("IsTestClient", [](Game::scr_entref_t entref) // Usage: <bot> IsTestClient();
|
Script::AddMethod("IsTestClient", [](Game::scr_entref_t entref) // Usage: <bot> IsTestClient();
|
||||||
{
|
{
|
||||||
const auto* gentity = Game::GetPlayerEntity(entref);
|
const auto* gentity = Game::GetPlayerEntity(entref);
|
||||||
const auto* client = Script::GetClient(gentity);
|
const auto* client = Script::GetClient(gentity);
|
||||||
@ -136,7 +136,7 @@ namespace Components
|
|||||||
Game::Scr_AddBool(client->bIsTestClient == 1);
|
Game::Scr_AddBool(client->bIsTestClient == 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("BotStop", [](Game::scr_entref_t entref) // Usage: <bot> BotStop();
|
Script::AddMethod("BotStop", [](Game::scr_entref_t entref) // Usage: <bot> BotStop();
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
const auto* client = Script::GetClient(ent);
|
const auto* client = Script::GetClient(ent);
|
||||||
@ -152,7 +152,7 @@ namespace Components
|
|||||||
g_botai[entref.entnum].active = false;
|
g_botai[entref.entnum].active = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("BotWeapon", [](Game::scr_entref_t entref) // Usage: <bot> BotWeapon(<str>);
|
Script::AddMethod("BotWeapon", [](Game::scr_entref_t entref) // Usage: <bot> BotWeapon(<str>);
|
||||||
{
|
{
|
||||||
const auto* weapon = Game::Scr_GetString(0);
|
const auto* weapon = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ namespace Components
|
|||||||
g_botai[entref.entnum].active = true;
|
g_botai[entref.entnum].active = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("BotAction", [](Game::scr_entref_t entref) // Usage: <bot> BotAction(<str action>);
|
Script::AddMethod("BotAction", [](Game::scr_entref_t entref) // Usage: <bot> BotAction(<str action>);
|
||||||
{
|
{
|
||||||
const auto* action = Game::Scr_GetString(0);
|
const auto* action = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ namespace Components
|
|||||||
Game::Scr_ParamError(0, "^1BotAction: Unknown action.\n");
|
Game::Scr_ParamError(0, "^1BotAction: Unknown action.\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("BotMovement", [](Game::scr_entref_t entref) // Usage: <bot> BotMovement(<int>, <int>);
|
Script::AddMethod("BotMovement", [](Game::scr_entref_t entref) // Usage: <bot> BotMovement(<int>, <int>);
|
||||||
{
|
{
|
||||||
auto forwardInt = Game::Scr_GetInt(0);
|
auto forwardInt = Game::Scr_GetInt(0);
|
||||||
auto rightInt = Game::Scr_GetInt(1);
|
auto rightInt = Game::Scr_GetInt(1);
|
||||||
|
@ -176,7 +176,7 @@ namespace Components
|
|||||||
|
|
||||||
void ClientCommand::AddScriptFunctions()
|
void ClientCommand::AddScriptFunctions()
|
||||||
{
|
{
|
||||||
Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(<optional int toggle>);
|
Script::AddMethod("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(<optional int toggle>);
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(<optional int toggle>);
|
Script::AddMethod("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(<optional int toggle>);
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(<optional int toggle>);
|
Script::AddMethod("God", [](Game::scr_entref_t entref) // gsc: God(<optional int toggle>);
|
||||||
{
|
{
|
||||||
auto* ent = Game::GetEntity(entref);
|
auto* ent = Game::GetEntity(entref);
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(<optional int toggle>);
|
Script::AddMethod("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(<optional int toggle>);
|
||||||
{
|
{
|
||||||
auto* ent = Game::GetEntity(entref);
|
auto* ent = Game::GetEntity(entref);
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(<optional int toggle>);
|
Script::AddMethod("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(<optional int toggle>);
|
||||||
{
|
{
|
||||||
auto* ent = Game::GetEntity(entref);
|
auto* ent = Game::GetEntity(entref);
|
||||||
|
|
||||||
|
@ -964,7 +964,7 @@ namespace Components
|
|||||||
Download::ScriptDownloads.clear();
|
Download::ScriptDownloads.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("HttpGet", [](Game::scr_entref_t)
|
Script::AddFunction("HttpGet", []()
|
||||||
{
|
{
|
||||||
if (!Flags::HasFlag("scriptablehttp"))
|
if (!Flags::HasFlag("scriptablehttp"))
|
||||||
return;
|
return;
|
||||||
@ -985,7 +985,7 @@ namespace Components
|
|||||||
Game::RemoveRefToObject(object);
|
Game::RemoveRefToObject(object);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("HttpCancel", [](Game::scr_entref_t)
|
Script::AddFunction("HttpCancel", []()
|
||||||
{
|
{
|
||||||
if (!Flags::HasFlag("scriptablehttp"))
|
if (!Flags::HasFlag("scriptablehttp"))
|
||||||
return;
|
return;
|
||||||
|
@ -4,7 +4,8 @@ namespace Components
|
|||||||
{
|
{
|
||||||
std::string Script::ScriptName;
|
std::string Script::ScriptName;
|
||||||
std::vector<int> Script::ScriptHandles;
|
std::vector<int> Script::ScriptHandles;
|
||||||
std::vector<Script::Function> Script::ScriptFunctions;
|
std::unordered_map<std::string, Game::BuiltinFunctionDef> Script::CustomScrFunctions;
|
||||||
|
std::unordered_map<std::string, Game::BuiltinMethodDef> Script::CustomScrMethods;
|
||||||
std::vector<std::string> Script::ScriptNameStack;
|
std::vector<std::string> Script::ScriptNameStack;
|
||||||
unsigned short Script::FunctionName;
|
unsigned short Script::FunctionName;
|
||||||
std::unordered_map<std::string, std::string> Script::ScriptStorage;
|
std::unordered_map<std::string, std::string> Script::ScriptStorage;
|
||||||
@ -139,11 +140,9 @@ namespace Components
|
|||||||
std::string buffer = script.getBuffer();
|
std::string buffer = script.getBuffer();
|
||||||
Utils::String::Replace(buffer, "\t", " ");
|
Utils::String::Replace(buffer, "\t", " ");
|
||||||
|
|
||||||
int line = 1;
|
auto line = 1, lineOffset = 0, inlineOffset = 0;
|
||||||
int lineOffset = 0;
|
|
||||||
int inlineOffset = 0;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < buffer.size(); ++i)
|
for (size_t i = 0; i < buffer.size(); ++i)
|
||||||
{
|
{
|
||||||
// Terminate line
|
// Terminate line
|
||||||
if (i == offset)
|
if (i == offset)
|
||||||
@ -160,7 +159,7 @@ namespace Components
|
|||||||
if (buffer[i] == '\n')
|
if (buffer[i] == '\n')
|
||||||
{
|
{
|
||||||
++line;
|
++line;
|
||||||
lineOffset = i; // Includes the line break!
|
lineOffset = static_cast<int>(i); // Includes the line break!
|
||||||
inlineOffset = 0;
|
inlineOffset = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -172,7 +171,7 @@ namespace Components
|
|||||||
Logger::Print(23, "in file %s, line %d:", filename, line);
|
Logger::Print(23, "in file %s, line %d:", filename, line);
|
||||||
Logger::Print(23, "%s\n", buffer.data() + lineOffset);
|
Logger::Print(23, "%s\n", buffer.data() + lineOffset);
|
||||||
|
|
||||||
for (int i = 0; i < (inlineOffset - 1); ++i)
|
for (auto i = 0; i < (inlineOffset - 1); ++i)
|
||||||
{
|
{
|
||||||
Logger::Print(23, " ");
|
Logger::Print(23, " ");
|
||||||
}
|
}
|
||||||
@ -248,7 +247,7 @@ namespace Components
|
|||||||
|
|
||||||
for (auto file : list)
|
for (auto file : list)
|
||||||
{
|
{
|
||||||
file = "scripts/" + file;
|
file.insert(0, "scripts/");
|
||||||
|
|
||||||
if (Utils::String::EndsWith(file, ".gsc"))
|
if (Utils::String::EndsWith(file, ".gsc"))
|
||||||
{
|
{
|
||||||
@ -271,62 +270,73 @@ namespace Components
|
|||||||
Game::GScr_LoadGameTypeScript();
|
Game::GScr_LoadGameTypeScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::AddFunction(const std::string& name, Game::scr_function_t function, bool isDev)
|
void Script::AddFunction(const char* name, Game::xfunction_t func, int type)
|
||||||
{
|
{
|
||||||
for (auto i = Script::ScriptFunctions.begin(); i != Script::ScriptFunctions.end();)
|
Game::BuiltinFunctionDef toAdd;
|
||||||
{
|
toAdd.actionString = name;
|
||||||
if (i->getName() == name)
|
toAdd.actionFunc = func;
|
||||||
{
|
toAdd.type = type;
|
||||||
i = Script::ScriptFunctions.erase(i);
|
|
||||||
continue;
|
CustomScrFunctions.insert_or_assign(Utils::String::ToLower(name), std::move(toAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
void Script::AddMethod(const char* name, Game::xmethod_t func, int type)
|
||||||
|
{
|
||||||
|
Game::BuiltinMethodDef toAdd;
|
||||||
|
toAdd.actionString = name;
|
||||||
|
toAdd.actionFunc = func;
|
||||||
|
toAdd.type = type;
|
||||||
|
|
||||||
|
CustomScrMethods.insert_or_assign(Utils::String::ToLower(name), std::move(toAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
Script::ScriptFunctions.push_back({ name, function, isDev });
|
Game::xfunction_t Script::BuiltIn_GetFunctionStub(const char** pName, int* type)
|
||||||
}
|
{
|
||||||
|
if (pName != nullptr)
|
||||||
|
{
|
||||||
|
const auto got = Script::CustomScrFunctions.find(Utils::String::ToLower(*pName));
|
||||||
|
|
||||||
Game::scr_function_t Script::GetFunction(void* caller, const char** name, int* isDev)
|
// If no function was found let's call game's function
|
||||||
|
if (got != Script::CustomScrFunctions.end())
|
||||||
{
|
{
|
||||||
for (auto& function : Script::ScriptFunctions)
|
*type = got->second.type;
|
||||||
{
|
return got->second.actionFunc;
|
||||||
if (name && *name)
|
|
||||||
{
|
|
||||||
if (Utils::String::ToLower(*name) == Utils::String::ToLower(function.getName()))
|
|
||||||
{
|
|
||||||
*name = function.getName();
|
|
||||||
*isDev = function.isDev();
|
|
||||||
return function.getFunction();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (caller == reinterpret_cast<void*>(0x465781))
|
else
|
||||||
{
|
{
|
||||||
Game::Scr_RegisterFunction(function.getFunction());
|
for (const auto& [name, builtin] : Script::CustomScrFunctions)
|
||||||
|
{
|
||||||
|
Game::Scr_RegisterFunction(reinterpret_cast<int>(builtin.actionFunc), name.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return Utils::Hook::Call<Game::xfunction_t(const char**, int*)>(0x5FA2B0)(pName, type); // BuiltIn_GetFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void Script::GetFunctionStub()
|
Game::xmethod_t Script::BuiltIn_GetMethod(const char** pName, int* type)
|
||||||
{
|
{
|
||||||
__asm
|
if (pName != nullptr)
|
||||||
{
|
{
|
||||||
test eax, eax
|
const auto got = Script::CustomScrMethods.find(Utils::String::ToLower(*pName));
|
||||||
jnz returnSafe
|
|
||||||
|
|
||||||
sub esp, 8h
|
// If no method was found let's call game's function
|
||||||
push [esp + 10h]
|
if (got != Script::CustomScrMethods.end())
|
||||||
call Script::GetFunction
|
{
|
||||||
add esp, 0Ch
|
*type = got->second.type;
|
||||||
|
return got->second.actionFunc;
|
||||||
returnSafe:
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
retn
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& [name, builtin] : Script::CustomScrMethods)
|
||||||
|
{
|
||||||
|
Game::Scr_RegisterFunction(reinterpret_cast<int>(builtin.actionFunc), name.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils::Hook::Call<Game::xmethod_t(const char**, int*)>(0x5FA360)(pName, type); // Player_GetMethod
|
||||||
|
}
|
||||||
|
|
||||||
void Script::StoreScriptBaseProgramNum()
|
void Script::StoreScriptBaseProgramNum()
|
||||||
{
|
{
|
||||||
@ -539,7 +549,7 @@ namespace Components
|
|||||||
|
|
||||||
void Script::AddFunctions()
|
void Script::AddFunctions()
|
||||||
{
|
{
|
||||||
Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(<function>, <function>)
|
Script::AddFunction("ReplaceFunc", []() // gsc: ReplaceFunc(<function>, <function>)
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetNumParam() != 2u)
|
if (Game::Scr_GetNumParam() != 2u)
|
||||||
{
|
{
|
||||||
@ -554,7 +564,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// System time
|
// System time
|
||||||
Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime()
|
Script::AddFunction("GetSystemTime", []() // gsc: GetSystemTime()
|
||||||
{
|
{
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
GetSystemTime(&time);
|
GetSystemTime(&time);
|
||||||
@ -562,7 +572,7 @@ namespace Components
|
|||||||
Game::Scr_AddInt(time.wSecond);
|
Game::Scr_AddInt(time.wSecond);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("GetSystemMilliseconds", [](Game::scr_entref_t) // gsc: GetSystemMilliseconds()
|
Script::AddFunction("GetSystemMilliseconds", []() // gsc: GetSystemMilliseconds()
|
||||||
{
|
{
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
GetSystemTime(&time);
|
GetSystemTime(&time);
|
||||||
@ -571,7 +581,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Executes command to the console
|
// Executes command to the console
|
||||||
Script::AddFunction("Exec", [](Game::scr_entref_t) // gsc: Exec(<string>)
|
Script::AddFunction("Exec", []() // gsc: Exec(<string>)
|
||||||
{
|
{
|
||||||
const auto str = Game::Scr_GetString(0);
|
const auto str = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -585,7 +595,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Allow printing to the console even when developer is 0
|
// Allow printing to the console even when developer is 0
|
||||||
Script::AddFunction("PrintConsole", [](Game::scr_entref_t) // gsc: PrintConsole(<string>)
|
Script::AddFunction("PrintConsole", []() // gsc: PrintConsole(<string>)
|
||||||
{
|
{
|
||||||
for (auto i = 0u; i < Game::Scr_GetNumParam(); i++)
|
for (auto i = 0u; i < Game::Scr_GetNumParam(); i++)
|
||||||
{
|
{
|
||||||
@ -602,7 +612,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Script Storage Functions
|
// Script Storage Functions
|
||||||
Script::AddFunction("StorageSet", [](Game::scr_entref_t) // gsc: StorageSet(<str key>, <str data>);
|
Script::AddFunction("StorageSet", []() // gsc: StorageSet(<str key>, <str data>);
|
||||||
{
|
{
|
||||||
const auto* key = Game::Scr_GetString(0);
|
const auto* key = Game::Scr_GetString(0);
|
||||||
const auto* value = Game::Scr_GetString(1);
|
const auto* value = Game::Scr_GetString(1);
|
||||||
@ -616,7 +626,7 @@ namespace Components
|
|||||||
Script::ScriptStorage.insert_or_assign(key, value);
|
Script::ScriptStorage.insert_or_assign(key, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageRemove", [](Game::scr_entref_t) // gsc: StorageRemove(<str key>);
|
Script::AddFunction("StorageRemove", []() // gsc: StorageRemove(<str key>);
|
||||||
{
|
{
|
||||||
const auto* key = Game::Scr_GetString(0);
|
const auto* key = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -635,7 +645,7 @@ namespace Components
|
|||||||
Script::ScriptStorage.erase(key);
|
Script::ScriptStorage.erase(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageGet", [](Game::scr_entref_t) // gsc: StorageGet(<str key>);
|
Script::AddFunction("StorageGet", []() // gsc: StorageGet(<str key>);
|
||||||
{
|
{
|
||||||
const auto* key = Game::Scr_GetString(0);
|
const auto* key = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -655,7 +665,7 @@ namespace Components
|
|||||||
Game::Scr_AddString(data.data());
|
Game::Scr_AddString(data.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageHas", [](Game::scr_entref_t) // gsc: StorageHas(<str key>);
|
Script::AddFunction("StorageHas", []() // gsc: StorageHas(<str key>);
|
||||||
{
|
{
|
||||||
const auto* key = Game::Scr_GetString(0);
|
const auto* key = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -668,13 +678,13 @@ namespace Components
|
|||||||
Game::Scr_AddBool(static_cast<int>(Script::ScriptStorage.count(key))); // Until C++17
|
Game::Scr_AddBool(static_cast<int>(Script::ScriptStorage.count(key))); // Until C++17
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("StorageClear", [](Game::scr_entref_t) // gsc: StorageClear();
|
Script::AddFunction("StorageClear", []() // gsc: StorageClear();
|
||||||
{
|
{
|
||||||
Script::ScriptStorage.clear();
|
Script::ScriptStorage.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
// PlayerCmd_AreControlsFrozen GSC function from Black Ops 2
|
// PlayerCmd_AreControlsFrozen GSC function from Black Ops 2
|
||||||
Script::AddFunction("AreControlsFrozen", [](Game::scr_entref_t entref) // Usage: self AreControlsFrozen();
|
Script::AddMethod("AreControlsFrozen", [](Game::scr_entref_t entref) // Usage: self AreControlsFrozen();
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
|
|
||||||
@ -704,8 +714,9 @@ namespace Components
|
|||||||
Utils::Hook(0x48EFFE, Script::LoadGameType, HOOK_CALL).install()->quick();
|
Utils::Hook(0x48EFFE, Script::LoadGameType, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x45D44A, Script::LoadGameTypeScript, HOOK_CALL).install()->quick();
|
Utils::Hook(0x45D44A, Script::LoadGameTypeScript, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
Utils::Hook(0x44E736, Script::GetFunctionStub, HOOK_JUMP).install()->quick(); // Scr_GetFunction
|
// Fetch custom functions
|
||||||
Utils::Hook(0x4EC8E5, Script::GetFunctionStub, HOOK_JUMP).install()->quick(); // Scr_GetMethod
|
Utils::Hook(0x44E72E, Script::BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction
|
||||||
|
Utils::Hook(0x4EC8DD, Script::BuiltIn_GetMethod, HOOK_CALL).install()->quick(); // Scr_GetMethod
|
||||||
|
|
||||||
Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
@ -735,7 +746,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Script::AddFunction("DebugBox", [](Game::scr_entref_t)
|
Script::AddFunction("DebugBox", []()
|
||||||
{
|
{
|
||||||
const auto* message = Game::Scr_GetString(0);
|
const auto* message = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -745,7 +756,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageBoxA(nullptr, message, "DEBUG", MB_OK);
|
MessageBoxA(nullptr, message, "DEBUG", MB_OK);
|
||||||
}, true);
|
}, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Script::AddFunctions();
|
Script::AddFunctions();
|
||||||
|
@ -6,26 +6,13 @@ namespace Components
|
|||||||
class Script : public Component
|
class Script : public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class Function
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Function(const std::string& _name, Game::scr_function_t _callback, bool _dev) : name(_name), callback(_callback), dev(_dev) {}
|
|
||||||
|
|
||||||
const char* getName() const { return this->name.data(); }
|
|
||||||
bool isDev() const { return this->dev; }
|
|
||||||
Game::scr_function_t getFunction() const { return this->callback; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
Game::scr_function_t callback;
|
|
||||||
bool dev;
|
|
||||||
};
|
|
||||||
|
|
||||||
Script();
|
Script();
|
||||||
~Script();
|
~Script();
|
||||||
|
|
||||||
static int LoadScriptAndLabel(const std::string& script, const std::string& label);
|
static int LoadScriptAndLabel(const std::string& script, const std::string& label);
|
||||||
static void AddFunction(const std::string& name, Game::scr_function_t function, bool isDev = false);
|
|
||||||
|
static void AddFunction(const char* name, Game::xfunction_t func, int type = 0);
|
||||||
|
static void AddMethod(const char* name, Game::xmethod_t func, int type = 0);
|
||||||
|
|
||||||
static void OnVMShutdown(Utils::Slot<Scheduler::Callback> callback);
|
static void OnVMShutdown(Utils::Slot<Scheduler::Callback> callback);
|
||||||
|
|
||||||
@ -34,7 +21,8 @@ namespace Components
|
|||||||
private:
|
private:
|
||||||
static std::string ScriptName;
|
static std::string ScriptName;
|
||||||
static std::vector<int> ScriptHandles;
|
static std::vector<int> ScriptHandles;
|
||||||
static std::vector<Function> ScriptFunctions;
|
static std::unordered_map<std::string, Game::BuiltinFunctionDef> CustomScrFunctions;
|
||||||
|
static std::unordered_map<std::string, Game::BuiltinMethodDef> CustomScrMethods;
|
||||||
static std::vector<std::string> ScriptNameStack;
|
static std::vector<std::string> ScriptNameStack;
|
||||||
static unsigned short FunctionName;
|
static unsigned short FunctionName;
|
||||||
static std::unordered_map<std::string, std::string> ScriptStorage;
|
static std::unordered_map<std::string, std::string> ScriptStorage;
|
||||||
@ -61,8 +49,8 @@ namespace Components
|
|||||||
static void LoadGameType();
|
static void LoadGameType();
|
||||||
static void LoadGameTypeScript();
|
static void LoadGameTypeScript();
|
||||||
|
|
||||||
static Game::scr_function_t GetFunction(void* caller, const char** name, int* isDev);
|
static Game::xfunction_t BuiltIn_GetFunctionStub(const char** pName, int* type);
|
||||||
static void GetFunctionStub();
|
static Game::xmethod_t BuiltIn_GetMethod(const char** pName, int* type);
|
||||||
|
|
||||||
static void ScrShutdownSystemStub(unsigned char sys);
|
static void ScrShutdownSystemStub(unsigned char sys);
|
||||||
static void StoreScriptBaseProgramNumStub();
|
static void StoreScriptBaseProgramNumStub();
|
||||||
|
@ -7,7 +7,7 @@ namespace Components
|
|||||||
void ScriptExtension::AddFunctions()
|
void ScriptExtension::AddFunctions()
|
||||||
{
|
{
|
||||||
// File functions
|
// File functions
|
||||||
Script::AddFunction("FileWrite", [](Game::scr_entref_t) // gsc: FileWrite(<filepath>, <string>, <mode>)
|
Script::AddFunction("FileWrite", []() // gsc: FileWrite(<filepath>, <string>, <mode>)
|
||||||
{
|
{
|
||||||
const auto* path = Game::Scr_GetString(0);
|
const auto* path = Game::Scr_GetString(0);
|
||||||
auto* text = Game::Scr_GetString(1);
|
auto* text = Game::Scr_GetString(1);
|
||||||
@ -50,7 +50,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("FileRead", [](Game::scr_entref_t) // gsc: FileRead(<filepath>)
|
Script::AddFunction("FileRead", []() // gsc: FileRead(<filepath>)
|
||||||
{
|
{
|
||||||
const auto* path = Game::Scr_GetString(0);
|
const auto* path = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ namespace Components
|
|||||||
Game::Scr_AddString(FileSystem::FileReader(path).getBuffer().data());
|
Game::Scr_AddString(FileSystem::FileReader(path).getBuffer().data());
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("FileExists", [](Game::scr_entref_t) // gsc: FileExists(<filepath>)
|
Script::AddFunction("FileExists", []() // gsc: FileExists(<filepath>)
|
||||||
{
|
{
|
||||||
const auto* path = Game::Scr_GetString(0);
|
const auto* path = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ namespace Components
|
|||||||
Game::Scr_AddInt(FileSystem::FileReader(path).exists());
|
Game::Scr_AddInt(FileSystem::FileReader(path).exists());
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("FileRemove", [](Game::scr_entref_t) // gsc: FileRemove(<filepath>)
|
Script::AddFunction("FileRemove", []() // gsc: FileRemove(<filepath>)
|
||||||
{
|
{
|
||||||
const auto* path = Game::Scr_GetString(0);
|
const auto* path = Game::Scr_GetString(0);
|
||||||
|
|
||||||
@ -124,12 +124,84 @@ namespace Components
|
|||||||
const auto& file = p.filename().string();
|
const auto& file = p.filename().string();
|
||||||
Game::Scr_AddInt(FileSystem::DeleteFile(folder, file));
|
Game::Scr_AddInt(FileSystem::DeleteFile(folder, file));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Misc functions
|
||||||
|
Script::AddFunction("ToUpper", []() // gsc: ToUpper(<string>)
|
||||||
|
{
|
||||||
|
const auto scriptValue = Game::Scr_GetConstString(0);
|
||||||
|
const auto* string = Game::SL_ConvertToString(scriptValue);
|
||||||
|
|
||||||
|
char out[1024] = {0}; // 1024 is the max for a string in this SL system
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < sizeof(out))
|
||||||
|
{
|
||||||
|
const auto value = *string;
|
||||||
|
const auto result = static_cast<char>(std::toupper(static_cast<unsigned char>(value)));
|
||||||
|
out[i] = result;
|
||||||
|
|
||||||
|
if (value != result)
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
if (result == '\0') // Finished converting string
|
||||||
|
break;
|
||||||
|
|
||||||
|
++string;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null terminating character was overwritten
|
||||||
|
if (i >= sizeof(out))
|
||||||
|
{
|
||||||
|
Game::Scr_Error("string too long");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
Game::Scr_AddString(out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Game::SL_AddRefToString(scriptValue);
|
||||||
|
Game::Scr_AddConstString(scriptValue);
|
||||||
|
Game::SL_RemoveRefToString(scriptValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Func present on IW5
|
||||||
|
Script::AddFunction("StrICmp", []() // gsc: StrICmp(<string>, <string>)
|
||||||
|
{
|
||||||
|
const auto value1 = Game::Scr_GetConstString(0);
|
||||||
|
const auto value2 = Game::Scr_GetConstString(1);
|
||||||
|
|
||||||
|
const auto result = _stricmp(Game::SL_ConvertToString(value1),
|
||||||
|
Game::SL_ConvertToString(value2));
|
||||||
|
|
||||||
|
Game::Scr_AddInt(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Func present on IW5
|
||||||
|
Script::AddFunction("IsEndStr", []() // gsc: IsEndStr(<string>, <string>)
|
||||||
|
{
|
||||||
|
const auto* s1 = Game::Scr_GetString(0);
|
||||||
|
const auto* s2 = Game::Scr_GetString(1);
|
||||||
|
|
||||||
|
if (s1 == nullptr || s2 == nullptr)
|
||||||
|
{
|
||||||
|
Game::Scr_Error("^1IsEndStr: Illegal parameters!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::Scr_AddBool(Utils::String::EndsWith(s1, s2));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptExtension::AddMethods()
|
void ScriptExtension::AddMethods()
|
||||||
{
|
{
|
||||||
// ScriptExtension methods
|
// ScriptExtension methods
|
||||||
Script::AddFunction("GetIp", [](Game::scr_entref_t entref) // gsc: self GetIp()
|
Script::AddMethod("GetIp", [](Game::scr_entref_t entref) // gsc: self GetIp()
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
const auto* client = Script::GetClient(ent);
|
const auto* client = Script::GetClient(ent);
|
||||||
@ -142,7 +214,7 @@ namespace Components
|
|||||||
Game::Scr_AddString(ip.data());
|
Game::Scr_AddString(ip.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("GetPing", [](Game::scr_entref_t entref) // gsc: self GetPing()
|
Script::AddMethod("GetPing", [](Game::scr_entref_t entref) // gsc: self GetPing()
|
||||||
{
|
{
|
||||||
const auto* ent = Game::GetPlayerEntity(entref);
|
const auto* ent = Game::GetPlayerEntity(entref);
|
||||||
const auto* client = Script::GetClient(ent);
|
const auto* client = Script::GetClient(ent);
|
||||||
|
@ -272,6 +272,7 @@ namespace Game
|
|||||||
|
|
||||||
Scr_AddEntity_t Scr_AddEntity = Scr_AddEntity_t(0x4BFB40);
|
Scr_AddEntity_t Scr_AddEntity = Scr_AddEntity_t(0x4BFB40);
|
||||||
Scr_AddString_t Scr_AddString = Scr_AddString_t(0x412310);
|
Scr_AddString_t Scr_AddString = Scr_AddString_t(0x412310);
|
||||||
|
Scr_AddConstString_t Scr_AddConstString = Scr_AddConstString_t(0x488860);
|
||||||
Scr_AddIString_t Scr_AddIString = Scr_AddIString_t(0x455F20);
|
Scr_AddIString_t Scr_AddIString = Scr_AddIString_t(0x455F20);
|
||||||
Scr_AddInt_t Scr_AddInt = Scr_AddInt_t(0x41D7D0);
|
Scr_AddInt_t Scr_AddInt = Scr_AddInt_t(0x41D7D0);
|
||||||
Scr_AddFloat_t Scr_AddFloat = Scr_AddFloat_t(0x61E860);
|
Scr_AddFloat_t Scr_AddFloat = Scr_AddFloat_t(0x61E860);
|
||||||
@ -313,6 +314,8 @@ namespace Game
|
|||||||
|
|
||||||
SL_ConvertToString_t SL_ConvertToString = SL_ConvertToString_t(0x4EC1D0);
|
SL_ConvertToString_t SL_ConvertToString = SL_ConvertToString_t(0x4EC1D0);
|
||||||
SL_GetString_t SL_GetString = SL_GetString_t(0x4CDC10);
|
SL_GetString_t SL_GetString = SL_GetString_t(0x4CDC10);
|
||||||
|
SL_AddRefToString_t SL_AddRefToString = SL_AddRefToString_t(0x4D9B00);
|
||||||
|
SL_RemoveRefToString_t SL_RemoveRefToString = SL_RemoveRefToString_t(0x47CD70);
|
||||||
|
|
||||||
SND_Init_t SND_Init = SND_Init_t(0x46A630);
|
SND_Init_t SND_Init = SND_Init_t(0x46A630);
|
||||||
SND_InitDriver_t SND_InitDriver = SND_InitDriver_t(0x4F5090);
|
SND_InitDriver_t SND_InitDriver = SND_InitDriver_t(0x4F5090);
|
||||||
|
@ -645,6 +645,9 @@ namespace Game
|
|||||||
typedef void(__cdecl * Scr_AddString_t)(const char* value);
|
typedef void(__cdecl * Scr_AddString_t)(const char* value);
|
||||||
extern Scr_AddString_t Scr_AddString;
|
extern Scr_AddString_t Scr_AddString;
|
||||||
|
|
||||||
|
typedef void(__cdecl * Scr_AddConstString_t)(unsigned int value);
|
||||||
|
extern Scr_AddConstString_t Scr_AddConstString;
|
||||||
|
|
||||||
typedef void(__cdecl * Scr_AddIString_t)(const char* value);
|
typedef void(__cdecl * Scr_AddIString_t)(const char* value);
|
||||||
extern Scr_AddIString_t Scr_AddIString;
|
extern Scr_AddIString_t Scr_AddIString;
|
||||||
|
|
||||||
@ -669,7 +672,7 @@ namespace Game
|
|||||||
typedef const char*(__cdecl * Scr_GetString_t)(unsigned int index);
|
typedef const char*(__cdecl * Scr_GetString_t)(unsigned int index);
|
||||||
extern Scr_GetString_t Scr_GetString;
|
extern Scr_GetString_t Scr_GetString;
|
||||||
|
|
||||||
typedef unsigned int(__cdecl * Scr_GetConstString_t)(unsigned int index);
|
typedef scr_string_t(__cdecl * Scr_GetConstString_t)(unsigned int index);
|
||||||
extern Scr_GetConstString_t Scr_GetConstString;
|
extern Scr_GetConstString_t Scr_GetConstString;
|
||||||
|
|
||||||
typedef const char*(__cdecl * Scr_GetDebugString_t)(unsigned int index);
|
typedef const char*(__cdecl * Scr_GetDebugString_t)(unsigned int index);
|
||||||
@ -705,7 +708,7 @@ namespace Game
|
|||||||
typedef void(__cdecl * Scr_ClearOutParams_t)();
|
typedef void(__cdecl * Scr_ClearOutParams_t)();
|
||||||
extern Scr_ClearOutParams_t Scr_ClearOutParams;
|
extern Scr_ClearOutParams_t Scr_ClearOutParams;
|
||||||
|
|
||||||
typedef void(__cdecl * Scr_RegisterFunction_t)(scr_function_t function);
|
typedef void(__cdecl * Scr_RegisterFunction_t)(int func, const char* name);
|
||||||
extern Scr_RegisterFunction_t Scr_RegisterFunction;
|
extern Scr_RegisterFunction_t Scr_RegisterFunction;
|
||||||
|
|
||||||
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
||||||
@ -753,6 +756,12 @@ namespace Game
|
|||||||
typedef short(__cdecl * SL_GetString_t)(const char *str, unsigned int user);
|
typedef short(__cdecl * SL_GetString_t)(const char *str, unsigned int user);
|
||||||
extern SL_GetString_t SL_GetString;
|
extern SL_GetString_t SL_GetString;
|
||||||
|
|
||||||
|
typedef void(__cdecl * SL_AddRefToString_t)(unsigned int stringValue);
|
||||||
|
extern SL_AddRefToString_t SL_AddRefToString;
|
||||||
|
|
||||||
|
typedef void(__cdecl * SL_RemoveRefToString_t)(unsigned int stringValue);
|
||||||
|
extern SL_RemoveRefToString_t SL_RemoveRefToString;
|
||||||
|
|
||||||
typedef void(__cdecl * SND_Init_t)(int a1, int a2, int a3);
|
typedef void(__cdecl * SND_Init_t)(int a1, int a2, int a3);
|
||||||
extern SND_Init_t SND_Init;
|
extern SND_Init_t SND_Init;
|
||||||
|
|
||||||
|
@ -20,13 +20,30 @@ namespace Game
|
|||||||
typedef vec_t vec3_t[3];
|
typedef vec_t vec3_t[3];
|
||||||
typedef vec_t vec4_t[4];
|
typedef vec_t vec4_t[4];
|
||||||
|
|
||||||
|
typedef unsigned __int16 scr_string_t;
|
||||||
|
|
||||||
struct scr_entref_t
|
struct scr_entref_t
|
||||||
{
|
{
|
||||||
unsigned __int16 entnum;
|
unsigned __int16 entnum;
|
||||||
unsigned __int16 classnum;
|
unsigned __int16 classnum;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void(__cdecl * scr_function_t)(scr_entref_t);
|
typedef void(__cdecl * xfunction_t)();
|
||||||
|
typedef void(__cdecl * xmethod_t)(scr_entref_t);
|
||||||
|
|
||||||
|
struct BuiltinFunctionDef
|
||||||
|
{
|
||||||
|
const char* actionString;
|
||||||
|
xfunction_t actionFunc;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuiltinMethodDef
|
||||||
|
{
|
||||||
|
const char* actionString;
|
||||||
|
xmethod_t actionFunc;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
enum XAssetType
|
enum XAssetType
|
||||||
{
|
{
|
||||||
|
@ -97,12 +97,13 @@ namespace Utils
|
|||||||
|
|
||||||
bool StartsWith(const std::string& haystack, const std::string& needle)
|
bool StartsWith(const std::string& haystack, const std::string& needle)
|
||||||
{
|
{
|
||||||
return (haystack.size() >= needle.size() && haystack.substr(0, needle.size()) == needle);
|
return haystack.find(needle) == 0; // If the pos of the first found char is 0, string starts with 'needle'
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EndsWith(const std::string& haystack, const std::string& needle)
|
bool EndsWith(const std::string& haystack, const std::string& needle)
|
||||||
{
|
{
|
||||||
return (haystack.size() >= needle.size() && haystack.substr(haystack.size() - needle.size()) == needle);
|
if (needle.size() > haystack.size()) return false;
|
||||||
|
return std::equal(needle.rbegin(), needle.rend(), haystack.rbegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
int IsSpace(int c)
|
int IsSpace(int c)
|
||||||
|
@ -77,10 +77,10 @@ namespace Utils
|
|||||||
int IsSpace(int c);
|
int IsSpace(int c);
|
||||||
std::string ToLower(std::string text);
|
std::string ToLower(std::string text);
|
||||||
std::string ToUpper(std::string text);
|
std::string ToUpper(std::string text);
|
||||||
bool EndsWith(const std::string& haystack, const std::string& needle);
|
|
||||||
std::vector<std::string> Split(const std::string& str, const char delim);
|
std::vector<std::string> Split(const std::string& str, const char delim);
|
||||||
void Replace(std::string& string, const std::string& find, const std::string& replace);
|
void Replace(std::string& string, const std::string& find, const std::string& replace);
|
||||||
bool StartsWith(const std::string& haystack, const std::string& needle);
|
bool StartsWith(const std::string& haystack, const std::string& needle);
|
||||||
|
bool EndsWith(const std::string& haystack, const std::string& needle);
|
||||||
|
|
||||||
std::string& LTrim(std::string& str);
|
std::string& LTrim(std::string& str);
|
||||||
std::string& RTrim(std::string& str);
|
std::string& RTrim(std::string& str);
|
||||||
|
Loading…
Reference in New Issue
Block a user