diff --git a/Minecraft.Client/ModLoader.cpp b/Minecraft.Client/ModLoader.cpp index fa9aad5a..f16cf957 100644 --- a/Minecraft.Client/ModLoader.cpp +++ b/Minecraft.Client/ModLoader.cpp @@ -11,53 +11,154 @@ #pragma comment(lib, "gdiplus.lib") -static HWND g_SplashWnd = NULL; -static HWND g_StatusWnd = NULL; -static HWND g_CountWnd = NULL; -static HWND g_FailWnd = NULL; -static int g_TotalMods = 0; -static int g_LoadedMods = 0; -static int g_FailedMods = 0; +// --------------------------------------------------------------------------- +// Splash state +// --------------------------------------------------------------------------- +static HWND g_SplashWnd = NULL; +static HBITMAP g_hLogoBmp = NULL; +static int g_LogoW = 0; +static int g_LogoH = 0; +static int g_TotalMods = 0; +static int g_LoadedMods = 0; +static int g_FailedMods = 0; +static std::wstring g_StatusText = L"Preparing..."; +static ULONG_PTR g_gdiplusToken; -static ULONG_PTR g_gdiplusToken; +static HFONT g_hFontTitle = NULL; +static HFONT g_hFontStatus = NULL; +static HFONT g_hFontCount = NULL; -LRESULT CALLBACK SplashWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_PAINT) { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1)); - EndPaint(hwnd, &ps); - return 0; +static const int SW = 600; +static const int SH = 400; + +#define SC_BG RGB(24, 24, 24) +#define SC_WHITE RGB(255, 255, 255) +#define SC_GREY RGB(160, 160, 160) +#define SC_RED RGB(220, 60, 60) +#define SC_ACCENT RGB(80, 140, 220) + +// --------------------------------------------------------------------------- +// Splash paint +// --------------------------------------------------------------------------- +static void PaintSplash(HWND hwnd) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hwnd, &ps); + + HDC mem = CreateCompatibleDC(hdc); + HBITMAP bmp = CreateCompatibleBitmap(hdc, SW, SH); + HBITMAP obmp = (HBITMAP)SelectObject(mem, bmp); + + RECT rc = { 0, 0, SW, SH }; + HBRUSH bgBr = CreateSolidBrush(SC_BG); + FillRect(mem, &rc, bgBr); + DeleteObject(bgBr); + + SetBkMode(mem, TRANSPARENT); + + HFONT of = (HFONT)SelectObject(mem, g_hFontTitle); + SetTextColor(mem, SC_WHITE); + RECT titleR = { 0, 18, SW, 58 }; + DrawTextW(mem, L"FAUCET", -1, &titleR, DT_CENTER | DT_SINGLELINE | DT_VCENTER); + + HPEN linePen = CreatePen(PS_SOLID, 1, SC_ACCENT); + HPEN oldPen = (HPEN)SelectObject(mem, linePen); + MoveToEx(mem, 40, 62, NULL); + LineTo(mem, SW - 40, 62); + SelectObject(mem, oldPen); + DeleteObject(linePen); + + if (g_hLogoBmp) + { + HDC logoDC = CreateCompatibleDC(mem); + HBITMAP old = (HBITMAP)SelectObject(logoDC, g_hLogoBmp); + int lx = (SW - g_LogoW) / 2; + int ly = 74; + BitBlt(mem, lx, ly, g_LogoW, g_LogoH, logoDC, 0, 0, SRCCOPY); + SelectObject(logoDC, old); + DeleteDC(logoDC); } + + SelectObject(mem, g_hFontStatus); + SetTextColor(mem, SC_GREY); + RECT statR = { 20, 240, SW - 20, 282 }; + DrawTextW(mem, g_StatusText.c_str(), -1, &statR, DT_CENTER | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); + + int barX = 20, barY = 292, barW = SW - 40, barH = 6; + HBRUSH trackBr = CreateSolidBrush(RGB(50, 50, 50)); + RECT trackR = { barX, barY, barX + barW, barY + barH }; + FillRect(mem, &trackR, trackBr); + DeleteObject(trackBr); + + if (g_TotalMods > 0) + { + int fillW = (int)((float)g_LoadedMods / g_TotalMods * barW); + HBRUSH fillBr = CreateSolidBrush(SC_ACCENT); + RECT fillR = { barX, barY, barX + fillW, barY + barH }; + FillRect(mem, &fillR, fillBr); + DeleteObject(fillBr); + } + + SelectObject(mem, g_hFontCount); + + std::wstring countText = std::to_wstring(g_LoadedMods) + L"/" + std::to_wstring(g_TotalMods) + L" MODS LOADED"; + SetTextColor(mem, SC_GREY); + RECT countR = { barX, barY + 14, barX + barW / 2, barY + 34 }; + DrawTextW(mem, countText.c_str(), -1, &countR, DT_LEFT | DT_SINGLELINE | DT_VCENTER); + + if (g_FailedMods > 0) + { + std::wstring failText = std::to_wstring(g_FailedMods) + L" FAILED"; + SetTextColor(mem, SC_RED); + RECT failR = { barX + barW / 2, barY + 14, barX + barW, barY + 34 }; + DrawTextW(mem, failText.c_str(), -1, &failR, DT_RIGHT | DT_SINGLELINE | DT_VCENTER); + } + + SelectObject(mem, of); + + BitBlt(hdc, 0, 0, SW, SH, mem, 0, 0, SRCCOPY); + SelectObject(mem, obmp); + DeleteObject(bmp); + DeleteDC(mem); + + EndPaint(hwnd, &ps); +} + +// --------------------------------------------------------------------------- +// Splash window proc +// --------------------------------------------------------------------------- +LRESULT CALLBACK SplashWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_PAINT) { PaintSplash(hwnd); return 0; } + if (msg == WM_ERASEBKGND) { return 1; } return DefWindowProc(hwnd, msg, wParam, lParam); } -void CreateSplash() { +// --------------------------------------------------------------------------- +// Splash creation +// --------------------------------------------------------------------------- +void CreateSplash() +{ Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&g_gdiplusToken, &gdiplusStartupInput, NULL); + g_hFontTitle = CreateFontW(28, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Segoe UI"); + g_hFontStatus = CreateFontW(15, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Segoe UI"); + g_hFontCount = CreateFontW(13, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Segoe UI"); + WNDCLASSW wc = {}; wc.lpfnWndProc = SplashWndProc; wc.hInstance = GetModuleHandle(NULL); wc.lpszClassName = L"ModLoaderSplash"; - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.hbrBackground = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); RegisterClassW(&wc); - const int w = 600, h = 400; - const int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; - const int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; + const int x = (GetSystemMetrics(SM_CXSCREEN) - SW) / 2; + const int y = (GetSystemMetrics(SM_CYSCREEN) - SH) / 2; g_SplashWnd = CreateWindowExW(WS_EX_TOPMOST, wc.lpszClassName, L"Faucet", - WS_POPUP | WS_BORDER | WS_VISIBLE, x, y, w, h, NULL, NULL, wc.hInstance, NULL); - - CreateWindowW(L"STATIC", L"FAUCET", - WS_CHILD | WS_VISIBLE | SS_CENTER, - 0, 20, w, 40, g_SplashWnd, NULL, wc.hInstance, NULL); - - HWND hLogo = CreateWindowW(L"STATIC", NULL, - WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_CENTERIMAGE, - 100, 70, 400, 150, g_SplashWnd, NULL, wc.hInstance, NULL); + WS_POPUP | WS_BORDER | WS_VISIBLE, x, y, SW, SH, NULL, NULL, wc.hInstance, NULL); wchar_t buffer[MAX_PATH]; GetModuleFileNameW(NULL, buffer, MAX_PATH); @@ -66,57 +167,72 @@ void CreateSplash() { std::wstring imagePath = exeDir + L"\\Common\\Media\\Faucet.png"; Gdiplus::Bitmap* bitmap = Gdiplus::Bitmap::FromFile(imagePath.c_str()); - if (bitmap && bitmap->GetLastStatus() == Gdiplus::Ok) { - HBITMAP hBmp = NULL; - if (bitmap->GetHBITMAP(Gdiplus::Color(255, 255, 255, 255), &hBmp) == Gdiplus::Ok && hBmp) { - HBITMAP hOld = (HBITMAP)SendMessage(hLogo, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp); - if (hOld) DeleteObject(hOld); + if (bitmap && bitmap->GetLastStatus() == Gdiplus::Ok) + { + g_LogoW = (int)bitmap->GetWidth(); + g_LogoH = (int)bitmap->GetHeight(); + + const int maxW = 400, maxH = 150; + if (g_LogoW > maxW || g_LogoH > maxH) + { + float scale = min((float)maxW / g_LogoW, (float)maxH / g_LogoH); + g_LogoW = (int)(g_LogoW * scale); + g_LogoH = (int)(g_LogoH * scale); } + + Gdiplus::Bitmap* scaled = new Gdiplus::Bitmap(g_LogoW, g_LogoH, PixelFormat32bppARGB); + Gdiplus::Graphics g(scaled); + g.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); + g.DrawImage(bitmap, 0, 0, g_LogoW, g_LogoH); + + HDC hdc = GetDC(g_SplashWnd); + HDC memDC = CreateCompatibleDC(hdc); + g_hLogoBmp = CreateCompatibleBitmap(hdc, g_LogoW, g_LogoH); + HBITMAP old = (HBITMAP)SelectObject(memDC, g_hLogoBmp); + Gdiplus::Graphics gdc(memDC); + gdc.DrawImage(scaled, 0, 0, g_LogoW, g_LogoH); + SelectObject(memDC, old); + DeleteDC(memDC); + ReleaseDC(g_SplashWnd, hdc); + + delete scaled; } delete bitmap; - g_StatusWnd = CreateWindowW(L"STATIC", L"Preparing...", - WS_CHILD | WS_VISIBLE | SS_CENTER, - 10, 240, 580, 40, g_SplashWnd, NULL, wc.hInstance, NULL); - - g_CountWnd = CreateWindowW(L"STATIC", L"0/0 MODS LOADED", - WS_CHILD | WS_VISIBLE | SS_LEFT, - 20, 350, 200, 20, g_SplashWnd, NULL, wc.hInstance, NULL); - - g_FailWnd = CreateWindowW(L"STATIC", L"", - WS_CHILD | WS_VISIBLE | SS_RIGHT, - 380, 350, 200, 20, g_SplashWnd, NULL, wc.hInstance, NULL); - UpdateWindow(g_SplashWnd); } -void UpdateSplashStatus(const std::wstring& text) { - if (!g_StatusWnd) return; +// --------------------------------------------------------------------------- +// Splash update +// --------------------------------------------------------------------------- +void UpdateSplashStatus(const std::wstring& text) +{ + if (!g_SplashWnd) return; - SendMessageW(g_StatusWnd, WM_SETTEXT, 0, (LPARAM)text.c_str()); + g_StatusText = text; - std::wstring countText = std::to_wstring(g_LoadedMods) + L"/" - + std::to_wstring(g_TotalMods) + L" MODS LOADED"; - SendMessageW(g_CountWnd, WM_SETTEXT, 0, (LPARAM)countText.c_str()); - - if (g_FailedMods > 0) { - std::wstring failText = std::to_wstring(g_FailedMods) + L" FAILED TO LOAD"; - SendMessageW(g_FailWnd, WM_SETTEXT, 0, (LPARAM)failText.c_str()); - } + InvalidateRect(g_SplashWnd, NULL, FALSE); + UpdateWindow(g_SplashWnd); MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { TranslateMessage(&msg); DispatchMessage(&msg); } } -ModLoader& ModLoader::Get() { +// --------------------------------------------------------------------------- +// ModLoader +// --------------------------------------------------------------------------- +ModLoader& ModLoader::Get() +{ static ModLoader instance; return instance; } -void ModLoader::Initialize() { +void ModLoader::Initialize() +{ if (m_initialized) return; m_initialized = true; @@ -136,99 +252,121 @@ void ModLoader::Initialize() { + std::to_string(g_FailedMods) + " failed, " + std::to_string(elapsed) + "ms total"); - if (elapsed < 1000) { + if (elapsed < 1000) + { UpdateSplashStatus(L"Finalizing..."); Sleep(static_cast(1000 - elapsed)); } - if (g_SplashWnd) { + if (g_SplashWnd) + { DestroyWindow(g_SplashWnd); g_SplashWnd = NULL; + if (g_hLogoBmp) { DeleteObject(g_hLogoBmp); g_hLogoBmp = NULL; } + if (g_hFontTitle) { DeleteObject(g_hFontTitle); g_hFontTitle = NULL; } + if (g_hFontStatus) { DeleteObject(g_hFontStatus); g_hFontStatus = NULL; } + if (g_hFontCount) { DeleteObject(g_hFontCount); g_hFontCount = NULL; } UnregisterClassW(L"ModLoaderSplash", GetModuleHandle(NULL)); Gdiplus::GdiplusShutdown(g_gdiplusToken); } } -void ModLoader::NotifyInit() { - for (auto& mod : m_mods) { +// --------------------------------------------------------------------------- +// Mod lifecycle +// --------------------------------------------------------------------------- +void ModLoader::NotifyInit() +{ + for (auto& mod : m_mods) + { if (!mod.healthy) continue; - try { - if (!mod.instance->OnInit()) { + try + { + if (!mod.instance->OnInit()) + { Log("OnInit() returned false for: " + std::string(mod.instance->GetInfo()->id)); mod.healthy = false; } } - catch (...) { + catch (...) + { Log("OnInit() threw for: " + std::string(mod.instance->GetInfo()->id)); mod.healthy = false; } } } -void ModLoader::OnLevelLoad() { +void ModLoader::OnLevelLoad() +{ if (m_levelLoaded) return; m_levelLoaded = true; Log(L"Level loaded"); - for (auto& mod : m_mods) { + for (auto& mod : m_mods) + { if (!mod.healthy) continue; - try { - mod.instance->OnLevelLoad(); - } - catch (...) { - mod.healthy = false; - } + try { mod.instance->OnLevelLoad(); } + catch (...) { mod.healthy = false; } } } -void ModLoader::OnLevelUnload() { +void ModLoader::OnLevelUnload() +{ if (!m_levelLoaded) return; m_levelLoaded = false; Log(L"Level unloaded"); - for (auto& mod : m_mods) { + for (auto& mod : m_mods) + { if (!mod.healthy) continue; - try { - mod.instance->OnLevelUnload(); - } - catch (...) { - mod.healthy = false; - } + try { mod.instance->OnLevelUnload(); } + catch (...) { mod.healthy = false; } } } -void ModLoader::NotifyUpdate(float deltaTime) { - for (auto& mod : m_mods) { +void ModLoader::NotifyUpdate(float deltaTime) +{ + for (auto& mod : m_mods) + { if (!mod.healthy) continue; - if (!mod.instance) { - mod.healthy = false; - continue; - } - try { - if (!mod.instance->OnUpdate(deltaTime)) { + if (!mod.instance) { mod.healthy = false; continue; } + try + { + if (!mod.instance->OnUpdate(deltaTime)) + { Log("OnUpdate() returned false for: " + std::string(mod.instance->GetInfo()->id)); mod.healthy = false; } } - catch (...) { + catch (...) + { Log("OnUpdate() threw for: " + std::string(mod.instance->GetInfo()->id)); mod.healthy = false; } } } -void ModLoader::Shutdown() { +// --------------------------------------------------------------------------- +// Shutdown +// --------------------------------------------------------------------------- +void ModLoader::Shutdown() +{ Log("Shutting down ModLoader"); for (int i = static_cast(m_mods.size()) - 1; i >= 0; --i) UnloadOneMod(m_mods[i]); m_mods.clear(); - if (m_logFile != INVALID_HANDLE_VALUE) { + if (m_logFile != INVALID_HANDLE_VALUE) + { CloseHandle(m_logFile); m_logFile = INVALID_HANDLE_VALUE; } } -IMod* ModLoader::FindMod(const std::string& id) const { - for (const auto& mod : m_mods) { +// --------------------------------------------------------------------------- +// Mod lookup +// --------------------------------------------------------------------------- +IMod* ModLoader::FindMod(const std::string& id) const +{ + for (const auto& mod : m_mods) + { if (mod.healthy && mod.instance && std::string(mod.instance->GetInfo()->id) == id) return mod.instance; @@ -236,9 +374,14 @@ IMod* ModLoader::FindMod(const std::string& id) const { return nullptr; } -void ModLoader::ScanAndLoadMods(const std::wstring& modsDir) { +// --------------------------------------------------------------------------- +// Scanning & loading +// --------------------------------------------------------------------------- +void ModLoader::ScanAndLoadMods(const std::wstring& modsDir) +{ DWORD dwAttrib = GetFileAttributesW(modsDir.c_str()); - if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) + { CreateDirectoryW(modsDir.c_str(), NULL); Log("Mods directory not found — created it"); return; @@ -248,7 +391,8 @@ void ModLoader::ScanAndLoadMods(const std::wstring& modsDir) { std::wstring searchPath = modsDir + L"\\*.dll"; WIN32_FIND_DATAW fd; HANDLE hFind = FindFirstFileW(searchPath.c_str(), &fd); - if (hFind != INVALID_HANDLE_VALUE) { + if (hFind != INVALID_HANDLE_VALUE) + { do { if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) dllPaths.push_back(modsDir + L"\\" + fd.cFileName); @@ -259,21 +403,24 @@ void ModLoader::ScanAndLoadMods(const std::wstring& modsDir) { g_TotalMods = static_cast(dllPaths.size()); Log("Found " + std::to_string(g_TotalMods) + " mod(s) to load"); - for (const auto& path : dllPaths) { + for (const auto& path : dllPaths) + { std::wstring filename = path.substr(path.find_last_of(L"\\/") + 1); UpdateSplashStatus(L"Loading: " + filename); LoadOneMod(path); } } -bool ModLoader::LoadOneMod(const std::wstring& dllPath) { +bool ModLoader::LoadOneMod(const std::wstring& dllPath) +{ std::string narrowPath(dllPath.begin(), dllPath.end()); std::string filename = narrowPath.substr(narrowPath.find_last_of("\\/") + 1); auto t0 = std::chrono::steady_clock::now(); HMODULE hMod = LoadLibraryW(dllPath.c_str()); - if (!hMod) { + if (!hMod) + { Log("FAIL [" + filename + "] LoadLibrary failed (error " + std::to_string(GetLastError()) + ")"); ++g_FailedMods; return false; @@ -281,7 +428,8 @@ bool ModLoader::LoadOneMod(const std::wstring& dllPath) { using CreateModFn = IMod * (*)(); auto createFn = reinterpret_cast(GetProcAddress(hMod, "CreateMod")); - if (!createFn) { + if (!createFn) + { Log("FAIL [" + filename + "] missing CreateMod export"); FreeLibrary(hMod); ++g_FailedMods; @@ -289,17 +437,17 @@ bool ModLoader::LoadOneMod(const std::wstring& dllPath) { } IMod* instance = nullptr; - try { - instance = createFn(); - } - catch (...) { + try { instance = createFn(); } + catch (...) + { Log("FAIL [" + filename + "] CreateMod() threw"); FreeLibrary(hMod); ++g_FailedMods; return false; } - if (!instance) { + if (!instance) + { Log("FAIL [" + filename + "] CreateMod() returned null"); FreeLibrary(hMod); ++g_FailedMods; @@ -309,9 +457,7 @@ bool ModLoader::LoadOneMod(const std::wstring& dllPath) { const ModInfo* info = instance->GetInfo(); std::string modId = info ? info->id : "(unknown)"; std::string modVer = info - ? std::to_string(info->version.major) + "." - + std::to_string(info->version.minor) + "." - + std::to_string(info->version.patch) + ? std::to_string(info->version.major) + "." + std::to_string(info->version.minor) + "." + std::to_string(info->version.patch) : "(unknown)"; LoadedMod record; @@ -319,13 +465,16 @@ bool ModLoader::LoadOneMod(const std::wstring& dllPath) { record.instance = instance; record.path = narrowPath; - try { - if (!instance->OnLoad()) { + try + { + if (!instance->OnLoad()) + { Log("WARN [" + modId + " " + modVer + "] OnLoad() returned false — marking unhealthy"); record.healthy = false; } } - catch (...) { + catch (...) + { Log("FAIL [" + modId + " " + modVer + "] OnLoad() threw — marking unhealthy"); record.healthy = false; } @@ -333,11 +482,13 @@ bool ModLoader::LoadOneMod(const std::wstring& dllPath) { auto elapsed = std::chrono::duration_cast( std::chrono::steady_clock::now() - t0).count(); - if (record.healthy) { + if (record.healthy) + { Log("OK [" + modId + " " + modVer + "] loaded in " + std::to_string(elapsed) + "ms"); ++g_LoadedMods; } - else { + else + { ++g_FailedMods; } @@ -345,7 +496,8 @@ bool ModLoader::LoadOneMod(const std::wstring& dllPath) { return record.healthy; } -void ModLoader::UnloadOneMod(LoadedMod& mod) { +void ModLoader::UnloadOneMod(LoadedMod& mod) +{ if (!mod.instance) return; if (mod.instance->GetInfo()) @@ -354,22 +506,26 @@ void ModLoader::UnloadOneMod(LoadedMod& mod) { delete mod.instance; mod.instance = nullptr; - if (mod.module) { + if (mod.module) + { FreeLibrary(mod.module); mod.module = nullptr; } } -void ModLoader::OpenLogFile() { +// --------------------------------------------------------------------------- +// Logging +// --------------------------------------------------------------------------- +void ModLoader::OpenLogFile() +{ std::wstring logPath = GetModsDirectory() + L"\\modloader.log"; CreateDirectoryW(GetModsDirectory().c_str(), NULL); m_logFile = CreateFileW(logPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - - } -void ModLoader::Log(const std::string& msg) { +void ModLoader::Log(const std::string& msg) +{ auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); struct tm buf; @@ -379,7 +535,8 @@ void ModLoader::Log(const std::string& msg) { std::string line = std::string(ts) + msg + "\r\n"; - if (m_logFile != INVALID_HANDLE_VALUE) { + if (m_logFile != INVALID_HANDLE_VALUE) + { DWORD written; WriteFile(m_logFile, line.c_str(), static_cast(line.size()), &written, nullptr); } @@ -387,11 +544,16 @@ void ModLoader::Log(const std::string& msg) { OutputDebugStringA(line.c_str()); } -void ModLoader::Log(const std::wstring& msg) { +void ModLoader::Log(const std::wstring& msg) +{ Log(std::string(msg.begin(), msg.end())); } -std::wstring ModLoader::GetModsDirectory() const { +// --------------------------------------------------------------------------- +// Paths +// --------------------------------------------------------------------------- +std::wstring ModLoader::GetModsDirectory() const +{ wchar_t exePath[MAX_PATH] = {}; GetModuleFileNameW(nullptr, exePath, MAX_PATH); std::wstring dir = exePath; diff --git a/Minecraft.Client/x64/Debug/Minecraft.Client.log b/Minecraft.Client/x64/Debug/Minecraft.Client.log index f4521513..f1a59897 100644 --- a/Minecraft.Client/x64/Debug/Minecraft.Client.log +++ b/Minecraft.Client/x64/Debug/Minecraft.Client.log @@ -1,4 +1,37 @@ - UIScene_ModsMenu.cpp + ModLoader.cpp +C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(4813,18): warning C4244: '=': conversion from 'const wchar_t' to 'char', possible loss of data + (compiling source file '/ModLoader.cpp') + C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(4813,18): + the template instantiation context (the oldest one first) is + S:\GitHub\Faucet\Minecraft.Client\ModLoader.cpp(416,27): + see reference to function template instantiation 'std::basic_string,std::allocator>::basic_string>>,0>(_Iter,_Iter,const _Alloc &)' being compiled + with + [ + _Elem=wchar_t, + _Iter=std::_String_const_iterator>>, + _Alloc=std::allocator + ] + S:\GitHub\Faucet\Minecraft.Client\ModLoader.cpp(416,27): + see the first reference to 'std::basic_string,std::allocator>::basic_string' in 'ModLoader::LoadOneMod' + C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xstring(812,17): + see reference to function template instantiation 'void std::basic_string,std::allocator>::_Construct_from_iter(_Iter,const _Sent,_Size)' being compiled + with + [ + _Size_type=unsigned __int64, + _Iter=const wchar_t *, + _Sent=const wchar_t *, + _Size=unsigned __int64 + ] + C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xstring(968,18): + see reference to function template instantiation '_OutIt *std::_Copy_n_unchecked4(_InIt,_SizeTy,_OutIt)' being compiled + with + [ + _OutIt=char *, + _Size=unsigned __int64, + _InIt=const wchar_t *, + _SizeTy=unsigned __int64 + ] + Microsoft (R) Incremental Linker Version 14.44.35222.0 Copyright (C) Microsoft Corporation. All rights reserved. "/OUT:S:\GitHub\Faucet\x64\Debug\Faucet.exe" /INCREMENTAL "/ILK:x64\Debug\Faucet.ilk" d3d11.lib ..\Minecraft.World\x64_Debug\Minecraft.World.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib XInput9_1_0.lib ..\Minecraft.Client\Windows64\Miles\Lib\mss64.lib wsock32.lib /MANIFEST "/MANIFESTUAC:level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG "/PDB:S:\GitHub\Faucet\x64\Debug\Minecraft.Client.pdb" /TLBID:1 /DYNAMICBASE /NXCOMPAT "/IMPLIB:S:\GitHub\Faucet\x64\Debug\Faucet.lib" /MACHINE:X64 x64\Debug\MinecraftWindows.res @@ -506,40 +539,6 @@ Windows64\Iggy\lib\iggy_w64.lib Windows64\Miles\lib\mss64.lib x64\Debug\iob_shim.obj -4J_Input_d.lib(4J_Input.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Input_d.lib(4J_Input.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Input_d.lib(INP_Keyboard.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Input_d.lib(INP_Keyboard.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Input_d.lib(INP_Main.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Input_d.lib(INP_Main.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Input_d.lib(stdafx.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Input_d.lib(stdafx.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Input_d.lib(LinkedList.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Input_d.lib(LinkedList.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Input_d.lib(INP_ForceFeedback.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Input_d.lib(INP_ForceFeedback.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(4J_Render.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(4J_Render.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(RendererMatrix.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(RendererMatrix.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(RendererCore.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(RendererCore.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(RendererVertex.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(RendererVertex.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(RendererCBuff.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(RendererCBuff.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(RendererTexture.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(RendererTexture.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(RendererState.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(RendererState.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(stdafx.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(stdafx.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngread.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngread.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngwrite.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngwrite.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(png.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(png.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngrtran.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngrtran.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngtrans.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngtrans.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngrio.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngrio.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngmem.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngmem.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngerror.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngerror.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngset.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngset.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngget.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngget.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngrutil.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngrutil.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngwutil.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngwutil.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngwio.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngwio.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Render_PC_d.lib(pngwtran.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Render_PC_d.lib(pngwtran.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Storage_d.lib(4J_Storage.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Storage_d.lib(4J_Storage.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Storage_d.lib(STO_SaveGame.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Storage_d.lib(STO_SaveGame.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Storage_d.lib(STO_DLC.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Storage_d.lib(STO_DLC.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Storage_d.lib(STO_Main.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Storage_d.lib(STO_Main.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info -4J_Storage_d.lib(stdafx.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with '4J_Storage_d.lib(stdafx.obj)' or at 'S:\GitHub\Faucet\x64\Debug\vc110.pdb'; linking object as if no debug info - Creating library S:\GitHub\Faucet\x64\Debug\Faucet.lib and object S:\GitHub\Faucet\x64\Debug\Faucet.exp Minecraft.Client.vcxproj -> S:\GitHub\Faucet\x64\Debug\Faucet.exe Run post-build script Post-build script started. Output Directory: S:\GitHub\Faucet\x64\Debug\/, Project Directory: S:\GitHub\Faucet\Minecraft.Client\/ diff --git a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.command.1.tlog b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.command.1.tlog index 33d5ad82..49293396 100644 Binary files a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.command.1.tlog and b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.command.1.tlog differ diff --git a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.read.1.tlog b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.read.1.tlog index 04c5680f..348887f4 100644 Binary files a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.read.1.tlog and b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.read.1.tlog differ diff --git a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.write.1.tlog b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.write.1.tlog index 435e543e..11d8b146 100644 Binary files a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.write.1.tlog and b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/CL.write.1.tlog differ diff --git a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/link.read.1.tlog b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/link.read.1.tlog index f663ade1..2bc0db85 100644 Binary files a/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/link.read.1.tlog and b/Minecraft.Client/x64/Debug/Minecraft.Client.tlog/link.read.1.tlog differ diff --git a/Minecraft.Client/x64/Debug/ModLoader.obj b/Minecraft.Client/x64/Debug/ModLoader.obj index ddb33182..9b866318 100644 Binary files a/Minecraft.Client/x64/Debug/ModLoader.obj and b/Minecraft.Client/x64/Debug/ModLoader.obj differ diff --git a/x64/Debug/Faucet.exe b/x64/Debug/Faucet.exe index 1fcf912e..f87c0cbe 100644 Binary files a/x64/Debug/Faucet.exe and b/x64/Debug/Faucet.exe differ diff --git a/x64/Debug/mods/modloader.log b/x64/Debug/mods/modloader.log index 8ed2f2cc..778c21b7 100644 --- a/x64/Debug/mods/modloader.log +++ b/x64/Debug/mods/modloader.log @@ -1,3 +1,3 @@ -[16:46:29] === Faucet ModLoader starting === -[16:46:29] Found 0 mod(s) to load -[16:46:29] Initialization complete — 0 loaded, 0 failed, 116ms total +[16:54:27] === Faucet ModLoader starting === +[16:54:27] Found 0 mod(s) to load +[16:54:27] Initialization complete — 0 loaded, 0 failed, 169ms total