Files
OpenAssetTools/src/ModMan/main.cpp
T
JanandGitHub 85aa7417c4 feat: xmodel preview in ModMan (#835)
* chore: upgrade webwindowed for dynamic assets

* chore: make enums in ModMan lowercase

* chore: add missing platform wiiu in ModMan

* fix: register asset handler on all windows

* chore: properly localize game and platform

* chore: render example cube as xmodel preview

* chore: allow origin * in debug

* feat: show preview of xmodels with ModMan

* feat: show images in xmodel preview

* feat: auto load search paths in ModMan

* chore: load objcontainer of loaded zones in ModMan

* chore: add iw4x specific recognized zone dirs

* chore: show when models are loading

* fix: make sure webwindowed handles window and app destruction in correct order

* chore: track and properly free threejs resources

* chore: add skybox for 3d preview

* chore: add small border radius to preview

* fix: linting

* fix: linux compilation

* chore: update package lock
2026-06-18 18:52:52 +02:00

165 lines
4.8 KiB
C++

#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 <format>
#include <iostream>
#include <string>
#ifdef _WIN32
#include <Windows.h>
#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<webwindowed::window>();
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<webwindowed::window>();
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<webwindowed::asset_handler_plugin>();
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<webwindowed::favicon_handler_plugin>());
app.register_plugin(std::make_shared<webwindowed::title_handler_plugin>());
#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<const char**>(__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;
}