void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output) { AStringVector split = StringSplit(a_Cmd, " "); if (split.empty()) { return; } // Special handling: "stop" and "restart" are built in if ((split[0].compare("stop") == 0) || (split[0].compare("restart") == 0)) { return; } // "help" and "reload" are to be handled by MCS, so that they work no matter what if (split[0] == "help") { PrintHelp(split, a_Output); return; } if (split[0] == "reload") { cPluginManager::Get()->ReloadPlugins(); return; } // There is currently no way a plugin can do these (and probably won't ever be): if (split[0].compare("chunkstats") == 0) { cRoot::Get()->LogChunkStats(a_Output); a_Output.Finished(); return; } #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) if (split[0].compare("dumpmem") == 0) { LeakFinderXmlOutput Output("memdump.xml"); DumpUsedMemory(&Output); return; } if (split[0].compare("killmem") == 0) { while (true) { new char[100 * 1024 * 1024]; // Allocate and leak 100 MiB in a loop -> fill memory and kill MCS } } #endif if (cPluginManager::Get()->ExecuteConsoleCommand(split, a_Output)) { a_Output.Finished(); return; } a_Output.Out("Unknown command, type 'help' for all commands."); a_Output.Finished(); }
void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output) { AStringVector split = StringSplit(a_Cmd, " "); if (split.empty()) { return; } // "stop" and "restart" are handled in cRoot::ExecuteConsoleCommand, our caller, due to its access to controlling variables // "help" and "reload" are to be handled by MCS, so that they work no matter what if (split[0] == "help") { PrintHelp(split, a_Output); a_Output.Finished(); return; } else if (split[0] == "reload") { cPluginManager::Get()->ReloadPlugins(); a_Output.Finished(); return; } else if (split[0] == "reloadplugins") { cPluginManager::Get()->ReloadPlugins(); a_Output.Out("Plugins reloaded"); a_Output.Finished(); return; } else if (split[0] == "load") { if (split.size() > 1) { cPluginManager::Get()->RefreshPluginList(); // Refresh the plugin list, so that if the plugin was added just now, it is loadable a_Output.Out(cPluginManager::Get()->LoadPlugin(split[1]) ? "Plugin loaded" : "Error occurred loading plugin"); } else { a_Output.Out("Usage: load <PluginFolder>"); } a_Output.Finished(); return; } else if (split[0] == "unload") { if (split.size() > 1) { cPluginManager::Get()->UnloadPlugin(split[1]); a_Output.Out("Plugin unload scheduled"); } else { a_Output.Out("Usage: unload <PluginFolder>"); } a_Output.Finished(); return; } if (split[0] == "destroyentities") { class WorldCallback : public cWorldListCallback { virtual bool Item(cWorld * a_World) override { class EntityCallback : public cEntityCallback { virtual bool Item(cEntity * a_Entity) override { if (!a_Entity->IsPlayer()) { a_Entity->Destroy(); } return false; } } EC; a_World->ForEachEntity(EC); return false; } } WC; cRoot::Get()->ForEachWorld(WC); a_Output.Out("Destroyed all entities"); a_Output.Finished(); return; } // There is currently no way a plugin can do these (and probably won't ever be): else if (split[0].compare("chunkstats") == 0) { cRoot::Get()->LogChunkStats(a_Output); a_Output.Finished(); return; } #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) else if (split[0].compare("dumpmem") == 0) { LeakFinderXmlOutput Output("memdump.xml"); DumpUsedMemory(&Output); return; } else if (split[0].compare("killmem") == 0) { for (;;) { new char[100 * 1024 * 1024]; // Allocate and leak 100 MiB in a loop -> fill memory and kill MCS } } #endif else if (cPluginManager::Get()->ExecuteConsoleCommand(split, a_Output, a_Cmd)) { a_Output.Finished(); return; } a_Output.Out("Unknown command, type 'help' for all commands."); a_Output.Finished(); }