mirror of
https://github.com/XLabsProject/s1x-client.git
synced 2023-08-02 15:02:12 +02:00
Merge pull request #605 from diamante0018/develop
revert new gsc compiler update: some scripts don't compile
This commit is contained in:
commit
086b98f887
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -47,7 +47,4 @@
|
|||||||
[submodule "deps/gsc-tool"]
|
[submodule "deps/gsc-tool"]
|
||||||
path = deps/gsc-tool
|
path = deps/gsc-tool
|
||||||
url = https://github.com/xensik/gsc-tool.git
|
url = https://github.com/xensik/gsc-tool.git
|
||||||
branch = dev
|
branch = xlabs
|
||||||
[submodule "deps/fmt"]
|
|
||||||
path = deps/fmt
|
|
||||||
url = https://github.com/fmtlib/fmt.git
|
|
||||||
|
@ -104,7 +104,7 @@ handlesuicidedeath( var_0, var_1 )
|
|||||||
[[ level.onsuicidedeath ]]( self );
|
[[ level.onsuicidedeath ]]( self );
|
||||||
|
|
||||||
if ( isdefined( self.friendlydamage ) )
|
if ( isdefined( self.friendlydamage ) )
|
||||||
self iprintlnbold( &"MP_FRIENDLY_FIRE_WILL_NOT" );
|
self _meth_826E( &"MP_FRIENDLY_FIRE_WILL_NOT" );
|
||||||
|
|
||||||
self.pers["suicideSpawnDelay"] = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "suicidespawndelay" );
|
self.pers["suicideSpawnDelay"] = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "suicidespawndelay" );
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ callback_playergrenadesuicide( var_0, var_1, var_2, var_3, var_4, var_5, var_6,
|
|||||||
var_8 = 1;
|
var_8 = 1;
|
||||||
|
|
||||||
if ( var_8 )
|
if ( var_8 )
|
||||||
var_0 laststanddie();
|
var_0 _meth_82C8();
|
||||||
|
|
||||||
[[ level.callbackplayerlaststand ]]( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, 0 );
|
[[ level.callbackplayerlaststand ]]( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, 0 );
|
||||||
}
|
}
|
||||||
@ -3240,17 +3240,17 @@ _obituary( var_0, var_1, var_2, var_3 )
|
|||||||
|
|
||||||
if ( var_7 == "spectator" )
|
if ( var_7 == "spectator" )
|
||||||
{
|
{
|
||||||
var_6 iprintlnbold( &"MP_OBITUARY_NEUTRAL", var_1.name, var_0.name );
|
var_6 _meth_826E( &"MP_OBITUARY_NEUTRAL", var_1.name, var_0.name );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( var_7 == var_4 )
|
if ( var_7 == var_4 )
|
||||||
{
|
{
|
||||||
var_6 iprintlnbold( &"MP_OBITUARY_ENEMY", var_1.name, var_0.name );
|
var_6 _meth_826E( &"MP_OBITUARY_ENEMY", var_1.name, var_0.name );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var_6 iprintlnbold( &"MP_OBITUARY_FRIENDLY", var_1.name, var_0.name );
|
var_6 _meth_826E( &"MP_OBITUARY_FRIENDLY", var_1.name, var_0.name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
deps/extra/gsc-tool/gsc_interface.cpp
vendored
6
deps/extra/gsc-tool/gsc_interface.cpp
vendored
@ -1,6 +0,0 @@
|
|||||||
#include "gsc_interface.hpp"
|
|
||||||
|
|
||||||
namespace gsc
|
|
||||||
{
|
|
||||||
const std::unique_ptr<xsk::gsc::s1_pc::context> cxt = std::make_unique<xsk::gsc::s1_pc::context>();
|
|
||||||
}
|
|
15
deps/extra/gsc-tool/gsc_interface.hpp
vendored
15
deps/extra/gsc-tool/gsc_interface.hpp
vendored
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#undef ERROR
|
|
||||||
#undef IN
|
|
||||||
#undef TRUE
|
|
||||||
#undef FALSE
|
|
||||||
|
|
||||||
#undef far
|
|
||||||
|
|
||||||
#include <stdinc.hpp>
|
|
||||||
#include <s1/s1_pc.hpp>
|
|
||||||
|
|
||||||
namespace gsc
|
|
||||||
{
|
|
||||||
extern const std::unique_ptr<xsk::gsc::s1_pc::context> cxt;
|
|
||||||
}
|
|
28
deps/extra/gsc-tool/interface.cpp
vendored
Normal file
28
deps/extra/gsc-tool/interface.cpp
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdafx.hpp>
|
||||||
|
#include <xsk/s1.hpp>
|
||||||
|
#include "interface.hpp"
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
std::unique_ptr<xsk::gsc::compiler> compiler()
|
||||||
|
{
|
||||||
|
auto compiler = std::make_unique<xsk::gsc::s1::compiler>();
|
||||||
|
compiler->mode(xsk::gsc::build::prod);
|
||||||
|
return compiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<xsk::gsc::decompiler> decompiler()
|
||||||
|
{
|
||||||
|
return std::make_unique<xsk::gsc::s1::decompiler>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<xsk::gsc::assembler> assembler()
|
||||||
|
{
|
||||||
|
return std::make_unique<xsk::gsc::s1::assembler>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<xsk::gsc::disassembler> disassembler()
|
||||||
|
{
|
||||||
|
return std::make_unique<xsk::gsc::s1::disassembler>();
|
||||||
|
}
|
||||||
|
}
|
9
deps/extra/gsc-tool/interface.hpp
vendored
Normal file
9
deps/extra/gsc-tool/interface.hpp
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace gsc
|
||||||
|
{
|
||||||
|
std::unique_ptr<xsk::gsc::compiler> compiler();
|
||||||
|
std::unique_ptr<xsk::gsc::decompiler> decompiler();
|
||||||
|
std::unique_ptr<xsk::gsc::assembler> assembler();
|
||||||
|
std::unique_ptr<xsk::gsc::disassembler> disassembler();
|
||||||
|
}
|
1
deps/fmt
vendored
1
deps/fmt
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit 05e3a9233ac1dd0c2d9643e046dbb5f788c39f61
|
|
2
deps/gsc-tool
vendored
2
deps/gsc-tool
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 66ecf90171a6dda4de515423379d30c13df0f1ef
|
Subproject commit 7d374025b7675bada64c247ebe9378dd335a33da
|
34
deps/premake/fmt.lua
vendored
34
deps/premake/fmt.lua
vendored
@ -1,34 +0,0 @@
|
|||||||
fmt = {
|
|
||||||
source = path.join(dependencies.basePath, "fmt"),
|
|
||||||
}
|
|
||||||
|
|
||||||
function fmt.import()
|
|
||||||
links { "fmt" }
|
|
||||||
|
|
||||||
fmt.includes()
|
|
||||||
end
|
|
||||||
|
|
||||||
function fmt.includes()
|
|
||||||
includedirs {
|
|
||||||
path.join(fmt.source, "include"),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
function fmt.project()
|
|
||||||
project "fmt"
|
|
||||||
kind "StaticLib"
|
|
||||||
language "C++"
|
|
||||||
|
|
||||||
fmt.includes()
|
|
||||||
|
|
||||||
files {
|
|
||||||
path.join(fmt.source, "include/fmt/*.h"),
|
|
||||||
path.join(fmt.source, "src/*.cc")
|
|
||||||
}
|
|
||||||
|
|
||||||
removefiles {
|
|
||||||
path.join(fmt.source, "src/fmt.cc")
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(dependencies, fmt)
|
|
29
deps/premake/gsc-tool.lua
vendored
29
deps/premake/gsc-tool.lua
vendored
@ -11,9 +11,6 @@ function gsc_tool.includes()
|
|||||||
includedirs {
|
includedirs {
|
||||||
path.join(gsc_tool.source, "s1"),
|
path.join(gsc_tool.source, "s1"),
|
||||||
path.join(gsc_tool.source, "utils"),
|
path.join(gsc_tool.source, "utils"),
|
||||||
path.join(gsc_tool.source, "gsc"),
|
|
||||||
gsc_tool.source,
|
|
||||||
|
|
||||||
path.join(dependencies.basePath, "extra/gsc-tool"),
|
path.join(dependencies.basePath, "extra/gsc-tool"),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -23,6 +20,9 @@ function gsc_tool.project()
|
|||||||
kind "StaticLib"
|
kind "StaticLib"
|
||||||
language "C++"
|
language "C++"
|
||||||
|
|
||||||
|
pchheader "stdafx.hpp"
|
||||||
|
pchsource (path.join(gsc_tool.source, "utils/stdafx.cpp"))
|
||||||
|
|
||||||
files {
|
files {
|
||||||
path.join(gsc_tool.source, "utils/**.hpp"),
|
path.join(gsc_tool.source, "utils/**.hpp"),
|
||||||
path.join(gsc_tool.source, "utils/**.cpp"),
|
path.join(gsc_tool.source, "utils/**.cpp"),
|
||||||
@ -34,30 +34,23 @@ function gsc_tool.project()
|
|||||||
}
|
}
|
||||||
|
|
||||||
zlib.includes()
|
zlib.includes()
|
||||||
fmt.includes()
|
|
||||||
|
|
||||||
project "xsk-gsc-s1"
|
project "xsk-gsc-s1"
|
||||||
kind "StaticLib"
|
kind "StaticLib"
|
||||||
language "C++"
|
language "C++"
|
||||||
|
|
||||||
filter "action:vs*"
|
filter "action:vs*"
|
||||||
|
buildoptions "/bigobj"
|
||||||
buildoptions "/Zc:__cplusplus"
|
buildoptions "/Zc:__cplusplus"
|
||||||
filter {}
|
filter {}
|
||||||
|
|
||||||
|
pchheader "stdafx.hpp"
|
||||||
|
pchsource (path.join(gsc_tool.source, "s1/stdafx.cpp"))
|
||||||
|
|
||||||
files {
|
files {
|
||||||
path.join(gsc_tool.source, "s1/s1_pc.hpp"),
|
path.join(gsc_tool.source, "s1/**.hpp"),
|
||||||
path.join(gsc_tool.source, "s1/s1_pc.cpp"),
|
path.join(gsc_tool.source, "s1/**.cpp"),
|
||||||
path.join(gsc_tool.source, "s1/s1_pc_code.cpp"),
|
path.join(dependencies.basePath, "extra/gsc-tool/interface.cpp"),
|
||||||
path.join(gsc_tool.source, "s1/s1_pc_func.cpp"),
|
|
||||||
path.join(gsc_tool.source, "s1/s1_pc_meth.cpp"),
|
|
||||||
path.join(gsc_tool.source, "s1/s1_pc_token.cpp"),
|
|
||||||
|
|
||||||
path.join(gsc_tool.source, "gsc/misc/*.hpp"),
|
|
||||||
path.join(gsc_tool.source, "gsc/misc/*.cpp"),
|
|
||||||
path.join(gsc_tool.source, "gsc/*.hpp"),
|
|
||||||
path.join(gsc_tool.source, "gsc/*.cpp"),
|
|
||||||
|
|
||||||
path.join(dependencies.basePath, "extra/gsc-tool/gsc_interface.cpp"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
includedirs {
|
includedirs {
|
||||||
@ -65,8 +58,6 @@ function gsc_tool.project()
|
|||||||
gsc_tool.source,
|
gsc_tool.source,
|
||||||
path.join(dependencies.basePath, "extra/gsc-tool"),
|
path.join(dependencies.basePath, "extra/gsc-tool"),
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.includes()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(dependencies, gsc_tool)
|
table.insert(dependencies, gsc_tool)
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
#include <gsc_interface.hpp>
|
#include <xsk/gsc/types.hpp>
|
||||||
|
#include <xsk/resolver.hpp>
|
||||||
|
|
||||||
namespace gsc
|
namespace gsc
|
||||||
{
|
{
|
||||||
@ -95,11 +96,11 @@ namespace gsc
|
|||||||
|
|
||||||
if (function_id > 0x1000)
|
if (function_id > 0x1000)
|
||||||
{
|
{
|
||||||
console::warn("in call to builtin method \"%s\"%s", gsc::cxt->meth_name(function_id).data(), error.data());
|
console::warn("in call to builtin method \"%s\"%s", xsk::gsc::s1::resolver::method_name(function_id).data(), error.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
console::warn("in call to builtin function \"%s\"%s", gsc::cxt->func_name(function_id).data(), error.data());
|
console::warn("in call to builtin function \"%s\"%s", xsk::gsc::s1::resolver::function_name(function_id).data(), error.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +108,7 @@ namespace gsc
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto index = gsc::cxt->opcode_enum(opcode);
|
return {xsk::gsc::s1::resolver::opcode_name(opcode)};
|
||||||
return {xsk::gsc::opcode_name(index)};
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -232,7 +232,7 @@ namespace gsc
|
|||||||
|
|
||||||
void override_function(const std::string& name, game::BuiltinFunction func)
|
void override_function(const std::string& name, game::BuiltinFunction func)
|
||||||
{
|
{
|
||||||
const auto id = gsc::cxt->func_id(name);
|
const auto id = xsk::gsc::s1::resolver::function_id(name);
|
||||||
builtin_funcs_overrides.emplace(id, func);
|
builtin_funcs_overrides.emplace(id, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ namespace gsc
|
|||||||
{
|
{
|
||||||
++function_id_start;
|
++function_id_start;
|
||||||
functions[function_id_start] = function;
|
functions[function_id_start] = function;
|
||||||
gsc::cxt->func_add(name, function_id_start);
|
xsk::gsc::s1::resolver::add_function(name, function_id_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
class extension final : public component_interface
|
class extension final : public component_interface
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <utils/io.hpp>
|
#include <utils/io.hpp>
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/compression.hpp>
|
|
||||||
|
|
||||||
#include "component/filesystem.hpp"
|
#include "component/filesystem.hpp"
|
||||||
#include "component/console.hpp"
|
#include "component/console.hpp"
|
||||||
@ -13,29 +12,37 @@
|
|||||||
|
|
||||||
#include "script_loading.hpp"
|
#include "script_loading.hpp"
|
||||||
|
|
||||||
#include <gsc_interface.hpp>
|
#include <xsk/gsc/types.hpp>
|
||||||
|
#include <xsk/gsc/interfaces/compiler.hpp>
|
||||||
|
#include <xsk/gsc/interfaces/decompiler.hpp>
|
||||||
|
#include <xsk/gsc/interfaces/assembler.hpp>
|
||||||
|
#include <xsk/gsc/interfaces/disassembler.hpp>
|
||||||
|
#include <xsk/utils/compression.hpp>
|
||||||
|
#include <xsk/resolver.hpp>
|
||||||
|
#include <interface.hpp>
|
||||||
|
|
||||||
namespace gsc
|
namespace gsc
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
auto compiler = ::gsc::compiler();
|
||||||
|
auto decompiler = ::gsc::decompiler();
|
||||||
|
auto assembler = ::gsc::assembler();
|
||||||
|
auto disassembler = ::gsc::disassembler();
|
||||||
|
|
||||||
std::unordered_map<std::string, unsigned int> main_handles;
|
std::unordered_map<std::string, unsigned int> main_handles;
|
||||||
std::unordered_map<std::string, unsigned int> init_handles;
|
std::unordered_map<std::string, unsigned int> init_handles;
|
||||||
|
|
||||||
std::unordered_map<std::string, game::ScriptFile*> loaded_scripts;
|
std::unordered_map<std::string, game::ScriptFile*> loaded_scripts;
|
||||||
std::unordered_map<std::string, std::string> script_stack_buffers;
|
|
||||||
|
|
||||||
const game::dvar_t* developer_script;
|
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
main_handles.clear();
|
main_handles.clear();
|
||||||
init_handles.clear();
|
init_handles.clear();
|
||||||
loaded_scripts.clear();
|
loaded_scripts.clear();
|
||||||
script_stack_buffers.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_raw_script_file(const std::string& name, std::string* data)
|
bool read_script_file(const std::string& name, std::string* data)
|
||||||
{
|
{
|
||||||
if (filesystem::read_file(name, data))
|
if (filesystem::read_file(name, data))
|
||||||
{
|
{
|
||||||
@ -80,7 +87,7 @@ namespace gsc
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string source_buffer{};
|
std::string source_buffer{};
|
||||||
if (!read_raw_script_file(real_name + ".gsc", &source_buffer))
|
if (!read_script_file(real_name + ".gsc", &source_buffer))
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -88,14 +95,9 @@ namespace gsc
|
|||||||
std::vector<std::uint8_t> data;
|
std::vector<std::uint8_t> data;
|
||||||
data.assign(source_buffer.begin(), source_buffer.end());
|
data.assign(source_buffer.begin(), source_buffer.end());
|
||||||
|
|
||||||
auto& compiler = gsc::cxt->compiler();
|
|
||||||
auto& assembler = gsc::cxt->assembler();
|
|
||||||
|
|
||||||
xsk::gsc::assembly::ptr assembly_ptr;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
assembly_ptr = compiler.compile(real_name, data);
|
compiler->compile(real_name, data);
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
@ -105,32 +107,11 @@ namespace gsc
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto assembly = compiler->output();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// second shoulde be stacc and first byte cum
|
assembler->assemble(real_name, assembly);
|
||||||
const auto output_script = assembler.assemble(*assembly_ptr);
|
|
||||||
|
|
||||||
const auto script_file_ptr = static_cast<game::ScriptFile*>(game::Hunk_AllocateTempMemoryHighInternal(sizeof(game::ScriptFile)));
|
|
||||||
script_file_ptr->name = file_name;
|
|
||||||
|
|
||||||
script_file_ptr->len = static_cast<int>(output_script.second.size);
|
|
||||||
|
|
||||||
script_file_ptr->bytecodeLen = static_cast<int>(output_script.first.size);
|
|
||||||
|
|
||||||
const auto stack_size = static_cast<std::uint32_t>(output_script.second.size + 1);
|
|
||||||
const auto byte_code_size = static_cast<std::uint32_t>(output_script.first.size + 1);
|
|
||||||
|
|
||||||
script_file_ptr->buffer = static_cast<char*>(game::Hunk_AllocateTempMemoryHighInternal(stack_size));
|
|
||||||
std::memcpy(const_cast<char*>(script_file_ptr->buffer), output_script.second.data, output_script.second.size);
|
|
||||||
|
|
||||||
script_file_ptr->bytecode = static_cast<std::uint8_t*>(game::PMem_AllocFromSource_NoDebug(byte_code_size, 4, 1, 5));
|
|
||||||
std::memcpy(script_file_ptr->bytecode, output_script.first.data, output_script.first.size);
|
|
||||||
|
|
||||||
script_file_ptr->compressedLen = 0;
|
|
||||||
|
|
||||||
loaded_scripts[real_name] = script_file_ptr;
|
|
||||||
|
|
||||||
return script_file_ptr;
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
@ -139,11 +120,35 @@ namespace gsc
|
|||||||
console::error("**********************************************\n");
|
console::error("**********************************************\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto script_file_ptr = static_cast<game::ScriptFile*>(game::Hunk_AllocateTempMemoryHighInternal(sizeof(game::ScriptFile)));
|
||||||
|
script_file_ptr->name = file_name;
|
||||||
|
|
||||||
|
const auto stack = assembler->output_stack();
|
||||||
|
script_file_ptr->len = static_cast<int>(stack.size());
|
||||||
|
|
||||||
|
const auto script = assembler->output_script();
|
||||||
|
script_file_ptr->bytecodeLen = static_cast<int>(script.size());
|
||||||
|
|
||||||
|
const auto stack_size = static_cast<std::uint32_t>(stack.size() + 1);
|
||||||
|
const auto byte_code_size = static_cast<std::uint32_t>(script.size() + 1);
|
||||||
|
|
||||||
|
script_file_ptr->buffer = static_cast<char*>(game::Hunk_AllocateTempMemoryHighInternal(stack_size));
|
||||||
|
std::memcpy(const_cast<char*>(script_file_ptr->buffer), stack.data(), stack.size());
|
||||||
|
|
||||||
|
script_file_ptr->bytecode = static_cast<std::uint8_t*>(game::PMem_AllocFromSource_NoDebug(byte_code_size, 4, 1, 5));
|
||||||
|
std::memcpy(script_file_ptr->bytecode, script.data(), script.size());
|
||||||
|
|
||||||
|
script_file_ptr->compressedLen = 0;
|
||||||
|
|
||||||
|
loaded_scripts[real_name] = script_file_ptr;
|
||||||
|
|
||||||
|
return script_file_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_script_file_name(const std::string& name)
|
std::string get_script_file_name(const std::string& name)
|
||||||
{
|
{
|
||||||
const auto id = gsc::cxt->token_id(name);
|
const auto id = xsk::gsc::s1::resolver::token_id(name);
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
@ -152,7 +157,7 @@ namespace gsc
|
|||||||
return std::to_string(id);
|
return std::to_string(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<xsk::gsc::buffer, xsk::gsc::buffer> read_compiled_script_file(const std::string& name, const std::string& real_name)
|
std::vector<std::uint8_t> decompile_script_file(const std::string& name, const std::string& real_name)
|
||||||
{
|
{
|
||||||
const auto* script_file = game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, name.data(), false).scriptfile;
|
const auto* script_file = game::DB_FindXAssetHeader(game::ASSET_TYPE_SCRIPTFILE, name.data(), false).scriptfile;
|
||||||
if (!script_file)
|
if (!script_file)
|
||||||
@ -162,15 +167,17 @@ namespace gsc
|
|||||||
|
|
||||||
console::info("Decompiling scriptfile '%s'\n", real_name.data());
|
console::info("Decompiling scriptfile '%s'\n", real_name.data());
|
||||||
|
|
||||||
const std::string stack{script_file->buffer, static_cast<std::uint32_t>(script_file->len)};
|
std::vector<std::uint8_t> stack{script_file->buffer, script_file->buffer + script_file->len};
|
||||||
|
std::vector<std::uint8_t> bytecode{script_file->bytecode, script_file->bytecode + script_file->bytecodeLen};
|
||||||
|
|
||||||
const auto decompressed_stack = utils::compression::zlib::decompress(stack);
|
auto decompressed_stack = xsk::utils::zlib::decompress(stack, static_cast<std::uint32_t>(stack.size()));
|
||||||
|
|
||||||
// Store buffer
|
disassembler->disassemble(name, bytecode, decompressed_stack);
|
||||||
script_stack_buffers[real_name] = decompressed_stack;
|
auto output = disassembler->output();
|
||||||
const auto itr = script_stack_buffers.find(real_name);
|
|
||||||
|
|
||||||
return {{script_file->bytecode, static_cast<std::uint32_t>(script_file->bytecodeLen)}, {reinterpret_cast<std::uint8_t*>(itr->second.data()), itr->second.size()}};
|
decompiler->decompile(name, output);
|
||||||
|
|
||||||
|
return decompiler->output();
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_script(const std::string& name)
|
void load_script(const std::string& name)
|
||||||
@ -180,8 +187,8 @@ namespace gsc
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto main_handle = game::Scr_GetFunctionHandle(name.data(), gsc::cxt->token_id("main"));
|
const auto main_handle = game::Scr_GetFunctionHandle(name.data(), xsk::gsc::s1::resolver::token_id("main"));
|
||||||
const auto init_handle = game::Scr_GetFunctionHandle(name.data(), gsc::cxt->token_id("init"));
|
const auto init_handle = game::Scr_GetFunctionHandle(name.data(), xsk::gsc::s1::resolver::token_id("init"));
|
||||||
|
|
||||||
if (main_handle)
|
if (main_handle)
|
||||||
{
|
{
|
||||||
@ -302,42 +309,6 @@ namespace gsc
|
|||||||
game::RemoveRefToObject(thread);
|
game::RemoveRefToObject(thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scr_begin_load_scripts_stub()
|
|
||||||
{
|
|
||||||
const auto comp_mode = developer_script->current.enabled ?
|
|
||||||
xsk::gsc::build::dev :
|
|
||||||
xsk::gsc::build::prod;
|
|
||||||
|
|
||||||
gsc::cxt->init(comp_mode, [](const std::string& include_name) -> std::pair<xsk::gsc::buffer, xsk::gsc::buffer>
|
|
||||||
{
|
|
||||||
const auto real_name = include_name + ".gsc";
|
|
||||||
|
|
||||||
std::string file_buffer;
|
|
||||||
if (!read_raw_script_file(real_name, &file_buffer) || file_buffer.empty())
|
|
||||||
{
|
|
||||||
const auto name = get_script_file_name(include_name);
|
|
||||||
if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, name.data()))
|
|
||||||
{
|
|
||||||
return read_compiled_script_file(name, real_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::runtime_error(std::format("Could not load gsc file '{}'", real_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {xsk::gsc::buffer(reinterpret_cast<std::uint8_t*>(file_buffer.data()), file_buffer.size()), {}};
|
|
||||||
});
|
|
||||||
|
|
||||||
utils::hook::invoke<void>(SELECT_VALUE(0x1403118E0, 0x1403EDE60));
|
|
||||||
}
|
|
||||||
|
|
||||||
void scr_end_load_scripts_stub()
|
|
||||||
{
|
|
||||||
// Cleanup the compiler
|
|
||||||
gsc::cxt->cleanup();
|
|
||||||
|
|
||||||
utils::hook::invoke<void>(SELECT_VALUE(0x140243780, 0x1403EDF90));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
game::ScriptFile* find_script(game::XAssetType type, const char* name, int allow_create_default)
|
game::ScriptFile* find_script(game::XAssetType type, const char* name, int allow_create_default)
|
||||||
@ -346,7 +317,7 @@ namespace gsc
|
|||||||
const auto id = static_cast<std::uint16_t>(std::atoi(name));
|
const auto id = static_cast<std::uint16_t>(std::atoi(name));
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
real_name = gsc::cxt->token_name(id);
|
real_name = xsk::gsc::s1::resolver::token_name(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* script = load_custom_script(name, real_name);
|
auto* script = load_custom_script(name, real_name);
|
||||||
@ -366,16 +337,34 @@ namespace gsc
|
|||||||
// Load our scripts with an uncompressed stack
|
// Load our scripts with an uncompressed stack
|
||||||
utils::hook::call(SELECT_VALUE(0x14031ABB0, 0x1403F7380), db_get_raw_buffer_stub);
|
utils::hook::call(SELECT_VALUE(0x14031ABB0, 0x1403F7380), db_get_raw_buffer_stub);
|
||||||
|
|
||||||
utils::hook::call(SELECT_VALUE(0x1403309E9, 0x1403309E9), scr_begin_load_scripts_stub); // GScr_LoadScripts
|
|
||||||
utils::hook::call(SELECT_VALUE(0x14023DA84, 0x140330B9C), scr_end_load_scripts_stub); // GScr_LoadScripts
|
|
||||||
|
|
||||||
developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments");
|
|
||||||
|
|
||||||
if (game::environment::is_sp())
|
if (game::environment::is_sp())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow custom scripts to include other custom scripts
|
||||||
|
xsk::gsc::s1::resolver::init([](const auto& include_name) -> std::vector<std::uint8_t>
|
||||||
|
{
|
||||||
|
const auto real_name = include_name + ".gsc";
|
||||||
|
|
||||||
|
std::string file_buffer;
|
||||||
|
if (!read_script_file(real_name, &file_buffer) || file_buffer.empty())
|
||||||
|
{
|
||||||
|
const auto name = get_script_file_name(include_name);
|
||||||
|
if (game::DB_XAssetExists(game::ASSET_TYPE_SCRIPTFILE, name.data()))
|
||||||
|
{
|
||||||
|
return decompile_script_file(name, real_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error(std::format("Could not load gsc file '{}'", real_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::uint8_t> result;
|
||||||
|
result.assign(file_buffer.begin(), file_buffer.end());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
// ProcessScript
|
// ProcessScript
|
||||||
utils::hook::call(0x1403F7317, find_script);
|
utils::hook::call(0x1403F7317, find_script);
|
||||||
utils::hook::call(0x1403F7327, db_is_x_asset_default);
|
utils::hook::call(0x1403F7327, db_is_x_asset_default);
|
||||||
@ -391,6 +380,7 @@ namespace gsc
|
|||||||
{
|
{
|
||||||
if (free_scripts)
|
if (free_scripts)
|
||||||
{
|
{
|
||||||
|
xsk::gsc::s1::resolver::cleanup();
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5,26 +5,33 @@
|
|||||||
|
|
||||||
#include "component/gsc/script_extension.hpp"
|
#include "component/gsc/script_extension.hpp"
|
||||||
|
|
||||||
#include <gsc_interface.hpp>
|
#include <xsk/gsc/types.hpp>
|
||||||
|
#include <xsk/resolver.hpp>
|
||||||
|
|
||||||
namespace scripting
|
namespace scripting
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
int find_function_index(const std::string& name, [[maybe_unused]] const bool prefer_global)
|
int find_function_index(const std::string& name, const bool prefer_global)
|
||||||
{
|
{
|
||||||
const auto target = utils::string::to_lower(name);
|
const auto target = utils::string::to_lower(name);
|
||||||
auto const& first = gsc::cxt->func_map();
|
auto first = xsk::gsc::s1::resolver::function_id;
|
||||||
auto const& second = gsc::cxt->meth_map();
|
auto second = xsk::gsc::s1::resolver::method_id;
|
||||||
|
if (!prefer_global)
|
||||||
if (const auto itr = first.find(name); itr != first.end())
|
|
||||||
{
|
{
|
||||||
return static_cast<int>(itr->second);
|
std::swap(first, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto itr = second.find(name); itr != second.end())
|
const auto first_res = first(target);
|
||||||
|
if (first_res)
|
||||||
{
|
{
|
||||||
return static_cast<int>(itr->second);
|
return first_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto second_res = second(target);
|
||||||
|
if (second_res)
|
||||||
|
{
|
||||||
|
return second_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -43,17 +50,17 @@ namespace scripting
|
|||||||
|
|
||||||
std::string find_token(std::uint32_t id)
|
std::string find_token(std::uint32_t id)
|
||||||
{
|
{
|
||||||
return gsc::cxt->token_name(id);
|
return xsk::gsc::s1::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string find_token_single(std::uint32_t id)
|
std::string find_token_single(std::uint32_t id)
|
||||||
{
|
{
|
||||||
return gsc::cxt->token_name(id);
|
return xsk::gsc::s1::resolver::token_name(static_cast<std::uint16_t>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int find_token_id(const std::string& name)
|
unsigned int find_token_id(const std::string& name)
|
||||||
{
|
{
|
||||||
const auto id = gsc::cxt->token_id(name);
|
const auto id = xsk::gsc::s1::resolver::token_id(name);
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
#include <utils/string.hpp>
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
#include <gsc_interface.hpp>
|
#include <xsk/gsc/types.hpp>
|
||||||
|
#include <xsk/resolver.hpp>
|
||||||
|
|
||||||
namespace scripting::lua
|
namespace scripting::lua
|
||||||
{
|
{
|
||||||
@ -245,7 +246,7 @@ namespace scripting::lua
|
|||||||
|
|
||||||
auto entity_type = state.new_usertype<entity>("entity");
|
auto entity_type = state.new_usertype<entity>("entity");
|
||||||
|
|
||||||
for (auto const& func : gsc::cxt->meth_map())
|
for (const auto& func : xsk::gsc::s1::resolver::get_methods())
|
||||||
{
|
{
|
||||||
const auto name = std::string(func.first);
|
const auto name = std::string(func.first);
|
||||||
entity_type[name] = [name](const entity& entity, const sol::this_state s, sol::variadic_args va)
|
entity_type[name] = [name](const entity& entity, const sol::this_state s, sol::variadic_args va)
|
||||||
@ -377,7 +378,7 @@ namespace scripting::lua
|
|||||||
auto game_type = state.new_usertype<game>("game_");
|
auto game_type = state.new_usertype<game>("game_");
|
||||||
state["game"] = game();
|
state["game"] = game();
|
||||||
|
|
||||||
for (auto const& func : gsc::cxt->func_map())
|
for (const auto& func : xsk::gsc::s1::resolver::get_functions())
|
||||||
{
|
{
|
||||||
const auto name = std::string(func.first);
|
const auto name = std::string(func.first);
|
||||||
game_type[name] = [name](const game&, const sol::this_state s, sol::variadic_args va)
|
game_type[name] = [name](const game&, const sol::this_state s, sol::variadic_args va)
|
||||||
|
Loading…
Reference in New Issue
Block a user