mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
dynload framework complete. Reloads DLL every game start, temporarily copies to prevent write protection.
This commit is contained in:
parent
b1d509236e
commit
a21391fc7d
BIN
ace_dynload.dll
BIN
ace_dynload.dll
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
#ifdef ACE_EXTENSION_DYNLOAD
|
#ifdef DEBUG_EXTENSION_DYNLOAD
|
||||||
"ace_dynload" callExtension format["ace_dynload:call:%1,%1", GVAR(extensionLibrary), _this];
|
"ace_dynload" callExtension format["call:%1,%2", GVAR(extensionLibrary), _this];
|
||||||
#else
|
#else
|
||||||
"ace_vd" callExtension _this;
|
"ace_vd" callExtension _this;
|
||||||
#endif
|
#endif
|
@ -1,11 +1,14 @@
|
|||||||
|
#define DEBUG_MODE_FULL
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
// Initialize our event handlers
|
// Initialize our event handlers
|
||||||
|
|
||||||
GVAR(ready) = false;
|
GVAR(ready) = false;
|
||||||
|
|
||||||
#ifdef ACE_EXTENSION_DYNLOAD
|
#ifdef DEBUG_EXTENSION_DYNLOAD
|
||||||
|
"ace_dynload" callExtension format["unload:%1", GVAR(extensionLibrary)];
|
||||||
"ace_dynload" callExtension format["load:%1", GVAR(extensionLibrary)];
|
"ace_dynload" callExtension format["load:%1", GVAR(extensionLibrary)];
|
||||||
|
diag_log text format["[ACE] - DEBUG - Dynamic extension loaded for Vehicle Damage"];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(GVAR(async)) then {
|
if(GVAR(async)) then {
|
||||||
@ -17,12 +20,15 @@ diag_log text format["[ACE] - Vehicle damage extension caching..."];
|
|||||||
|
|
||||||
#ifdef ACE_VEHICLEDAMAGE_RENDER_DEBUG
|
#ifdef ACE_VEHICLEDAMAGE_RENDER_DEBUG
|
||||||
"debug_render:" call FUNC(callExtension);
|
"debug_render:" call FUNC(callExtension);
|
||||||
|
diag_log text format["[ACE] - DEBUG - DirectX11 Debug Rendering initialized"];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[{
|
[{
|
||||||
private["_result"];
|
private["_result"];
|
||||||
// Wait until the extension is ready
|
// Wait until the extension is ready
|
||||||
_result = "ready" call FUNC(callExtension);
|
_result = "ready" call FUNC(callExtension);
|
||||||
|
TRACE_1("ready check", _result);
|
||||||
|
|
||||||
if(!isNil "_result" && {_result == "0" } ) then {
|
if(!isNil "_result" && {_result == "0" } ) then {
|
||||||
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
||||||
|
|
||||||
|
@ -14,3 +14,5 @@
|
|||||||
#define CALL_EXT(x) "ace_vd" callExtension x
|
#define CALL_EXT(x) "ace_vd" callExtension x
|
||||||
#define VECTOR_TEXT(x) ([(x)] call FUNC(_textVector))
|
#define VECTOR_TEXT(x) ([(x)] call FUNC(_textVector))
|
||||||
#define RELATIVE_VECTOR_TEXT(o,x) ([(o worldToModelVisual ((x) call EFUNC(common,ASLToPosition)))] call FUNC(_textVector))
|
#define RELATIVE_VECTOR_TEXT(o,x) ([(o worldToModelVisual ((x) call EFUNC(common,ASLToPosition)))] call FUNC(_textVector))
|
||||||
|
|
||||||
|
#define DEBUG_EXTENSION_DYNLOAD
|
@ -76,7 +76,11 @@ namespace ace {
|
|||||||
|
|
||||||
_message_id = _message_id + 1;
|
_message_id = _message_id + 1;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (_messages.front().command != "fetch_result") {
|
||||||
LOG(TRACE) << "dispatch[immediate]:\t[" << name_ << "] { " << args_.get() << " }";
|
LOG(TRACE) << "dispatch[immediate]:\t[" << name_ << "] { " << args_.get() << " }";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return dispatcher::call(name_, args_, result_);
|
return dispatcher::call(name_, args_, result_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) {
|
|||||||
|
|
||||||
/*************************/
|
/*************************/
|
||||||
// Real functionality goes here
|
// Real functionality goes here
|
||||||
result = ace::dispatch::get().call(command, _args, result);
|
ace::dispatch::get().call(command, _args, result);
|
||||||
|
|
||||||
|
|
||||||
sprintf_s(output, outputSize, "%s", result.c_str());
|
sprintf_s(output, outputSize, "%s", result.c_str());
|
||||||
|
@ -4,16 +4,17 @@
|
|||||||
#include "dispatch.hpp"
|
#include "dispatch.hpp"
|
||||||
#include "arguments.hpp"
|
#include "arguments.hpp"
|
||||||
|
|
||||||
typedef void (*__stdcall RVExtension)(char *output, int outputSize, const char *function);
|
typedef void (__stdcall *RVExtension)(char *output, int outputSize, const char *function);
|
||||||
|
|
||||||
namespace ace {
|
namespace ace {
|
||||||
|
|
||||||
class module {
|
class module {
|
||||||
public:
|
public:
|
||||||
module() : handle(nullptr), function(nullptr), name("") {}
|
module() : handle(nullptr), function(nullptr), name("") {}
|
||||||
module(std::string name_, HANDLE handle_, RVExtension function_) : handle(nullptr), function(function_), name(name_) {}
|
module(const std::string & name_, HANDLE handle_, RVExtension function_, const std::string & file_) : handle(nullptr), function(function_), name(name_), temp_filename(file_) {}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string temp_filename;
|
||||||
HINSTANCE handle;
|
HINSTANCE handle;
|
||||||
RVExtension function;
|
RVExtension function;
|
||||||
};
|
};
|
||||||
@ -41,7 +42,31 @@ namespace ace {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dllHandle = LoadLibrary(args_.as_string(0).c_str());
|
#ifdef _WINDOWS
|
||||||
|
// Make a copy of the file to temp, and load it from there, referencing the current path name
|
||||||
|
char tmpPath[MAX_PATH +1], buffer[MAX_PATH + 1];
|
||||||
|
|
||||||
|
if(!GetTempPathA(MAX_PATH, tmpPath)) {
|
||||||
|
LOG(ERROR) << "GetTempPath() failed, e=" << GetLastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!GetTempFileNameA(tmpPath, "ace_dynload", TRUE, buffer)) {
|
||||||
|
LOG(ERROR) << "GetTempFileName() failed, e=" << GetLastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string temp_filename = buffer;
|
||||||
|
if (!CopyFileA(args_.as_string(0).c_str(), temp_filename.c_str(), TRUE)) {
|
||||||
|
DeleteFile(temp_filename.c_str());
|
||||||
|
if (!CopyFileA(args_.as_string(0).c_str(), temp_filename.c_str(), TRUE)) {
|
||||||
|
LOG(ERROR) << "CopyFile() , e=" << GetLastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::string temp_filename = args_.as_string(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dllHandle = LoadLibrary(temp_filename.c_str());
|
||||||
if (!dllHandle) {
|
if (!dllHandle) {
|
||||||
LOG(ERROR) << "LoadLibrary() failed, e=" << GetLastError() << " [" << args_.as_string(0) << "]";
|
LOG(ERROR) << "LoadLibrary() failed, e=" << GetLastError() << " [" << args_.as_string(0) << "]";
|
||||||
return false;
|
return false;
|
||||||
@ -56,7 +81,7 @@ namespace ace {
|
|||||||
|
|
||||||
LOG(INFO) << "Load completed [" << args_.as_string(0) << "]";
|
LOG(INFO) << "Load completed [" << args_.as_string(0) << "]";
|
||||||
|
|
||||||
_modules[args_.as_string(0)] = module(args_.as_string(0), dllHandle, function);
|
_modules[args_.as_string(0)] = module(args_.as_string(0), dllHandle, function, temp_filename);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -79,7 +104,7 @@ namespace ace {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool call(const arguments & args_, std::string & result) {
|
bool call(const arguments & args_, std::string & result) {
|
||||||
LOG(INFO) << "Calling [" << args_.as_string(0) << "]";
|
//LOG(INFO) << "Calling [" << args_.as_string(0) << "]";
|
||||||
|
|
||||||
if (_modules.find(args_.as_string(0)) == _modules.end()) {
|
if (_modules.find(args_.as_string(0)) == _modules.end()) {
|
||||||
return false;
|
return false;
|
||||||
@ -91,13 +116,16 @@ namespace ace {
|
|||||||
std::string function_str;
|
std::string function_str;
|
||||||
std::vector<std::string> temp = ace::split(args_.get(), ',');
|
std::vector<std::string> temp = ace::split(args_.get(), ',');
|
||||||
|
|
||||||
for (int x = 1; x < temp.size(); x++)
|
function_str = temp[1] + ":";
|
||||||
|
for (int x = 2; x < temp.size(); x++)
|
||||||
function_str = function_str + temp[x] + ",";
|
function_str = function_str + temp[x] + ",";
|
||||||
|
|
||||||
_modules[args_.as_string(0)].function((char *)result.c_str(), 4096, (const char *)function_str.c_str());
|
_modules[args_.as_string(0)].function((char *)result.c_str(), 4096, (const char *)function_str.c_str());
|
||||||
|
#ifdef _DEBUG
|
||||||
LOG(INFO) << "Called [" << args_.as_string(0) << "], result={" << result << "}";
|
//if (args_.as_string(0) != "fetch_result" && args_.as_string(0) != "ready") {
|
||||||
|
// LOG(INFO) << "Called [" << args_.as_string(0) << "], with {" << function_str << "} result={" << result << "}";
|
||||||
|
//}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user