#include #include #include "Modules/Bans.hpp" #include "Modules/Bots.hpp" #include "Modules/Branding.hpp" #include "Modules/Bullet.hpp" #include "Modules/CardTitles.hpp" #include "Modules/Ceg.hpp" #include "Modules/Changelog.hpp" #include "Modules/Chat.hpp" #include "Modules/ClanTags.hpp" #include "Modules/ClientCommand.hpp" #include "Modules/ConnectProtocol.hpp" #include "Modules/Console.hpp" #include "Modules/D3D9Ex.hpp" #include "Modules/Debug.hpp" #include "Modules/Discord.hpp" #include "Modules/Discovery.hpp" #include "Modules/Download.hpp" #include "Modules/Elevators.hpp" #include "Modules/FastFiles.hpp" #include "Modules/Gamepad.hpp" #include "Modules/Lean.hpp" #include "Modules/MapDump.hpp" #include "Modules/MapRotation.hpp" #include "Modules/NetworkDebug.hpp" #include "Modules/News.hpp" #include "Modules/Party.hpp" #include "Modules/PlayerMovement.hpp" #include "Modules/PlayerName.hpp" #include "Modules/Playlist.hpp" #include "Modules/QuickPatch.hpp" #include "Modules/RawFiles.hpp" #include "Modules/RawMouse.hpp" #include "Modules/RCon.hpp" #include "Modules/Security.hpp" #include "Modules/ServerCommands.hpp" #include "Modules/ServerInfo.hpp" #include "Modules/ServerList.hpp" #include "Modules/Session.hpp" #include "Modules/SlowMotion.hpp" #include "Modules/SoundMutexFix.hpp" #include "Modules/StartupMessages.hpp" #include "Modules/Stats.hpp" #include "Modules/StringTable.hpp" #include "Modules/StructuredData.hpp" #include "Modules/Theatre.hpp" #include "Modules/Threading.hpp" #include "Modules/UIFeeder.hpp" #include "Modules/UserInfo.hpp" #include "Modules/VisionFile.hpp" #include "Modules/Voice.hpp" #include "Modules/Vote.hpp" #include "Modules/Weapon.hpp" #include "Modules/BotLib/lPrecomp.hpp" namespace Components { bool Loader::Pregame = true; bool Loader::Postgame = false; bool Loader::Uninitializing = false; std::vector Loader::Components; bool Loader::IsPregame() { return Pregame; } bool Loader::IsPostgame() { return Postgame; } bool Loader::IsUninitializing() { return Uninitializing; } void Loader::Initialize() { Pregame = true; Postgame = false; Uninitializing = false; Utils::Memory::GetAllocator()->clear(); // High priority Register(new Singleton()); Register(new Auth()); Register(new Command()); Register(new Dvar()); Register(new Exception()); // Install our exception handler as early as possible to get better debug dumps from startup crashes Register(new IPCPipe()); Register(new Network()); Register(new Logger()); Register(new UIScript()); Register(new ZoneBuilder()); Register(new ArenaLength()); Register(new AssetHandler()); Register(new Bans()); Register(new Bots()); Register(new Branding()); Register(new Bullet()); Register(new CardTitles()); Register(new Ceg()); Register(new Changelog()); Register(new Chat()); Register(new ClanTags()); Register(new ClientCommand()); Register(new ConnectProtocol()); Register(new Console()); Register(new D3D9Ex()); Register(new Debug()); Register(new Dedicated()); Register(new Discord()); Register(new Discovery()); Register(new Download()); Register(new Elevators()); Register(new Events()); Register(new FastFiles()); Register(new FileSystem()); Register(new Friends()); Register(new Gamepad()); Register(new Lean()); Register(new Localization()); Register(new MapDump()); Register(new MapRotation()); Register(new Maps()); Register(new Materials()); Register(new Menus()); Register(new ModList()); Register(new ModelSurfs()); Register(new NetworkDebug()); Register(new News()); Register(new Node()); Register(new Party()); Register(new PlayerMovement()); Register(new PlayerName()); Register(new Playlist()); Register(new QuickPatch()); Register(new RawFiles()); Register(new RawMouse()); Register(new RCon()); Register(new Renderer()); Register(new Scheduler()); Register(new Security()); Register(new ServerCommands()); Register(new ServerInfo()); Register(new ServerList()); Register(new Session()); Register(new SlowMotion()); Register(new SoundMutexFix()); Register(new StartupMessages()); Register(new Stats()); Register(new StringTable()); Register(new StructuredData()); Register(new TextRenderer()); Register(new Theatre()); Register(new Threading()); Register(new Toast()); Register(new UIFeeder()); Register(new UserInfo()); Register(new VisionFile()); Register(new Voice()); Register(new Vote()); Register(new Weapon()); Register(new Window()); Register(new Zones()); Register(new GSC()); Register(new lPrecomp()); Pregame = false; // Make sure preDestroy is called when the game shuts down Scheduler::OnGameShutdown(PreDestroy); } void Loader::Uninitialize() { Uninitializing = true; PreDestroyNoPostGame(); std::reverse(Components.begin(), Components.end()); for (auto& component : Components) { #ifdef DEBUG if (!IsPerformingUnitTests()) { Logger::Print("Unregister component: {}\n", component->getName()); } #endif delete component; } Components.clear(); Utils::Memory::GetAllocator()->clear(); Uninitializing = false; } void Loader::PreDestroy() { if (!Postgame) { Postgame = true; auto components = Components; std::reverse(components.begin(), components.end()); for (auto& component : components) { component->preDestroy(); } } } void Loader::PreDestroyNoPostGame() { if (!Postgame) { auto components = Components; std::reverse(components.begin(), components.end()); for (auto& component : components) { component->preDestroy(); } Postgame = true; } } bool Loader::PerformUnitTests() { bool result = true; Logger::Print("Performing unit tests for components:\n"); for (const auto& component : Components) { #if defined(FORCE_UNIT_TESTS) Logger::Debug("Testing '{}'...\n", component->getName()); #endif auto startTime = std::chrono::high_resolution_clock::now(); auto testRes = component->unitTest(); auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - startTime).count(); Logger::Print("Test done ({}ms): {}\n\n", duration, (testRes ? "Success" : "Error")); result &= testRes; } return result; } bool Loader::IsPerformingUnitTests() { #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) return Flags::HasFlag("tests"); #else return false; #endif } void Loader::Register(Component* component) { if (component) { #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) if (!IsPerformingUnitTests()) { Logger::Print("Component registered: {}\n", component->getName()); } #endif Components.push_back(component); } } }