From 497a4856015dfd76fa15e53dbfef6a052deb539c Mon Sep 17 00:00:00 2001 From: Unreal Karaulov Date: Sun, 10 Dec 2023 09:46:00 +0300 Subject: [PATCH] Fix crashes in console mode. Update language.ini! Fix crashes in console mode. Update language.ini is required! --- .gitignore | 1 + cfg/language.ini | 10 +- src/bsp/Bsp.cpp | 2 +- src/bsp/BspMerger.cpp | 2 +- src/cli/CommandLine.cpp | 3 +- src/cli/CommandLine.h | 1 + src/editor/Gui.cpp | 2 +- src/editor/Renderer.cpp | 3 - src/editor/Settings.cpp | 4 +- src/main.cpp | 281 ++++++++++++++++++++------------- vs-project/bspguy.vcxproj | 1 + vs-project/bspguy.vcxproj.user | 2 +- 12 files changed, 191 insertions(+), 121 deletions(-) diff --git a/.gitignore b/.gitignore index 65e7a8a4..d554a895 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ vs-project/fmt/fmt.dir/Release/fmt.vcxproj.FileListAbsolute.txt *.lit vs-project/Release/newbspguy.zip vs-project/Release/language.ini +vs-project/log.txt diff --git a/cfg/language.ini b/cfg/language.ini index f4d9bf72..74625e20 100644 --- a/cfg/language.ini +++ b/cfg/language.ini @@ -32,7 +32,7 @@ LANG_0030 = Generating minidump at path {}\n LANG_0031 = Crash\n WINAPI_LASTERROR:{}.\n Exception code: {}.\n Exception address: {}.\n Main module address: {}\n LANG_0032 = Open editor with empty map. LANG_0033 = Load settings from : {}\n -LANG_0034 = ERROR: File not found: {} +LANG_0034 = ERROR: File not found: {}\n LANG_0035 = Loaded empty map.\n LANG_0036 = ERROR: {} not found\n LANG_0037 = {} is not a valid BSP file\n @@ -105,9 +105,9 @@ LANG_0103 = {}.bsp ent data (line {}): Unexpected '{'\n LANG_0104 = {}.bsp ent data (line {}): Unexpected '}'\n LANG_0105 = Found unknown classname entity. Skip it.\n LANG_0106 = First entity has classname different from 'woldspawn', we do fixup it\n -LANG_0107 = {:-12s} +LANG_0107 = {:>12} LANG_0108 = (OVERFLOW!!!) -LANG_0109 = {:-26s} {:-26s} *{:-6d} {:9d} +LANG_0109 = {:>26} {:>26} *{:>6d} {:9d} LANG_0110 = Bad face reference in marksurf {}: {} / {}\n LANG_0111 = Bad edge reference in surfedge {}: {} / {}\n LANG_0112 = Bad texture reference in textureinfo {}: {} / {}\n @@ -136,7 +136,7 @@ LANG_0134 = Error: found memory leak in texture->name of {} texture.\n LANG_0135 = Warning: texture data buffer overrun in {} texture. {} > {}.\n LANG_0136 = Tex size {}. Tex name "{}". Tex offset {}. Data offset {}. \n LANG_0137 = Unable to show model stats while BSP limits are exceeded.\n -LANG_0138 = Classname Targetname Model {:-10s} Usage\n +LANG_0138 = Classname Targetname Model {:>10} Usage\n LANG_0139 = Data Type Current / Max Fullness\n LANG_0140 = NODE ({:.2f}, {:.2f}, {:.2f} @ {:.2}\n LANG_0141 = Invalid hull number. Clipnode hull numbers are 0 - {}\n @@ -264,7 +264,7 @@ LANG_0262 = Converted WADTEX to RGBA name {} size {}/{}\n LANG_0263 = Convert BSPMIPTEX to RGBA name {} size {}/{}\n LANG_0264 = Converted BSPMIPTEX to RGBA name {} size {}/{}\n LANG_0265 = ERROR: invalid number of coordinates for option {}\n -LANG_0266 = \r {:-32s} {:.0f}% +LANG_0266 = \r {:>32} {:.0f}% LANG_0267 = Move camera to first entity...\n LANG_0268 = Missing WAD: {}\n LANG_0269 = Loading WAD {}\n diff --git a/src/bsp/Bsp.cpp b/src/bsp/Bsp.cpp index d71edd82..b88696bd 100644 --- a/src/bsp/Bsp.cpp +++ b/src/bsp/Bsp.cpp @@ -3919,7 +3919,7 @@ void Bsp::print_stat(const std::string& name, unsigned int val, unsigned int max } else { - logf("{:8u} / {:-8u}", val, max); + logf("{:8} / {:>8}", val, max); } logf(" {:6.1f}%", percent); diff --git a/src/bsp/BspMerger.cpp b/src/bsp/BspMerger.cpp index 0e0530ab..4be3494b 100644 --- a/src/bsp/BspMerger.cpp +++ b/src/bsp/BspMerger.cpp @@ -131,7 +131,7 @@ void BspMerger::merge(MAPBLOCK& dst, MAPBLOCK& src, std::string resultType) std::string thisName = dst.merge_name.size() ? dst.merge_name : dst.map->bsp_name; std::string otherName = src.merge_name.size() ? src.merge_name : src.map->bsp_name; dst.merge_name = std::move(resultType); - logf(" {:-8s} = {} + {}\n", dst.merge_name, thisName, otherName); + logf(" {:>8} = {} + {}\n", dst.merge_name, thisName, otherName); merge(*dst.map, *src.map); } diff --git a/src/cli/CommandLine.cpp b/src/cli/CommandLine.cpp index 9d98a60f..8d1f8f19 100644 --- a/src/cli/CommandLine.cpp +++ b/src/cli/CommandLine.cpp @@ -5,8 +5,7 @@ #endif CommandLine::CommandLine(int argc, char* argv[]) { - askingForHelp = argc <= 1; - + askingForHelp = false; for (int i = 0; i < argc; i++) { std::string arg = argv[i]; diff --git a/src/cli/CommandLine.h b/src/cli/CommandLine.h index e3a07e2f..3f476828 100644 --- a/src/cli/CommandLine.h +++ b/src/cli/CommandLine.h @@ -9,6 +9,7 @@ class CommandLine std::vector options; bool askingForHelp; + CommandLine() = default; CommandLine(int argc, char* argv[]); bool hasOption(const std::string& optionName); diff --git a/src/editor/Gui.cpp b/src/editor/Gui.cpp index 4cab6129..14881f51 100644 --- a/src/editor/Gui.cpp +++ b/src/editor/Gui.cpp @@ -8530,7 +8530,7 @@ ModelInfo Gui::calcModelStat(Bsp* map, STRUCTUSAGE* modelInfo, unsigned int val, tmp = fmt::format("{:8.1f}", val / meg); stat.val = std::to_string(val); - tmp = fmt::format("{:-5.1f} MB", max / meg); + tmp = fmt::format("{:>5.1f} MB", max / meg); stat.usage = tmp; } else diff --git a/src/editor/Renderer.cpp b/src/editor/Renderer.cpp index c3b7f149..176e6987 100644 --- a/src/editor/Renderer.cpp +++ b/src/editor/Renderer.cpp @@ -138,9 +138,6 @@ Renderer::Renderer() return; } - g_settings.loadDefault(); - g_settings.load(); - gui = new Gui(this); loadSettings(); diff --git a/src/editor/Settings.cpp b/src/editor/Settings.cpp index 2b14076f..e4e9dca6 100644 --- a/src/editor/Settings.cpp +++ b/src/editor/Settings.cpp @@ -12,7 +12,7 @@ std::string g_current_dir = "."; std::string g_game_dir = ""; std::string g_working_dir = ""; -AppSettings g_settings; +AppSettings g_settings{}; void AppSettings::loadDefault() { @@ -160,6 +160,8 @@ void AppSettings::reset() void AppSettings::load() { + set_localize_lang("EN"); + std::ifstream file(g_settings_path); if (!file.is_open()) { diff --git a/src/main.cpp b/src/main.cpp index f0475386..93da0b36 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -96,7 +96,7 @@ // Removing HULL 0 from solid model crashes game when standing on it -std::string g_version_string = "bspguy v4.10"; +std::string g_version_string = "newbspguy v4.10"; bool g_verbose = false; @@ -138,8 +138,8 @@ bool start_viewer(const char* map) int test() { -//start_viewer("hl_c09.bsp"); -//return 0; + //start_viewer("hl_c09.bsp"); + //return 0; std::vector maps; @@ -168,7 +168,7 @@ int test() { logf(""); } - logf(get_localized_string(LANG_0002),maps[i]->bsp_name); + logf(get_localized_string(LANG_0002), maps[i]->bsp_name); maps[i]->delete_hull(2, 1); //removed.add(maps[i]->delete_unused_hulls()); removed.add(maps[i]->remove_unused_model_structures()); @@ -219,7 +219,7 @@ int merge_maps(CommandLine& cli) for (int i = 0; i < maps.size(); i++) { - logf(get_localized_string(LANG_0004),maps[i]->bsp_name); + logf(get_localized_string(LANG_0004), maps[i]->bsp_name); logf(get_localized_string(LANG_0005)); STRUCTCOUNT removed = maps[i]->remove_unused_model_structures(); @@ -294,7 +294,7 @@ int print_info(CommandLine& cli) } else { - logf(get_localized_string(LANG_0008),limitName); + logf(get_localized_string(LANG_0008), limitName); delete map; return 0; } @@ -371,22 +371,22 @@ int noclip(CommandLine& cli) if (model < 0 || model >= map->modelCount) { - logf(get_localized_string(LANG_0014),map->modelCount); + logf(get_localized_string(LANG_0014), map->modelCount); return 1; } if (hull != -1) { if (redirect) - logf(get_localized_string(LANG_0015),hull,redirect,model); + logf(get_localized_string(LANG_0015), hull, redirect, model); else - logf(get_localized_string(LANG_0016),hull,model); + logf(get_localized_string(LANG_0016), hull, model); map->delete_hull(hull, model, redirect); } else { - logf(get_localized_string(LANG_0017),model); + logf(get_localized_string(LANG_0017), model); for (int i = 1; i < MAX_MAP_HULLS; i++) { map->delete_hull(i, model, redirect); @@ -405,14 +405,14 @@ int noclip(CommandLine& cli) if (hull != -1) { if (redirect) - logf(get_localized_string(LANG_0019),hull,redirect); + logf(get_localized_string(LANG_0019), hull, redirect); else - logf(get_localized_string(LANG_0020),hull); + logf(get_localized_string(LANG_0020), hull); map->delete_hull(hull, redirect); } else { - logf(get_localized_string(LANG_0021),hull); + logf(get_localized_string(LANG_0021), hull); for (int i = 1; i < MAX_MAP_HULLS; i++) { map->delete_hull(i, redirect); @@ -480,17 +480,17 @@ int simplify(CommandLine& cli) if (modelIdx < 0 || modelIdx >= map->modelCount) { - logf(get_localized_string(LANG_1018),map->modelCount); + logf(get_localized_string(LANG_1018), map->modelCount); return 1; } if (hull != 0) { - logf(get_localized_string(LANG_0025),hull,modelIdx); + logf(get_localized_string(LANG_0025), hull, modelIdx); } else { - logf(get_localized_string(LANG_0026),modelIdx); + logf(get_localized_string(LANG_0026), modelIdx); } map->simplify_model_collision(modelIdx, hull); @@ -536,7 +536,7 @@ int deleteCmd(CommandLine& cli) { int modelIdx = cli.getOptionInt("-model"); - logf(get_localized_string(LANG_0027),modelIdx); + logf(get_localized_string(LANG_0027), modelIdx); map->delete_model(modelIdx); map->update_ent_lump(); removed = map->remove_unused_model_structures(); @@ -569,7 +569,7 @@ int transform(CommandLine& cli) move = cli.getOptionVector("-move"); logf("Applying offset ({:.2f}, {:.2f}, {:.2f})\n", - move.x, move.y, move.z); + move.x, move.y, move.z); map->move(move); } @@ -597,7 +597,7 @@ int unembed(CommandLine& cli) if (map->bsp_valid) { int deleted = map->delete_embedded_textures(); - logf(get_localized_string(LANG_0029),deleted); + logf(get_localized_string(LANG_0029), deleted); if (map->isValid()) map->write(cli.hasOption("-o") ? cli.getOption("-o") : map->bsp_path); logf("\n"); @@ -797,10 +797,10 @@ void make_minidump(EXCEPTION_POINTERS* e) SYSTEMTIME t; GetSystemTime(&t); wsprintfA(nameEnd - strlen(".exe"), - "_%4d%02d%02d_%02d%02d%02d(%d).dmp", - t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, crashdumps); + "_%4d%02d%02d_%02d%02d%02d(%d).dmp", + t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, crashdumps); - logf(get_localized_string(LANG_0030),name); + logf(get_localized_string(LANG_0030), name); auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) @@ -831,15 +831,15 @@ LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) { DWORD exceptionCode = e->ExceptionRecord->ExceptionCode; - // Not interested in non-error exceptions. In this category falls exceptions - // like: - // 0x40010006 - OutputDebugStringA. Seen when no debugger is attached - // (otherwise debugger swallows the exception and prints - // the string). - // 0x406D1388 - DebuggerProbe. Used by debug CRT - for example see source - // code of isatty(). Used to name a thread as well. - // RPC_E_DISCONNECTED and Co. - COM IPC non-fatal warnings - // STATUS_BREAKPOINT and Co. - Debugger related breakpoints + // Not interested in non-error exceptions. In this category falls exceptions + // like: + // 0x40010006 - OutputDebugStringA. Seen when no debugger is attached + // (otherwise debugger swallows the exception and prints + // the string). + // 0x406D1388 - DebuggerProbe. Used by debug CRT - for example see source + // code of isatty(). Used to name a thread as well. + // RPC_E_DISCONNECTED and Co. - COM IPC non-fatal warnings + // STATUS_BREAKPOINT and Co. - Debugger related breakpoints if ((exceptionCode & ERROR_SEVERITY_ERROR) != ERROR_SEVERITY_ERROR) { return ExceptionContinueExecution; @@ -854,8 +854,8 @@ LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) return ExceptionContinueExecution; } - logf(get_localized_string(LANG_0031),GetLastError(),e->ExceptionRecord->ExceptionCode,e->ExceptionRecord->ExceptionAddress,(void *)GetModuleHandleA(0)); - + logf(get_localized_string(LANG_0031), GetLastError(), e->ExceptionRecord->ExceptionCode, e->ExceptionRecord->ExceptionAddress, (void*)GetModuleHandleA(0)); + if (crashdumps > 0) { crashdumps--; @@ -873,92 +873,131 @@ int main(int argc, char* argv[]) setlocale(LC_ALL, ".utf8"); setlocale(LC_NUMERIC, "C"); - std::cout << std::endl << "BSPGUY" << std::endl; + std::cout << "BSPGUY:" << g_version_string << std::endl; //std::fesetround(FE_TONEAREST); + try + { #ifdef WIN32 - ::ShowWindow(::GetConsoleWindow(), SW_SHOW); + ::ShowWindow(::GetConsoleWindow(), SW_SHOW); #ifndef NDEBUG - SetUnhandledExceptionFilter(unhandled_handler); - AddVectoredExceptionHandler(1, unhandled_handler); + SetUnhandledExceptionFilter(unhandled_handler); + AddVectoredExceptionHandler(1, unhandled_handler); #endif - DisableProcessWindowsGhosting(); + DisableProcessWindowsGhosting(); #endif - - if (argv && argv[0] && argv[0][0] != '\0') - { + + if (argv && argv[0] && argv[0][0] != '\0') + { #ifdef WIN32 - int nArgs; - LPWSTR* szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); - g_current_dir = fs::path(szArglist[0]).parent_path().string(); + int nArgs; + LPWSTR* szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); + g_current_dir = fs::path(szArglist[0]).parent_path().string(); #else - g_current_dir = fs::path(argv[0]).parent_path().string(); + g_current_dir = fs::path(argv[0]).parent_path().string(); #endif - fs::current_path(g_current_dir); - } + if (g_current_dir.empty()) + g_current_dir = "./"; + fs::current_path(g_current_dir); + } + #ifdef WIN32 - g_settings_path = GetCurrentDir() + "bspguy.cfg"; - g_config_dir = GetCurrentDir(); + g_settings_path = GetCurrentDir() + "bspguy.cfg"; + g_config_dir = GetCurrentDir(); #else - g_settings_path = GetCurrentDir() + "bspguy.cfg"; - g_config_dir = GetCurrentDir(); + g_settings_path = GetCurrentDir() + "bspguy.cfg"; + g_config_dir = GetCurrentDir(); #endif - // test svencoop merge - //return test(); - CommandLine cli(argc, argv); + g_settings.loadDefault(); + g_settings.load(); - if (cli.command == "version" || cli.command == "--version" || cli.command == "-version") - { - logf("{}", g_version_string); - return 0; - } + CommandLine cli(argc, argv); - if (cli.command == "exportobj") - { - Bsp* tmpBsp = new Bsp(cli.bspfile); - tmpBsp->ExportToObjWIP(cli.bspfile); - delete tmpBsp; - return 0; - } + if (cli.command == "version" || cli.command == "--version" || cli.command == "-version") + { + return 0; + } - if (cli.hasOption("-v") || cli.hasOption("-verbose")) - { - g_verbose = true; - } + if (cli.command == "exportobj") + { + Bsp* tmpBsp = new Bsp(cli.bspfile); + tmpBsp->ExportToObjWIP(cli.bspfile); + delete tmpBsp; + return 0; + } - if (cli.command == "info") - { - return print_info(cli); - } - else if (cli.command == "noclip") - { - return noclip(cli); - } - else if (cli.command == "simplify") - { - return simplify(cli); - } - else if (cli.command == "delete") - { - return deleteCmd(cli); - } - else if (cli.command == "transform") - { - return transform(cli); - } - else if (cli.command == "merge") - { - return merge_maps(cli); - } - else if (cli.command == "unembed") - { - return unembed(cli); - } - else - { - if (cli.bspfile.size() == 0) - logf("{}\n",get_localized_string(LANG_0032)); + if (cli.hasOption("-v") || cli.hasOption("-verbose")) + { + g_verbose = true; + } + + int retval = 0; + + if (cli.command == "info") + { + if (!fileExists(cli.bspfile)) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + retval = 1; + } + else + retval = print_info(cli); + } + else if (cli.command == "noclip") + { + if (!fileExists(cli.bspfile)) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + retval = 1; + } + else + retval = noclip(cli); + } + else if (cli.command == "simplify") + { + if (!fileExists(cli.bspfile)) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + retval = 1; + } + else + retval = simplify(cli); + } + else if (cli.command == "delete") + { + if (!fileExists(cli.bspfile)) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + retval = 1; + } + else + retval = deleteCmd(cli); + } + else if (cli.command == "transform") + { + if (!fileExists(cli.bspfile)) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + retval = 1; + } + else + retval = transform(cli); + } + else if (cli.command == "merge") + { + retval = merge_maps(cli); + } + else if (cli.command == "unembed") + { + if (!fileExists(cli.bspfile)) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + retval = 1; + } + else + retval = unembed(cli); + } else { if (cli.askingForHelp) @@ -966,14 +1005,44 @@ int main(int argc, char* argv[]) print_help(cli.command); return 0; } + else if (cli.bspfile.size() == 0) + logf("{}\n", get_localized_string(LANG_0032)); + else + logf("{}\n", ("Start bspguy editor with: " + cli.bspfile)); + + logf(get_localized_string(LANG_0033), g_settings_path); + if (!start_viewer(cli.bspfile.c_str())) + { + logf(get_localized_string(LANG_0034), cli.bspfile); + } } - logf("{}\n", ("Start bspguy editor with: " + cli.bspfile)); - logf(get_localized_string(LANG_0033),g_settings_path); - if (!start_viewer(cli.bspfile.c_str())) + + if (retval != 0) { - logf(get_localized_string(LANG_0034),cli.bspfile); + print_help(cli.command); + return 1; } } + catch (fs::filesystem_error& ex) + { + std::cout << "std::filesystem fatal error." << std::endl << "what(): " << ex.what() << '\n' + << "path1(): " << ex.path1() << '\n' + << "path2(): " << ex.path2() << '\n' + << "code().value(): " << ex.code().value() << '\n' + << "code().message(): " << ex.code().message() << '\n' + << "code().category(): " << ex.code().category().name() << '\n'; + return 1; + } + catch (std::exception& ex) + { + std::cout << g_version_string << "FATAL ERROR \"" << ex.what() << "\"" << std::endl; + return 1; + } + catch (...) + { + std::cout << g_version_string << "UNKNOWN FATAL ERROR" << std::endl; + return 1; + } return 0; } diff --git a/vs-project/bspguy.vcxproj b/vs-project/bspguy.vcxproj index cefa0ec6..31d83e15 100644 --- a/vs-project/bspguy.vcxproj +++ b/vs-project/bspguy.vcxproj @@ -31,6 +31,7 @@ MultiByte v143 false + Application diff --git a/vs-project/bspguy.vcxproj.user b/vs-project/bspguy.vcxproj.user index b19f6c05..0f0d1164 100644 --- a/vs-project/bspguy.vcxproj.user +++ b/vs-project/bspguy.vcxproj.user @@ -1,7 +1,7 @@  - "c:\Users\Karaulov\Downloads\Desktop\models\test_door.mdl" + info d:\SteamLibrary\steamapps\common\Half-Life\cstrike\maps\cs_backalley.bsp WindowsLocalDebugger