/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) This file is part of EQ2Emulator. EQ2Emulator is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. EQ2Emulator is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with EQ2Emulator. If not, see . */ #include using namespace std; #include #include #include #include "../../common/debug.h" #include "../../common/Log.h" #include "../../common/seperator.h" #include "ConsoleCommands.h" #include "../World.h" #include "../Rules/Rules.h" #include "../WorldDatabase.h" extern volatile bool RunLoops; bool ContinueLoops = false; extern Variables variables; extern ZoneList zone_list; extern RuleManager rule_manager; extern WorldDatabase database; void ProcessConsoleInput(const char * cmdInput) { static ConsoleCommand Commands[] = { // account controls { &ConsoleBanCommand, "ban", "[player] {duration} {reason}", "Ban player with {optional} duration and reason." }, { &ConsoleUnbanCommand, "unban", "[player]", "Unban a player." }, { &ConsoleKickCommand, "kick", "[player] {reason}", "Kick player with {optional} reason." }, // chat controls { &ConsoleAnnounceCommand, "announce", "[message]", "Sends Announcement message to all channels/clients." }, { &ConsoleBroadcastCommand, "broadcast","[message]", "Sends Broadcast message to all channels/clients." }, { &ConsoleChannelCommand, "channel", "[channel] [message]", "Sends Channel message to channel." }, { &ConsoleTellCommand, "tell", "[player] [message]", "Sends Private message to player." }, // world system controls { &ConsoleGuildCommand, "guild", "[params]", "" }, { &ConsolePlayerCommand, "player", "[params]", "" }, { &ConsoleSetAdminPlayer, "makeadmin", "[charname] [status=0]", "" }, { &ConsoleZoneCommand, "zone", "[command][value]", "command = help to get help" }, { &ConsoleWorldCommand, "world", "[params]", "" }, { &ConsoleGetMOTDCommand, "getmotd", "", "Display current MOTD" }, { &ConsoleSetMOTDCommand, "setmotd", "[new motd]", "Sets a new MOTD" }, /// misc controls { &ConsoleWhoCommand, "who", "{zone id | player}", "Shows who is online globally, or in a given zone." }, { &ConsoleReloadCommand, "reload", "[all | [type]]", "Reload main systems." }, { &ConsoleRulesCommand, "rules", "{zone} {id}", "Show Global Ruleset (or Zone ruleset {optional})" }, { &ConsoleShutdownCommand, "shutdown", "[delay]", "Gracefully shutdown world in [delay] sesconds." }, { &ConsoleCancelShutdownCommand,"cancel", "", "Cancel shutdown command." }, { &ConsoleExitCommand, "exit", "", "Brutally kills the world without mercy." }, { &ConsoleExitCommand, "quit", "", "Brutally kills the world without mercy." }, { &ConsoleTestCommand, "test", "", "Dev testing command." }, { NULL, NULL, NULL, NULL }, }; Seperator *sep = new Seperator(cmdInput, ' ', 20, 100, true); bool found = false; uint32 i; if (!sep) return; if (!strcasecmp(sep->arg[0], "help") || sep->arg[0][0] == 'h' || sep->arg[0][0] == 'H' || sep->arg[0][0] == '?') { found = true; printf("======================================================================================================\n"); printf("| %10s | %30s | %52s |\n", "Name", "Params", "Description"); printf("======================================================================================================\n"); for (i = 0; Commands[i].Name != NULL; i++) { printf("| %10s | %30s | %52s |\n", Commands[i].Name, Commands[i].ParameterFormat, Commands[i].Description); } printf("======================================================================================================\n"); printf("-[ Help formatted for 120 chars wide screen ]-\n"); } else { for (i = 0; Commands[i].Name != NULL; ++i) { if (!strcasecmp(Commands[i].Name, sep->arg[0])) { found = true; if (!Commands[i].CommandPointer(sep)) printf("\nError, incorrect syntax for '%s'.\n Correct syntax is: '%s'.\n\n", Commands[i].Name, Commands[i].ParameterFormat ); } } } if (!found) printf("Invalid Command '%s'! Type '?' or 'help' to get a command list.\n\n", sep->arg[0]); fflush(stdout); delete sep; } /************************************************* COMMANDS *************************************************/ bool ConsoleBanCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleUnbanCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleKickCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleAnnounceCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleBroadcastCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; char message[4096]; snprintf(message, sizeof(message), "%s %s", "BROADCAST:", sep->argplus[1]); zone_list.HandleGlobalBroadcast(message); return true; } bool ConsoleChannelCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleTellCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleWhoCommand(Seperator *sep) { // zone_list.ProcessWhoQuery(who, client); if (!strcasecmp(sep->arg[1], "zone")) { printf("Who's Online in Zone"); if (sep->IsNumber(2)) { printf("ID %s:\n", sep->arg[2]); printf("===============================================================================\n"); printf("| %10s | %62s |\n", "CharID", "Name"); printf("===============================================================================\n"); } else { printf(" '%s':\n", sep->arg[2]); printf("===============================================================================\n"); printf("| %10s | %62s |\n", "CharID", "Name"); printf("===============================================================================\n"); } } else { printf("Who's Online (Global):\n"); printf("===============================================================================\n"); printf("| %10s | %20s | %39s |\n", "CharID", "Name", "Zone"); printf("===============================================================================\n"); } printf("Not Implemented... yet :)\n"); printf("===============================================================================\n"); return true; } bool ConsoleGuildCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsolePlayerCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleSetAdminPlayer(Seperator *sep) { if(!sep->arg[1] || strlen(sep->arg[1]) == 0) return false; sint16 status = 0; if(sep->IsNumber(2)) status = atoi(sep->arg[2]); Client* client = zone_list.GetClientByCharName(sep->arg[1]); if(!client) { printf("Client not found by char name, must be logged in\n"); return true; } if(!client->GetPlayer()) { printf("Player is not available for client class, try again\n"); return true; } client->SetAdminStatus(status); if(status) client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Admin status updated."); database.UpdateAdminStatus(client->GetPlayer()->GetName(), status); printf("Admin status for %s is updated to %i\n", client->GetPlayer()->GetName(), status); return true; } bool ConsoleWorldCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleZoneCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) // has to be at least 1 arg (command) return false; ZoneServer* zone = 0; if( strlen(sep->arg[2]) == 0 ) { // process commands without values if (!strcasecmp(sep->arg[1], "active") ) { // not correct, but somehow need to access the Private zlist from World.h ??? list zlist; list::iterator zone_iter; ZoneServer* tmp = 0; int zonesListed = 0; printf("> List Active Zones...\n"); printf("======================================================================================================\n"); printf("| %7s | %30s | %10s | %42s |\n", "ID", "Name", "Instance", "Description"); printf("======================================================================================================\n"); for(zone_iter=zlist.begin(); zone_iter!=zlist.end(); zone_iter++){ tmp = *zone_iter; zonesListed++; printf("| %7d | %30s | %10d | %42s |\n", tmp->GetZoneID(), tmp->GetZoneName(), tmp->GetInstanceID(),tmp->GetZoneDescription()); } return true; } else if (!strcasecmp(sep->arg[1], "help") || sep->arg[1][0] == '?') { printf("======================================================================================================\n"); printf("| %10s | %30s | %52s |\n", "Command", "Value", "Description"); printf("======================================================================================================\n"); printf("| %10s | %30s | %52s |\n", "active", "n/a", "List currently active zones"); printf("| %10s | %30s | %52s |\n", "list", "[name]", "Lookup zone by name"); printf("| %10s | %30s | %52s |\n", "status", "[zone_id | name | ALL]", "List zone stats"); printf("| %10s | %30s | %52s |\n", "lock", "[zone_id | name]", "Locks a zone"); printf("| %10s | %30s | %52s |\n", "unlock", "[zone_id | name]", "Unlocks a zone"); printf("| %10s | %30s | %52s |\n", "shutdown", "[zone_id | name | ALL]", "Gracefully shuts down a zone"); printf("| %10s | %30s | %52s |\n", "kill", "[zone_id | name | ALL]", "Terminates a zone"); printf("======================================================================================================\n"); return true; } else return false; } else { if( !strcasecmp(sep->arg[1], "list") ) { const char* name = 0; name = sep->argplus[2]; map* zone_names = database.GetZoneList(name); if(!zone_names) { printf("> No zones found.\n"); } else { printf("> List zones matching '%s'...\n", sep->arg[2]); printf("====================================================\n"); printf("| %3s | %42s |\n", "ID", "Name"); printf("====================================================\n"); map::iterator itr; for(itr = zone_names->begin(); itr != zone_names->end(); itr++) printf("| %3u | %42s |\n", itr->first, itr->second.c_str()); safe_delete(zone_names); printf("====================================================\n"); } return true; } if( !strcasecmp(sep->arg[1], "lock") ) { if( sep->IsNumber(2) ) printf("> Locking zone ID %i...\n", atoul(sep->arg[2])); else printf("> Locking zone '%s'...\n", sep->arg[2]); return true; } if( !strcasecmp(sep->arg[1], "unlock") ) { if( strlen(sep->arg[2]) > 0 && sep->IsNumber(2) ) printf("> Unlocking zone ID %i...\n", atoi(sep->arg[2])); else printf("> Unlocking zone '%s'...\n", sep->arg[2]); return true; } if( !strcasecmp(sep->arg[1], "status") ) { if( sep->IsNumber(2) ) { ZoneChangeDetails zone_details; if( zone_list.GetZone(&zone_details, atoi(sep->arg[2]), "", false, false, false) ) { printf("> Zone status for zone ID %i...\n", atoi(sep->arg[2])); printf("============================================================================================\n"); printf("| %30s | %10s | %42s |\n", "Zone", "Param", "Value"); printf("============================================================================================\n"); printf("| %30s | %10s | %42s |\n", zone_details.zoneName, "locked", zone_details.lockState ? "true" : "false"); } else { printf("> Zone ID %i not running, so not locked.\n", atoi(sep->arg[2])); } } else if( !strcasecmp(sep->arg[2], "ALL") ) { printf("> Zone status for ALL active zones...\n"); } else { printf("> Zone status for zone '%s'...\n", sep->arg[2]); } return true; } if( !strcasecmp(sep->arg[1], "shutdown") ) { if( sep->IsNumber(2) ) printf("> Shutdown zone ID %i...\n", atoi(sep->arg[2])); else if( !strcasecmp(sep->arg[2], "ALL") ) printf("> Shutdown ALL active zones...\n"); else printf("> Shutdown zone '%s'...\n", sep->arg[2]); return true; } if( !strcasecmp(sep->arg[1], "kill") ) { if( sep->IsNumber(2) ) printf("> Kill zone ID %i...\n", atoi(sep->arg[2])); else if( !strcasecmp(sep->arg[2], "ALL") ) printf("> Kill ALL active zones...\n"); else printf("> Kill zone '%s'...\n", sep->arg[2]); return true; } } return false; } bool ConsoleGetMOTDCommand(Seperator *sep) { const char* motd = 0; Variable* var = variables.FindVariable("motd"); if( var == NULL || strlen (var->GetValue()) == 0){ printf("No MOTD."); } else{ motd = var->GetValue(); printf("%s\n", motd); } return true; } bool ConsoleSetMOTDCommand(Seperator *sep) { if( strlen(sep->arg[1]) == 0 ) return false; return true; } bool ConsoleReloadCommand(Seperator *sep) { #ifdef _WIN32 HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(console, FOREGROUND_YELLOW_BOLD); #else printf("\033[1;33m"); #endif printf("Usage: "); #ifdef _WIN32 SetConsoleTextAttribute(console, FOREGROUND_WHITE_BOLD); #else printf("\033[1;37m"); #endif printf("reload [type]\n"); #ifdef _WIN32 SetConsoleTextAttribute(console, 8); #else printf("\033[0m"); #endif printf("Valid [type] paramters are:\n"); printf("===============================================================================\n"); printf("| %21s | %51s |\n", "all", "Reloads all systems (why not just restart?)"); printf("| %21s | %51s |\n", "structs", "Reloads structs (XMLs)"); printf("| %21s | %51s |\n", "items", "Reload Items data"); printf("| %21s | %51s |\n", "luasystem", "Reload LUA System Scripts"); printf("| %21s | %51s |\n", "spawnscripts", "Reload SpawnScripts"); printf("| %21s | %51s |\n", "quests", "Reload Quest Data and Scripts"); printf("| %21s | %51s |\n", "spawns", "Reload ALL Spawns from DB"); printf("| %21s | %51s |\n", "groundspawn_items", "Reload Groundspawn Items lists"); printf("| %21s | %51s |\n", "zonescripts", "Reload Zone Scripts"); printf("| %21s | %51s |\n", "entity_commands", "Reload Entity Commands"); printf("| %21s | %51s |\n", "factions", "Reload Factions"); printf("| %21s | %51s |\n", "mail", "Reload in-game Mail data"); printf("| %21s | %51s |\n", "guilds", "Reload Guilds"); printf("| %21s | %51s |\n", "locations", "Reload Locations data"); printf("===============================================================================\n"); if( strlen(sep->arg[1]) > 0 ) { // handle reloads here if (!strcasecmp(sep->arg[1], "spawns")) zone_list.ReloadSpawns(); } return true; } bool ConsoleShutdownCommand(Seperator *sep) { if ( IsNumber(sep->arg[1]) ) { int8 shutdown_delay = atoi(sep->arg[1]); printf("Shutdown World in %i second(s)...\n", shutdown_delay); // shutting down gracefully, warn players. char message[4096]; snprintf(message, sizeof(message), "BROADCAST: Server is shutting down in %s second(s)", sep->arg[1]); zone_list.HandleGlobalBroadcast(message); Sleep(shutdown_delay * 1000); } else { printf("Shutdown World immediately... you probably won't even see this message, huh!\n"); } if( !ContinueLoops ) RunLoops = false; return true; } bool ConsoleCancelShutdownCommand(Seperator *sep) { printf("Cancel World Shutdown...\n"); ContinueLoops = true; return true; } bool ConsoleExitCommand(Seperator *sep) { // I wanted this to be a little more Terminate-y... killkillkill printf("Terminate World immediately...\n"); RunLoops = false; return true; } bool ConsoleRulesCommand(Seperator *sep) { /*if( strlen(sep->arg[1]) == 0 ) return false;*/ printf("Current Active Ruleset"); if (!strcasecmp(sep->arg[1], "zone")) { if (sep->IsNumber(2)) { printf(" in Zone ID: %s\n", sep->arg[2]); } else return false; } else { printf(" (global):\n"); } printf("===============================================================================\n"); printf("| %20s | %20s | %29s |\n", "Category", "Type", "Value"); printf("===============================================================================\n"); return true; } bool ConsoleTestCommand(Seperator *sep) { // devs put whatever test code in here printf("Testing Server Guild Rules values:\n"); printf("AutoJoin: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoin)->GetInt8()); printf("Guild ID: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoinID)->GetInt32()); printf("Rank: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoinDefaultRankID)->GetInt8()); return true; }