#include "Context/ModManContext.h" #include "GitVersion.h" #include "ModManArgs.h" #include "Web/Binds/Binds.h" #include "Web/UiCommunication.h" #include "Web/ViteAssets.h" #include "Web/WebWindowedLib.h" // Assets #include "Asset/Image/DynamicAssetsImage.h" #include "Asset/XModel/DynamicAssetsXModel.h" #include #include #include #ifdef _WIN32 #include #endif using namespace std::string_literals; namespace { #ifdef _DEBUG void CreateDevToolsWindow() { con::debug("Creating dev tools window"); auto& context = ModManContext::Get(); context.m_dev_tools_window = std::make_shared(); auto& newWindow = *context.m_dev_tools_window; newWindow.set_title("Devtools"); newWindow.set_window_size(640, 480); newWindow.set_window_min(480, 320); const auto result = newWindow.navigate(std::format("http://localhost:{}/__devtools__/", VITE_DEV_SERVER_PORT)); if (!result.has_value()) con::error("Dev tools window navigation failed: {}", result.error().message()); } #endif void RegisterDynamicAssets(webwindowed::asset_handler_plugin& assetHandler) { image::RegisterDynamicAssets(assetHandler); xmodel::RegisterDynamicAssets(assetHandler); } int RunModManApp() { con::debug("Creating main window"); auto& context = ModManContext::Get(); context.m_main_window = std::make_shared(); auto& newWindow = *context.m_main_window; #ifdef _DEBUG newWindow.set_debug(true); #endif newWindow.set_title("OpenAssetTools ModMan"); newWindow.set_window_min(640, 480); newWindow.set_window_size(1280, 640); const auto assetHandlerPlugin = std::make_shared(); assetHandlerPlugin->set_protocol_name("modman"); #ifdef _DEBUG // Allow assets from dev server to access dynamic assets assetHandlerPlugin->set_allow_all_origins(true); #endif for (const auto& asset : VITE_ASSETS) assetHandlerPlugin->add_static_asset(webwindowed::static_asset(asset.filename, asset.data, asset.dataSize)); RegisterDynamicAssets(*assetHandlerPlugin); webwindowed::commands_builder commands; ui::RegisterAllBinds(commands); newWindow.set_commands(commands.build()); #ifdef _DEBUG auto result = newWindow.navigate(VITE_DEV_SERVER ? std::format("http://localhost:{}", VITE_DEV_SERVER_PORT) : assetHandlerPlugin->get_url_for_asset("index.html")); #else auto result = newWindow.navigate(assetHandlerPlugin->get_url_for_asset("index.html")); #endif if (!result.has_value()) con::error("Main window navigation failed: {}", result.error().message()); webwindowed::app app; app.register_plugin(assetHandlerPlugin); app.register_plugin(std::make_shared()); app.register_plugin(std::make_shared()); #ifdef _DEBUG if (VITE_DEV_SERVER) { CreateDevToolsWindow(); result = app.open_window(context.m_dev_tools_window); if (!result.has_value()) con::error("Failed to open dev tools window: {}", result.error().message()); } #endif result = app.run(context.m_main_window); if (!result.has_value()) con::error("Error while running app: {}", result.error().message()); return 0; } } // namespace #ifdef _WIN32 #define MODMAN_ARGC __argc #define MODMAN_ARGV const_cast(__argv) int WINAPI WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/) #else #define MODMAN_ARGC argc #define MODMAN_ARGV argv int main(int argc, const char** argv) #endif { #ifdef _WIN32 // Attach console if possible on Windows for stdout/stderr in console if (AttachConsole(-1)) { FILE* fDummy; (void)freopen_s(&fDummy, "CONOUT$", "w", stdout); (void)freopen_s(&fDummy, "CONOUT$", "w", stderr); (void)freopen_s(&fDummy, "CONIN$", "r", stdin); std::cout.clear(); std::clog.clear(); std::cerr.clear(); std::cin.clear(); } #endif #ifdef __linux__ g_set_prgname("OpenAssetTools-ModMan"); g_set_application_name("OpenAssetTools ModMan"); #endif con::init(); ModManArgs args; auto shouldContinue = true; if (!args.ParseArgs(MODMAN_ARGC, MODMAN_ARGV, shouldContinue)) return 1; if (!shouldContinue) return 0; con::info("Starting ModMan " GIT_VERSION); ModManContext::Get().Startup(); const auto result = RunModManApp(); ModManContext::Get().Destroy(); return result; }