mirror of
https://github.com/fedddddd/iw5-gsc-utils.git
synced 2026-08-01 04:40:34 +00:00
httpget fix
This commit is contained in:
+79
-11
@@ -4,9 +4,76 @@
|
|||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
#include "gsc.hpp"
|
#include "gsc.hpp"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
#include "scripting.hpp"
|
||||||
|
|
||||||
namespace io
|
namespace io
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct http_request_t
|
||||||
|
{
|
||||||
|
std::string url;
|
||||||
|
bool completed;
|
||||||
|
std::string result;
|
||||||
|
scripting::entity handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::concurrency::container<std::vector<http_request_t>> requests;
|
||||||
|
|
||||||
|
void run_requests()
|
||||||
|
{
|
||||||
|
requests.access([&](std::vector<http_request_t>& r)
|
||||||
|
{
|
||||||
|
for (auto& request : r)
|
||||||
|
{
|
||||||
|
const auto data = utils::http::get_data(request.url.data());
|
||||||
|
if (data.has_value())
|
||||||
|
{
|
||||||
|
request.result = data->substr(0, 0x5000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.result = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
request.completed = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_requests()
|
||||||
|
{
|
||||||
|
requests.access([&](std::vector<http_request_t>& r)
|
||||||
|
{
|
||||||
|
for (auto i = r.begin(); i != r.end(); )
|
||||||
|
{
|
||||||
|
if (!i->completed)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scripting::notify(i->handle, "done", {i->result});
|
||||||
|
i = r.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_request(const std::string& url, const scripting::entity& handle)
|
||||||
|
{
|
||||||
|
requests.access([&](std::vector<http_request_t>& r)
|
||||||
|
{
|
||||||
|
http_request_t request{};
|
||||||
|
request.handle = handle;
|
||||||
|
request.url = url;
|
||||||
|
request.completed = false;
|
||||||
|
r.emplace_back(request);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -24,6 +91,17 @@ namespace io
|
|||||||
|
|
||||||
void on_startup([[maybe_unused]] plugin::plugin* plugin) override
|
void on_startup([[maybe_unused]] plugin::plugin* plugin) override
|
||||||
{
|
{
|
||||||
|
scheduler::loop(run_requests, scheduler::async);
|
||||||
|
scheduler::loop(check_requests, scheduler::server);
|
||||||
|
|
||||||
|
scripting::on_shutdown([]()
|
||||||
|
{
|
||||||
|
requests.access([&](std::vector<http_request_t>& r)
|
||||||
|
{
|
||||||
|
r.clear();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
gsc::function::add("jsonprint", [](const gsc::function_args& args) -> scripting::script_value
|
gsc::function::add("jsonprint", [](const gsc::function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
@@ -116,17 +194,7 @@ namespace io
|
|||||||
const auto url = args[0].as<std::string>();
|
const auto url = args[0].as<std::string>();
|
||||||
const auto object = scripting::entity(scripting::make_object());
|
const auto object = scripting::entity(scripting::make_object());
|
||||||
|
|
||||||
scheduler::once([object, url]()
|
add_request(url, object);
|
||||||
{
|
|
||||||
const auto result = utils::http::get_data(url.data());
|
|
||||||
scheduler::once([object, result]()
|
|
||||||
{
|
|
||||||
const auto value = result.has_value()
|
|
||||||
? result.value().substr(0, 0x5000)
|
|
||||||
: "";
|
|
||||||
scripting::notify(object, "done", {value});
|
|
||||||
});
|
|
||||||
}, scheduler::pipeline::async);
|
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ namespace scheduler
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
|
std::atomic_bool killed;
|
||||||
task_pipeline pipelines[pipeline::count];
|
task_pipeline pipelines[pipeline::count];
|
||||||
|
|
||||||
void execute(const pipeline type)
|
void execute(const pipeline type)
|
||||||
@@ -132,7 +133,7 @@ namespace scheduler
|
|||||||
{
|
{
|
||||||
thread = std::thread([]()
|
thread = std::thread([]()
|
||||||
{
|
{
|
||||||
while (true)
|
while (!killed)
|
||||||
{
|
{
|
||||||
execute(pipeline::async);
|
execute(pipeline::async);
|
||||||
std::this_thread::sleep_for(10ms);
|
std::this_thread::sleep_for(10ms);
|
||||||
@@ -141,6 +142,16 @@ namespace scheduler
|
|||||||
|
|
||||||
utils::hook::call(0x50CEDC, server_frame_stub);
|
utils::hook::call(0x50CEDC, server_frame_stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_shutdown([[maybe_unused]] plugin::plugin* plugin) override
|
||||||
|
{
|
||||||
|
killed = true;
|
||||||
|
|
||||||
|
if (thread.joinable())
|
||||||
|
{
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include <stdinc.hpp>
|
#include <stdinc.hpp>
|
||||||
#include "execution.hpp"
|
#include "execution.hpp"
|
||||||
#include "safe_execution.hpp"
|
|
||||||
#include "stack_isolation.hpp"
|
#include "stack_isolation.hpp"
|
||||||
#include "event.hpp"
|
#include "event.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
#include <stdinc.hpp>
|
|
||||||
#include "safe_execution.hpp"
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable: 4611)
|
|
||||||
|
|
||||||
namespace scripting::safe_execution
|
|
||||||
{
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
bool execute_with_seh(const script_function function, const game::scr_entref_t& entref)
|
|
||||||
{
|
|
||||||
__try
|
|
||||||
{
|
|
||||||
function(entref);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool call(const script_function function, const game::scr_entref_t& entref)
|
|
||||||
{
|
|
||||||
*game::g_script_error_level += 1;
|
|
||||||
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level], 0, 0, 0))
|
|
||||||
{
|
|
||||||
*game::g_script_error_level -= 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto result = execute_with_seh(function, entref);
|
|
||||||
*game::g_script_error_level -= 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool set_entity_field(const game::scr_entref_t& entref, const int offset)
|
|
||||||
{
|
|
||||||
*game::g_script_error_level += 1;
|
|
||||||
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level], 0, 0, 0))
|
|
||||||
{
|
|
||||||
*game::g_script_error_level -= 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
game::Scr_SetObjectField(entref.classnum, entref.entnum, offset);
|
|
||||||
|
|
||||||
*game::g_script_error_level -= 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get_entity_field(const game::scr_entref_t& entref, const int offset, game::VariableValue* value)
|
|
||||||
{
|
|
||||||
*game::g_script_error_level += 1;
|
|
||||||
if (game::_setjmp(&game::g_script_error[*game::g_script_error_level], 0, 0, 0))
|
|
||||||
{
|
|
||||||
value->type = game::SCRIPT_NONE;
|
|
||||||
value->u.intValue = 0;
|
|
||||||
*game::g_script_error_level -= 1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto _value = game::GetEntityFieldValue(entref.classnum, entref.entnum, offset);
|
|
||||||
value->type = _value.type;
|
|
||||||
value->u = _value.u;
|
|
||||||
|
|
||||||
*game::g_script_error_level -= 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning(pop)
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "functions.hpp"
|
|
||||||
|
|
||||||
namespace scripting::safe_execution
|
|
||||||
{
|
|
||||||
bool call(script_function function, const game::scr_entref_t& entref);
|
|
||||||
|
|
||||||
bool set_entity_field(const game::scr_entref_t& entref, int offset);
|
|
||||||
bool get_entity_field(const game::scr_entref_t& entref, int offset, game::VariableValue* value);
|
|
||||||
}
|
|
||||||
@@ -25,8 +25,6 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<const dvar_t*(const char*)> Dvar_FindVar{0x5BDCC0};
|
WEAK symbol<const dvar_t*(const char*)> Dvar_FindVar{0x5BDCC0};
|
||||||
|
|
||||||
WEAK symbol<char*(const char*)> I_CleanStr{0x0};
|
|
||||||
|
|
||||||
WEAK symbol<VariableValue(unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x56AF20};
|
WEAK symbol<VariableValue(unsigned int classnum, int entnum, int offset)> GetEntityFieldValue{0x56AF20};
|
||||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x5651F0};
|
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x5651F0};
|
||||||
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindObject{0x565BD0};
|
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindObject{0x565BD0};
|
||||||
|
|||||||
Reference in New Issue
Block a user