mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-27 15:44:12 +08:00
fix
1 Update winsharedutils.py 1 1 1 Update texthook.py Update static_data.json
This commit is contained in:
parent
6cec2a00bc
commit
072cf92917
@ -551,8 +551,8 @@ class WebivewWidget(QWidget):
|
||||
|
||||
self.webview = _Webview(debug=debug, window=int(self.winId()))
|
||||
|
||||
# self.webview.bind("__on_load", self._on_load)
|
||||
# self.webview.init("""window.__on_load(window.location.href)""")
|
||||
self.webview.bind("__on_load", self._on_load)
|
||||
self.webview.init("""window.__on_load(window.location.href)""")
|
||||
|
||||
def _on_load(self, _, href):
|
||||
self.on_load.emit(json.loads(href)[0])
|
||||
|
@ -1,7 +1,6 @@
|
||||
from libcurl import *
|
||||
import winsharedutils
|
||||
import threading
|
||||
from ctypes import c_long, cast, pointer, POINTER
|
||||
import threading, functools, queue
|
||||
from ctypes import c_long, cast, pointer, POINTER, c_char
|
||||
from network.requests_common import *
|
||||
from traceback import print_exc
|
||||
|
||||
@ -25,9 +24,8 @@ class Response(ResponseBase):
|
||||
downloadeddata = b""
|
||||
canend = False
|
||||
allbs = 0
|
||||
while not (self.cqueue.empty() and canend):
|
||||
buff = self.cqueue.get()
|
||||
|
||||
while not (self.queue.empty() and canend):
|
||||
buff = self.queue.get()
|
||||
if buff is None:
|
||||
canend = True
|
||||
continue
|
||||
@ -174,23 +172,33 @@ class Session(Sessionbase):
|
||||
resp = Response()
|
||||
|
||||
if stream:
|
||||
resp.cqueue = winsharedutils.lockedqueue()
|
||||
curl_easy_setopt(curl, CURLoption.CURLOPT_WRITEDATA, resp.cqueue.ptr)
|
||||
|
||||
def WriteMemoryCallback(queue, contents, size, nmemb, userp):
|
||||
realsize = size * nmemb
|
||||
queue.put(cast(contents, POINTER(c_char))[:realsize])
|
||||
return realsize
|
||||
|
||||
_content = []
|
||||
_headers = []
|
||||
resp.queue = queue.Queue()
|
||||
headerqueue = queue.Queue()
|
||||
resp.keepref1 = WRITEFUNCTION(
|
||||
functools.partial(WriteMemoryCallback, resp.queue)
|
||||
)
|
||||
resp.keepref2 = WRITEFUNCTION(
|
||||
functools.partial(WriteMemoryCallback, headerqueue)
|
||||
)
|
||||
curl_easy_setopt(
|
||||
curl,
|
||||
CURLoption.CURLOPT_WRITEFUNCTION,
|
||||
winsharedutils.WriteMemoryToQueue,
|
||||
cast(resp.keepref1, c_void_p).value,
|
||||
)
|
||||
|
||||
headercqueue = winsharedutils.lockedqueue()
|
||||
curl_easy_setopt(curl, CURLoption.CURLOPT_HEADERDATA, headercqueue.ptr)
|
||||
curl_easy_setopt(
|
||||
curl,
|
||||
CURLoption.CURLOPT_HEADERFUNCTION,
|
||||
winsharedutils.WriteMemoryToQueue,
|
||||
cast(resp.keepref2, c_void_p).value,
|
||||
)
|
||||
headerok = threading.Lock()
|
||||
headerok.acquire()
|
||||
|
||||
def ___perform():
|
||||
try:
|
||||
@ -198,31 +206,22 @@ class Session(Sessionbase):
|
||||
except:
|
||||
print_exc()
|
||||
self.raise_for_status()
|
||||
headercqueue.pushnone()
|
||||
headerok.acquire()
|
||||
headerqueue.put(None)
|
||||
curl_easy_reset(curl)
|
||||
resp.cqueue.pushnone()
|
||||
resp.queue.put(None)
|
||||
|
||||
threading.Thread(target=___perform, daemon=True).start()
|
||||
|
||||
headerb = b""
|
||||
CLRFnum = 1 + int(bool((proxy)))
|
||||
while True:
|
||||
_headerb = headercqueue.get()
|
||||
_headerb = headerqueue.get()
|
||||
if _headerb is None:
|
||||
self.raise_for_status()
|
||||
headerb += _headerb
|
||||
if _headerb == b"\r\n":
|
||||
# 使用代理时:
|
||||
# b'HTTP/1.1 200 Connection established\r\n'
|
||||
# b'\r\n'
|
||||
CLRFnum -= 1
|
||||
if CLRFnum == 0:
|
||||
break
|
||||
else:
|
||||
headerb = b""
|
||||
break
|
||||
resp.headers = self._update_header_cookie(headerb.decode("utf8"))
|
||||
headerok.release()
|
||||
|
||||
if proxy:
|
||||
resp.status_code = int(
|
||||
headerb.decode("utf8").split("\r\n")[0].split(" ")[1]
|
||||
@ -230,24 +229,35 @@ class Session(Sessionbase):
|
||||
else:
|
||||
resp.status_code = self._getStatusCode(curl)
|
||||
else:
|
||||
_content = winsharedutils.MemoryStruct()
|
||||
curl_easy_setopt(curl, CURLoption.CURLOPT_WRITEDATA, pointer(_content))
|
||||
|
||||
def WriteMemoryCallback(saver, contents, size, nmemb, userp):
|
||||
realsize = size * nmemb
|
||||
saver.append(cast(contents, POINTER(c_char))[:realsize])
|
||||
return realsize
|
||||
|
||||
_content = []
|
||||
_headers = []
|
||||
resp.keepref1 = WRITEFUNCTION(
|
||||
functools.partial(WriteMemoryCallback, _content)
|
||||
)
|
||||
resp.keepref2 = WRITEFUNCTION(
|
||||
functools.partial(WriteMemoryCallback, _headers)
|
||||
)
|
||||
|
||||
curl_easy_setopt(
|
||||
curl,
|
||||
CURLoption.CURLOPT_WRITEFUNCTION,
|
||||
winsharedutils.WriteMemoryCallback,
|
||||
cast(resp.keepref1, c_void_p).value,
|
||||
)
|
||||
_headers = winsharedutils.MemoryStruct()
|
||||
curl_easy_setopt(curl, CURLoption.CURLOPT_HEADERDATA, pointer(_headers))
|
||||
curl_easy_setopt(
|
||||
curl,
|
||||
CURLoption.CURLOPT_HEADERFUNCTION,
|
||||
winsharedutils.WriteMemoryCallback,
|
||||
cast(resp.keepref2, c_void_p).value,
|
||||
)
|
||||
# curl_easy_setopt(curl,CURLoption.CURLOPT_HEADERFUNCTION,cast(WRITEFUNCTION(WRITEFUNCTIONXX),c_void_p))
|
||||
|
||||
self._perform(curl)
|
||||
resp.content = _content.get()
|
||||
resp.headers = self._update_header_cookie(_headers.get().decode("utf8"))
|
||||
resp.content = b"".join(_content)
|
||||
resp.headers = self._update_header_cookie(b"".join(_headers).decode("utf8"))
|
||||
resp.status_code = self._getStatusCode(curl)
|
||||
curl_easy_reset(curl)
|
||||
resp.last_error = self.last_error
|
||||
|
@ -12,11 +12,13 @@ from myutils.hwnd import injectdll
|
||||
from myutils.wrapper import threader
|
||||
from ctypes import (
|
||||
CDLL,
|
||||
CFUNCTYPE,
|
||||
c_bool,
|
||||
POINTER,
|
||||
Structure,
|
||||
c_int,
|
||||
pointer,
|
||||
c_char_p,
|
||||
c_wchar_p,
|
||||
c_uint64,
|
||||
sizeof,
|
||||
@ -71,21 +73,13 @@ class SearchParam(Structure):
|
||||
]
|
||||
|
||||
|
||||
class Message(Structure):
|
||||
_fields_ = [
|
||||
("read", c_bool),
|
||||
("type", c_int),
|
||||
("pid", DWORD),
|
||||
("hn", c_char * HOOK_NAME_SIZE),
|
||||
("hc", c_wchar * HOOKCODE_LEN),
|
||||
("tp", ThreadParam),
|
||||
("stringptr", c_void_p),
|
||||
("addr", c_uint64),
|
||||
]
|
||||
|
||||
|
||||
class simplehooks(Structure):
|
||||
_fields_ = [("hookcode", c_wchar * 500), ("text", c_void_p)]
|
||||
findhookcallback_t = CFUNCTYPE(None, c_wchar_p, c_wchar_p)
|
||||
ProcessEvent = CFUNCTYPE(None, DWORD)
|
||||
ThreadEvent = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam)
|
||||
OutputCallback = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam, c_wchar_p)
|
||||
ConsoleHandler = CFUNCTYPE(None, c_wchar_p)
|
||||
HookInsertHandler = CFUNCTYPE(None, c_uint64, c_wchar_p)
|
||||
EmbedCallback = CFUNCTYPE(None, c_wchar_p, ThreadParam)
|
||||
|
||||
|
||||
class texthook(basetext):
|
||||
@ -96,7 +90,7 @@ class texthook(basetext):
|
||||
autostarthookcode = []
|
||||
if needinserthookcode is None:
|
||||
needinserthookcode = []
|
||||
|
||||
self.keepref = []
|
||||
self.newline = Queue()
|
||||
self.newline_delaywait = Queue()
|
||||
self.is64bit = Is64bit(pids[0])
|
||||
@ -147,7 +141,16 @@ class texthook(basetext):
|
||||
self.Luna_Settings = LunaHost.Luna_Settings
|
||||
self.Luna_Settings.argtypes = c_int, c_bool, c_int, c_int
|
||||
self.Luna_Start = LunaHost.Luna_Start
|
||||
self.Luna_Start.argtypes = (POINTER(HANDLE),)
|
||||
self.Luna_Start.argtypes = (
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
c_void_p,
|
||||
)
|
||||
self.Luna_Inject = LunaHost.Luna_Inject
|
||||
self.Luna_Inject.argtypes = DWORD, LPCWSTR
|
||||
self.Luna_CreatePipeAndCheck = LunaHost.Luna_CreatePipeAndCheck
|
||||
@ -160,17 +163,12 @@ class texthook(basetext):
|
||||
self.Luna_RemoveHook.argtypes = DWORD, c_uint64
|
||||
self.Luna_Detach = LunaHost.Luna_Detach
|
||||
self.Luna_Detach.argtypes = (DWORD,)
|
||||
self.Luna_cfree = LunaHost.Luna_cfree
|
||||
self.Luna_cfree.argtypes = (c_void_p,)
|
||||
self.Luna_FindHooks = LunaHost.Luna_FindHooks
|
||||
self.Luna_FindHooks.argtypes = (
|
||||
DWORD,
|
||||
SearchParam,
|
||||
POINTER(HANDLE),
|
||||
POINTER(POINTER(c_int)),
|
||||
c_void_p,
|
||||
)
|
||||
self.Luna_FindHooks_waiting = LunaHost.Luna_FindHooks_waiting
|
||||
self.Luna_FindHooks_waiting.argtypes = (POINTER(c_int),)
|
||||
self.Luna_EmbedSettings = LunaHost.Luna_EmbedSettings
|
||||
self.Luna_EmbedSettings.argtypes = (
|
||||
DWORD,
|
||||
@ -190,10 +188,24 @@ class texthook(basetext):
|
||||
self.Luna_embedcallback = LunaHost.Luna_embedcallback
|
||||
self.Luna_embedcallback.argtypes = DWORD, LPCWSTR, LPCWSTR
|
||||
|
||||
def Luna_Startup(self):
|
||||
procs = [
|
||||
ProcessEvent(self.onprocconnect),
|
||||
ProcessEvent(self.connectedpids.remove),
|
||||
ThreadEvent(self.onnewhook),
|
||||
ThreadEvent(lambda _1, _2, tp: self.onremovehook(tp)),
|
||||
OutputCallback(self.handle_output),
|
||||
ConsoleHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit),
|
||||
HookInsertHandler(self.newhookinsert),
|
||||
EmbedCallback(self.getembedtext),
|
||||
]
|
||||
self.keepref += procs
|
||||
ptrs = [cast(_, c_void_p).value for _ in procs]
|
||||
self.Luna_Start(*ptrs)
|
||||
|
||||
def start(self):
|
||||
self.hRead = HANDLE()
|
||||
self.Luna_Start(pointer(self.hRead))
|
||||
self.solveeventthread()
|
||||
|
||||
self.Luna_Startup()
|
||||
self.setsettings()
|
||||
|
||||
injectpids = []
|
||||
@ -216,7 +228,6 @@ class texthook(basetext):
|
||||
# subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll))
|
||||
injectdll(injectpids, injecter, dll)
|
||||
|
||||
@threader
|
||||
def onprocconnect(self, pid):
|
||||
self.connectedpids.append(pid)
|
||||
time.sleep(savehook_new_data[self.pname]["inserthooktimeout"] / 1000)
|
||||
@ -225,45 +236,6 @@ class texthook(basetext):
|
||||
self.showgamename()
|
||||
self.flashembedsettings(pid)
|
||||
|
||||
@threader
|
||||
def solveeventthread(self):
|
||||
while self.ending == False:
|
||||
message = windows.ReadFile(self.hRead, sizeof(Message))
|
||||
if len(message) != sizeof(Message):
|
||||
break
|
||||
message = Message.from_buffer_copy(message)
|
||||
_type = message.type
|
||||
if _type in [0, 1]:
|
||||
pid = message.pid
|
||||
if _type == 0:
|
||||
self.onprocconnect(pid)
|
||||
elif _type == 1:
|
||||
self.connectedpids.remove(pid)
|
||||
elif _type in [2, 3]:
|
||||
if _type == 2:
|
||||
self.onnewhook(message.hc, message.hn, message.tp)
|
||||
elif _type == 3:
|
||||
self.onremovehook(message.tp)
|
||||
elif _type == 4:
|
||||
self.handle_output(
|
||||
message.hc,
|
||||
message.hn,
|
||||
message.tp,
|
||||
cast(message.stringptr, c_wchar_p).value,
|
||||
)
|
||||
elif _type == 5:
|
||||
gobject.baseobject.hookselectdialog.sysmessagesignal.emit(
|
||||
cast(message.stringptr, c_wchar_p).value
|
||||
)
|
||||
elif _type == 6:
|
||||
self.newhookinsert(
|
||||
message.addr, cast(message.stringptr, c_wchar_p).value
|
||||
)
|
||||
elif _type == 7:
|
||||
self.getembedtext(cast(message.stringptr, c_wchar_p).value, message.tp)
|
||||
if message.stringptr:
|
||||
self.Luna_cfree(message.stringptr)
|
||||
|
||||
def newhookinsert(self, addr, hcode):
|
||||
for _hc, _addr, _ctx1, _ctx2 in savehook_new_data[self.pname]["embedablehook"]:
|
||||
if hcode == _hc:
|
||||
@ -415,32 +387,24 @@ class texthook(basetext):
|
||||
def findhook(self, usestruct):
|
||||
savefound = {}
|
||||
pids = self.connectedpids.copy()
|
||||
cntref = []
|
||||
|
||||
headers = {}
|
||||
waiters = {}
|
||||
def __callback(cntref, hcode, text):
|
||||
if hcode not in savefound:
|
||||
savefound[hcode] = []
|
||||
savefound[hcode].append(text)
|
||||
cntref.append(0)
|
||||
|
||||
_callback = findhookcallback_t(functools.partial(__callback, cntref))
|
||||
self.keepref.append(_callback)
|
||||
for pid in pids:
|
||||
headers[pid] = HANDLE()
|
||||
count = POINTER(c_int)()
|
||||
waiters[pid] = count
|
||||
self.Luna_FindHooks(pid, usestruct, pointer(headers[pid]), pointer(count))
|
||||
self.Luna_FindHooks(pid, usestruct, cast(_callback, c_void_p).value)
|
||||
|
||||
def ReadThread(hread):
|
||||
while True:
|
||||
message = windows.ReadFile(hread, sizeof(simplehooks))
|
||||
if len(message) != sizeof(simplehooks):
|
||||
break
|
||||
message = simplehooks.from_buffer_copy(message)
|
||||
hc = message.hookcode
|
||||
text = cast(message.text, c_wchar_p).value
|
||||
if hc not in savefound:
|
||||
savefound[hc] = []
|
||||
savefound[hc].append(text)
|
||||
self.Luna_cfree(message.text)
|
||||
windows.CloseHandle(hread)
|
||||
|
||||
threading.Thread(target=ReadThread, args=(headers[pid],)).start()
|
||||
for pid in pids:
|
||||
self.Luna_FindHooks_waiting(waiters[pid])
|
||||
while True:
|
||||
lastsize = len(cntref)
|
||||
time.sleep(2)
|
||||
if lastsize == len(cntref) and lastsize != 0:
|
||||
break
|
||||
gobject.baseobject.hookselectdialog.getfoundhooksignal.emit(savefound)
|
||||
|
||||
def inserthook(self, hookcode):
|
||||
|
@ -238,65 +238,10 @@ def extracticon2data(fname):
|
||||
return None
|
||||
|
||||
|
||||
WriteMemoryCallback = utilsdll.WriteMemoryCallback
|
||||
c_free = utilsdll.c_free
|
||||
c_free.argtypes = (c_void_p,)
|
||||
|
||||
|
||||
class MemoryStruct(Structure):
|
||||
_fields_ = [("memory", c_void_p), ("size", c_size_t)]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.memory = 0
|
||||
self.size = 0
|
||||
|
||||
def __del__(self):
|
||||
if self.memory:
|
||||
c_free(self.memory)
|
||||
|
||||
def get(self):
|
||||
return cast(self.memory, POINTER(c_char))[: self.size]
|
||||
|
||||
|
||||
WriteMemoryToQueue = utilsdll.WriteMemoryToQueue
|
||||
lockedqueuecreate = utilsdll.lockedqueuecreate
|
||||
lockedqueuecreate.restype = c_void_p
|
||||
lockedqueuefree = utilsdll.lockedqueuefree
|
||||
lockedqueuefree.argtypes = (c_void_p,)
|
||||
lockedqueueget = utilsdll.lockedqueueget
|
||||
lockedqueueget.argtypes = c_void_p, POINTER(c_size_t)
|
||||
lockedqueueget.restype = c_void_p
|
||||
lockedqueuepush = utilsdll.lockedqueuepush
|
||||
lockedqueuepush.argtypes = c_void_p, c_size_t, c_void_p
|
||||
lockedqueueempty = utilsdll.lockedqueueempty
|
||||
lockedqueueempty.argtypes = (c_void_p,)
|
||||
lockedqueueempty.restype = c_bool
|
||||
|
||||
|
||||
class lockedqueue:
|
||||
def __init__(self) -> None:
|
||||
self.ptr = lockedqueuecreate()
|
||||
|
||||
def __del__(self):
|
||||
lockedqueuefree(self.ptr)
|
||||
|
||||
def get(self):
|
||||
sz = c_size_t()
|
||||
dataptr = lockedqueueget(self.ptr, pointer(sz))
|
||||
data = cast(dataptr, POINTER(c_char))[: sz.value]
|
||||
c_free(dataptr)
|
||||
if sz.value == 0:
|
||||
return None
|
||||
return data
|
||||
|
||||
def pushnone(self):
|
||||
lockedqueuepush(self.ptr, 0, b"\0")
|
||||
|
||||
def empty(self):
|
||||
return lockedqueueempty(self.ptr)
|
||||
|
||||
|
||||
_queryversion = utilsdll.queryversion
|
||||
_queryversion.restype = c_bool
|
||||
_queryversion.argtypes = (
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version":"v2.46.2",
|
||||
"version":"v2.47.0",
|
||||
"themes":{
|
||||
"dark":[
|
||||
{"file":"dark1.qss","name":"PyQtDarkTheme"},
|
||||
|
@ -1,6 +1,6 @@
|
||||
PyQt5==5.15.10
|
||||
PyQt5-Qt5==5.15.2
|
||||
webviewpy==1.0.4
|
||||
webviewpy==1.0.5
|
||||
nuitka==2.0.5
|
||||
imageio
|
||||
pefile
|
@ -102,36 +102,33 @@ struct ThreadParam
|
||||
uint64_t ctx; // The context of the hook: by default the first value on stack, usually the return address
|
||||
uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook
|
||||
};
|
||||
struct messagelist
|
||||
{
|
||||
bool read;
|
||||
int type;
|
||||
DWORD pid;
|
||||
char name[HOOK_NAME_SIZE];
|
||||
wchar_t hookcode[HOOKCODE_LEN];
|
||||
ThreadParam tp;
|
||||
wchar_t *stringptr;
|
||||
uint64_t addr;
|
||||
};
|
||||
|
||||
typedef void (*ProcessEvent)(DWORD);
|
||||
typedef void (*ThreadEvent)(wchar_t *, char *, ThreadParam);
|
||||
typedef void (*OutputCallback)(wchar_t *, char *, ThreadParam, const wchar_t *);
|
||||
typedef void (*ConsoleHandler)(const wchar_t *);
|
||||
typedef void (*HookInsertHandler)(uint64_t, const wchar_t *);
|
||||
typedef void (*EmbedCallback)(const wchar_t *, ThreadParam);
|
||||
nlohmann::json config;
|
||||
std::map<std::string, std::string> translation;
|
||||
std::unordered_set<DWORD> connectedpids;
|
||||
void (*Luna_Start)(ProcessEvent Connect, ProcessEvent Disconnect, ThreadEvent Create, ThreadEvent Destroy, OutputCallback Output, ConsoleHandler console, HookInsertHandler hookinsert, EmbedCallback embed);
|
||||
void (*Luna_Inject)(DWORD pid, LPCWSTR basepath);
|
||||
void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 spaceadjustpolicy, UINT32 keeprawtext, bool fastskipignore);
|
||||
void (*Luna_useembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2, bool use);
|
||||
bool (*Luna_checkisusingembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2);
|
||||
void (*Luna_embedcallback)(DWORD pid, LPCWSTR text, LPCWSTR trans);
|
||||
std::set<std::string> notranslation;
|
||||
HANDLE hsema;
|
||||
class lunapatch
|
||||
{
|
||||
public:
|
||||
HANDLE hMessage;
|
||||
HANDLE hwait;
|
||||
nlohmann::json config;
|
||||
std::map<std::string, std::string> translation;
|
||||
std::unordered_set<DWORD> connectedpids;
|
||||
void (*Luna_Start)(HANDLE *hRead);
|
||||
void (*Luna_Inject)(DWORD pid, LPCWSTR basepath);
|
||||
void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 spaceadjustpolicy, UINT32 keeprawtext, bool fastskipignore);
|
||||
void (*Luna_useembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2, bool use);
|
||||
bool (*Luna_checkisusingembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2);
|
||||
void (*Luna_embedcallback)(DWORD pid, LPCWSTR text, LPCWSTR trans);
|
||||
std::set<std::string> notranslation;
|
||||
HANDLE hsema;
|
||||
lunapatch(std::wstring dll, nlohmann::json &&_translation, nlohmann::json &&_config) : translation(_translation), config(_config)
|
||||
|
||||
lunapatch(std::wstring dll, nlohmann::json &&_translation, nlohmann::json &&_config)
|
||||
{
|
||||
translation = _translation;
|
||||
config = _config;
|
||||
auto LunaHost = LoadLibraryW(dll.c_str());
|
||||
|
||||
Luna_Start = (decltype(Luna_Start))GetProcAddress(LunaHost, "Luna_Start");
|
||||
@ -141,10 +138,54 @@ public:
|
||||
Luna_checkisusingembed = (decltype(Luna_checkisusingembed))GetProcAddress(LunaHost, "Luna_checkisusingembed");
|
||||
Luna_embedcallback = (decltype(Luna_embedcallback))GetProcAddress(LunaHost, "Luna_embedcallback");
|
||||
hsema = CreateSemaphore(NULL, 0, 100, NULL);
|
||||
Luna_Start(&hMessage);
|
||||
std::thread([&]()
|
||||
{ Parsehostmessage(); })
|
||||
.detach();
|
||||
Luna_Start(
|
||||
[](DWORD pid)
|
||||
{
|
||||
auto font = StringToWideString(config["embedsettings"]["font"]);
|
||||
auto insertspace_policy = config["embedsettings"]["insertspace_policy"];
|
||||
auto keeprawtext = config["embedsettings"]["keeprawtext"];
|
||||
Luna_EmbedSettings(pid, 1000, 2, false, font.data(), insertspace_policy, keeprawtext, false);
|
||||
connectedpids.insert(pid);
|
||||
},
|
||||
[](DWORD pid)
|
||||
{
|
||||
connectedpids.erase(pid);
|
||||
ReleaseSemaphore(hsema, 1, NULL);
|
||||
},
|
||||
[](auto, auto, auto) {},
|
||||
[](auto, auto, auto) {},
|
||||
[](auto, auto, auto, auto) {},
|
||||
[](auto) {},
|
||||
[](uint64_t addr, const wchar_t *output)
|
||||
{
|
||||
std::wstring newhookcode = output;
|
||||
for (auto hook : config["embedhook"])
|
||||
{
|
||||
auto hookcode = StringToWideString(hook[0]);
|
||||
uint64_t _addr = hook[1];
|
||||
uint64_t _ctx1 = hook[2];
|
||||
uint64_t _ctx2 = hook[3];
|
||||
if (hookcode == newhookcode)
|
||||
{
|
||||
for (auto pid : connectedpids)
|
||||
{
|
||||
Luna_useembed(pid, addr, _ctx1, _ctx2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[](const wchar_t *output, ThreadParam tp)
|
||||
{
|
||||
std::wstring text = output;
|
||||
for (auto pid : connectedpids)
|
||||
{
|
||||
if ((Luna_checkisusingembed(pid, tp.addr, tp.ctx, tp.ctx2)))
|
||||
{
|
||||
auto trans = findtranslation(text);
|
||||
Luna_embedcallback(pid, output, trans.c_str());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
void run()
|
||||
{
|
||||
@ -194,7 +235,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
std::wstring findtranslation(const std::wstring &text)
|
||||
static std::wstring findtranslation(const std::wstring &text)
|
||||
{
|
||||
auto utf8text = WideStringToString(text);
|
||||
if (translation.find(utf8text) == translation.end())
|
||||
@ -205,71 +246,6 @@ public:
|
||||
}
|
||||
return StringToWideString(translation.at(utf8text));
|
||||
}
|
||||
void Parsehostmessage()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
messagelist message;
|
||||
DWORD _;
|
||||
ReadFile(hMessage, &message, sizeof(message), &_, NULL);
|
||||
switch (message.type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
auto font = StringToWideString(config["embedsettings"]["font"]);
|
||||
auto insertspace_policy = config["embedsettings"]["insertspace_policy"];
|
||||
auto keeprawtext = config["embedsettings"]["keeprawtext"];
|
||||
Luna_EmbedSettings(message.pid, 1000, 2, false, font.data(), insertspace_policy, keeprawtext, false);
|
||||
connectedpids.insert(message.pid);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
connectedpids.erase(message.pid);
|
||||
ReleaseSemaphore(hsema, 1, NULL);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
{
|
||||
std::wstring text = message.stringptr;
|
||||
auto tp = message.tp;
|
||||
for (auto pid : connectedpids)
|
||||
{
|
||||
if ((Luna_checkisusingembed(pid, tp.addr, tp.ctx, tp.ctx2)))
|
||||
{
|
||||
auto trans = findtranslation(text);
|
||||
Luna_embedcallback(pid, text.c_str(), trans.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
{
|
||||
std::wstring newhookcode = message.stringptr;
|
||||
for (auto hook : config["embedhook"])
|
||||
{
|
||||
auto hookcode = StringToWideString(hook[0]);
|
||||
uint64_t _addr = hook[1];
|
||||
uint64_t _ctx1 = hook[2];
|
||||
uint64_t _ctx2 = hook[3];
|
||||
if (hookcode == newhookcode)
|
||||
{
|
||||
for (auto pid : connectedpids)
|
||||
{
|
||||
Luna_useembed(pid, message.addr, _ctx1, _ctx2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (message.stringptr)
|
||||
free(message.stringptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
std::wstring GetExecutablePath()
|
||||
{
|
||||
|
@ -64,104 +64,7 @@ wchar_t **vecwstr2c(std::vector<std::wstring> &vs)
|
||||
return argv;
|
||||
}
|
||||
|
||||
struct MemoryStruct
|
||||
{
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
char *ptr;
|
||||
if (mem->memory)
|
||||
ptr = (char *)realloc(mem->memory, mem->size + realsize + 1);
|
||||
else
|
||||
ptr = (char *)malloc(mem->size + realsize + 1);
|
||||
if (!ptr)
|
||||
{
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
void c_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
class lockedqueue
|
||||
{
|
||||
std::mutex lock;
|
||||
std::queue<std::string> data;
|
||||
HANDLE hsema;
|
||||
|
||||
public:
|
||||
lockedqueue()
|
||||
{
|
||||
hsema = CreateSemaphore(NULL, 0, 65535, NULL);
|
||||
}
|
||||
~lockedqueue()
|
||||
{
|
||||
CloseHandle(hsema);
|
||||
}
|
||||
void push(std::string &&_)
|
||||
{
|
||||
std::lock_guard _l(lock);
|
||||
data.push(std::move(_));
|
||||
ReleaseSemaphore(hsema, 1, NULL);
|
||||
}
|
||||
std::string pop()
|
||||
{
|
||||
WaitForSingleObject(hsema, INFINITE);
|
||||
std::lock_guard _l(lock);
|
||||
auto _ = data.front();
|
||||
data.pop();
|
||||
return _;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
std::lock_guard _l(lock);
|
||||
return data.empty();
|
||||
}
|
||||
};
|
||||
void *lockedqueuecreate()
|
||||
{
|
||||
return new lockedqueue();
|
||||
}
|
||||
void lockedqueuefree(void *q)
|
||||
{
|
||||
delete reinterpret_cast<lockedqueue *>(q);
|
||||
}
|
||||
void *lockedqueueget(void *q, size_t *l)
|
||||
{
|
||||
auto data = reinterpret_cast<lockedqueue *>(q)->pop();
|
||||
auto datastatic = new char[data.size()];
|
||||
memcpy(datastatic, data.data(), data.size());
|
||||
*l = data.size();
|
||||
return datastatic;
|
||||
}
|
||||
void lockedqueuepush(void *q, size_t l, void *ptr)
|
||||
{
|
||||
reinterpret_cast<lockedqueue *>(q)->push(std::string((char *)ptr, l));
|
||||
}
|
||||
bool lockedqueueempty(void *q)
|
||||
{
|
||||
return reinterpret_cast<lockedqueue *>(q)->empty();
|
||||
}
|
||||
|
||||
size_t WriteMemoryToQueue(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
auto queue = reinterpret_cast<lockedqueue *>(userp);
|
||||
queue->push(std::string((char *)contents, realsize));
|
||||
return realsize;
|
||||
}
|
||||
|
@ -33,12 +33,5 @@ extern "C"
|
||||
|
||||
__declspec(dllexport) void *extracticon2data(const wchar_t *name, size_t *l);
|
||||
|
||||
__declspec(dllexport) size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
|
||||
__declspec(dllexport) size_t WriteMemoryToQueue(void *contents, size_t size, size_t nmemb, void *userp);
|
||||
__declspec(dllexport) void *lockedqueuecreate();
|
||||
__declspec(dllexport) void lockedqueuefree(void *);
|
||||
__declspec(dllexport) void *lockedqueueget(void *, size_t *);
|
||||
__declspec(dllexport) void lockedqueuepush(void *, size_t, void *);
|
||||
__declspec(dllexport) bool lockedqueueempty(void *);
|
||||
__declspec(dllexport) void c_free(void *);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user