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 "gsc.hpp"
|
||||
#include "json.hpp"
|
||||
#include "scripting.hpp"
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -24,6 +91,17 @@ namespace io
|
||||
|
||||
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
|
||||
{
|
||||
std::string buffer;
|
||||
@@ -116,17 +194,7 @@ namespace io
|
||||
const auto url = args[0].as<std::string>();
|
||||
const auto object = scripting::entity(scripting::make_object());
|
||||
|
||||
scheduler::once([object, url]()
|
||||
{
|
||||
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);
|
||||
add_request(url, object);
|
||||
|
||||
return object;
|
||||
});
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace scheduler
|
||||
};
|
||||
|
||||
std::thread thread;
|
||||
std::atomic_bool killed;
|
||||
task_pipeline pipelines[pipeline::count];
|
||||
|
||||
void execute(const pipeline type)
|
||||
@@ -132,7 +133,7 @@ namespace scheduler
|
||||
{
|
||||
thread = std::thread([]()
|
||||
{
|
||||
while (true)
|
||||
while (!killed)
|
||||
{
|
||||
execute(pipeline::async);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
@@ -141,6 +142,16 @@ namespace scheduler
|
||||
|
||||
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 "execution.hpp"
|
||||
#include "safe_execution.hpp"
|
||||
#include "stack_isolation.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<char*(const char*)> I_CleanStr{0x0};
|
||||
|
||||
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)> FindObject{0x565BD0};
|
||||
|
||||
Reference in New Issue
Block a user