mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-30 17:00:41 -05:00
impr: Merge in script loader structure improvements from python branch
This commit is contained in:
@@ -3,10 +3,8 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <Windows.h>
|
||||
#define STRING(str) L##str
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define STRING(str) str
|
||||
#endif
|
||||
|
||||
@@ -34,38 +32,6 @@ namespace hex::script::loader {
|
||||
|
||||
using get_hostfxr_path_fn = int(*)(char_t * buffer, size_t * buffer_size, const get_hostfxr_parameters *parameters);
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
void *loadLibrary(const char_t *path) {
|
||||
try {
|
||||
HMODULE h = ::LoadLibraryW(path);
|
||||
return h;
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getExport(void *h, const char *name) {
|
||||
try {
|
||||
FARPROC f = ::GetProcAddress(static_cast<HMODULE>(h), name);
|
||||
return reinterpret_cast<T>(reinterpret_cast<uintptr_t>(f));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void *loadLibrary(const char_t *path) {
|
||||
void *h = dlopen(path, RTLD_LAZY);
|
||||
return h;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getExport(void *h, const char *name) {
|
||||
void *f = dlsym(h, name);
|
||||
return reinterpret_cast<T>(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config = nullptr;
|
||||
hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate = nullptr;
|
||||
hostfxr_close_fn hostfxr_close = nullptr;
|
||||
|
||||
@@ -16,7 +16,7 @@ using namespace hex;
|
||||
using namespace hex::script::loader;
|
||||
|
||||
using ScriptLoaders = std::tuple<
|
||||
#if defined(DOTNET_PLUGINS)
|
||||
#if defined(IMHEX_DOTNET_SCRIPT_SUPPORT)
|
||||
DotNetLoader
|
||||
#endif
|
||||
>;
|
||||
@@ -106,11 +106,11 @@ namespace {
|
||||
}
|
||||
|
||||
for (const auto &script : scripts) {
|
||||
const auto &[name, background, entryPoint] = *script;
|
||||
const auto &[name, background, entryPoint, loader] = *script;
|
||||
if (background)
|
||||
continue;
|
||||
|
||||
if (ImGui::MenuItem(name.c_str())) {
|
||||
if (ImGui::MenuItem(name.c_str(), loader->getTypeName().c_str())) {
|
||||
runnerTask = TaskManager::createTask("Running script...", TaskManager::NoProgress, [entryPoint](auto&) {
|
||||
entryPoint();
|
||||
});
|
||||
@@ -140,4 +140,4 @@ IMHEX_PLUGIN_SETUP("Script Loader", "WerWolv", "Script Loader plugin") {
|
||||
if (initializeAllLoaders()) {
|
||||
addScriptsMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#include <script_api.hpp>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#define VERSION V1
|
||||
|
||||
SCRIPT_API(void createBookmark, u64 address, u64 size, u32 color, const char *name, const char *description) {
|
||||
hex::ImHexApi::Bookmarks::add(address, size, name, description, color);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#include <script_api.hpp>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#define VERSION V1
|
||||
|
||||
SCRIPT_API(void logPrint, const char *message) {
|
||||
hex::log::print("{}", message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void logPrintln, const char *message) {
|
||||
hex::log::println("{}", message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void logDebug, const char *message) {
|
||||
hex::log::debug("{}", message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void logInfo, const char *message) {
|
||||
hex::log::info("{}", message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void logWarn, const char *message) {
|
||||
hex::log::warn("{}", message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void logError, const char *message) {
|
||||
hex::log::error("{}", message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void logFatal, const char *message) {
|
||||
hex::log::fatal("{}", message);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#include <script_api.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#define VERSION V1
|
||||
|
||||
SCRIPT_API(void readMemory, u64 address, size_t size, void *buffer) {
|
||||
auto provider = hex::ImHexApi::Provider::get();
|
||||
|
||||
if (provider == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
provider->read(address, buffer, size);
|
||||
}
|
||||
|
||||
SCRIPT_API(void writeMemory, u64 address, size_t size, const void *buffer) {
|
||||
auto provider = hex::ImHexApi::Provider::get();
|
||||
|
||||
if (provider == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
provider->write(address, buffer, size);
|
||||
}
|
||||
|
||||
SCRIPT_API(bool getSelection, u64 *start, u64 *end) {
|
||||
if (start == nullptr || end == nullptr)
|
||||
return false;
|
||||
|
||||
if (!hex::ImHexApi::Provider::isValid())
|
||||
return false;
|
||||
|
||||
if (!hex::ImHexApi::HexEditor::isSelectionValid())
|
||||
return false;
|
||||
|
||||
auto selection = hex::ImHexApi::HexEditor::getSelection();
|
||||
|
||||
*start = selection->getStartAddress();
|
||||
*end = selection->getEndAddress();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class ScriptDataProvider : public hex::prv::Provider {
|
||||
public:
|
||||
using ReadFunction = void(*)(u64, void*, u64);
|
||||
using WriteFunction = void(*)(u64, const void*, u64);
|
||||
using GetSizeFunction = u64(*)();
|
||||
using GetNameFunction = std::string(*)();
|
||||
|
||||
bool open() override { return true; }
|
||||
void close() override { }
|
||||
|
||||
[[nodiscard]] bool isAvailable() const override { return true; }
|
||||
[[nodiscard]] bool isReadable() const override { return true; }
|
||||
[[nodiscard]] bool isWritable() const override { return true; }
|
||||
[[nodiscard]] bool isResizable() const override { return true; }
|
||||
[[nodiscard]] bool isSavable() const override { return true; }
|
||||
[[nodiscard]] bool isDumpable() const override { return true; }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override {
|
||||
m_readFunction(offset, buffer, size);
|
||||
}
|
||||
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override {
|
||||
m_writeFunction(offset, const_cast<void*>(buffer), size);
|
||||
}
|
||||
|
||||
void setFunctions(ReadFunction readFunc, WriteFunction writeFunc, GetSizeFunction getSizeFunc) {
|
||||
m_readFunction = readFunc;
|
||||
m_writeFunction = writeFunc;
|
||||
m_getSizeFunction = getSizeFunc;
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 getActualSize() const override { return m_getSizeFunction(); }
|
||||
|
||||
void setTypeName(std::string typeName) { m_typeName = std::move(typeName);}
|
||||
void setName(std::string name) { m_name = std::move(name);}
|
||||
[[nodiscard]] std::string getTypeName() const override { return m_typeName; }
|
||||
[[nodiscard]] std::string getName() const override { return m_name; }
|
||||
|
||||
private:
|
||||
ReadFunction m_readFunction = nullptr;
|
||||
WriteFunction m_writeFunction = nullptr;
|
||||
GetSizeFunction m_getSizeFunction = nullptr;
|
||||
|
||||
std::string m_typeName, m_name;
|
||||
};
|
||||
|
||||
SCRIPT_API(void registerProvider, const char *typeName, const char *name, ScriptDataProvider::ReadFunction readFunc, ScriptDataProvider::WriteFunction writeFunc, ScriptDataProvider::GetSizeFunction getSizeFunc) {
|
||||
auto typeNameString = std::string(typeName);
|
||||
auto nameString = std::string(name);
|
||||
|
||||
hex::ContentRegistry::Provider::impl::add(typeNameString, [typeNameString, nameString, readFunc, writeFunc, getSizeFunc] -> std::unique_ptr<hex::prv::Provider> {
|
||||
auto provider = std::make_unique<ScriptDataProvider>();
|
||||
provider->setTypeName(typeNameString);
|
||||
provider->setName(nameString);
|
||||
provider->setFunctions(readFunc, writeFunc, getSizeFunc);
|
||||
return provider;
|
||||
});
|
||||
hex::ContentRegistry::Provider::impl::addProviderName(typeNameString);
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
#include <script_api.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <hex/ui/popup.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <popups/popup_notification.hpp>
|
||||
#include <toasts/toast_notification.hpp>
|
||||
|
||||
using namespace hex;
|
||||
|
||||
#define VERSION V1
|
||||
|
||||
static std::optional<std::string> s_inputTextBoxResult;
|
||||
static std::optional<bool> s_yesNoQuestionBoxResult;
|
||||
|
||||
class PopupYesNo : public Popup<PopupYesNo> {
|
||||
public:
|
||||
PopupYesNo(std::string title, std::string message)
|
||||
: hex::Popup<PopupYesNo>(std::move(title), false),
|
||||
m_message(std::move(message)) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
||||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
if (ImGui::Button("hex.ui.common.yes"_lang, ImVec2(width / 3, 0))) {
|
||||
s_yesNoQuestionBoxResult = true;
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width / 9 * 5);
|
||||
if (ImGui::Button("hex.ui.common.no"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
s_yesNoQuestionBoxResult = false;
|
||||
this->close();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||
return ImGuiWindowFlags_AlwaysAutoResize;
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMinSize() const override {
|
||||
return scaled({ 400, 100 });
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMaxSize() const override {
|
||||
return scaled({ 600, 300 });
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
class PopupInputText : public Popup<PopupInputText> {
|
||||
public:
|
||||
PopupInputText(std::string title, std::string message, size_t maxSize)
|
||||
: hex::Popup<PopupInputText>(std::move(title), false),
|
||||
m_message(std::move(message)), m_maxSize(maxSize) { }
|
||||
|
||||
void drawContent() override {
|
||||
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
bool submitted = ImGui::InputText("##input", m_input, ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
if (m_input.size() > m_maxSize)
|
||||
m_input.resize(m_maxSize);
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
|
||||
auto width = ImGui::GetWindowWidth();
|
||||
ImGui::SetCursorPosX(width / 9);
|
||||
ImGui::BeginDisabled(m_input.empty());
|
||||
if (ImGui::Button("hex.ui.common.okay"_lang, ImVec2(width / 3, 0)) || submitted) {
|
||||
s_inputTextBoxResult = m_input;
|
||||
this->close();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width / 9 * 5);
|
||||
if (ImGui::Button("hex.ui.common.cancel"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
s_inputTextBoxResult = "";
|
||||
this->close();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||
return ImGuiWindowFlags_AlwaysAutoResize;
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMinSize() const override {
|
||||
return scaled({ 400, 100 });
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMaxSize() const override {
|
||||
return scaled({ 600, 300 });
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
std::string m_input;
|
||||
size_t m_maxSize;
|
||||
};
|
||||
|
||||
SCRIPT_API(void showMessageBox, const char *message) {
|
||||
ui::PopupInfo::open(message);
|
||||
}
|
||||
|
||||
SCRIPT_API(void showInputTextBox, const char *title, const char *message, char *buffer, u32 bufferSize) {
|
||||
PopupInputText::open(std::string(title), std::string(message), bufferSize - 1);
|
||||
|
||||
while (!s_inputTextBoxResult.has_value()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
auto &value = s_inputTextBoxResult.value();
|
||||
std::memcpy(buffer, value.c_str(), std::min<size_t>(value.size() + 1, bufferSize));
|
||||
s_inputTextBoxResult.reset();
|
||||
}
|
||||
|
||||
SCRIPT_API(void showYesNoQuestionBox, const char *title, const char *message, bool *result) {
|
||||
PopupYesNo::open(std::string(title), std::string(message));
|
||||
|
||||
while (!s_yesNoQuestionBoxResult.has_value()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
*result = s_yesNoQuestionBoxResult.value();
|
||||
s_yesNoQuestionBoxResult.reset();
|
||||
}
|
||||
|
||||
SCRIPT_API(void showToast, const char *message, u32 type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
ui::ToastInfo::open(message);
|
||||
break;
|
||||
case 1:
|
||||
ui::ToastWarning::open(message);
|
||||
break;
|
||||
case 2:
|
||||
ui::ToastError::open(message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SCRIPT_API(void* getImGuiContext) {
|
||||
return ImGui::GetCurrentContext();
|
||||
}
|
||||
|
||||
class ScriptView : public View::Window {
|
||||
public:
|
||||
using DrawFunction = void(*)();
|
||||
ScriptView(const char *icon, const char *name, DrawFunction function) : View::Window(UnlocalizedString(name), icon), m_drawFunction(function) { }
|
||||
void drawContent() override {
|
||||
m_drawFunction();
|
||||
}
|
||||
|
||||
private:
|
||||
DrawFunction m_drawFunction;
|
||||
};
|
||||
|
||||
SCRIPT_API(void registerView, const char *icon, const char *name, void *drawFunction) {
|
||||
ContentRegistry::Views::add<ScriptView>(icon, name, ScriptView::DrawFunction(drawFunction));
|
||||
}
|
||||
|
||||
SCRIPT_API(void addMenuItem, const char *icon, const char *menuName, const char *itemName, void *function) {
|
||||
using MenuFunction = void(*)();
|
||||
ContentRegistry::Interface::addMenuItem({ menuName, itemName }, icon, 9999, Shortcut::None, reinterpret_cast<MenuFunction>(function));
|
||||
}
|
||||
Reference in New Issue
Block a user