Compare commits
3 Commits
1fc9e69ded
...
d02864526c
Author | SHA1 | Date |
---|---|---|
|
d02864526c | |
|
de9a3ede6d | |
|
4be0798660 |
|
@ -514,6 +514,26 @@ namespace GakumasLocal::HookMain {
|
||||||
UpdateFont(self);
|
UpdateFont(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK(void, TMP_Text_SetText_2, (void* self, Il2cppString* sourceText, bool syncTextInputBox, void* mtd)) {
|
||||||
|
if (!sourceText) {
|
||||||
|
return TMP_Text_SetText_2_Orig(self, sourceText, syncTextInputBox, mtd);
|
||||||
|
}
|
||||||
|
const std::string origText = sourceText->ToString();
|
||||||
|
std::string transText;
|
||||||
|
if (Local::GetGenericText(origText, &transText)) {
|
||||||
|
const auto newText = UnityResolve::UnityType::String::New(transText);
|
||||||
|
UpdateFont(self);
|
||||||
|
return TMP_Text_SetText_2_Orig(self, newText, syncTextInputBox, mtd);
|
||||||
|
}
|
||||||
|
if (Config::textTest) {
|
||||||
|
TMP_Text_SetText_2_Orig(self, UnityResolve::UnityType::String::New("[TS]" + sourceText->ToString()), syncTextInputBox, mtd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TMP_Text_SetText_2_Orig(self, sourceText, syncTextInputBox, mtd);
|
||||||
|
}
|
||||||
|
UpdateFont(self);
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_HOOK(void, TextMeshProUGUI_Awake, (void* self, void* method)) {
|
DEFINE_HOOK(void, TextMeshProUGUI_Awake, (void* self, void* method)) {
|
||||||
// Log::InfoFmt("TextMeshProUGUI_Awake at %p, self at %p", TextMeshProUGUI_Awake_Orig, self);
|
// Log::InfoFmt("TextMeshProUGUI_Awake at %p, self at %p", TextMeshProUGUI_Awake_Orig, self);
|
||||||
|
|
||||||
|
@ -1240,6 +1260,70 @@ namespace GakumasLocal::HookMain {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GKMS_WINDOWS
|
||||||
|
// DMM Only
|
||||||
|
DEFINE_HOOK(void*, WindowHandle_SetWindowLong, (int32_t nIndex, intptr_t dwNewLong, void* mtd)) {
|
||||||
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
|
// Log::DebugFmt("WindowHandle_SetWindowLong: %d, %p\n", nIndex, dwNewLong);
|
||||||
|
|
||||||
|
if (nIndex == GWLP_WNDPROC) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WindowHandle_SetWindowLong_Orig(nIndex, dwNewLong, mtd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMM Only
|
||||||
|
void SetResolution(int width, int height, bool fullscreen) {
|
||||||
|
static auto Screen_SetResolution = reinterpret_cast<void (*)(UINT, UINT, UINT, void*)>(
|
||||||
|
Il2cppUtils::il2cpp_resolve_icall("UnityEngine.Screen::SetResolution_Injected(System.Int32,System.Int32,UnityEngine.FullScreenMode,UnityEngine.RefreshRate&)"));
|
||||||
|
|
||||||
|
int64_t v8[3];
|
||||||
|
v8[0] = 0x100000000LL;
|
||||||
|
Screen_SetResolution(width, height, 2 * !fullscreen + 1, v8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMM Only
|
||||||
|
DEFINE_HOOK(void, WindowManager_ApplyOrientationSettings, (int orientation, void* method)) {
|
||||||
|
if (!GakumasLocal::Config::dmmUnlockSize) return WindowManager_ApplyOrientationSettings_Orig(orientation, method);
|
||||||
|
|
||||||
|
static auto get_Height = reinterpret_cast<int (*)()>(Il2cppUtils::il2cpp_resolve_icall("UnityEngine.Screen::get_height()"));
|
||||||
|
static auto get_Width = reinterpret_cast<int (*)()>(Il2cppUtils::il2cpp_resolve_icall("UnityEngine.Screen::get_width()"));
|
||||||
|
|
||||||
|
static auto lastWidth = -1;
|
||||||
|
static auto lastHeight = -1;
|
||||||
|
|
||||||
|
const auto currWidth = get_Width();
|
||||||
|
const auto currHeight = get_Height();
|
||||||
|
|
||||||
|
if (lastWidth == -1) {
|
||||||
|
lastWidth = currWidth;
|
||||||
|
lastHeight = currHeight;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool lastIsPortrait = lastWidth < lastHeight;
|
||||||
|
const bool currIsPortrait = currWidth < currHeight;
|
||||||
|
if (lastIsPortrait == currIsPortrait) {
|
||||||
|
lastWidth = currWidth;
|
||||||
|
lastHeight = currHeight;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetResolution(lastWidth, lastHeight, false);
|
||||||
|
lastWidth = currWidth;
|
||||||
|
lastHeight = currHeight;
|
||||||
|
|
||||||
|
Log::DebugFmt("WindowManager_ApplyOrientationSettings: %d (%d, %d)\n", orientation, get_Width(), get_Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMM Only
|
||||||
|
DEFINE_HOOK(void, AspectRatioHandler_NudgeWindow, (void* method)) {
|
||||||
|
if (!GakumasLocal::Config::dmmUnlockSize) return AspectRatioHandler_NudgeWindow_Orig(method);
|
||||||
|
// printf("AspectRatioHandler_NudgeWindow\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void UpdateSwingBreastBonesData(void* initializeData) {
|
void UpdateSwingBreastBonesData(void* initializeData) {
|
||||||
if (!Config::enableBreastParam) return;
|
if (!Config::enableBreastParam) return;
|
||||||
|
@ -1444,6 +1528,9 @@ namespace GakumasLocal::HookMain {
|
||||||
ADD_HOOK(TMP_Text_PopulateTextBackingArray, Il2cppUtils::GetMethodPointer("Unity.TextMeshPro.dll", "TMPro",
|
ADD_HOOK(TMP_Text_PopulateTextBackingArray, Il2cppUtils::GetMethodPointer("Unity.TextMeshPro.dll", "TMPro",
|
||||||
"TMP_Text", "PopulateTextBackingArray",
|
"TMP_Text", "PopulateTextBackingArray",
|
||||||
{"System.String", "System.Int32", "System.Int32"}));
|
{"System.String", "System.Int32", "System.Int32"}));
|
||||||
|
ADD_HOOK(TMP_Text_SetText_2, Il2cppUtils::GetMethodPointer("Unity.TextMeshPro.dll", "TMPro",
|
||||||
|
"TMP_Text", "SetText",
|
||||||
|
{ "System.String", "System.Boolean" }));
|
||||||
|
|
||||||
ADD_HOOK(TextField_set_value, Il2cppUtils::GetMethodPointer("UnityEngine.UIElementsModule.dll", "UnityEngine.UIElements",
|
ADD_HOOK(TextField_set_value, Il2cppUtils::GetMethodPointer("UnityEngine.UIElementsModule.dll", "UnityEngine.UIElements",
|
||||||
"TextField", "set_value"));
|
"TextField", "set_value"));
|
||||||
|
@ -1634,6 +1721,32 @@ namespace GakumasLocal::HookMain {
|
||||||
"RenderPipeline", "EndCameraRendering"));
|
"RenderPipeline", "EndCameraRendering"));
|
||||||
|
|
||||||
#ifdef GKMS_WINDOWS
|
#ifdef GKMS_WINDOWS
|
||||||
|
ADD_HOOK(WindowHandle_SetWindowLong, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
"WindowHandle", "SetWindowLong"));
|
||||||
|
//ADD_HOOK(WindowHandle_SetWindowLong32, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
// "WindowHandle", "SetWindowLong32"));
|
||||||
|
//ADD_HOOK(WindowHandle_SetWindowLongPtr64, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
// "WindowHandle", "SetWindowLongPtr64"));
|
||||||
|
//ADD_HOOK(WindowSizeUtility_RestoreWindowSize, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
// "WindowSizeUtility", "RestoreWindowSize"));
|
||||||
|
ADD_HOOK(WindowManager_ApplyOrientationSettings, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
"WindowManager", "ApplyOrientationSettings"));
|
||||||
|
ADD_HOOK(AspectRatioHandler_NudgeWindow, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
"AspectRatioHandler", "NudgeWindow"));
|
||||||
|
//ADD_HOOK(AspectRatioHandler_WindowProc, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.Common.StandAloneWindow",
|
||||||
|
// "AspectRatioHandler", "WindowProc"));
|
||||||
|
|
||||||
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
|
std::thread([]() {
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||||
|
auto hWnd = FindWindowW(L"UnityWndClass", L"gakumas");
|
||||||
|
// 添加可调整大小的边框和最大化按钮
|
||||||
|
LONG style = GetWindowLong(hWnd, GWL_STYLE);
|
||||||
|
style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||||
|
SetWindowLong(hWnd, GWL_STYLE, style);
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
g_extra_assetbundle_paths.push_back((gakumasLocalPath / "local-files/gakumasassets").string());
|
g_extra_assetbundle_paths.push_back((gakumasLocalPath / "local-files/gakumasassets").string());
|
||||||
LoadExtraAssetBundle();
|
LoadExtraAssetBundle();
|
||||||
GkmsResourceUpdate::CheckUpdateFromAPI(false);
|
GkmsResourceUpdate::CheckUpdateFromAPI(false);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "BaseDefine.h"
|
#include "BaseDefine.h"
|
||||||
#include "string_parser/StringParser.hpp"
|
#include "string_parser/StringParser.hpp"
|
||||||
|
|
||||||
|
#include "cpprest/details/http_helpers.h"
|
||||||
|
|
||||||
|
|
||||||
namespace GakumasLocal::Local {
|
namespace GakumasLocal::Local {
|
||||||
std::unordered_map<std::string, std::string> i18nData{};
|
std::unordered_map<std::string, std::string> i18nData{};
|
||||||
|
@ -249,7 +251,7 @@ namespace GakumasLocal::Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetSplitTagsTranslation(const std::string& origText, std::string* newText, std::vector<std::string>& unTransResultRet) {
|
bool GetSplitTagsTranslation(const std::string& origText, std::string* newText, std::vector<std::string>& unTransResultRet) {
|
||||||
if (!origText.contains(L'<')) return false;
|
if (!origText.contains('<')) return false;
|
||||||
const auto splitResult = SplitByTags(origText);
|
const auto splitResult = SplitByTags(origText);
|
||||||
if (splitResult.empty()) return false;
|
if (splitResult.empty()) return false;
|
||||||
|
|
||||||
|
@ -289,10 +291,18 @@ namespace GakumasLocal::Local {
|
||||||
|
|
||||||
std::u16string currentWaitingReplaceText;
|
std::u16string currentWaitingReplaceText;
|
||||||
|
|
||||||
|
#ifdef GKMS_WINDOWS
|
||||||
|
#define checkCurrentWaitingReplaceTextAndClear() \
|
||||||
|
if (!currentWaitingReplaceText.empty()) { \
|
||||||
|
auto trimmed = trim(Misc::ToUTF8(currentWaitingReplaceText)); \
|
||||||
|
waitingReplaceTexts.push_back(trimmed); \
|
||||||
|
currentWaitingReplaceText.clear(); }
|
||||||
|
#else
|
||||||
#define checkCurrentWaitingReplaceTextAndClear() \
|
#define checkCurrentWaitingReplaceTextAndClear() \
|
||||||
if (!currentWaitingReplaceText.empty()) { \
|
if (!currentWaitingReplaceText.empty()) { \
|
||||||
waitingReplaceTexts.push_back(Misc::ToUTF8(currentWaitingReplaceText)); \
|
waitingReplaceTexts.push_back(Misc::ToUTF8(currentWaitingReplaceText)); \
|
||||||
currentWaitingReplaceText.clear(); }
|
currentWaitingReplaceText.clear(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
for (char16_t currChar : origText) {
|
for (char16_t currChar : origText) {
|
||||||
if (currChar == u'<') {
|
if (currChar == u'<') {
|
||||||
|
|
|
@ -14,6 +14,24 @@
|
||||||
|
|
||||||
|
|
||||||
namespace GakumasLocal::Misc {
|
namespace GakumasLocal::Misc {
|
||||||
|
|
||||||
|
#ifdef GKMS_WINDOWS
|
||||||
|
std::string ToUTF8(const std::wstring_view& str) {
|
||||||
|
return utility::conversions::to_utf8string(str.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::u16string ToUTF16(const std::string_view& str) {
|
||||||
|
std::string input(str);
|
||||||
|
std::wstring wstr = utility::conversions::utf8_to_utf16(input);
|
||||||
|
return std::u16string(wstr.begin(), wstr.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToUTF8(const std::u16string_view& str) {
|
||||||
|
std::u16string u16(str);
|
||||||
|
std::wstring wstr(u16.begin(), u16.end());
|
||||||
|
return utility::conversions::utf16_to_utf8(wstr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
std::u16string ToUTF16(const std::string_view& str) {
|
std::u16string ToUTF16(const std::string_view& str) {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
|
||||||
return utf16conv.from_bytes(str.data(), str.data() + str.size());
|
return utf16conv.from_bytes(str.data(), str.data() + str.size());
|
||||||
|
@ -23,11 +41,6 @@ namespace GakumasLocal::Misc {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
|
||||||
return utf16conv.to_bytes(str.data(), str.data() + str.size());
|
return utf16conv.to_bytes(str.data(), str.data() + str.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GKMS_WINDOWS
|
|
||||||
std::string ToUTF8(const std::wstring_view& str) {
|
|
||||||
return utility::conversions::to_utf8string(str.data());
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GKMS_WINDOWS
|
#ifndef GKMS_WINDOWS
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace GakumasLocal::Config {
|
||||||
float bLimitZx = 1.0f;
|
float bLimitZx = 1.0f;
|
||||||
float bLimitZy = 1.0f;
|
float bLimitZy = 1.0f;
|
||||||
|
|
||||||
|
bool dmmUnlockSize = false;
|
||||||
|
|
||||||
void LoadConfig(const std::string& configStr) {
|
void LoadConfig(const std::string& configStr) {
|
||||||
try {
|
try {
|
||||||
const auto config = nlohmann::json::parse(configStr);
|
const auto config = nlohmann::json::parse(configStr);
|
||||||
|
@ -102,6 +104,7 @@ namespace GakumasLocal::Config {
|
||||||
GetConfigItem(bLimitYy);
|
GetConfigItem(bLimitYy);
|
||||||
GetConfigItem(bLimitZx);
|
GetConfigItem(bLimitZx);
|
||||||
GetConfigItem(bLimitZy);
|
GetConfigItem(bLimitZy);
|
||||||
|
GetConfigItem(dmmUnlockSize);
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
Log::ErrorFmt("LoadConfig error: %s", e.what());
|
Log::ErrorFmt("LoadConfig error: %s", e.what());
|
||||||
|
@ -157,6 +160,7 @@ namespace GakumasLocal::Config {
|
||||||
SetConfigItem(bLimitYy);
|
SetConfigItem(bLimitYy);
|
||||||
SetConfigItem(bLimitZx);
|
SetConfigItem(bLimitZx);
|
||||||
SetConfigItem(bLimitZy);
|
SetConfigItem(bLimitZy);
|
||||||
|
SetConfigItem(dmmUnlockSize);
|
||||||
|
|
||||||
std::ofstream out(configPath);
|
std::ofstream out(configPath);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace GakumasLocal::Config {
|
||||||
extern float bLimitZx;
|
extern float bLimitZx;
|
||||||
extern float bLimitZy;
|
extern float bLimitZy;
|
||||||
|
|
||||||
|
extern bool dmmUnlockSize;
|
||||||
|
|
||||||
void LoadConfig(const std::string& configStr);
|
void LoadConfig(const std::string& configStr);
|
||||||
void SaveConfig(const std::string& configPath);
|
void SaveConfig(const std::string& configPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,6 +222,10 @@ namespace GkmsGUILoop {
|
||||||
ImGui::RadioButton(ts("orientation_portrait"), &Config::gameOrientation, 1);
|
ImGui::RadioButton(ts("orientation_portrait"), &Config::gameOrientation, 1);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton(ts("orientation_landscape"), &Config::gameOrientation, 2);
|
ImGui::RadioButton(ts("orientation_landscape"), &Config::gameOrientation, 2);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Checkbox(ts("dmmUnlockSize"), &Config::dmmUnlockSize);
|
||||||
|
ImGui::SameLine();
|
||||||
|
HELP_TOOLTIP("(?)", ts("dmmUnlockSizeHelp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::CollapsingHeader((std::string(ts("useCustomeGraphicSettings")) + "##customeGraphicSettings1").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
|
if (ImGui::CollapsingHeader((std::string(ts("useCustomeGraphicSettings")) + "##customeGraphicSettings1").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
namespace I18nData {
|
namespace I18nData {
|
||||||
static const std::unordered_map<std::string, std::string> i18nData_default = {
|
static const std::unordered_map<std::string, std::string> i18nData_default = {
|
||||||
{ "local_file_already_latest", "The local file is the latest version. Do you want to update it?" },
|
{ "local_file_already_latest", "The local file is the latest version. Do you want to update it?" },
|
||||||
|
{ "dmmUnlockSize", "Unlock Window Size" },
|
||||||
|
{ "dmmUnlockSizeHelp", "You can freely resize the window. Press F11 to toggle fullscreen." },
|
||||||
|
|
||||||
{ "app_name", "Gakumas Localify" },
|
{ "app_name", "Gakumas Localify" },
|
||||||
{ "gakumas_localify", "Gakumas Localify" },
|
{ "gakumas_localify", "Gakumas Localify" },
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
namespace I18nData {
|
namespace I18nData {
|
||||||
static const std::unordered_map<std::string, std::string> i18nData_ja = {
|
static const std::unordered_map<std::string, std::string> i18nData_ja = {
|
||||||
{ "local_file_already_latest", "ローカルファイルはすでに最新バージョンです。それでも更新を続けますか?" },
|
{ "local_file_already_latest", "ローカルファイルはすでに最新バージョンです。それでも更新を続けますか?" },
|
||||||
|
{ "dmmUnlockSize", "ウィンドウサイズの制限を解除" },
|
||||||
|
{ "dmmUnlockSizeHelp", "ウィンドウサイズは自由に変更できます。F11キーで全画面表示を切り替えます。" },
|
||||||
|
|
||||||
{ "about", "情報" },
|
{ "about", "情報" },
|
||||||
{ "about_about_p1", "このプラグインは完全に無料で提供されます。このプラグインで料金を支払ってしまった場合は、販売者に報告をしてください。" },
|
{ "about_about_p1", "このプラグインは完全に無料で提供されます。このプラグインで料金を支払ってしまった場合は、販売者に報告をしてください。" },
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
namespace I18nData {
|
namespace I18nData {
|
||||||
static const std::unordered_map<std::string, std::string> i18nData_zh_rCN = {
|
static const std::unordered_map<std::string, std::string> i18nData_zh_rCN = {
|
||||||
{ "local_file_already_latest", "本地文件已经是最新版本,是否继续更新?" },
|
{ "local_file_already_latest", "本地文件已经是最新版本,是否继续更新?" },
|
||||||
|
{ "dmmUnlockSize", "解锁窗口大小" },
|
||||||
|
{ "dmmUnlockSizeHelp", "可随意拖动窗口大小。使用F11切换全屏。" },
|
||||||
|
|
||||||
{ "app_name", "Gakumas Localify" },
|
{ "app_name", "Gakumas Localify" },
|
||||||
{ "gakumas_localify", "Gakumas Localify" },
|
{ "gakumas_localify", "Gakumas Localify" },
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#define LogMinVersion ANDROID_LOG_DEBUG
|
#define LogMinVersion ANDROID_LOG_DEBUG
|
||||||
|
|
||||||
#define PLUGIN_VERSION "3.0.1"
|
#define PLUGIN_VERSION "3.0.3"
|
||||||
|
|
||||||
#define ADD_HOOK(name, addr) \
|
#define ADD_HOOK(name, addr) \
|
||||||
name##_Addr = reinterpret_cast<name##_Type>(addr); \
|
name##_Addr = reinterpret_cast<name##_Type>(addr); \
|
||||||
|
|
|
@ -147,7 +147,7 @@ namespace GkmsResourceUpdate {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckUpdateFromAPI(bool isManual) {
|
void CheckUpdateFromAPI(bool isManual) {
|
||||||
std::thread([&isManual]() {
|
std::thread([isManual]() {
|
||||||
try {
|
try {
|
||||||
if (!g_useAPIAssets) {
|
if (!g_useAPIAssets) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -218,6 +218,36 @@ namespace GakumasLocal::WinHooks {
|
||||||
return get_assetBundle->Invoke<void*>(bundleTask);
|
return get_assetBundle->Invoke<void*>(bundleTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwitchFullScreen(HWND hWnd) {
|
||||||
|
static auto Screen_SetResolution = reinterpret_cast<void (*)(UINT, UINT, UINT, void*)>(
|
||||||
|
Il2cppUtils::il2cpp_resolve_icall("UnityEngine.Screen::SetResolution_Injected(System.Int32,System.Int32,UnityEngine.FullScreenMode,UnityEngine.RefreshRate&)"));
|
||||||
|
static auto get_Height = reinterpret_cast<int (*)()>(Il2cppUtils::il2cpp_resolve_icall("UnityEngine.Screen::get_height()"));
|
||||||
|
static auto get_Width = reinterpret_cast<int (*)()>(Il2cppUtils::il2cpp_resolve_icall("UnityEngine.Screen::get_width()"));
|
||||||
|
|
||||||
|
LONG style = GetWindowLong(hWnd, GWL_STYLE);
|
||||||
|
bool currFullScreen = style & WS_POPUP;
|
||||||
|
|
||||||
|
static int savedWidth = -1;
|
||||||
|
static int savedHeight = -1;
|
||||||
|
|
||||||
|
int64_t v8[3];
|
||||||
|
v8[0] = 0x100000000LL;
|
||||||
|
|
||||||
|
if (currFullScreen) {
|
||||||
|
// 取消全屏
|
||||||
|
if (savedWidth == -1) {
|
||||||
|
savedWidth = 542;
|
||||||
|
savedHeight = 990;
|
||||||
|
}
|
||||||
|
Screen_SetResolution(savedWidth, savedHeight, 2 * !false + 1, v8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
savedWidth = get_Width();
|
||||||
|
savedHeight = get_Height();
|
||||||
|
Screen_SetResolution(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 2 * !true + 1, v8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace Keyboard {
|
namespace Keyboard {
|
||||||
std::function<void(int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD)> mKeyBoardCallBack = nullptr;
|
std::function<void(int, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD)> mKeyBoardCallBack = nullptr;
|
||||||
|
|
||||||
|
@ -232,6 +262,8 @@ namespace GakumasLocal::WinHooks {
|
||||||
DWORD LEFT_key = 0;
|
DWORD LEFT_key = 0;
|
||||||
DWORD RIGHT_key = 0;
|
DWORD RIGHT_key = 0;
|
||||||
|
|
||||||
|
// printf("WndProcCallback: 0x%x (%d)\n", uMsg, uMsg);
|
||||||
|
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
case WM_INPUT: {
|
case WM_INPUT: {
|
||||||
RAWINPUT rawInput;
|
RAWINPUT rawInput;
|
||||||
|
@ -291,7 +323,13 @@ namespace GakumasLocal::WinHooks {
|
||||||
if (mKeyBoardCallBack != nullptr) {
|
if (mKeyBoardCallBack != nullptr) {
|
||||||
mKeyBoardCallBack(key, SHIFT_key, CTRL_key, ALT_key, SPACE_key, UP_key, DOWN_key, LEFT_key, RIGHT_key);
|
mKeyBoardCallBack(key, SHIFT_key, CTRL_key, ALT_key, SPACE_key, UP_key, DOWN_key, LEFT_key, RIGHT_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key == 122) {
|
||||||
|
// F11
|
||||||
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
|
SwitchFullScreen(hWnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (key >= 'A' && key <= 'Z')
|
if (key >= 'A' && key <= 'Z')
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -327,30 +365,70 @@ namespace GakumasLocal::WinHooks {
|
||||||
case WM_CLOSE: {
|
case WM_CLOSE: {
|
||||||
if (g_on_close) g_on_close();
|
if (g_on_close) g_on_close();
|
||||||
}; break;
|
}; break;
|
||||||
|
|
||||||
case WM_NCHITTEST:
|
case WM_NCHITTEST:
|
||||||
{
|
{
|
||||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
ScreenToClient(hWnd, &pt);
|
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||||
RECT rcClient;
|
ScreenToClient(hWnd, &pt);
|
||||||
GetClientRect(hWnd, &rcClient);
|
RECT rcClient;
|
||||||
const int borderWidth = 8; // 根据需要调整边缘宽度
|
GetClientRect(hWnd, &rcClient);
|
||||||
|
const int borderWidth = 8; // 根据需要调整边缘宽度
|
||||||
|
|
||||||
bool left = pt.x < borderWidth;
|
bool left = pt.x < borderWidth;
|
||||||
bool right = pt.x >= rcClient.right - borderWidth;
|
bool right = pt.x >= rcClient.right - borderWidth;
|
||||||
bool top = pt.y < borderWidth;
|
bool top = pt.y < borderWidth;
|
||||||
bool bottom = pt.y >= rcClient.bottom - borderWidth;
|
bool bottom = pt.y >= rcClient.bottom - borderWidth;
|
||||||
|
|
||||||
if (top && left) return HTTOPLEFT;
|
if (top && left) return HTTOPLEFT;
|
||||||
if (top && right) return HTTOPRIGHT;
|
if (top && right) return HTTOPRIGHT;
|
||||||
if (bottom && left) return HTBOTTOMLEFT;
|
if (bottom && left) return HTBOTTOMLEFT;
|
||||||
if (bottom && right) return HTBOTTOMRIGHT;
|
if (bottom && right) return HTBOTTOMRIGHT;
|
||||||
if (left) return HTLEFT;
|
if (left) return HTLEFT;
|
||||||
if (right) return HTRIGHT;
|
if (right) return HTRIGHT;
|
||||||
if (top) return HTTOP;
|
if (top) return HTTOP;
|
||||||
if (bottom) return HTBOTTOM;
|
if (bottom) return HTBOTTOM;
|
||||||
return HTCLIENT;
|
return HTCLIENT;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case WM_GETMINMAXINFO:
|
||||||
|
{
|
||||||
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
|
LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
|
||||||
|
// 设置最大尺寸为屏幕分辨率,这样就不限制窗口的最大尺寸
|
||||||
|
lpMMI->ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN) * 3;
|
||||||
|
lpMMI->ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN) * 3;
|
||||||
|
// 可选:设置窗口最小尺寸(例如200x200)
|
||||||
|
lpMMI->ptMinTrackSize.x = 200;
|
||||||
|
lpMMI->ptMinTrackSize.y = 200;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WM_SYSCOMMAND: {
|
||||||
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
|
if ((wParam & 0xFFF0) == SC_MAXIMIZE) {
|
||||||
|
SwitchFullScreen(hWnd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WM_NCPAINT: {
|
||||||
|
if (GakumasLocal::Config::dmmUnlockSize) {
|
||||||
|
LONG style = GetWindowLong(hWnd, GWL_STYLE);
|
||||||
|
// printf("WM_NCPAINT: 0x%x\n", style);
|
||||||
|
|
||||||
|
if (!(style & WS_POPUP)) {
|
||||||
|
// 添加可调整大小的边框和最大化按钮
|
||||||
|
style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||||
|
SetWindowLong(hWnd, GWL_STYLE, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,17 +436,13 @@ namespace GakumasLocal::WinHooks {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallWndProcHook() {
|
void InstallWndProcHook() {
|
||||||
g_pfnOldWndProc = (WNDPROC)GetWindowLongPtr(FindWindowW(L"UnityWndClass", L"gakumas"), GWLP_WNDPROC);
|
auto hWnd = FindWindowW(L"UnityWndClass", L"gakumas");
|
||||||
|
g_pfnOldWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
|
||||||
SetWindowLongPtr(FindWindowW(L"UnityWndClass", L"gakumas"), GWLP_WNDPROC, (LONG_PTR)WndProcCallback);
|
SetWindowLongPtr(FindWindowW(L"UnityWndClass", L"gakumas"), GWLP_WNDPROC, (LONG_PTR)WndProcCallback);
|
||||||
|
// 添加可调整大小的边框和最大化按钮
|
||||||
HWND hwnd = FindWindowW(L"UnityWndClass", L"gakumas");
|
LONG style = GetWindowLong(hWnd, GWL_STYLE);
|
||||||
LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
|
style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||||
// 加上可调整大小、标题栏、系统菜单等样式
|
SetWindowLong(hWnd, GWL_STYLE, style);
|
||||||
style |= WS_OVERLAPPEDWINDOW;
|
|
||||||
SetWindowLongPtr(hwnd, GWL_STYLE, style);
|
|
||||||
// 通知系统样式已改变
|
|
||||||
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
|
|
||||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UninstallWndProcHook(HWND hWnd)
|
void UninstallWndProcHook(HWND hWnd)
|
||||||
|
|
Loading…
Reference in New Issue