ConsoleCommands.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <iostream>
  17. using namespace std;
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include "../../common/debug.h"
  22. #include "../../common/Log.h"
  23. #include "../../common/seperator.h"
  24. #include "ConsoleCommands.h"
  25. #include "../World.h"
  26. #include "../Rules/Rules.h"
  27. #include "../WorldDatabase.h"
  28. extern volatile bool RunLoops;
  29. bool ContinueLoops = false;
  30. extern Variables variables;
  31. extern ZoneList zone_list;
  32. extern RuleManager rule_manager;
  33. extern WorldDatabase database;
  34. void ProcessConsoleInput(const char * cmdInput)
  35. {
  36. static ConsoleCommand Commands[] = {
  37. // account controls
  38. { &ConsoleBanCommand, "ban", "[player] {duration} {reason}", "Ban player with {optional} duration and reason." },
  39. { &ConsoleUnbanCommand, "unban", "[player]", "Unban a player." },
  40. { &ConsoleKickCommand, "kick", "[player] {reason}", "Kick player with {optional} reason." },
  41. // chat controls
  42. { &ConsoleAnnounceCommand, "announce", "[message]", "Sends Announcement message to all channels/clients." },
  43. { &ConsoleBroadcastCommand, "broadcast","[message]", "Sends Broadcast message to all channels/clients." },
  44. { &ConsoleChannelCommand, "channel", "[channel] [message]", "Sends Channel message to channel." },
  45. { &ConsoleTellCommand, "tell", "[player] [message]", "Sends Private message to player." },
  46. // world system controls
  47. { &ConsoleGuildCommand, "guild", "[params]", "" },
  48. { &ConsolePlayerCommand, "player", "[params]", "" },
  49. { &ConsoleSetAdminPlayer, "makeadmin", "[charname] [status=0]", "" },
  50. { &ConsoleZoneCommand, "zone", "[command][value]", "command = help to get help" },
  51. { &ConsoleWorldCommand, "world", "[params]", "" },
  52. { &ConsoleGetMOTDCommand, "getmotd", "", "Display current MOTD" },
  53. { &ConsoleSetMOTDCommand, "setmotd", "[new motd]", "Sets a new MOTD" },
  54. /// misc controls
  55. { &ConsoleWhoCommand, "who", "{zone id | player}", "Shows who is online globally, or in a given zone." },
  56. { &ConsoleReloadCommand, "reload", "[all | [type]]", "Reload main systems." },
  57. { &ConsoleRulesCommand, "rules", "{zone} {id}", "Show Global Ruleset (or Zone ruleset {optional})" },
  58. { &ConsoleShutdownCommand, "shutdown", "[delay]", "Gracefully shutdown world in [delay] sesconds." },
  59. { &ConsoleCancelShutdownCommand,"cancel", "", "Cancel shutdown command." },
  60. { &ConsoleExitCommand, "exit", "", "Brutally kills the world without mercy." },
  61. { &ConsoleExitCommand, "quit", "", "Brutally kills the world without mercy." },
  62. { &ConsoleTestCommand, "test", "", "Dev testing command." },
  63. { NULL, NULL, NULL, NULL },
  64. };
  65. Seperator *sep = new Seperator(cmdInput, ' ', 20, 100, true);
  66. bool found = false;
  67. uint32 i;
  68. if (!sep)
  69. return;
  70. if (!strcasecmp(sep->arg[0], "help") || sep->arg[0][0] == 'h' || sep->arg[0][0] == 'H' || sep->arg[0][0] == '?') {
  71. found = true;
  72. printf("======================================================================================================\n");
  73. printf("| %10s | %30s | %52s |\n", "Name", "Params", "Description");
  74. printf("======================================================================================================\n");
  75. for (i = 0; Commands[i].Name != NULL; i++) {
  76. printf("| %10s | %30s | %52s |\n", Commands[i].Name, Commands[i].ParameterFormat, Commands[i].Description);
  77. }
  78. printf("======================================================================================================\n");
  79. printf("-[ Help formatted for 120 chars wide screen ]-\n");
  80. }
  81. else {
  82. for (i = 0; Commands[i].Name != NULL; ++i) {
  83. if (!strcasecmp(Commands[i].Name, sep->arg[0])) {
  84. found = true;
  85. if (!Commands[i].CommandPointer(sep))
  86. printf("\nError, incorrect syntax for '%s'.\n Correct syntax is: '%s'.\n\n", Commands[i].Name, Commands[i].ParameterFormat );
  87. }
  88. }
  89. }
  90. if (!found)
  91. printf("Invalid Command '%s'! Type '?' or 'help' to get a command list.\n\n", sep->arg[0]);
  92. fflush(stdout);
  93. delete sep;
  94. }
  95. /************************************************* COMMANDS *************************************************/
  96. bool ConsoleBanCommand(Seperator *sep)
  97. {
  98. if( strlen(sep->arg[1]) == 0 )
  99. return false;
  100. return true;
  101. }
  102. bool ConsoleUnbanCommand(Seperator *sep)
  103. {
  104. if( strlen(sep->arg[1]) == 0 )
  105. return false;
  106. return true;
  107. }
  108. bool ConsoleKickCommand(Seperator *sep)
  109. {
  110. if( strlen(sep->arg[1]) == 0 )
  111. return false;
  112. return true;
  113. }
  114. bool ConsoleAnnounceCommand(Seperator *sep)
  115. {
  116. if( strlen(sep->arg[1]) == 0 )
  117. return false;
  118. return true;
  119. }
  120. bool ConsoleBroadcastCommand(Seperator *sep)
  121. {
  122. if( strlen(sep->arg[1]) == 0 )
  123. return false;
  124. char message[4096];
  125. snprintf(message, sizeof(message), "%s %s", "BROADCAST:", sep->argplus[1]);
  126. zone_list.HandleGlobalBroadcast(message);
  127. return true;
  128. }
  129. bool ConsoleChannelCommand(Seperator *sep)
  130. {
  131. if( strlen(sep->arg[1]) == 0 )
  132. return false;
  133. return true;
  134. }
  135. bool ConsoleTellCommand(Seperator *sep)
  136. {
  137. if( strlen(sep->arg[1]) == 0 )
  138. return false;
  139. return true;
  140. }
  141. bool ConsoleWhoCommand(Seperator *sep)
  142. {
  143. // zone_list.ProcessWhoQuery(who, client);
  144. if (!strcasecmp(sep->arg[1], "zone")) {
  145. printf("Who's Online in Zone");
  146. if (sep->IsNumber(2)) {
  147. printf("ID %s:\n", sep->arg[2]);
  148. printf("===============================================================================\n");
  149. printf("| %10s | %62s |\n", "CharID", "Name");
  150. printf("===============================================================================\n");
  151. }
  152. else {
  153. printf(" '%s':\n", sep->arg[2]);
  154. printf("===============================================================================\n");
  155. printf("| %10s | %62s |\n", "CharID", "Name");
  156. printf("===============================================================================\n");
  157. }
  158. }
  159. else {
  160. printf("Who's Online (Global):\n");
  161. printf("===============================================================================\n");
  162. printf("| %10s | %20s | %39s |\n", "CharID", "Name", "Zone");
  163. printf("===============================================================================\n");
  164. }
  165. printf("Not Implemented... yet :)\n");
  166. printf("===============================================================================\n");
  167. return true;
  168. }
  169. bool ConsoleGuildCommand(Seperator *sep)
  170. {
  171. if( strlen(sep->arg[1]) == 0 )
  172. return false;
  173. return true;
  174. }
  175. bool ConsolePlayerCommand(Seperator *sep)
  176. {
  177. if( strlen(sep->arg[1]) == 0 )
  178. return false;
  179. return true;
  180. }
  181. bool ConsoleSetAdminPlayer(Seperator *sep)
  182. {
  183. if(!sep->arg[1] || strlen(sep->arg[1]) == 0)
  184. return false;
  185. sint16 status = 0;
  186. if(sep->IsNumber(2))
  187. status = atoi(sep->arg[2]);
  188. Client* client = zone_list.GetClientByCharName(sep->arg[1]);
  189. if(!client) {
  190. printf("Client not found by char name, must be logged in\n");
  191. return true;
  192. }
  193. if(!client->GetPlayer()) {
  194. printf("Player is not available for client class, try again\n");
  195. return true;
  196. }
  197. client->SetAdminStatus(status);
  198. if(status)
  199. client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Admin status updated.");
  200. database.UpdateAdminStatus(client->GetPlayer()->GetName(), status);
  201. printf("Admin status for %s is updated to %i\n", client->GetPlayer()->GetName(), status);
  202. return true;
  203. }
  204. bool ConsoleWorldCommand(Seperator *sep)
  205. {
  206. if( strlen(sep->arg[1]) == 0 )
  207. return false;
  208. return true;
  209. }
  210. bool ConsoleZoneCommand(Seperator *sep)
  211. {
  212. if( strlen(sep->arg[1]) == 0 ) // has to be at least 1 arg (command)
  213. return false;
  214. ZoneServer* zone = 0;
  215. if( strlen(sep->arg[2]) == 0 )
  216. {
  217. // process commands without values
  218. if (!strcasecmp(sep->arg[1], "active") )
  219. {
  220. // not correct, but somehow need to access the Private zlist from World.h ???
  221. list<ZoneServer*> zlist;
  222. list<ZoneServer*>::iterator zone_iter;
  223. ZoneServer* tmp = 0;
  224. int zonesListed = 0;
  225. printf("> List Active Zones...\n");
  226. printf("======================================================================================================\n");
  227. printf("| %7s | %30s | %10s | %42s |\n", "ID", "Name", "Instance", "Description");
  228. printf("======================================================================================================\n");
  229. for(zone_iter=zlist.begin(); zone_iter!=zlist.end(); zone_iter++){
  230. tmp = *zone_iter;
  231. zonesListed++;
  232. printf("| %7d | %30s | %10d | %42s |\n", tmp->GetZoneID(), tmp->GetZoneName(), tmp->GetInstanceID(),tmp->GetZoneDescription());
  233. }
  234. return true;
  235. }
  236. else if (!strcasecmp(sep->arg[1], "help") || sep->arg[1][0] == '?')
  237. {
  238. printf("======================================================================================================\n");
  239. printf("| %10s | %30s | %52s |\n", "Command", "Value", "Description");
  240. printf("======================================================================================================\n");
  241. printf("| %10s | %30s | %52s |\n", "active", "n/a", "List currently active zones");
  242. printf("| %10s | %30s | %52s |\n", "list", "[name]", "Lookup zone by name");
  243. printf("| %10s | %30s | %52s |\n", "status", "[zone_id | name | ALL]", "List zone stats");
  244. printf("| %10s | %30s | %52s |\n", "lock", "[zone_id | name]", "Locks a zone");
  245. printf("| %10s | %30s | %52s |\n", "unlock", "[zone_id | name]", "Unlocks a zone");
  246. printf("| %10s | %30s | %52s |\n", "shutdown", "[zone_id | name | ALL]", "Gracefully shuts down a zone");
  247. printf("| %10s | %30s | %52s |\n", "kill", "[zone_id | name | ALL]", "Terminates a zone");
  248. printf("======================================================================================================\n");
  249. return true;
  250. }
  251. else
  252. return false;
  253. }
  254. else
  255. {
  256. if( !strcasecmp(sep->arg[1], "list") )
  257. {
  258. const char* name = 0;
  259. name = sep->argplus[2];
  260. map<int32, string>* zone_names = database.GetZoneList(name);
  261. if(!zone_names)
  262. {
  263. printf("> No zones found.\n");
  264. }
  265. else
  266. {
  267. printf("> List zones matching '%s'...\n", sep->arg[2]);
  268. printf("====================================================\n");
  269. printf("| %3s | %42s |\n", "ID", "Name");
  270. printf("====================================================\n");
  271. map<int32, string>::iterator itr;
  272. for(itr = zone_names->begin(); itr != zone_names->end(); itr++)
  273. printf("| %3u | %42s |\n", itr->first, itr->second.c_str());
  274. safe_delete(zone_names);
  275. printf("====================================================\n");
  276. }
  277. return true;
  278. }
  279. if( !strcasecmp(sep->arg[1], "lock") )
  280. {
  281. if( sep->IsNumber(2) )
  282. printf("> Locking zone ID %i...\n", atoul(sep->arg[2]));
  283. else
  284. printf("> Locking zone '%s'...\n", sep->arg[2]);
  285. return true;
  286. }
  287. if( !strcasecmp(sep->arg[1], "unlock") )
  288. {
  289. if( strlen(sep->arg[2]) > 0 && sep->IsNumber(2) )
  290. printf("> Unlocking zone ID %i...\n", atoi(sep->arg[2]));
  291. else
  292. printf("> Unlocking zone '%s'...\n", sep->arg[2]);
  293. return true;
  294. }
  295. if( !strcasecmp(sep->arg[1], "status") )
  296. {
  297. if( sep->IsNumber(2) )
  298. {
  299. ZoneChangeDetails zone_details;
  300. if( zone_list.GetZone(&zone_details, atoi(sep->arg[2]), "", false, false, false) )
  301. {
  302. printf("> Zone status for zone ID %i...\n", atoi(sep->arg[2]));
  303. printf("============================================================================================\n");
  304. printf("| %30s | %10s | %42s |\n", "Zone", "Param", "Value");
  305. printf("============================================================================================\n");
  306. printf("| %30s | %10s | %42s |\n", zone_details.zoneName, "locked", zone_details.lockState ? "true" : "false");
  307. }
  308. else
  309. {
  310. printf("> Zone ID %i not running, so not locked.\n", atoi(sep->arg[2]));
  311. }
  312. }
  313. else if( !strcasecmp(sep->arg[2], "ALL") )
  314. {
  315. printf("> Zone status for ALL active zones...\n");
  316. }
  317. else
  318. {
  319. printf("> Zone status for zone '%s'...\n", sep->arg[2]);
  320. }
  321. return true;
  322. }
  323. if( !strcasecmp(sep->arg[1], "shutdown") )
  324. {
  325. if( sep->IsNumber(2) )
  326. printf("> Shutdown zone ID %i...\n", atoi(sep->arg[2]));
  327. else if( !strcasecmp(sep->arg[2], "ALL") )
  328. printf("> Shutdown ALL active zones...\n");
  329. else
  330. printf("> Shutdown zone '%s'...\n", sep->arg[2]);
  331. return true;
  332. }
  333. if( !strcasecmp(sep->arg[1], "kill") )
  334. {
  335. if( sep->IsNumber(2) )
  336. printf("> Kill zone ID %i...\n", atoi(sep->arg[2]));
  337. else if( !strcasecmp(sep->arg[2], "ALL") )
  338. printf("> Kill ALL active zones...\n");
  339. else
  340. printf("> Kill zone '%s'...\n", sep->arg[2]);
  341. return true;
  342. }
  343. }
  344. return false;
  345. }
  346. bool ConsoleGetMOTDCommand(Seperator *sep)
  347. {
  348. const char* motd = 0;
  349. Variable* var = variables.FindVariable("motd");
  350. if( var == NULL || strlen (var->GetValue()) == 0){
  351. printf("No MOTD.");
  352. }
  353. else{
  354. motd = var->GetValue();
  355. printf("%s\n", motd);
  356. }
  357. return true;
  358. }
  359. bool ConsoleSetMOTDCommand(Seperator *sep)
  360. {
  361. if( strlen(sep->arg[1]) == 0 )
  362. return false;
  363. return true;
  364. }
  365. bool ConsoleReloadCommand(Seperator *sep)
  366. {
  367. #ifdef _WIN32
  368. HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
  369. SetConsoleTextAttribute(console, FOREGROUND_YELLOW_BOLD);
  370. #else
  371. printf("\033[1;33m");
  372. #endif
  373. printf("Usage: ");
  374. #ifdef _WIN32
  375. SetConsoleTextAttribute(console, FOREGROUND_WHITE_BOLD);
  376. #else
  377. printf("\033[1;37m");
  378. #endif
  379. printf("reload [type]\n");
  380. #ifdef _WIN32
  381. SetConsoleTextAttribute(console, 8);
  382. #else
  383. printf("\033[0m");
  384. #endif
  385. printf("Valid [type] paramters are:\n");
  386. printf("===============================================================================\n");
  387. printf("| %21s | %51s |\n", "all", "Reloads all systems (why not just restart?)");
  388. printf("| %21s | %51s |\n", "structs", "Reloads structs (XMLs)");
  389. printf("| %21s | %51s |\n", "items", "Reload Items data");
  390. printf("| %21s | %51s |\n", "luasystem", "Reload LUA System Scripts");
  391. printf("| %21s | %51s |\n", "spawnscripts", "Reload SpawnScripts");
  392. printf("| %21s | %51s |\n", "quests", "Reload Quest Data and Scripts");
  393. printf("| %21s | %51s |\n", "spawns", "Reload ALL Spawns from DB");
  394. printf("| %21s | %51s |\n", "groundspawn_items", "Reload Groundspawn Items lists");
  395. printf("| %21s | %51s |\n", "zonescripts", "Reload Zone Scripts");
  396. printf("| %21s | %51s |\n", "entity_commands", "Reload Entity Commands");
  397. printf("| %21s | %51s |\n", "factions", "Reload Factions");
  398. printf("| %21s | %51s |\n", "mail", "Reload in-game Mail data");
  399. printf("| %21s | %51s |\n", "guilds", "Reload Guilds");
  400. printf("| %21s | %51s |\n", "locations", "Reload Locations data");
  401. printf("===============================================================================\n");
  402. if( strlen(sep->arg[1]) > 0 ) {
  403. // handle reloads here
  404. if (!strcasecmp(sep->arg[1], "spawns"))
  405. zone_list.ReloadSpawns();
  406. }
  407. return true;
  408. }
  409. bool ConsoleShutdownCommand(Seperator *sep)
  410. {
  411. if ( IsNumber(sep->arg[1]) ) {
  412. int8 shutdown_delay = atoi(sep->arg[1]);
  413. printf("Shutdown World in %i second(s)...\n", shutdown_delay);
  414. // shutting down gracefully, warn players.
  415. char message[4096];
  416. snprintf(message, sizeof(message), "BROADCAST: Server is shutting down in %s second(s)", sep->arg[1]);
  417. zone_list.HandleGlobalBroadcast(message);
  418. Sleep(shutdown_delay * 1000);
  419. }
  420. else {
  421. printf("Shutdown World immediately... you probably won't even see this message, huh!\n");
  422. }
  423. if( !ContinueLoops )
  424. RunLoops = false;
  425. return true;
  426. }
  427. bool ConsoleCancelShutdownCommand(Seperator *sep)
  428. {
  429. printf("Cancel World Shutdown...\n");
  430. ContinueLoops = true;
  431. return true;
  432. }
  433. bool ConsoleExitCommand(Seperator *sep)
  434. {
  435. // I wanted this to be a little more Terminate-y... killkillkill
  436. printf("Terminate World immediately...\n");
  437. RunLoops = false;
  438. return true;
  439. }
  440. bool ConsoleRulesCommand(Seperator *sep)
  441. {
  442. /*if( strlen(sep->arg[1]) == 0 )
  443. return false;*/
  444. printf("Current Active Ruleset");
  445. if (!strcasecmp(sep->arg[1], "zone"))
  446. {
  447. if (sep->IsNumber(2)) {
  448. printf(" in Zone ID: %s\n", sep->arg[2]);
  449. }
  450. else
  451. return false;
  452. }
  453. else
  454. {
  455. printf(" (global):\n");
  456. }
  457. printf("===============================================================================\n");
  458. printf("| %20s | %20s | %29s |\n", "Category", "Type", "Value");
  459. printf("===============================================================================\n");
  460. return true;
  461. }
  462. bool ConsoleTestCommand(Seperator *sep)
  463. {
  464. // devs put whatever test code in here
  465. printf("Testing Server Guild Rules values:\n");
  466. printf("AutoJoin: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoin)->GetInt8());
  467. printf("Guild ID: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoinID)->GetInt32());
  468. printf("Rank: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoinDefaultRankID)->GetInt8());
  469. return true;
  470. }