mirror of
https://github.com/HIllya51/LunaHook.git
synced 2025-01-11 20:39:34 +08:00
fix maybe crash
This commit is contained in:
parent
58d90aef00
commit
47c0a2a299
@ -1,9 +1,10 @@
|
||||
#include"python.h"
|
||||
#include "python.h"
|
||||
#include <dwrite.h>
|
||||
extern "C" __declspec(dllexport) const wchar_t* internal_renpy_call_host(const wchar_t* text,int split){
|
||||
extern "C" __declspec(dllexport) const wchar_t *internal_renpy_call_host(const wchar_t *text, int split)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
bool Luna_checkisusingembed(uint64_t address, uint64_t ctx1, uint64_t ctx2)
|
||||
bool Luna_checkisusingembed(uint64_t address, uint64_t ctx2, bool usingsplit)
|
||||
{
|
||||
auto sm = embedsharedmem;
|
||||
if (!sm)
|
||||
@ -12,265 +13,292 @@ bool Luna_checkisusingembed(uint64_t address, uint64_t ctx1, uint64_t ctx2)
|
||||
{
|
||||
if (sm->use[i])
|
||||
{
|
||||
if ((sm->addr[i] == address) && (sm->ctx1[i] == ctx1) && (sm->ctx2[i] == ctx2))
|
||||
if (!usingsplit)
|
||||
return true;
|
||||
if ((sm->addr[i] == address) && (sm->ctx2[i] == ctx2))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
extern "C" __declspec(dllexport) bool internal_renpy_call_is_embed_using(int split){
|
||||
return Luna_checkisusingembed((uint64_t)internal_renpy_call_host,0,split);
|
||||
}
|
||||
namespace{
|
||||
|
||||
typedef enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
|
||||
PyGILState_STATE;
|
||||
typedef PyGILState_STATE (*PyGILState_Ensure_t)(void);
|
||||
typedef void (*PyGILState_Release_t)(PyGILState_STATE);
|
||||
typedef int (*PyRun_SimpleString_t)(const char *command);
|
||||
|
||||
PyRun_SimpleString_t PyRun_SimpleString;
|
||||
PyGILState_Release_t PyGILState_Release;
|
||||
PyGILState_Ensure_t PyGILState_Ensure;
|
||||
|
||||
bool LoadPyRun(HMODULE module)
|
||||
extern "C" __declspec(dllexport) bool internal_renpy_call_is_embed_using(int split, bool usingsplit)
|
||||
{
|
||||
PyGILState_Ensure=(PyGILState_Ensure_t)GetProcAddress(module, "PyGILState_Ensure");
|
||||
PyGILState_Release=(PyGILState_Release_t)GetProcAddress(module, "PyGILState_Release");
|
||||
PyRun_SimpleString=(PyRun_SimpleString_t)GetProcAddress(module, "PyRun_SimpleString");
|
||||
return PyGILState_Ensure&&PyGILState_Release&&PyRun_SimpleString;
|
||||
return Luna_checkisusingembed((uint64_t)internal_renpy_call_host, split, usingsplit);
|
||||
}
|
||||
|
||||
void PyRunScript(const char* script)
|
||||
namespace
|
||||
{
|
||||
if(!(PyGILState_Ensure&&PyGILState_Release&&PyRun_SimpleString))return;
|
||||
|
||||
auto state=PyGILState_Ensure();
|
||||
PyRun_SimpleString(script);
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
void hook_internal_renpy_call_host(){
|
||||
HookParam hp_internal;
|
||||
hp_internal.address=(uintptr_t)internal_renpy_call_host;
|
||||
hp_internal.offset=GETARG1;
|
||||
hp_internal.split=GETARG2;
|
||||
hp_internal.type=USING_SPLIT|USING_STRING|CODEC_UTF16|EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_AFTER_NEW|NO_CONTEXT;
|
||||
NewHook(hp_internal, "internal_renpy_call_host");
|
||||
PyRunScript(LoadResData(L"renpy_hook_text",L"PYSOURCE").c_str());
|
||||
}
|
||||
|
||||
typedef BOOL(WINAPI* PGFRI)(LPCWSTR, LPDWORD, LPVOID, DWORD);
|
||||
typedef enum
|
||||
{
|
||||
PyGILState_LOCKED,
|
||||
PyGILState_UNLOCKED
|
||||
} PyGILState_STATE;
|
||||
typedef PyGILState_STATE (*PyGILState_Ensure_t)(void);
|
||||
typedef void (*PyGILState_Release_t)(PyGILState_STATE);
|
||||
typedef int (*PyRun_SimpleString_t)(const char *command);
|
||||
|
||||
PyRun_SimpleString_t PyRun_SimpleString;
|
||||
PyGILState_Release_t PyGILState_Release;
|
||||
PyGILState_Ensure_t PyGILState_Ensure;
|
||||
|
||||
bool LoadPyRun(HMODULE module)
|
||||
{
|
||||
PyGILState_Ensure = (PyGILState_Ensure_t)GetProcAddress(module, "PyGILState_Ensure");
|
||||
PyGILState_Release = (PyGILState_Release_t)GetProcAddress(module, "PyGILState_Release");
|
||||
PyRun_SimpleString = (PyRun_SimpleString_t)GetProcAddress(module, "PyRun_SimpleString");
|
||||
return PyGILState_Ensure && PyGILState_Release && PyRun_SimpleString;
|
||||
}
|
||||
|
||||
void PyRunScript(const char *script)
|
||||
{
|
||||
if (!(PyGILState_Ensure && PyGILState_Release && PyRun_SimpleString))
|
||||
return;
|
||||
|
||||
auto state = PyGILState_Ensure();
|
||||
PyRun_SimpleString(script);
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
void hook_internal_renpy_call_host()
|
||||
{
|
||||
HookParam hp_internal;
|
||||
hp_internal.address = (uintptr_t)internal_renpy_call_host;
|
||||
hp_internal.offset = GETARG1;
|
||||
hp_internal.split = GETARG2;
|
||||
hp_internal.type = USING_SPLIT | USING_STRING | CODEC_UTF16 | EMBED_ABLE | EMBED_BEFORE_SIMPLE | EMBED_AFTER_NEW | NO_CONTEXT;
|
||||
NewHook(hp_internal, "internal_renpy_call_host");
|
||||
PyRunScript(LoadResData(L"renpy_hook_text", L"PYSOURCE").c_str());
|
||||
}
|
||||
|
||||
typedef BOOL(WINAPI *PGFRI)(LPCWSTR, LPDWORD, LPVOID, DWORD);
|
||||
#define QFR_LOGFONT (2)
|
||||
#define LOADFONTTHREADNUM 4
|
||||
std::unordered_map<std::wstring, std::wstring> loadfontfiles() {
|
||||
std::unordered_map<std::wstring, std::wstring> loadfontfiles()
|
||||
{
|
||||
|
||||
PWSTR localAppDataPath;
|
||||
HRESULT result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppDataPath);
|
||||
std::unordered_map<std::wstring, std::wstring> fnts;
|
||||
|
||||
std::vector< std::wstring>collectfile;
|
||||
for (auto fontdir : { std::wstring(LR"(C:\Windows\Fonts)"),std::wstring(localAppDataPath) + LR"(\Microsoft\Windows\Fonts)" }) {
|
||||
if (!std::filesystem::exists(fontdir))continue;
|
||||
for (auto entry : std::filesystem::directory_iterator(fontdir)) {
|
||||
collectfile.emplace_back(entry.path());
|
||||
PWSTR localAppDataPath;
|
||||
HRESULT result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &localAppDataPath);
|
||||
std::unordered_map<std::wstring, std::wstring> fnts;
|
||||
|
||||
std::vector<std::wstring> collectfile;
|
||||
for (auto fontdir : {std::wstring(LR"(C:\Windows\Fonts)"), std::wstring(localAppDataPath) + LR"(\Microsoft\Windows\Fonts)"})
|
||||
{
|
||||
if (!std::filesystem::exists(fontdir))
|
||||
continue;
|
||||
for (auto entry : std::filesystem::directory_iterator(fontdir))
|
||||
{
|
||||
collectfile.emplace_back(entry.path());
|
||||
}
|
||||
}
|
||||
std::vector<std::thread> ts;
|
||||
std::vector<decltype(fnts)> fntss(LOADFONTTHREADNUM);
|
||||
auto singletask = [&](int i)
|
||||
{
|
||||
HINSTANCE hGdi32 = GetModuleHandleA("gdi32.dll");
|
||||
if (hGdi32 == 0)
|
||||
return;
|
||||
PGFRI GetFontResourceInfo = (PGFRI)GetProcAddress(hGdi32, "GetFontResourceInfoW");
|
||||
for (auto j = i; j < collectfile.size(); j += LOADFONTTHREADNUM)
|
||||
{
|
||||
auto fontfile = collectfile[j];
|
||||
DWORD dwFontsLoaded = AddFontResourceExW(fontfile.c_str(), FR_PRIVATE, 0);
|
||||
if (dwFontsLoaded == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto lpLogfonts = std::make_unique<LOGFONTW[]>(dwFontsLoaded);
|
||||
DWORD cbBuffer = dwFontsLoaded * sizeof(LOGFONTW);
|
||||
auto succ = GetFontResourceInfo(fontfile.c_str(), &cbBuffer, lpLogfonts.get(), QFR_LOGFONT);
|
||||
RemoveFontResourceExW(fontfile.c_str(), FR_PRIVATE, 0);
|
||||
if (!succ)
|
||||
continue;
|
||||
for (int k = 0; k < dwFontsLoaded; k++)
|
||||
fntss[i].insert(std::make_pair(lpLogfonts[k].lfFaceName, fontfile));
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < LOADFONTTHREADNUM; i++)
|
||||
{
|
||||
ts.emplace_back(std::thread(singletask, i));
|
||||
}
|
||||
for (int i = 0; i < LOADFONTTHREADNUM; i++)
|
||||
ts[i].join();
|
||||
for (int i = 0; i < LOADFONTTHREADNUM; i++)
|
||||
{
|
||||
for (auto p : fntss[i])
|
||||
fnts.insert(std::move(p));
|
||||
}
|
||||
return fnts;
|
||||
}
|
||||
std::vector<std::thread>ts;
|
||||
std::vector<decltype(fnts)> fntss(LOADFONTTHREADNUM);
|
||||
auto singletask = [&](int i) {
|
||||
HINSTANCE hGdi32 = GetModuleHandleA("gdi32.dll");
|
||||
if (hGdi32 == 0)return;
|
||||
PGFRI GetFontResourceInfo = (PGFRI)GetProcAddress(hGdi32, "GetFontResourceInfoW");
|
||||
for (auto j = i; j < collectfile.size(); j += LOADFONTTHREADNUM) {
|
||||
auto fontfile = collectfile[j];
|
||||
DWORD dwFontsLoaded = AddFontResourceExW(fontfile.c_str(), FR_PRIVATE, 0);
|
||||
if (dwFontsLoaded == 0) {
|
||||
|
||||
// https://stackoverflow.com/questions/16769758/get-a-font-filename-based-on-the-font-handle-hfont
|
||||
HRESULT(*fnDWriteCreateFactory)
|
||||
(
|
||||
_In_ DWRITE_FACTORY_TYPE factoryType,
|
||||
_In_ REFIID iid,
|
||||
_COM_Outptr_ IUnknown **factory);
|
||||
std::list<WCHAR *> get_fonts_path(LPCWSTR family_name, BOOL is_bold, BOOL is_italic, BYTE charset)
|
||||
{
|
||||
std::list<WCHAR *> fonts_filename_list;
|
||||
HRESULT hr;
|
||||
|
||||
IDWriteFactory *dwrite_factory;
|
||||
hr = fnDWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
IDWriteGdiInterop *gdi_interop;
|
||||
hr = dwrite_factory->GetGdiInterop(&gdi_interop);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
LOGFONT lf;
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
wcscpy_s(lf.lfFaceName, LF_FACESIZE, family_name);
|
||||
lf.lfWeight = is_bold ? FW_BOLD : FW_REGULAR; // TODO Change with the real ass weight
|
||||
lf.lfItalic = is_italic;
|
||||
lf.lfCharSet = charset;
|
||||
lf.lfOutPrecision = OUT_TT_PRECIS;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfQuality = ANTIALIASED_QUALITY;
|
||||
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
|
||||
HFONT hFont = CreateFontIndirect(&lf);
|
||||
HDC hdc = CreateCompatibleDC(NULL);
|
||||
HFONT hOldFont = SelectFont(hdc, hFont);
|
||||
|
||||
IDWriteFontFace *font_face;
|
||||
hr = gdi_interop->CreateFontFaceFromHdc(hdc, &font_face);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
gdi_interop->Release();
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
UINT file_count;
|
||||
hr = font_face->GetFiles(&file_count, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_face->Release();
|
||||
gdi_interop->Release();
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
IDWriteFontFile **font_files = new IDWriteFontFile *[file_count];
|
||||
hr = font_face->GetFiles(&file_count, font_files);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_face->Release();
|
||||
gdi_interop->Release();
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
for (int i = 0; i < file_count; i++)
|
||||
{
|
||||
LPCVOID font_file_reference_key;
|
||||
UINT font_file_reference_key_size;
|
||||
hr = font_files[i]->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto lpLogfonts = std::make_unique<LOGFONTW[]>(dwFontsLoaded);
|
||||
DWORD cbBuffer = dwFontsLoaded * sizeof(LOGFONTW);
|
||||
auto succ=GetFontResourceInfo(fontfile.c_str(), &cbBuffer, lpLogfonts.get(), QFR_LOGFONT);
|
||||
RemoveFontResourceExW(fontfile.c_str(), FR_PRIVATE, 0);
|
||||
if (!succ)continue;
|
||||
for (int k = 0; k < dwFontsLoaded; k++)
|
||||
fntss[i].insert(std::make_pair(lpLogfonts[k].lfFaceName, fontfile));
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < LOADFONTTHREADNUM; i++) {
|
||||
ts.emplace_back(std::thread(singletask,i));
|
||||
}
|
||||
for (int i = 0; i < LOADFONTTHREADNUM; i++)
|
||||
ts[i].join();
|
||||
for (int i = 0; i < LOADFONTTHREADNUM; i++) {
|
||||
for (auto p : fntss[i])
|
||||
fnts.insert(std::move(p));
|
||||
}
|
||||
return fnts;
|
||||
}
|
||||
IDWriteFontFileLoader *loader;
|
||||
hr = font_files[i]->GetLoader(&loader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
//https://stackoverflow.com/questions/16769758/get-a-font-filename-based-on-the-font-handle-hfont
|
||||
HRESULT (*fnDWriteCreateFactory)(
|
||||
_In_ DWRITE_FACTORY_TYPE factoryType,
|
||||
_In_ REFIID iid,
|
||||
_COM_Outptr_ IUnknown **factory
|
||||
);
|
||||
std::list<WCHAR*> get_fonts_path(LPCWSTR family_name, BOOL is_bold, BOOL is_italic, BYTE charset)
|
||||
IDWriteLocalFontFileLoader *local_loader;
|
||||
hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), (void **)&local_loader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
UINT32 path_length;
|
||||
hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
local_loader->Release();
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
WCHAR *path = new WCHAR[path_length + 1];
|
||||
hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, path, path_length + 1);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
local_loader->Release();
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
fonts_filename_list.push_back(path);
|
||||
|
||||
local_loader->Release();
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
}
|
||||
|
||||
font_face->Release();
|
||||
gdi_interop->Release();
|
||||
SelectObject(hdc, hOldFont);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteObject(hFont);
|
||||
|
||||
dwrite_factory->Release();
|
||||
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
}
|
||||
extern "C" __declspec(dllexport) const wchar_t *internal_renpy_get_font()
|
||||
{
|
||||
std::list<WCHAR*> fonts_filename_list;
|
||||
HRESULT hr;
|
||||
if (wcslen(embedsharedmem->fontFamily) == 0)
|
||||
return NULL;
|
||||
|
||||
IDWriteFactory* dwrite_factory;
|
||||
hr = fnDWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&dwrite_factory));
|
||||
if (FAILED(hr))
|
||||
fnDWriteCreateFactory = (decltype(fnDWriteCreateFactory))GetProcAddress(LoadLibrary(L"Dwrite.dll"), "DWriteCreateFactory");
|
||||
if (fnDWriteCreateFactory)
|
||||
{
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
IDWriteGdiInterop* gdi_interop;
|
||||
hr = dwrite_factory->GetGdiInterop(&gdi_interop);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
LOGFONT lf;
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
wcscpy_s(lf.lfFaceName, LF_FACESIZE, family_name);
|
||||
lf.lfWeight = is_bold ? FW_BOLD : FW_REGULAR; // TODO Change with the real ass weight
|
||||
lf.lfItalic = is_italic;
|
||||
lf.lfCharSet = charset;
|
||||
lf.lfOutPrecision = OUT_TT_PRECIS;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfQuality = ANTIALIASED_QUALITY;
|
||||
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||
|
||||
HFONT hFont = CreateFontIndirect(&lf);
|
||||
HDC hdc = CreateCompatibleDC(NULL);
|
||||
HFONT hOldFont = SelectFont(hdc, hFont);
|
||||
|
||||
IDWriteFontFace* font_face;
|
||||
hr = gdi_interop->CreateFontFaceFromHdc(hdc, &font_face);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
gdi_interop->Release();
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
UINT file_count;
|
||||
hr = font_face->GetFiles(&file_count, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_face->Release();
|
||||
gdi_interop->Release();
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
|
||||
IDWriteFontFile** font_files = new IDWriteFontFile * [file_count];
|
||||
hr = font_face->GetFiles(&file_count, font_files);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_face->Release();
|
||||
gdi_interop->Release();
|
||||
dwrite_factory->Release();
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
for (int i = 0; i < file_count; i++)
|
||||
{
|
||||
LPCVOID font_file_reference_key;
|
||||
UINT font_file_reference_key_size;
|
||||
hr = font_files[i]->GetReferenceKey(&font_file_reference_key, &font_file_reference_key_size);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
IDWriteFontFileLoader* loader;
|
||||
hr = font_files[i]->GetLoader(&loader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
IDWriteLocalFontFileLoader* local_loader;
|
||||
hr = loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), (void**)&local_loader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
UINT32 path_length;
|
||||
hr = local_loader->GetFilePathLengthFromKey(font_file_reference_key, font_file_reference_key_size, &path_length);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
local_loader->Release();
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
WCHAR* path = new WCHAR[path_length + 1];
|
||||
hr = local_loader->GetFilePathFromKey(font_file_reference_key, font_file_reference_key_size, path, path_length + 1);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
local_loader->Release();
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
fonts_filename_list.push_back(path);
|
||||
|
||||
local_loader->Release();
|
||||
loader->Release();
|
||||
font_files[i]->Release();
|
||||
|
||||
}
|
||||
|
||||
font_face->Release();
|
||||
gdi_interop->Release();
|
||||
SelectObject(hdc, hOldFont);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteObject(hFont);
|
||||
|
||||
dwrite_factory->Release();
|
||||
|
||||
return fonts_filename_list;
|
||||
}
|
||||
|
||||
}
|
||||
extern "C" __declspec(dllexport) const wchar_t* internal_renpy_get_font(){
|
||||
if(wcslen(embedsharedmem->fontFamily)==0)return NULL;
|
||||
|
||||
fnDWriteCreateFactory=(decltype(fnDWriteCreateFactory))GetProcAddress(LoadLibrary(L"Dwrite.dll"),"DWriteCreateFactory");
|
||||
if(fnDWriteCreateFactory){
|
||||
auto fonts_filename_list = get_fonts_path(embedsharedmem->fontFamily, false, false, DEFAULT_CHARSET);
|
||||
if(fonts_filename_list.size()==0)return NULL;
|
||||
if (fonts_filename_list.size() == 0)
|
||||
return NULL;
|
||||
return *fonts_filename_list.begin();
|
||||
}
|
||||
else{
|
||||
static auto fontname2fontfile=std::move(loadfontfiles());
|
||||
if(fontname2fontfile.find(embedsharedmem->fontFamily)==fontname2fontfile.end())return NULL;
|
||||
else return fontname2fontfile.at(embedsharedmem->fontFamily).c_str();
|
||||
else
|
||||
{
|
||||
static auto fontname2fontfile = std::move(loadfontfiles());
|
||||
if (fontname2fontfile.find(embedsharedmem->fontFamily) == fontname2fontfile.end())
|
||||
return NULL;
|
||||
else
|
||||
return fontname2fontfile.at(embedsharedmem->fontFamily).c_str();
|
||||
}
|
||||
}
|
||||
bool hookrenpy(HMODULE module){
|
||||
if(!LoadPyRun(module))return false;
|
||||
patch_fun=[](){
|
||||
PyRunScript(LoadResData(L"renpy_hook_font",L"PYSOURCE").c_str());
|
||||
bool hookrenpy(HMODULE module)
|
||||
{
|
||||
if (!LoadPyRun(module))
|
||||
return false;
|
||||
patch_fun = []()
|
||||
{
|
||||
PyRunScript(LoadResData(L"renpy_hook_font", L"PYSOURCE").c_str());
|
||||
};
|
||||
hook_internal_renpy_call_host();
|
||||
dont_detach=true;
|
||||
dont_detach = true;
|
||||
return true;
|
||||
}
|
@ -1,32 +1,62 @@
|
||||
def callLunaHostFont():
|
||||
try:
|
||||
import ctypes
|
||||
|
||||
try:
|
||||
internal_renpy_get_font=ctypes.CDLL('LunaHook64').internal_renpy_get_font
|
||||
internal_renpy_get_font = ctypes.CDLL("LunaHook64").internal_renpy_get_font
|
||||
except:
|
||||
internal_renpy_get_font=ctypes.CDLL('LunaHook32').internal_renpy_get_font
|
||||
internal_renpy_get_font.restype=ctypes.c_wchar_p
|
||||
internal_renpy_get_font = ctypes.CDLL("LunaHook32").internal_renpy_get_font
|
||||
internal_renpy_get_font.restype = ctypes.c_wchar_p
|
||||
return internal_renpy_get_font()
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def callLunaIsUsingEmbed_nosplit():
|
||||
try:
|
||||
import ctypes
|
||||
|
||||
try:
|
||||
internal_renpy_call_is_embed_using = ctypes.CDLL(
|
||||
"LunaHook64"
|
||||
).internal_renpy_call_is_embed_using
|
||||
except:
|
||||
internal_renpy_call_is_embed_using = ctypes.CDLL(
|
||||
"LunaHook32"
|
||||
).internal_renpy_call_is_embed_using
|
||||
internal_renpy_call_is_embed_using.argstype = ctypes.c_int, ctypes.c_bool
|
||||
internal_renpy_call_is_embed_using.restype = ctypes.c_bool
|
||||
|
||||
return internal_renpy_call_is_embed_using(0, False)
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
try:
|
||||
import os
|
||||
import renpy
|
||||
|
||||
def hook_renpy_text_font_get_font_init(original):
|
||||
def new_init(*args, **kwargs):
|
||||
#ctypes.windll.user32.MessageBoxW(None, str(kwargs), str(args), 0)
|
||||
font=callLunaHostFont()
|
||||
if font and font!='' and os.path.exists(font):
|
||||
font=font.replace('\\','/')#不知道为什么,用\会报错,但之前写死C:\Windows\Fonts\msyh.ttc时就没事
|
||||
args=(font,)+args[1:]
|
||||
if 'fn' in kwargs:
|
||||
kwargs['fn']=font
|
||||
# ctypes.windll.user32.MessageBoxW(None, str(kwargs), str(args), 0)
|
||||
if callLunaIsUsingEmbed_nosplit():
|
||||
font = callLunaHostFont()
|
||||
if font and font != "" and os.path.exists(font):
|
||||
font = font.replace(
|
||||
"\\", "/"
|
||||
) # 不知道为什么,用\会报错,但之前写死C:\Windows\Fonts\msyh.ttc时就没事
|
||||
args = (font,) + args[1:]
|
||||
if "fn" in kwargs:
|
||||
kwargs["fn"] = font
|
||||
return original(*args, **kwargs)
|
||||
|
||||
return new_init
|
||||
|
||||
if "original_renpy_text_font_get_font" not in globals():
|
||||
original_renpy_text_font_get_font = renpy.text.font.get_font
|
||||
renpy.text.font.get_font = hook_renpy_text_font_get_font_init(original_renpy_text_font_get_font)
|
||||
renpy.text.font.get_font = hook_renpy_text_font_get_font_init(
|
||||
original_renpy_text_font_get_font
|
||||
)
|
||||
|
||||
except:
|
||||
pass
|
||||
pass
|
||||
|
@ -22,6 +22,7 @@ def callLunaHost(text, split):
|
||||
pass
|
||||
return text
|
||||
|
||||
|
||||
def callLunaIsUsingEmbed(split):
|
||||
try:
|
||||
import ctypes
|
||||
@ -34,13 +35,14 @@ def callLunaIsUsingEmbed(split):
|
||||
internal_renpy_call_is_embed_using = ctypes.CDLL(
|
||||
"LunaHook32"
|
||||
).internal_renpy_call_is_embed_using
|
||||
internal_renpy_call_is_embed_using.argstype = ctypes.c_int,
|
||||
internal_renpy_call_is_embed_using.argstype = ctypes.c_int, ctypes.c_bool
|
||||
internal_renpy_call_is_embed_using.restype = ctypes.c_bool
|
||||
|
||||
return internal_renpy_call_is_embed_using(split)
|
||||
return internal_renpy_call_is_embed_using(split, True)
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
try:
|
||||
# 6.1.0
|
||||
import renpy
|
||||
@ -48,18 +50,18 @@ try:
|
||||
def hook_initT0(original_init):
|
||||
|
||||
def new_init(self, *args, **kwargs):
|
||||
changed=False
|
||||
changed = False
|
||||
if isinstance(args[0], list):
|
||||
trs = []
|
||||
for _ in args[0]:
|
||||
_n=callLunaHost(_, 1)
|
||||
if _n!=_:
|
||||
changed=True
|
||||
_n = callLunaHost(_, 1)
|
||||
if _n != _:
|
||||
changed = True
|
||||
trs += [_n]
|
||||
else:
|
||||
trs = callLunaHost(args[0], 1)
|
||||
if args[0]!=trs:
|
||||
changed=True
|
||||
if args[0] != trs:
|
||||
changed = True
|
||||
|
||||
if changed and callLunaIsUsingEmbed(1):
|
||||
args = (trs,) + args[1:]
|
||||
@ -78,25 +80,25 @@ try:
|
||||
def hook_init_renderT0(original):
|
||||
def new_init(self, *args, **kwargs):
|
||||
if not hasattr(self, "LunaHooked"):
|
||||
changed=False
|
||||
changed = False
|
||||
if isinstance(self.text, list):
|
||||
trs = []
|
||||
for _ in self.text:
|
||||
_n=callLunaHost(_, 2)
|
||||
if _n!=_:
|
||||
changed=True
|
||||
_n = callLunaHost(_, 2)
|
||||
if _n != _:
|
||||
changed = True
|
||||
trs += [_n]
|
||||
else:
|
||||
trs = callLunaHost(self.text, 2)
|
||||
if self.text!=trs:
|
||||
changed=True
|
||||
if self.text != trs:
|
||||
changed = True
|
||||
if changed and callLunaIsUsingEmbed(2):
|
||||
self.set_text(trs)
|
||||
self.LunaHooked = True
|
||||
return original(self, *args, **kwargs)
|
||||
|
||||
return new_init
|
||||
|
||||
|
||||
if "original_hook_init_renderT0" not in globals():
|
||||
original_hook_init_renderT0 = renpy.text.text.Text.render
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user