Initial re-upload of spice2x-24-08-24

This commit is contained in:
2024-08-28 11:10:34 -04:00
commit caa9e02285
1181 changed files with 380065 additions and 0 deletions

73
script/api/analogs.cpp Normal file
View File

@@ -0,0 +1,73 @@
#include "analogs.h"
#include "external/LuaBridge.h"
#include "games/io.h"
#include "misc/eamuse.h"
#include "launcher/launcher.h"
#include "util/utils.h"
using namespace luabridge;
namespace script::api::analogs {
typedef std::unordered_map<std::string, std::unordered_map<std::string, std::string>> analog_data_t;
static std::vector<Analog> *get_analogs() {
static thread_local std::vector<Analog> *analogs = nullptr;
if (!analogs) {
if (!(analogs = games::get_analogs(eamuse_get_game()))) {
static auto empty = std::vector<Analog>();
return &empty;
}
}
return analogs;
}
auto read() {
analog_data_t ret;
for (auto &analog : *get_analogs()) {
auto &map = ret[analog.getName()];
map["state"] = std::to_string(GameAPI::Analogs::getState(RI_MGR, analog));
map["enabled"] = std::to_string(analog.override_enabled);
}
return ret;
}
void write(analog_data_t data) {
for (auto &[name, map] : data) {
// get state
auto state_it = map.find("state");
if (state_it == map.end()) continue;
try {
float state = std::stof(state_it->second);
// find analog
for (auto &analog : *get_analogs()) {
if (analog.getName() == name) {
analog.override_state = CLAMP(state, 0.f, 1.f);
analog.override_enabled = true;
break;
}
}
} catch (...) {
continue;
}
}
}
void write_reset(const std::string &name) {
for (auto &analog : *get_analogs()) {
if (name.empty() || analog.getName() == name) {
analog.override_enabled = false;
break;
}
}
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("analogs")
.addFunction("read", read)
.addFunction("write", write)
.endNamespace();
}
}

7
script/api/analogs.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::analogs {
void init(lua_State *L);
}

82
script/api/buttons.cpp Normal file
View File

@@ -0,0 +1,82 @@
#include "buttons.h"
#include "external/LuaBridge.h"
#include "games/io.h"
#include "misc/eamuse.h"
#include "launcher/launcher.h"
#include "util/utils.h"
using namespace luabridge;
namespace script::api::buttons {
typedef std::unordered_map<std::string, std::unordered_map<std::string, std::string>> button_data_t;
static std::vector<Button> *get_buttons() {
static thread_local std::vector<Button> *buttons = nullptr;
if (!buttons) {
if (!(buttons = games::get_buttons(eamuse_get_game()))) {
static auto empty = std::vector<Button>();
return &empty;
}
}
return buttons;
}
auto read() {
button_data_t ret;
for (auto &button : *get_buttons()) {
auto &map = ret[button.getName()];
map["state"] = std::to_string(GameAPI::Buttons::getState(RI_MGR, button));
map["enabled"] = std::to_string(button.override_enabled);
}
return ret;
}
void write(button_data_t data) {
for (auto &[name, map] : data) {
// get state
auto state_it = map.find("state");
if (state_it == map.end()) continue;
try {
float state;
if (state_it->second == "true") {
state = 1.f;
} else if (state_it->second == "false") {
state = 0.f;
} else {
state = std::stof(state_it->second);
}
// find button
for (auto &button : *get_buttons()) {
if (button.getName() == name) {
button.override_state = state > 0.f ?
GameAPI::Buttons::BUTTON_PRESSED : GameAPI::Buttons::BUTTON_NOT_PRESSED;
button.override_velocity = CLAMP(state, 0.f, 1.f);
button.override_enabled = true;
break;
}
}
} catch (...) {
continue;
}
}
}
void write_reset(const std::string &name) {
for (auto &button : *get_buttons()) {
if (name.empty() || button.getName() == name) {
button.override_enabled = false;
break;
}
}
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("buttons")
.addFunction("read", read)
.addFunction("write", write)
.endNamespace();
}
}

7
script/api/buttons.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::buttons {
void init(lua_State *n);
}

53
script/api/capture.cpp Normal file
View File

@@ -0,0 +1,53 @@
#include "capture.h"
#include "external/LuaBridge.h"
#include "hooks/graphics/graphics.h"
#include "util/crypt.h"
using namespace luabridge;
namespace script::api::capture {
static thread_local std::vector<uint8_t> CAPTURE_BUFFER;
std::vector<int> get_screens() {
// get screen IDs
std::vector<int> screens;
graphics_screens_get(screens);
return screens;
}
std::string get_jpg(int screen, int quality, int divide) {
CAPTURE_BUFFER.reserve(1024 * 128);
// receive JPEG data
uint64_t timestamp = 0;
int width = 0;
int height = 0;
graphics_capture_trigger(screen);
bool success = graphics_capture_receive_jpeg(screen, [] (uint8_t byte) {
CAPTURE_BUFFER.push_back(byte);
}, true, quality, true, divide, &timestamp, &width, &height);
if (!success) {
return std::string();
}
// encode to base64
auto encoded = crypt::base64_encode(
CAPTURE_BUFFER.data(),
CAPTURE_BUFFER.size());
// clear buffer
CAPTURE_BUFFER.clear();
// return base64
return encoded;
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("capture")
.addFunction("get_screens", get_screens)
.addFunction("get_jpg", get_jpg)
.endNamespace();
}
}

7
script/api/capture.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::capture {
void init(lua_State *n);
}

28
script/api/card.cpp Normal file
View File

@@ -0,0 +1,28 @@
#include "card.h"
#include "external/LuaBridge.h"
#include "util/utils.h"
#include "misc/eamuse.h"
using namespace luabridge;
namespace script::api::card {
void insert(int index, const std::string &card_hex) {
// convert to binary
uint8_t card_bin[8] {};
if (!hex2bin(card_hex.c_str(), card_bin)) {
return;
}
// insert card
eamuse_card_insert(index & 1, card_bin);
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("card")
.addFunction("insert", insert)
.endNamespace();
}
}

7
script/api/card.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::card {
void init(lua_State *n);
}

38
script/api/coin.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include "coin.h"
#include "external/LuaBridge.h"
#include "misc/eamuse.h"
using namespace luabridge;
namespace script::api::coin {
int get() {
return eamuse_coin_get_stock();
}
void set(int amount) {
eamuse_coin_set_stock(amount);
}
void insert(int amount) {
if (amount == 1) {
eamuse_coin_add();
} else if (amount > 1) {
eamuse_coin_set_stock(eamuse_coin_get_stock() + amount);
}
}
bool blocker_get() {
return eamuse_coin_get_block();
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("coin")
.addFunction("get", get)
.addFunction("set", set)
.addFunction("insert", insert)
.addFunction("blocker_get", blocker_get)
.endNamespace();
}
}

7
script/api/coin.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::coin {
void init(lua_State *n);
}

121
script/api/control.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include "control.h"
#include <csignal>
#include <cstring>
#include "external/LuaBridge.h"
#include "launcher/shutdown.h"
using namespace luabridge;
namespace script::api::control {
struct SignalMapping {
int signum;
const char* name;
};
static SignalMapping SIGNAL_MAPPINGS[] = {
{ SIGABRT, "SIGABRT" },
{ SIGFPE, "SIGFPE" },
{ SIGILL, "SIGILL" },
{ SIGINT, "SIGINT" },
{ SIGSEGV, "SIGSEGV" },
{ SIGTERM, "SIGTERM" },
};
static inline bool acquire_shutdown_privs() {
// check if already acquired
static bool acquired = false;
if (acquired)
return true;
// get process token
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return false;
// get the LUID for the shutdown privilege
TOKEN_PRIVILEGES tkp;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// get the shutdown privilege for this process
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
// check for error
bool success = GetLastError() == ERROR_SUCCESS;
if (success)
acquired = true;
return success;
}
void raise(const std::string &signal) {
// get signal
int signal_val = -1;
for (auto mapping : SIGNAL_MAPPINGS) {
if (_stricmp(mapping.name, signal.c_str()) == 0) {
signal_val = mapping.signum;
break;
}
}
// raise if found
if (signal_val >= 0) {
::raise(signal_val);
}
}
void exit(int code) {
launcher::shutdown(code);
}
void restart() {
launcher::restart();
}
bool shutdown() {
// acquire privileges
if (!acquire_shutdown_privs())
return false;
// exit windows
if (!ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,
SHTDN_REASON_MAJOR_APPLICATION |
SHTDN_REASON_MINOR_MAINTENANCE))
return false;
// terminate this process
launcher::shutdown(0);
return true;
}
bool reboot() {
// acquire privileges
if (!acquire_shutdown_privs())
return false;
// exit windows
if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE,
SHTDN_REASON_MAJOR_APPLICATION |
SHTDN_REASON_MINOR_MAINTENANCE))
return false;
// terminate this process
launcher::shutdown(0);
return true;
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("control")
.addFunction("raise", raise)
.addFunction("exit", exit)
.addFunction("restart", restart)
.addFunction("shutdown", shutdown)
.addFunction("reboot", reboot)
.endNamespace();
}
}

7
script/api/control.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::control {
void init(lua_State *n);
}

21
script/api/drs.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include "drs.h"
#include "external/LuaBridge.h"
#include "games/drs/drs.h"
#include "util/utils.h"
using namespace luabridge;
namespace script::api::drs {
std::string tapeled_get() {
const size_t len = sizeof(games::drs::DRS_TAPELED);
return bin2hex((uint8_t*) games::drs::DRS_TAPELED, len);
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("drs")
.addFunction("tapeled_get", tapeled_get)
.endNamespace();
}
}

7
script/api/drs.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::drs {
void init(lua_State *n);
}

46
script/api/iidx.cpp Normal file
View File

@@ -0,0 +1,46 @@
#include "iidx.h"
#include <cstring>
#include "external/LuaBridge.h"
#include "games/iidx/iidx.h"
using namespace luabridge;
namespace script::api::iidx {
// settings
static const size_t TICKER_SIZE = 9;
std::string ticker_get() {
std::lock_guard<std::mutex> lock(games::iidx::IIDX_LED_TICKER_LOCK);
return std::string(games::iidx::IIDXIO_LED_TICKER);
}
void ticker_set(const std::string &text) {
// lock
std::lock_guard<std::mutex> ticker_lock(games::iidx::IIDX_LED_TICKER_LOCK);
// set to read only
games::iidx::IIDXIO_LED_TICKER_READONLY = true;
// set led ticker
memset(games::iidx::IIDXIO_LED_TICKER, ' ', TICKER_SIZE);
for (size_t i = 0; i < TICKER_SIZE && i < text.size(); i++) {
games::iidx::IIDXIO_LED_TICKER[i] = text[i];
}
}
void ticker_reset() {
std::lock_guard<std::mutex> ticker_lock(games::iidx::IIDX_LED_TICKER_LOCK);
games::iidx::IIDXIO_LED_TICKER_READONLY = false;
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("iidx")
.addFunction("ticker_get", ticker_get)
.addFunction("ticker_set", ticker_set)
.addFunction("ticker_reset", ticker_reset)
.endNamespace();
}
}

7
script/api/iidx.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::iidx {
void init(lua_State *n);
}

68
script/api/info.cpp Normal file
View File

@@ -0,0 +1,68 @@
#include "coin.h"
#include "external/LuaBridge.h"
#include "avs/game.h"
#include "avs/ea3.h"
#include "build/defs.h"
#include "util/memutils.h"
#include "util/utils.h"
using namespace luabridge;
namespace script::api::info {
auto avs() {
std::unordered_map<std::string, std::string> map;
map["model"] = std::string(avs::game::MODEL);
map["dest"] = std::string(avs::game::DEST);
map["spec"] = std::string(avs::game::SPEC);
map["rev"] = std::string(avs::game::REV);
map["ext"] = std::string(avs::game::EXT);
map["services"] = avs::ea3::EA3_BOOT_URL;
return map;
}
auto launcher() {
// build args
std::string args;
for (int count = 0; count < LAUNCHER_ARGC; count++) {
auto arg = LAUNCHER_ARGV[count];
if (count > 0) args += " ";
args += arg;
}
// get system time
auto t_now = std::time(nullptr);
auto tm_now = *std::gmtime(&t_now);
auto tm_str = to_string(std::put_time(&tm_now, "%Y-%m-%dT%H:%M:%SZ"));
// build info
std::unordered_map<std::string, std::string> map;
map["version"] = VERSION_STRING;
map["compile_date"] = __DATE__;
map["compile_time"] = __TIME__;
map["system_time"] = tm_str.c_str();
map["args"] = args;
return map;
}
auto memory() {
std::unordered_map<std::string, std::string> map;
map["mem_total"] = memutils::mem_total();
map["mem_total_used"] = memutils::mem_total_used();
map["mem_used"] = memutils::mem_used();
map["vmem_total"] = memutils::vmem_total();
map["vmem_total_used"] = memutils::vmem_total_used();
map["vmem_used"] = memutils::vmem_used();
return map;
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("info")
.addFunction("avs", avs)
.addFunction("launcher", launcher)
.addFunction("memory", memory)
.endNamespace();
}
}

7
script/api/info.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::info {
void init(lua_State *n);
}

114
script/api/keypads.cpp Normal file
View File

@@ -0,0 +1,114 @@
#include "keypads.h"
#include "external/LuaBridge.h"
#include "avs/game.h"
#include "misc/eamuse.h"
using namespace luabridge;
namespace script::api::keypads {
struct KeypadMapping {
char character;
uint16_t state;
};
static KeypadMapping KEYPAD_MAPPINGS[] = {
{ '0', 1 << EAM_IO_KEYPAD_0 },
{ '1', 1 << EAM_IO_KEYPAD_1 },
{ '2', 1 << EAM_IO_KEYPAD_2 },
{ '3', 1 << EAM_IO_KEYPAD_3 },
{ '4', 1 << EAM_IO_KEYPAD_4 },
{ '5', 1 << EAM_IO_KEYPAD_5 },
{ '6', 1 << EAM_IO_KEYPAD_6 },
{ '7', 1 << EAM_IO_KEYPAD_7 },
{ '8', 1 << EAM_IO_KEYPAD_8 },
{ '9', 1 << EAM_IO_KEYPAD_9 },
{ 'A', 1 << EAM_IO_KEYPAD_00 },
{ 'D', 1 << EAM_IO_KEYPAD_DECIMAL },
};
void write(uint32_t keypad, const std::string &input) {
// process all chars
for (auto c : input) {
uint16_t state = 0;
// find mapping
bool mapping_found = false;
for (auto &mapping : KEYPAD_MAPPINGS) {
if (_strnicmp(&mapping.character, &c, 1) == 0) {
state |= mapping.state;
mapping_found = true;
break;
}
}
// check for error
if (!mapping_found) {
continue;
}
/*
* Write input to keypad.
* We try to make sure it was accepted by waiting a bit more than two frames.
*/
DWORD sleep_time = 70;
if (avs::game::is_model("MDX")) {
// cuz fuck DDR
sleep_time = 150;
}
// set
eamuse_set_keypad_overrides(keypad, state);
Sleep(sleep_time);
// unset
eamuse_set_keypad_overrides(keypad, 0);
Sleep(sleep_time);
}
}
void set(uint32_t keypad, const std::string &keys) {
// iterate params
uint16_t state = 0;
for (auto key : keys) {
// find mapping
for (auto &mapping : KEYPAD_MAPPINGS) {
if (_strnicmp(&mapping.character, &key, 1) == 0) {
state |= mapping.state;
break;
}
}
}
// set keypad state
eamuse_set_keypad_overrides(keypad, state);
}
std::string get(uint32_t keypad) {
// get keypad state
auto state = eamuse_get_keypad_state(keypad);
// add keys
std::string res = "";
for (auto &mapping : KEYPAD_MAPPINGS) {
if (state & mapping.state) {
res += std::to_string(mapping.character);
}
}
return res;
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("keypads")
.addFunction("write", write)
.addFunction("set", set)
.addFunction("get", get)
.endNamespace();
}
}

7
script/api/keypads.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::keypads {
void init(lua_State *n);
}

28
script/api/lcd.cpp Normal file
View File

@@ -0,0 +1,28 @@
#include "lcd.h"
#include "external/LuaBridge.h"
#include "games/shared/lcdhandle.h"
using namespace luabridge;
namespace script::api::lcd {
auto info() {
std::unordered_map<std::string, std::string> map;
map["enabled"] = std::to_string(games::shared::LCD_ENABLED);
map["csm"] = games::shared::LCD_CSM;
map["bri"] = std::to_string(games::shared::LCD_BRI);
map["con"] = std::to_string(games::shared::LCD_CON);
map["bl"] = std::to_string(games::shared::LCD_BL);
map["red"] = std::to_string(games::shared::LCD_RED);
map["green"] = std::to_string(games::shared::LCD_GREEN);
map["blue"] = std::to_string(games::shared::LCD_BLUE);
return map;
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("lcd")
.addFunction("info", info)
.endNamespace();
}
}

7
script/api/lcd.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::lcd {
void init(lua_State *n);
}

104
script/api/lights.cpp Normal file
View File

@@ -0,0 +1,104 @@
#include "lights.h"
#include <cfg/configurator.h>
#include "external/LuaBridge.h"
#include "games/io.h"
#include "misc/eamuse.h"
#include "launcher/launcher.h"
#include "util/utils.h"
#include "rawinput/rawinput.h"
using namespace luabridge;
namespace script::api::lights {
typedef std::unordered_map<std::string, std::unordered_map<std::string, std::string>> light_data_t;
static std::vector<Light> *get_lights() {
static thread_local std::vector<Light> *lights = nullptr;
if (!lights) {
if (!(lights = games::get_lights(eamuse_get_game()))) {
static auto empty = std::vector<Light>();
return &empty;
}
}
return lights;
}
auto read() {
light_data_t ret;
for (auto &light : *get_lights()) {
auto &map = ret[light.getName()];
map["state"] = std::to_string(GameAPI::Lights::readLight(RI_MGR, light));
map["enabled"] = std::to_string(light.override_enabled);
}
return ret;
}
auto read_original() {
light_data_t ret;
for (auto &light : *get_lights()) {
auto &map = ret[light.getName()];
map["state"] = std::to_string(light.last_state);
map["enabled"] = std::to_string(light.override_enabled);
}
return ret;
}
void write(light_data_t data) {
for (auto &[name, map] : data) {
// get state
auto state_it = map.find("state");
if (state_it == map.end()) continue;
try {
float state = std::stof(state_it->second);
// find light
for (auto &light : *get_lights()) {
if (light.getName() == name) {
light.override_state = CLAMP(state, 0.f, 1.f);
light.override_enabled = true;
if (cfg::CONFIGURATOR_STANDALONE) {
GameAPI::Lights::writeLight(RI_MGR, light, state);
}
break;
}
}
} catch (...) {
continue;
}
}
}
void write_reset(const std::string &name) {
for (auto &light : *get_lights()) {
if (name.empty() || light.getName() == name) {
if (light.override_enabled) {
if (cfg::CONFIGURATOR_STANDALONE) {
GameAPI::Lights::writeLight(RI_MGR, light, light.last_state);
}
light.override_enabled = false;
}
break;
}
}
}
void update() {
RI_MGR->devices_flush_output();
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("lights")
.addFunction("read", read)
.addFunction("read_original", read_original)
.addFunction("write", write)
.addFunction("write_reset", write_reset)
.addFunction("update", update)
.endNamespace();
}
}

7
script/api/lights.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::lights {
void init(lua_State *n);
}

143
script/api/memory.cpp Normal file
View File

@@ -0,0 +1,143 @@
#include "memory.h"
#include "external/LuaBridge.h"
#include "util/fileutils.h"
#include "util/libutils.h"
#include "util/memutils.h"
#include "util/sigscan.h"
#include "util/utils.h"
using namespace luabridge;
namespace script::api::memory {
std::string read(const std::string &dll_name, intptr_t offset, uint64_t size) {
auto dll_path = MODULE_PATH / dll_name;
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return std::string();
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return std::string();
}
// convert offset to RVA
offset = libutils::offset2rva(dll_path, offset);
if (offset == ~0) {
return std::string();
}
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(MODULEINFO))) {
return std::string();
}
// check bounds
auto max = offset + size;
if ((size_t) max >= (size_t) module_info.lpBaseOfDll + module_info.SizeOfImage) {
return std::string();
}
// read memory to hex (without virtual protect)
return bin2hex((uint8_t*) module_info.lpBaseOfDll + offset, size);
}
bool write(const std::string &dll_name, const std::string &data, intptr_t offset) {
auto dll_path = MODULE_PATH / dll_name;
// convert data to bin
size_t data_bin_size = data.length() / 2;
auto data_bin = std::make_unique<uint8_t[]>(data_bin_size);
hex2bin(data.c_str(), data_bin.get());
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return false;
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return false;
}
// convert offset to RVA
offset = libutils::offset2rva(dll_path, offset);
if (offset == ~0) {
return false;
}
// get module information
MODULEINFO module_info {};
if (!GetModuleInformation(GetCurrentProcess(), module, &module_info, sizeof(MODULEINFO))) {
return false;
}
// check bounds
if (offset + data_bin_size >= (size_t) module_info.lpBaseOfDll + module_info.SizeOfImage) {
return false;
}
auto data_pos = reinterpret_cast<uint8_t *>(module_info.lpBaseOfDll) + offset;
// replace data
memutils::VProtectGuard guard(data_pos, data_bin_size);
memcpy(data_pos, data_bin.get(), data_bin_size);
return true;
}
uint64_t signature(const std::string &dll_name, const std::string &signature,
const std::string &replacement, uint64_t offset, uint64_t usage) {
auto dll_path = MODULE_PATH / dll_name;
// check if file exists in modules
if (!fileutils::file_exists(dll_path)) {
return 0;
}
// get module
auto module = libutils::try_module(dll_name);
if (!module) {
return 0;
}
// execute
auto result = replace_pattern(
module,
signature,
replacement,
offset,
usage
);
// check result
if (!result) {
return 0;
}
// convert to offset
auto rva = result - reinterpret_cast<intptr_t>(module);
result = libutils::rva2offset(dll_path, rva);
if (result == -1) {
return 0;
}
// success
return result;
}
void init(lua_State *L, bool sandbox) {
auto n = getGlobalNamespace(L).beginNamespace("memory")
.addFunction("read", read);
if (!sandbox) {
n.addFunction("write", write)
.addFunction("signature", signature)
.endNamespace();
} else {
n.endNamespace();
}
}
}

7
script/api/memory.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::memory {
void init(lua_State *n, bool sandbox);
}

67
script/api/touch.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include "touch.h"
#include "external/LuaBridge.h"
#include "touch/touch.h"
using namespace luabridge;
namespace script::api::touch {
typedef std::vector<std::unordered_map<std::string, std::string>> touch_data_t;
touch_data_t read() {
// get touch points
std::vector<TouchPoint> touch_points;
touch_get_points(touch_points);
// add state for each touch point
touch_data_t ret;
for (auto &touch : touch_points) {
auto &state = ret.emplace_back();
state["id"] = std::to_string(touch.id);
state["x"] = std::to_string(touch.x);
state["y"] = std::to_string(touch.y);
state["mouse"] = std::to_string(touch.mouse);
}
return ret;
}
void write(touch_data_t data) {
// get all touch points
std::vector<TouchPoint> touch_points;
for (auto &state : data) {
try {
uint32_t touch_id = std::stoul(state["id"]);
int32_t touch_x = std::stol(state["x"]);
int32_t touch_y = std::stol(state["y"]);
TouchPoint tp {
.id = touch_id,
.x = touch_x,
.y = touch_y,
.mouse = false,
};
touch_points.emplace_back(tp);
} catch (...) {
continue;
}
}
// apply touch points
touch_write_points(&touch_points);
}
void write_reset(uint32_t id) {
std::vector<DWORD> touch_point_ids;
touch_point_ids.push_back(id);
touch_remove_points(&touch_point_ids);
}
void init(lua_State *L) {
getGlobalNamespace(L)
.beginNamespace("touch")
.addFunction("read", read)
.addFunction("write", write)
.addFunction("write_reset", write_reset)
.endNamespace();
}
}

7
script/api/touch.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <lua.hpp>
namespace script::api::touch {
void init(lua_State *n);
}