7 Commits

Author SHA1 Message Date
0ac5225114 #5 2021-12-13 03:05:22 +01:00
e918bdf28f Update dllmain.cpp 2021-12-02 00:42:58 +01:00
fed
50b83787e7 Update pointers 2021-12-02 00:38:28 +01:00
e6ca925562 Fix setjmp 2021-11-15 22:06:44 +01:00
0f92a7ce25 Fixes for pluto update 2021-11-09 23:55:25 +01:00
d4d91de80f Small change 2021-11-09 22:48:15 +01:00
a508a7e3a4 Also function 2021-11-08 01:42:55 +01:00
13 changed files with 77 additions and 49 deletions

View File

@ -93,7 +93,7 @@ namespace gsc
{ {
if (id < 0x200) if (id < 0x200)
{ {
return reinterpret_cast<builtin_function*>(0x20689DD8)[id](); return reinterpret_cast<builtin_function*>(game::plutonium::function_table.get())[id]();
} }
try try
@ -119,7 +119,7 @@ namespace gsc
{ {
if (id < 0x8400) if (id < 0x8400)
{ {
return reinterpret_cast<builtin_method*>(0x2068A5A8)[id - 0x8000](ent); return reinterpret_cast<builtin_method*>(game::plutonium::method_table.get())[id - 0x8000](ent);
} }
try try
@ -270,7 +270,7 @@ namespace gsc
namespace field namespace field
{ {
void add(classid classnum, const std::string& name, void add(const classid classnum, const std::string& name,
const std::function<scripting::script_value(unsigned int entnum)>& getter, const std::function<scripting::script_value(unsigned int entnum)>& getter,
const std::function<void(unsigned int entnum, const scripting::script_value&)>& setter) const std::function<void(unsigned int entnum, const scripting::script_value&)>& setter)
{ {

View File

@ -1,4 +1,6 @@
#pragma once #pragma once
#include "game/scripting/array.hpp"
#include "game/scripting/execution.hpp"
namespace gsc namespace gsc
{ {
@ -46,7 +48,7 @@ namespace gsc
namespace field namespace field
{ {
void add(classid classnum, const std::string& name, void add(const classid classnum, const std::string& name,
const std::function<scripting::script_value(unsigned int entnum)>& getter, const std::function<scripting::script_value(unsigned int entnum)>& getter,
const std::function<void(unsigned int entnum, const scripting::script_value&)>& setter); const std::function<void(unsigned int entnum, const scripting::script_value&)>& setter);
} }

View File

@ -2,12 +2,6 @@
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "game/scripting/event.hpp"
#include "game/scripting/execution.hpp"
#include "game/scripting/functions.hpp"
#include "game/scripting/array.hpp"
#include "gsc.hpp" #include "gsc.hpp"
#include "json.hpp" #include "json.hpp"

View File

@ -2,12 +2,6 @@
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "game/scripting/event.hpp"
#include "game/scripting/execution.hpp"
#include "game/scripting/functions.hpp"
#include "game/scripting/array.hpp"
#include "gsc.hpp" #include "gsc.hpp"
#include "json.hpp" #include "json.hpp"

View File

@ -1,14 +1,15 @@
#include <stdinc.hpp> #include <stdinc.hpp>
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "scheduler.hpp"
#include "game/scripting/entity.hpp" #include "scheduler.hpp"
#include "game/scripting/execution.hpp" #include "gsc.hpp"
#include "scripting.hpp"
namespace notifies namespace notifies
{ {
namespace namespace
{ {
std::vector<scripting::function> say_callbacks;
utils::hook::detour client_command_hook; utils::hook::detour client_command_hook;
void client_command_stub(int clientNum) void client_command_stub(int clientNum)
@ -17,19 +18,28 @@ namespace notifies
game::SV_Cmd_ArgvBuffer(0, cmd, 1024); game::SV_Cmd_ArgvBuffer(0, cmd, 1024);
auto hidden = false;
if (cmd == "say"s || cmd == "say_team"s) if (cmd == "say"s || cmd == "say_team"s)
{ {
std::string message = game::ConcatArgs(1); std::string message = game::ConcatArgs(1);
message.erase(0, 1); message.erase(0, 1);
const scripting::entity level{*game::levelEntityId}; for (const auto& callback : say_callbacks)
const auto player = scripting::call("getEntByNum", {clientNum}).as<scripting::entity>(); {
const auto entity_id = game::Scr_GetEntityId(clientNum, 0);
const auto result = callback(entity_id, {message, cmd == "say_team"s});
scripting::notify(level, cmd, {player, message}); if (result.is<int>())
scripting::notify(player, cmd, {message}); {
hidden = result.as<int>() == 0;
}
}
} }
return client_command_hook.invoke<void>(clientNum); if (!hidden)
{
client_command_hook.invoke<void>(clientNum);
}
} }
} }
@ -39,6 +49,18 @@ namespace notifies
void post_unpack() override void post_unpack() override
{ {
client_command_hook.create(0x502CB0, client_command_stub); client_command_hook.create(0x502CB0, client_command_stub);
scripting::on_shutdown([]()
{
say_callbacks.clear();
});
gsc::function::add("onplayersay", [](const gsc::function_args& args) -> scripting::script_value
{
const auto function = args[0].as<scripting::function>();
say_callbacks.push_back(function);
return {};
});
} }
}; };
} }

View File

@ -29,6 +29,8 @@ namespace scripting
std::string current_file; std::string current_file;
std::vector<std::function<void()>> shutdown_callbacks;
void vm_notify_stub(const unsigned int notify_list_owner_id, const unsigned int string_value, void vm_notify_stub(const unsigned int notify_list_owner_id, const unsigned int string_value,
game::VariableValue* top) game::VariableValue* top)
{ {
@ -77,6 +79,13 @@ namespace scripting
{ {
userinfo::clear_overrides(); userinfo::clear_overrides();
command::clear_script_commands(); command::clear_script_commands();
for (const auto& callback : shutdown_callbacks)
{
callback();
}
shutdown_callbacks = {};
g_shutdown_game_hook.invoke<void>(free_scripts); g_shutdown_game_hook.invoke<void>(free_scripts);
} }
@ -106,6 +115,11 @@ namespace scripting
} }
} }
void on_shutdown(const std::function<void()>& callback)
{
shutdown_callbacks.push_back(callback);
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:

View File

@ -4,4 +4,6 @@ namespace scripting
{ {
extern std::unordered_map<int, std::unordered_map<std::string, int>> fields_table; extern std::unordered_map<int, std::unordered_map<std::string, int>> fields_table;
extern std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table; extern std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
void on_shutdown(const std::function<void()>& callback);
} }

View File

@ -2,12 +2,6 @@
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "game/scripting/event.hpp"
#include "game/scripting/execution.hpp"
#include "game/scripting/functions.hpp"
#include "game/scripting/array.hpp"
#include "gsc.hpp" #include "gsc.hpp"
namespace userinfo namespace userinfo
@ -109,8 +103,6 @@ namespace userinfo
gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
{ {
const auto name = args[0].as<std::string>();
if (ent.classnum != 0 || ent.entnum > 17) if (ent.classnum != 0 || ent.entnum > 17)
{ {
throw std::runtime_error("Invalid entity"); throw std::runtime_error("Invalid entity");
@ -141,8 +133,6 @@ namespace userinfo
gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
{ {
const auto name = args[0].as<std::string>();
if (ent.classnum != 0 || ent.entnum > 17) if (ent.classnum != 0 || ent.entnum > 17)
{ {
throw std::runtime_error("Invalid entity"); throw std::runtime_error("Invalid entity");

View File

@ -5,16 +5,18 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
{ {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{ {
const auto value = *reinterpret_cast<DWORD*>(0x20800000); const auto value = *reinterpret_cast<DWORD*>(0x20900000);
if (value != 0xB9C9566) if (value != 0xF0681B6A)
{ {
printf("\x1b[31m\n**************************************************************************************\n\n"); MessageBoxA(NULL,
printf("This version of \x1b[33miw5-gsc-utils\x1b[31m is outdated.\n"); "This version of iw5-gsc-utils is outdated.\n" \
printf("Download the latest dll from here:\x1b[34m https://github.com/fedddddd/iw5-gsc-utils/releases \x1b[31m\n"); "Download the latest dll from here: https://github.com/fedddddd/iw5-gsc-utils/releases" \
printf("\n**************************************************************************************\n\n\x1b[37m"); , "ERROR", MB_ICONERROR);
return FALSE; return FALSE;
} }
utils::hook::jump(reinterpret_cast<uintptr_t>(&printf), game::plutonium::printf);
component_loader::post_unpack(); component_loader::post_unpack();
} }

View File

@ -59,8 +59,8 @@ namespace scripting
script_function get_function_by_index(const unsigned index) script_function get_function_by_index(const unsigned index)
{ {
static const auto function_table = 0x20689DD8; static const auto function_table = game::plutonium::function_table.get();
static const auto method_table = 0x2068A5A8; static const auto method_table = game::plutonium::method_table.get();
if (index < 0x1C7) if (index < 0x1C7)
{ {

View File

@ -25,7 +25,7 @@ namespace scripting::safe_execution
bool call(const script_function function, const game::scr_entref_t& entref) bool call(const script_function function, const game::scr_entref_t& entref)
{ {
*game::g_script_error_level += 1; *game::g_script_error_level += 1;
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) if (game::_setjmp(&game::g_script_error[*game::g_script_error_level], 0, 0, 0))
{ {
*game::g_script_error_level -= 1; *game::g_script_error_level -= 1;
return false; return false;
@ -39,7 +39,7 @@ namespace scripting::safe_execution
bool set_entity_field(const game::scr_entref_t& entref, const int offset) bool set_entity_field(const game::scr_entref_t& entref, const int offset)
{ {
*game::g_script_error_level += 1; *game::g_script_error_level += 1;
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) if (game::_setjmp(&game::g_script_error[*game::g_script_error_level], 0, 0, 0))
{ {
*game::g_script_error_level -= 1; *game::g_script_error_level -= 1;
return false; return false;
@ -54,7 +54,7 @@ namespace scripting::safe_execution
bool get_entity_field(const game::scr_entref_t& entref, const int offset, game::VariableValue* value) bool get_entity_field(const game::scr_entref_t& entref, const int offset, game::VariableValue* value)
{ {
*game::g_script_error_level += 1; *game::g_script_error_level += 1;
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) if (game::_setjmp(&game::g_script_error[*game::g_script_error_level], 0, 0, 0))
{ {
value->type = game::SCRIPT_NONE; value->type = game::SCRIPT_NONE;
value->u.intValue = 0; value->u.intValue = 0;

View File

@ -82,6 +82,11 @@ namespace scripting
return "array"; return "array";
} }
if (info == typeid(function))
{
return "function";
}
if (info == typeid(vector)) if (info == typeid(vector))
{ {
return "vector"; return "vector";

View File

@ -62,7 +62,7 @@ namespace game
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0}; WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0};
WEAK symbol<void* (jmp_buf* Buf, int Value)> longjmp{0x7363BC}; WEAK symbol<void* (jmp_buf* Buf, int Value)> longjmp{0x7363BC};
WEAK symbol<int(jmp_buf* Buf)> _setjmp{0x734CF8}; WEAK symbol<int(jmp_buf* Buf, int a2, int a3, int a4)> _setjmp{0x734CF8};
// Variables // Variables
@ -81,8 +81,11 @@ namespace game
namespace plutonium namespace plutonium
{ {
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> function_map_rev{0x20691228}; WEAK symbol<std::unordered_map<std::string, std::uint16_t>> function_map_rev{0x20693038};
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> method_map_rev{0x20691248}; WEAK symbol<std::unordered_map<std::string, std::uint16_t>> method_map_rev{0x20693058};
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> token_map_rev{0x20691288}; WEAK symbol<std::unordered_map<std::string, std::uint16_t>> token_map_rev{0x20693098};
WEAK symbol<int(const char* fmt, ...)> printf{0x208879B0};
WEAK symbol<void*> function_table{0x2068BCF0};
WEAK symbol<void*> method_table{0x2068C4C0};
} }
} }