[Script] Refactor loading code & add pseudo int64 (#419)
This commit is contained in:
parent
c0433ce883
commit
3246ed1bf5
@ -24,10 +24,10 @@ namespace Components
|
||||
|
||||
Game::SafeArea Console::OriginalSafeArea;
|
||||
|
||||
char** Console::GetAutoCompleteFileList(const char* path, const char* extension, Game::FsListBehavior_e behavior, int* numfiles, int allocTrackType)
|
||||
const char** Console::GetAutoCompleteFileList(const char* path, const char* extension, Game::FsListBehavior_e behavior, int* numfiles, int allocTrackType)
|
||||
{
|
||||
if (path == reinterpret_cast<char*>(0xBAADF00D) || path == reinterpret_cast<char*>(0xCDCDCDCD) || ::Utils::Memory::IsBadReadPtr(path)) return nullptr;
|
||||
return Game::FS_GetFileList(path, extension, behavior, numfiles, allocTrackType);
|
||||
return Game::FS_ListFiles(path, extension, behavior, numfiles, allocTrackType);
|
||||
}
|
||||
|
||||
void Console::RefreshStatus()
|
||||
|
@ -63,7 +63,7 @@ namespace Components
|
||||
static void StoreSafeArea();
|
||||
static void RestoreSafeArea();
|
||||
|
||||
static char** GetAutoCompleteFileList(const char *path, const char *extension, Game::FsListBehavior_e behavior, int *numfiles, int allocTrackType);
|
||||
static const char** GetAutoCompleteFileList(const char *path, const char *extension, Game::FsListBehavior_e behavior, int *numfiles, int allocTrackType);
|
||||
|
||||
static void Con_ToggleConsole();
|
||||
static void AddConsoleCommand();
|
||||
|
@ -160,8 +160,8 @@ namespace Components
|
||||
{
|
||||
std::vector<std::string> fileList;
|
||||
|
||||
int numFiles = 0;
|
||||
char** files = Game::FS_GetFileList(path.data(), extension.data(), Game::FS_LIST_PURE_ONLY, &numFiles, 0);
|
||||
auto numFiles = 0;
|
||||
const auto** files = Game::FS_ListFiles(path.data(), extension.data(), Game::FS_LIST_PURE_ONLY, &numFiles, 10);
|
||||
|
||||
if (files)
|
||||
{
|
||||
@ -169,11 +169,11 @@ namespace Components
|
||||
{
|
||||
if (files[i])
|
||||
{
|
||||
fileList.push_back(files[i]);
|
||||
fileList.emplace_back(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Game::FS_FreeFileList(files);
|
||||
Game::FS_FreeFileList(files, 10);
|
||||
}
|
||||
|
||||
return fileList;
|
||||
@ -183,8 +183,8 @@ namespace Components
|
||||
{
|
||||
std::vector<std::string> fileList;
|
||||
|
||||
int numFiles = 0;
|
||||
char** files = Game::Sys_ListFiles(path.data(), extension.data(), nullptr, &numFiles, folders);
|
||||
auto numFiles = 0;
|
||||
const auto** files = Game::Sys_ListFiles(path.data(), extension.data(), nullptr, &numFiles, folders);
|
||||
|
||||
if (files)
|
||||
{
|
||||
@ -192,7 +192,7 @@ namespace Components
|
||||
{
|
||||
if (files[i])
|
||||
{
|
||||
fileList.push_back(files[i]);
|
||||
fileList.emplace_back(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ namespace Components
|
||||
|
||||
bool FileSystem::_DeleteFile(const std::string& folder, const std::string& file)
|
||||
{
|
||||
char path[MAX_PATH] = { 0 };
|
||||
char path[MAX_PATH] = {0};
|
||||
Game::FS_BuildPathToFile(Dvar::Var("fs_basepath").get<const char*>(), reinterpret_cast<char*>(0x63D0BB8), Utils::String::VA("%s/%s", folder.data(), file.data()), reinterpret_cast<char**>(&path));
|
||||
return Game::FS_Remove(path);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <STDInclude.hpp>
|
||||
|
||||
#include "Int64.hpp"
|
||||
#include "IO.hpp"
|
||||
#include "Script.hpp"
|
||||
#include "ScriptExtension.hpp"
|
||||
@ -9,6 +10,7 @@ namespace Components
|
||||
{
|
||||
GSC::GSC()
|
||||
{
|
||||
Loader::Register(new Int64());
|
||||
Loader::Register(new IO());
|
||||
Loader::Register(new Script());
|
||||
Loader::Register(new ScriptExtension());
|
||||
|
95
src/Components/Modules/GSC/Int64.cpp
Normal file
95
src/Components/Modules/GSC/Int64.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include <STDInclude.hpp>
|
||||
#include "Int64.hpp"
|
||||
#include "Script.hpp"
|
||||
|
||||
#define INT64_OPERATION(expr) [](const std::int64_t a, [[maybe_unused]] const std::int64_t b) { return expr; }
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::unordered_map<std::string, Int64::int64_OP> Int64::Operations =
|
||||
{
|
||||
{"+", INT64_OPERATION(a + b)},
|
||||
{"-", INT64_OPERATION(a - b)},
|
||||
{"*", INT64_OPERATION(a * b)},
|
||||
{"/", INT64_OPERATION(a / b)},
|
||||
{"&", INT64_OPERATION(a & b)},
|
||||
{"^", INT64_OPERATION(a ^ b)},
|
||||
{"|", INT64_OPERATION(a | b)},
|
||||
{"~", INT64_OPERATION(~a)},
|
||||
{"%", INT64_OPERATION(a % b)},
|
||||
{">>", INT64_OPERATION(a >> b)},
|
||||
{"<<", INT64_OPERATION(a << b)},
|
||||
{"++", INT64_OPERATION(a + 1)},
|
||||
{"--", INT64_OPERATION(a - 1)},
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, Int64::int64_Comp> Int64::Comparisons
|
||||
{
|
||||
{">", INT64_OPERATION(a > b)},
|
||||
{">=", INT64_OPERATION(a >= b)},
|
||||
{"==", INT64_OPERATION(a == b)},
|
||||
{"<=", INT64_OPERATION(a <= b)},
|
||||
{"<", INT64_OPERATION(a < b)},
|
||||
};
|
||||
|
||||
std::int64_t Int64::GetInt64Arg(unsigned int index, bool optional)
|
||||
{
|
||||
if ((optional) && (index >= Game::Scr_GetNumParam()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetType(index) == Game::VAR_INTEGER)
|
||||
{
|
||||
return Game::Scr_GetInt(index);
|
||||
}
|
||||
|
||||
if (Game::Scr_GetType(index) == Game::VAR_STRING)
|
||||
{
|
||||
return std::strtoll(Game::Scr_GetString(index), nullptr, 0);
|
||||
}
|
||||
|
||||
Game::Scr_ParamError(index, Utils::String::VA("cannot cast %s to int64", Game::Scr_GetTypeName(index)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Int64::AddFunctions()
|
||||
{
|
||||
Script::AddFunction("Int64IsInt", []
|
||||
{
|
||||
const auto value = GetInt64Arg(0, false);
|
||||
Game::Scr_AddBool(value <= std::numeric_limits<std::int32_t>::max() && value >= std::numeric_limits<std::int32_t>::min());
|
||||
});
|
||||
|
||||
Script::AddFunction("Int64ToInt", []
|
||||
{
|
||||
Game::Scr_AddInt(static_cast<std::int32_t>(GetInt64Arg(0, false)));
|
||||
});
|
||||
|
||||
Script::AddFunction("Int64OP", []
|
||||
{
|
||||
const auto a = GetInt64Arg(0, false);
|
||||
const auto* op = Game::Scr_GetString(1);
|
||||
const auto b = GetInt64Arg(2, true);
|
||||
|
||||
if (const auto got = Operations.find(op); got != Operations.end())
|
||||
{
|
||||
Game::Scr_AddString(Utils::String::VA("%lld", got->second(a, b)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto got = Comparisons.find(op); got != Comparisons.end())
|
||||
{
|
||||
Game::Scr_AddBool(got->second(a, b));
|
||||
return;
|
||||
}
|
||||
|
||||
Game::Scr_ParamError(1, "Invalid int64 operation");
|
||||
});
|
||||
}
|
||||
|
||||
Int64::Int64()
|
||||
{
|
||||
AddFunctions();
|
||||
}
|
||||
}
|
20
src/Components/Modules/GSC/Int64.hpp
Normal file
20
src/Components/Modules/GSC/Int64.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Int64 : public Component
|
||||
{
|
||||
public:
|
||||
Int64();
|
||||
|
||||
private:
|
||||
using int64_OP = std::function<std::int64_t(std::int64_t, std::int64_t)>;
|
||||
using int64_Comp = std::function<bool(std::int64_t, std::int64_t)>;
|
||||
|
||||
static std::unordered_map<std::string, int64_OP> Operations;
|
||||
static std::unordered_map<std::string, int64_Comp> Comparisons;
|
||||
|
||||
static std::int64_t GetInt64Arg(unsigned int index, bool optional);
|
||||
static void AddFunctions();
|
||||
};
|
||||
}
|
@ -225,42 +225,44 @@ namespace Components
|
||||
Game::Scr_StartupGameType();
|
||||
}
|
||||
|
||||
// Do not use C++ objects because Scr_LoadScript may longjmp
|
||||
void Script::GScr_LoadGameTypeScript_Stub()
|
||||
{
|
||||
// Clear handles (from previous GSC loading session)
|
||||
Script::ScriptMainHandles.clear();
|
||||
Script::ScriptInitHandles.clear();
|
||||
|
||||
const auto list = FileSystem::GetFileList("scripts/", "gsc");
|
||||
char path[MAX_PATH]{};
|
||||
|
||||
for (const auto& file : list)
|
||||
auto numFiles = 0;
|
||||
const auto** files = Game::FS_ListFiles("scripts/", "gsc", Game::FS_LIST_ALL, &numFiles, 10);
|
||||
|
||||
for (auto i = 0; i < numFiles; ++i)
|
||||
{
|
||||
std::string script = "scripts/" + file;
|
||||
const auto* scriptFile = files[i];
|
||||
Logger::Print("Loading script {}...\n", scriptFile);
|
||||
|
||||
if (Utils::String::EndsWith(script, ".gsc"))
|
||||
sprintf_s(path, "%s/%s", "scripts", scriptFile);
|
||||
|
||||
// Scr_LoadScriptInternal will add the '.gsc' suffix so we remove it
|
||||
path[std::strlen(path) - 4] = '\0';
|
||||
|
||||
if (!Game::Scr_LoadScript(path))
|
||||
{
|
||||
script = script.substr(0, script.size() - 4);
|
||||
Logger::Print("Script {} encountered an error while loading. (doesn't exist?)", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger::Print("Loading script {}.gsc...\n", script);
|
||||
|
||||
if (!Game::Scr_LoadScript(script.data()))
|
||||
{
|
||||
Logger::Print("Script {} encountered an error while loading. (doesn't exist?)", script);
|
||||
Logger::Error(Game::ERR_DROP, "Could not find script '{}'", script);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger::Print("Script {}.gsc loaded successfully.\n", script);
|
||||
Logger::Print("Script {}.gsc loaded successfully.\n", path);
|
||||
Logger::Debug("Finding script handle main or init...");
|
||||
|
||||
const auto initHandle = Game::Scr_GetFunctionHandle(script.data(), "init");
|
||||
const auto initHandle = Game::Scr_GetFunctionHandle(path, "init");
|
||||
if (initHandle != 0)
|
||||
{
|
||||
Script::ScriptInitHandles.push_back(initHandle);
|
||||
}
|
||||
|
||||
const auto mainHandle = Game::Scr_GetFunctionHandle(script.data(), "main");
|
||||
const auto mainHandle = Game::Scr_GetFunctionHandle(path, "main");
|
||||
if (mainHandle != 0)
|
||||
{
|
||||
Script::ScriptMainHandles.push_back(mainHandle);
|
||||
@ -269,6 +271,7 @@ namespace Components
|
||||
// Allow scripts with no handles
|
||||
}
|
||||
|
||||
Game::FS_FreeFileList(files, 10);
|
||||
Game::GScr_LoadGameTypeScript();
|
||||
}
|
||||
|
||||
|
@ -3483,14 +3483,14 @@ namespace Components
|
||||
|
||||
Command::Add("decryptImages", [](Command::Params*)
|
||||
{
|
||||
auto images = Game::Sys_ListFilesWrapper("iw4x/images", "iwi");
|
||||
auto images = FileSystem::GetSysFileList("iw4x/images", "iwi");
|
||||
Logger::Print("decrypting {} images...\n", images.size());
|
||||
|
||||
for (auto& image : images)
|
||||
{
|
||||
char* buffer = nullptr;
|
||||
auto fileLength = Game::FS_ReadFile(Utils::String::VA("images/%s", image.data()), &buffer);
|
||||
|
||||
|
||||
if (fileLength && buffer)
|
||||
{
|
||||
if (!std::filesystem::exists("raw/images"))
|
||||
@ -3514,9 +3514,10 @@ namespace Components
|
||||
|
||||
Logger::Print("decrypted {} images!\n", images.size());
|
||||
});
|
||||
|
||||
Command::Add("decryptSounds", [](Command::Params*)
|
||||
{
|
||||
auto sounds = Game::Sys_ListFilesWrapper("iw4x/sound", "iwi");
|
||||
auto sounds = FileSystem::GetSysFileList("iw4x/sound", "iwi");
|
||||
Logger::Print("decrypting {} sounds...\n", sounds.size());
|
||||
|
||||
for (auto& sound : sounds)
|
||||
|
@ -2,26 +2,6 @@
|
||||
|
||||
namespace Game
|
||||
{
|
||||
std::vector<std::string> Sys_ListFilesWrapper(const std::string& directory, const std::string& extension)
|
||||
{
|
||||
auto fileCount = 0;
|
||||
auto** const files = Sys_ListFiles(directory.data(), extension.data(), nullptr, &fileCount, 0);
|
||||
|
||||
std::vector<std::string> result;
|
||||
|
||||
for (auto i = 0; i < fileCount; i++)
|
||||
{
|
||||
if (files[i] != nullptr)
|
||||
{
|
||||
result.emplace_back(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
FS_FreeFileList(files);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
AddRefToObject_t AddRefToObject = AddRefToObject_t(0x61C360);
|
||||
AllocObject_t AllocObject = AllocObject_t(0x434320);
|
||||
AddRefToValue_t AddRefToValue = AddRefToValue_t(0x482740);
|
||||
@ -150,7 +130,7 @@ namespace Game
|
||||
FS_FileExists_t FS_FileExists = FS_FileExists_t(0x4DEFA0);
|
||||
FS_FreeFile_t FS_FreeFile = FS_FreeFile_t(0x4416B0);
|
||||
FS_ReadFile_t FS_ReadFile = FS_ReadFile_t(0x4F4B90);
|
||||
FS_GetFileList_t FS_GetFileList = FS_GetFileList_t(0x441BB0);
|
||||
FS_ListFiles_t FS_ListFiles = FS_ListFiles_t(0x441BB0);
|
||||
FS_FreeFileList_t FS_FreeFileList = FS_FreeFileList_t(0x4A5DE0);
|
||||
FS_FOpenFileAppend_t FS_FOpenFileAppend = FS_FOpenFileAppend_t(0x410BB0);
|
||||
FS_FOpenFileAppend_t FS_FOpenFileWrite = FS_FOpenFileAppend_t(0x4BA530);
|
||||
|
@ -20,8 +20,6 @@ namespace Game
|
||||
return retval;
|
||||
}
|
||||
|
||||
std::vector<std::string> Sys_ListFilesWrapper(const std::string& directory, const std::string& extension);
|
||||
|
||||
typedef void(__cdecl * AddRefToObject_t)(unsigned int id);
|
||||
extern AddRefToObject_t AddRefToObject;
|
||||
|
||||
@ -376,10 +374,10 @@ namespace Game
|
||||
typedef int(__cdecl * FS_ReadFile_t)(const char* path, char** buffer);
|
||||
extern FS_ReadFile_t FS_ReadFile;
|
||||
|
||||
typedef char** (__cdecl * FS_GetFileList_t)(const char *path, const char *extension, FsListBehavior_e behavior, int *numfiles, int allocTrackType);
|
||||
extern FS_GetFileList_t FS_GetFileList;
|
||||
typedef const char**(__cdecl * FS_ListFiles_t)(const char* path, const char* extension, FsListBehavior_e behavior, int* numfiles, int allocTrackType);
|
||||
extern FS_ListFiles_t FS_ListFiles;
|
||||
|
||||
typedef void(__cdecl * FS_FreeFileList_t)(char** list);
|
||||
typedef void(__cdecl * FS_FreeFileList_t)(const char** list, int allocTrackType);
|
||||
extern FS_FreeFileList_t FS_FreeFileList;
|
||||
|
||||
typedef int(__cdecl * FS_FOpenFileAppend_t)(const char* file);
|
||||
@ -978,7 +976,7 @@ namespace Game
|
||||
typedef void(__cdecl * Sys_Error_t)(const char* error, ...);
|
||||
extern Sys_Error_t Sys_Error;
|
||||
|
||||
typedef void(__cdecl * Sys_FreeFileList_t)(char** list);
|
||||
typedef void(__cdecl * Sys_FreeFileList_t)(const char** list);
|
||||
extern Sys_FreeFileList_t Sys_FreeFileList;
|
||||
|
||||
typedef int(__cdecl * Sys_IsDatabaseReady_t)();
|
||||
@ -999,7 +997,7 @@ namespace Game
|
||||
typedef bool(__cdecl * Sys_IsDatabaseThread_t)();
|
||||
extern Sys_IsDatabaseThread_t Sys_IsDatabaseThread;
|
||||
|
||||
typedef char**(__cdecl * Sys_ListFiles_t)(const char* directory, const char* extension, const char* filter, int* numfiles, int wantsubs);
|
||||
typedef const char**(__cdecl * Sys_ListFiles_t)(const char* directory, const char* extension, const char* filter, int* numfiles, int wantsubs);
|
||||
extern Sys_ListFiles_t Sys_ListFiles;
|
||||
|
||||
typedef int(__cdecl * Sys_Milliseconds_t)();
|
||||
|
Loading…
x
Reference in New Issue
Block a user