mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-10-22 23:18:16 +08:00
v8
This commit is contained in:
parent
b79bda0f1f
commit
ea03dc7dd6
@ -62,7 +62,7 @@ include(generate_product_version)
|
|||||||
|
|
||||||
set(VERSION_MAJOR 3)
|
set(VERSION_MAJOR 3)
|
||||||
set(VERSION_MINOR 15)
|
set(VERSION_MINOR 15)
|
||||||
set(VERSION_PATCH 0)
|
set(VERSION_PATCH 1)
|
||||||
set(VERSION_REVISION 0)
|
set(VERSION_REVISION 0)
|
||||||
|
|
||||||
if(BUILD_CORE)
|
if(BUILD_CORE)
|
||||||
|
@ -471,29 +471,6 @@ Return Value:
|
|||||||
|
|
||||||
--***************************************************************************/
|
--***************************************************************************/
|
||||||
|
|
||||||
std::string urlDecode(const std::string &encoded)
|
|
||||||
{
|
|
||||||
std::string decoded;
|
|
||||||
for (size_t i = 0; i < encoded.size(); i++)
|
|
||||||
{
|
|
||||||
if (encoded[i] == '%')
|
|
||||||
{
|
|
||||||
char ch = std::stoi(encoded.substr(i + 1, 2), 0, 16);
|
|
||||||
decoded += ch;
|
|
||||||
i = i + 2;
|
|
||||||
}
|
|
||||||
else if (encoded[i] == '+')
|
|
||||||
{
|
|
||||||
decoded += ' ';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
decoded += encoded[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return decoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma optimize("", off)
|
#pragma optimize("", off)
|
||||||
const wchar_t *LUNA_CONTENTBYPASS(const wchar_t *_)
|
const wchar_t *LUNA_CONTENTBYPASS(const wchar_t *_)
|
||||||
{
|
{
|
||||||
@ -507,57 +484,114 @@ SendHttpResponse(
|
|||||||
IN PHTTP_REQUEST pRequest)
|
IN PHTTP_REQUEST pRequest)
|
||||||
{
|
{
|
||||||
HTTP_RESPONSE response;
|
HTTP_RESPONSE response;
|
||||||
HTTP_DATA_CHUNK dataChunk;
|
|
||||||
DWORD result;
|
DWORD result;
|
||||||
DWORD bytesSent;
|
DWORD bytesSent;
|
||||||
USHORT StatusCode = 200;
|
ULONG BytesRead;
|
||||||
PSTR pReason = "OK";
|
HTTP_DATA_CHUNK dataChunk;
|
||||||
|
std::string recv;
|
||||||
|
std::string buff;
|
||||||
|
buff.resize(2048);
|
||||||
|
bool recving = true;
|
||||||
//
|
//
|
||||||
// Initialize the HTTP response structure.
|
// Initialize the HTTP response structure.
|
||||||
//
|
//
|
||||||
INITIALIZE_HTTP_RESPONSE(&response, StatusCode, pReason);
|
INITIALIZE_HTTP_RESPONSE(&response, 200, "OK");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add a known header.
|
// For POST, we'll echo back the entity that we got from the client.
|
||||||
//
|
//
|
||||||
ADD_KNOWN_HEADER(response, HttpHeaderContentType, "text/html");
|
// NOTE: If we had passed the HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY
|
||||||
std::string url(pRequest->pRawUrl, pRequest->RawUrlLength);
|
// flag with HttpReceiveHttpRequest(), the entity would have
|
||||||
auto fnd = url.find('?');
|
// been a part of HTTP_REQUEST (using the pEntityChunks field).
|
||||||
|
// Since we have not passed that flag, we can be assured that
|
||||||
if (fnd != url.npos)
|
// there are no entity bodies in HTTP_REQUEST.
|
||||||
|
//
|
||||||
|
if (pRequest->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS)
|
||||||
{
|
{
|
||||||
url = url.substr(fnd + 1);
|
// The entity body is send over multiple calls. Let's collect all
|
||||||
url = urlDecode(url);
|
// of these in a file & send it back. We'll create a temp file
|
||||||
url = WideStringToString(LUNA_CONTENTBYPASS(StringToWideString(url).c_str()));
|
|
||||||
//
|
//
|
||||||
// Add an entity chunk
|
|
||||||
//
|
|
||||||
dataChunk.DataChunkType = HttpDataChunkFromMemory;
|
|
||||||
dataChunk.FromMemory.pBuffer = (PVOID)url.c_str();
|
|
||||||
dataChunk.FromMemory.BufferLength = (ULONG)url.size();
|
|
||||||
|
|
||||||
response.EntityChunkCount = 1;
|
do
|
||||||
response.pEntityChunks = &dataChunk;
|
{
|
||||||
|
//
|
||||||
|
// Read the entity chunk from the request.
|
||||||
|
//
|
||||||
|
BytesRead = 0;
|
||||||
|
result = HttpReceiveRequestEntityBody(
|
||||||
|
hReqQueue,
|
||||||
|
pRequest->RequestId,
|
||||||
|
0,
|
||||||
|
buff.data(),
|
||||||
|
buff.capacity(),
|
||||||
|
&BytesRead,
|
||||||
|
NULL);
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case NO_ERROR:
|
||||||
|
case ERROR_HANDLE_EOF:
|
||||||
|
|
||||||
|
if (BytesRead != 0)
|
||||||
|
{
|
||||||
|
recv += buff.substr(0, BytesRead);
|
||||||
|
}
|
||||||
|
if (result == ERROR_HANDLE_EOF)
|
||||||
|
recving = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
recving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (recving);
|
||||||
}
|
}
|
||||||
|
if (recv.size())
|
||||||
|
recv = WideStringToString(LUNA_CONTENTBYPASS(StringToWideString(recv).c_str()));
|
||||||
|
if (recv.size())
|
||||||
|
{
|
||||||
|
ADD_KNOWN_HEADER(
|
||||||
|
response,
|
||||||
|
HttpHeaderContentLength,
|
||||||
|
std::to_string(recv.size()).c_str());
|
||||||
|
}
|
||||||
|
result =
|
||||||
|
HttpSendHttpResponse(
|
||||||
|
hReqQueue, // ReqQueueHandle
|
||||||
|
pRequest->RequestId, // Request ID
|
||||||
|
recv.size() ? HTTP_SEND_RESPONSE_FLAG_MORE_DATA : 0,
|
||||||
|
&response, // HTTP response
|
||||||
|
NULL, // pReserved1
|
||||||
|
&bytesSent, // bytes sent (optional)
|
||||||
|
NULL, // pReserved2
|
||||||
|
0, // Reserved3
|
||||||
|
NULL, // LPOVERLAPPED
|
||||||
|
NULL // pReserved4
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != NO_ERROR)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!recv.size())
|
||||||
|
return result;
|
||||||
//
|
//
|
||||||
// Since we are sending all the entity body in one call, we don't have
|
// Send entity body from a file handle.
|
||||||
// to specify the Content-Length.
|
|
||||||
//
|
//
|
||||||
|
dataChunk.DataChunkType = HttpDataChunkFromMemory;
|
||||||
|
dataChunk.FromMemory.pBuffer = (PVOID)recv.c_str();
|
||||||
|
dataChunk.FromMemory.BufferLength = (ULONG)recv.size();
|
||||||
|
|
||||||
result = HttpSendHttpResponse(
|
result = HttpSendResponseEntityBody(
|
||||||
hReqQueue, // ReqQueueHandle
|
hReqQueue,
|
||||||
pRequest->RequestId, // Request ID
|
pRequest->RequestId,
|
||||||
0, // Flags
|
0, // This is the last send.
|
||||||
&response, // HTTP response
|
1, // Entity Chunk Count.
|
||||||
NULL, // pReserved1
|
&dataChunk,
|
||||||
&bytesSent, // bytes sent (OPTIONAL)
|
NULL,
|
||||||
NULL, // pReserved2 (must be NULL)
|
NULL,
|
||||||
0, // Reserved3 (must be 0)
|
0,
|
||||||
NULL, // LPOVERLAPPED (OPTIONAL)
|
NULL,
|
||||||
NULL // pReserved4 (must be NULL)
|
NULL);
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
@ -8,6 +8,12 @@ namespace
|
|||||||
constexpr auto magicrecv = L"\x01LUNAFROMHOST\x01";
|
constexpr auto magicrecv = L"\x01LUNAFROMHOST\x01";
|
||||||
}
|
}
|
||||||
namespace
|
namespace
|
||||||
|
{
|
||||||
|
bool useclipboard = true;
|
||||||
|
bool usehttp = true;
|
||||||
|
int usehttp_port = 0;
|
||||||
|
}
|
||||||
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
void parsebefore(wchar_t *text, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
void parsebefore(wchar_t *text, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
||||||
@ -150,25 +156,11 @@ namespace v8script
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto port = 0;
|
|
||||||
|
|
||||||
auto useclipboard = !std::filesystem::exists(std::filesystem::path(getModuleFilename().value()).replace_filename("disable.clipboard"));
|
|
||||||
auto usehttp = !std::filesystem::exists(std::filesystem::path(getModuleFilename().value()).replace_filename("disable.http"));
|
|
||||||
if (usehttp)
|
|
||||||
{
|
|
||||||
port = makehttpgetserverinternal();
|
|
||||||
ConsoleOutput("%d %d", GetCurrentProcessId(), port);
|
|
||||||
hook_LUNA_CONTENTBYPASS();
|
|
||||||
dont_detach = true;
|
|
||||||
}
|
|
||||||
if (useclipboard)
|
|
||||||
{
|
|
||||||
hookClipboard();
|
|
||||||
}
|
|
||||||
auto lunajspatch = LoadResData(L"lunajspatch", L"JSSOURCE");
|
auto lunajspatch = LoadResData(L"lunajspatch", L"JSSOURCE");
|
||||||
strReplace(lunajspatch, "IS_PACKED", std::to_string(is_packed));
|
strReplace(lunajspatch, "IS_PACKED", std::to_string(is_packed));
|
||||||
strReplace(lunajspatch, "IS_USECLIPBOARD", std::to_string(useclipboard));
|
strReplace(lunajspatch, "IS_USECLIPBOARD", std::to_string(useclipboard));
|
||||||
strReplace(lunajspatch, "INTERNAL_HTTP_PORT", std::to_string(port));
|
strReplace(lunajspatch, "INTERNAL_HTTP_PORT", std::to_string(usehttp_port));
|
||||||
NewFromUtf8(&v8string, isolate, lunajspatch.c_str(), 1, -1);
|
NewFromUtf8(&v8string, isolate, lunajspatch.c_str(), 1, -1);
|
||||||
ConsoleOutput("v8string %p", v8string);
|
ConsoleOutput("v8string %p", v8string);
|
||||||
if (v8string == 0)
|
if (v8string == 0)
|
||||||
@ -363,10 +355,24 @@ bool tryhookv8()
|
|||||||
auto hm = GetModuleHandleW(moduleName);
|
auto hm = GetModuleHandleW(moduleName);
|
||||||
if (hm == 0)
|
if (hm == 0)
|
||||||
continue;
|
continue;
|
||||||
auto ok = hookstring(hm);
|
if (hookstring(hm))
|
||||||
ok |= v8script::v8runscript(hm);
|
{
|
||||||
if (ok)
|
useclipboard = !std::filesystem::exists(std::filesystem::path(getModuleFilename().value()).replace_filename("disable.clipboard"));
|
||||||
return true;
|
usehttp = !std::filesystem::exists(std::filesystem::path(getModuleFilename().value()).replace_filename("disable.http"));
|
||||||
|
if (usehttp)
|
||||||
|
{
|
||||||
|
usehttp_port = makehttpgetserverinternal();
|
||||||
|
ConsoleOutput("%d %d", GetCurrentProcessId(), usehttp_port);
|
||||||
|
hook_LUNA_CONTENTBYPASS();
|
||||||
|
dont_detach = true;
|
||||||
|
}
|
||||||
|
if (useclipboard)
|
||||||
|
{
|
||||||
|
hookClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
return v8script::v8runscript(hm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ function splitfonttext(transwithfont) {
|
|||||||
}
|
}
|
||||||
else if (transwithfont.substr(0, magicrecv.length) == magicrecv) {
|
else if (transwithfont.substr(0, magicrecv.length) == magicrecv) {
|
||||||
transwithfont = transwithfont.substr(magicrecv.length)
|
transwithfont = transwithfont.substr(magicrecv.length)
|
||||||
//magic font \x02 text
|
|
||||||
split = transwithfont.search('\x02')
|
split = transwithfont.search('\x02')
|
||||||
fontface = transwithfont.substr(0, split)
|
fontface = transwithfont.substr(0, split)
|
||||||
text = transwithfont.substr(split + 1)
|
text = transwithfont.substr(split + 1)
|
||||||
@ -22,61 +21,40 @@ function splitfonttext(transwithfont) {
|
|||||||
return transwithfont;
|
return transwithfont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function syncquery(s) {
|
function cppjsio(name, s_raw, lpsplit) {
|
||||||
if (internal_http_port == 0) { throw new Error('') }
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
var url = 'http://127.0.0.1:' + internal_http_port + '/fuck?' + s
|
|
||||||
xhr.open('GET', url, false);
|
|
||||||
xhr.send();
|
|
||||||
if (xhr.status === 200) {
|
|
||||||
return xhr.responseText;//解析这个会导致v8::String::Length的v8StringUtf8Length出现错误,但不影响。
|
|
||||||
} else {
|
|
||||||
throw new Error('')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
function makecomplexs(name, s_raw, lpsplit) {
|
|
||||||
return magicsend + name + '\x03' + lpsplit.toString() + '\x02' + s_raw;
|
|
||||||
}
|
|
||||||
function cppjsio(s) {
|
|
||||||
try {
|
|
||||||
return syncquery(s)
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
try {
|
|
||||||
if (!is_useclipboard) { throw new Error('') }
|
|
||||||
const _clipboard = require('nw.gui').Clipboard.get();
|
|
||||||
_clipboard.set(s, 'text');
|
|
||||||
return _clipboard.get('text');
|
|
||||||
}
|
|
||||||
catch (err2) {
|
|
||||||
try {
|
|
||||||
if (!is_useclipboard) { throw new Error('') }
|
|
||||||
const clipboard = require('electron').clipboard;
|
|
||||||
clipboard.writeText(s);
|
|
||||||
return clipboard.readText();
|
|
||||||
}
|
|
||||||
catch (err3) {
|
|
||||||
return s_raw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function clipboardsender(name, s_raw, lpsplit) {
|
|
||||||
//magic split \x02 text
|
|
||||||
if (!s_raw)
|
if (!s_raw)
|
||||||
return s_raw
|
return s_raw
|
||||||
transwithfont = cppjsio(makecomplexs(name, s_raw, lpsplit))
|
transwithfont = ''
|
||||||
if (transwithfont.length == 0) return s_raw;
|
s = magicsend + name + '\x03' + lpsplit.toString() + '\x02' + s_raw;
|
||||||
|
if (internal_http_port) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
var url = 'http://127.0.0.1:' + internal_http_port + '/fuck'
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.send(s);
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
transwithfont = xhr.responseText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_useclipboard) {
|
||||||
|
try {
|
||||||
|
const _clipboard = require('nw.gui').Clipboard.get();
|
||||||
|
_clipboard.set(s, 'text');
|
||||||
|
transwithfont = _clipboard.get('text');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
try {
|
||||||
|
const clipboard = require('electron').clipboard;
|
||||||
|
clipboard.writeText(s);
|
||||||
|
transwithfont = clipboard.readText();
|
||||||
|
}
|
||||||
|
catch (err2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!transwithfont) return s_raw;
|
||||||
return splitfonttext(transwithfont)
|
return splitfonttext(transwithfont)
|
||||||
}
|
}
|
||||||
|
|
||||||
function clipboardsender_only_send(name, s_raw, lpsplit) {
|
|
||||||
//magic split \x02 text
|
|
||||||
if (!s_raw)
|
|
||||||
return s_raw
|
|
||||||
cppjsio(makecomplexs(name, s_raw, lpsplit))
|
|
||||||
}
|
|
||||||
function rpgmakerhook() {
|
function rpgmakerhook() {
|
||||||
|
|
||||||
if (Window_Message.prototype.originstartMessage) { }
|
if (Window_Message.prototype.originstartMessage) { }
|
||||||
@ -99,7 +77,7 @@ function rpgmakerhook() {
|
|||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
for (lpsplit in Bitmap.prototype.collectstring) {
|
for (lpsplit in Bitmap.prototype.collectstring) {
|
||||||
if (Bitmap.prototype.collectstring[lpsplit].length) {
|
if (Bitmap.prototype.collectstring[lpsplit].length) {
|
||||||
clipboardsender_only_send('rpgmakermv', Bitmap.prototype.collectstring[lpsplit], lpsplit)
|
cppjsio('rpgmakermv', Bitmap.prototype.collectstring[lpsplit], lpsplit)
|
||||||
Bitmap.prototype.collectstring[lpsplit] = ''
|
Bitmap.prototype.collectstring[lpsplit] = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,12 +99,12 @@ function rpgmakerhook() {
|
|||||||
}
|
}
|
||||||
Window_Message.prototype.startMessage = function () {
|
Window_Message.prototype.startMessage = function () {
|
||||||
gametext = $gameMessage.allText();
|
gametext = $gameMessage.allText();
|
||||||
resp = clipboardsender('rpgmakermv', gametext, 0);
|
resp = cppjsio('rpgmakermv', gametext, 0);
|
||||||
$gameMessage._texts = [resp]
|
$gameMessage._texts = [resp]
|
||||||
this.originstartMessage();
|
this.originstartMessage();
|
||||||
};
|
};
|
||||||
Window_Base.prototype.drawText = function (text, x, y, maxWidth, align) {
|
Window_Base.prototype.drawText = function (text, x, y, maxWidth, align) {
|
||||||
text = clipboardsender('rpgmakermv', text, 1)
|
text = cppjsio('rpgmakermv', text, 1)
|
||||||
return this.drawText_origin(text, x, y, maxWidth, align)
|
return this.drawText_origin(text, x, y, maxWidth, align)
|
||||||
}
|
}
|
||||||
Window_Base.prototype.lastcalltime = 0
|
Window_Base.prototype.lastcalltime = 0
|
||||||
@ -135,7 +113,7 @@ function rpgmakerhook() {
|
|||||||
__now = new Date().getTime()
|
__now = new Date().getTime()
|
||||||
Window_Base.prototype.lastcalltime = __now
|
Window_Base.prototype.lastcalltime = __now
|
||||||
if (__now - __last > 100)
|
if (__now - __last > 100)
|
||||||
text = clipboardsender('rpgmakermv', text, 2)
|
text = cppjsio('rpgmakermv', text, 2)
|
||||||
else {
|
else {
|
||||||
Bitmap.prototype.collectstring[2] += text;
|
Bitmap.prototype.collectstring[2] += text;
|
||||||
}
|
}
|
||||||
@ -150,7 +128,7 @@ function tyranohook() {
|
|||||||
tyrano.plugin.kag.tag.chara_ptext.startorigin = tyrano.plugin.kag.tag.chara_ptext.start;
|
tyrano.plugin.kag.tag.chara_ptext.startorigin = tyrano.plugin.kag.tag.chara_ptext.start;
|
||||||
tyrano.plugin.kag.tag.text.start = function (pm) {
|
tyrano.plugin.kag.tag.text.start = function (pm) {
|
||||||
if (1 != this.kag.stat.is_script && 1 != this.kag.stat.is_html) {
|
if (1 != this.kag.stat.is_script && 1 != this.kag.stat.is_html) {
|
||||||
pm.val = clipboardsender('tyranoscript', pm.val, 0);
|
pm.val = cppjsio('tyranoscript', pm.val, 0);
|
||||||
if (fontface) {
|
if (fontface) {
|
||||||
this.kag.stat.font.face = fontface
|
this.kag.stat.font.face = fontface
|
||||||
}
|
}
|
||||||
@ -158,7 +136,7 @@ function tyranohook() {
|
|||||||
return this.originstart(pm)
|
return this.originstart(pm)
|
||||||
}
|
}
|
||||||
tyrano.plugin.kag.tag.chara_ptext.start = function (pm) {
|
tyrano.plugin.kag.tag.chara_ptext.start = function (pm) {
|
||||||
pm.name = clipboardsender('tyranoscript', pm.name, 1)
|
pm.name = cppjsio('tyranoscript', pm.name, 1)
|
||||||
return this.startorigin(pm)
|
return this.startorigin(pm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user