ConsoleCommands.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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. { &ConsoleZoneCommand, "zone", "[command][value]", "command = help to get help" },
  50. { &ConsoleWorldCommand, "world", "[params]", "" },
  51. { &ConsoleGetMOTDCommand, "getmotd", "", "Display current MOTD" },
  52. { &ConsoleSetMOTDCommand, "setmotd", "[new motd]", "Sets a new MOTD" },
  53. /// misc controls
  54. { &ConsoleWhoCommand, "who", "{zone id | player}", "Shows who is online globally, or in a given zone." },
  55. { &ConsoleReloadCommand, "reload", "[all | [type]]", "Reload main systems." },
  56. { &ConsoleRulesCommand, "rules", "{zone} {id}", "Show Global Ruleset (or Zone ruleset {optional})" },
  57. { &ConsoleShutdownCommand, "shutdown", "[delay]", "Gracefully shutdown world in [delay] sesconds." },
  58. { &ConsoleCancelShutdownCommand,"cancel", "", "Cancel shutdown command." },
  59. { &ConsoleExitCommand, "exit", "", "Brutally kills the world without mercy." },
  60. { &ConsoleExitCommand, "quit", "", "Brutally kills the world without mercy." },
  61. { &ConsoleTestCommand, "test", "", "Dev testing command." },
  62. { NULL, NULL, NULL, NULL },
  63. };
  64. Seperator *sep = new Seperator(cmdInput, ' ', 20, 100, true);
  65. bool found = false;
  66. uint32 i;
  67. if (!sep)
  68. return;
  69. if (!strcasecmp(sep->arg[0], "help") || sep->arg[0][0] == 'h' || sep->arg[0][0] == 'H' || sep->arg[0][0] == '?') {
  70. found = true;
  71. printf("======================================================================================================\n");
  72. printf("| %10s | %30s | %52s |\n", "Name", "Params", "Description");
  73. printf("======================================================================================================\n");
  74. for (i = 0; Commands[i].Name != NULL; i++) {
  75. printf("| %10s | %30s | %52s |\n", Commands[i].Name, Commands[i].ParameterFormat, Commands[i].Description);
  76. }
  77. printf("======================================================================================================\n");
  78. printf("-[ Help formatted for 120 chars wide screen ]-\n");
  79. }
  80. else {
  81. for (i = 0; Commands[i].Name != NULL; ++i) {
  82. if (!strcasecmp(Commands[i].Name, sep->arg[0])) {
  83. found = true;
  84. if (!Commands[i].CommandPointer(sep))
  85. printf("\nError, incorrect syntax for '%s'.\n Correct syntax is: '%s'.\n\n", Commands[i].Name, Commands[i].ParameterFormat );
  86. }
  87. }
  88. }
  89. if (!found)
  90. printf("Invalid Command '%s'! Type '?' or 'help' to get a command list.\n\n", sep->arg[0]);
  91. fflush(stdout);
  92. delete sep;
  93. }
  94. /************************************************* COMMANDS *************************************************/
  95. bool ConsoleBanCommand(Seperator *sep)
  96. {
  97. if( strlen(sep->arg[1]) == 0 )
  98. return false;
  99. return true;
  100. }
  101. bool ConsoleUnbanCommand(Seperator *sep)
  102. {
  103. if( strlen(sep->arg[1]) == 0 )
  104. return false;
  105. return true;
  106. }
  107. bool ConsoleKickCommand(Seperator *sep)
  108. {
  109. if( strlen(sep->arg[1]) == 0 )
  110. return false;
  111. return true;
  112. }
  113. bool ConsoleAnnounceCommand(Seperator *sep)
  114. {
  115. if( strlen(sep->arg[1]) == 0 )
  116. return false;
  117. return true;
  118. }
  119. bool ConsoleBroadcastCommand(Seperator *sep)
  120. {
  121. if( strlen(sep->arg[1]) == 0 )
  122. return false;
  123. char message[4096];
  124. snprintf(message, sizeof(message), "%s %s", "BROADCAST:", sep->argplus[1]);
  125. zone_list.HandleGlobalBroadcast(message);
  126. return true;
  127. }
  128. bool ConsoleChannelCommand(Seperator *sep)
  129. {
  130. if( strlen(sep->arg[1]) == 0 )
  131. return false;
  132. return true;
  133. }
  134. bool ConsoleTellCommand(Seperator *sep)
  135. {
  136. if( strlen(sep->arg[1]) == 0 )
  137. return false;
  138. return true;
  139. }
  140. bool ConsoleWhoCommand(Seperator *sep)
  141. {
  142. // zone_list.ProcessWhoQuery(who, client);
  143. if (!strcasecmp(sep->arg[1], "zone")) {
  144. printf("Who's Online in Zone");
  145. if (sep->IsNumber(2)) {
  146. printf("ID %s:\n", sep->arg[2]);
  147. printf("===============================================================================\n");
  148. printf("| %10s | %62s |\n", "CharID", "Name");
  149. printf("===============================================================================\n");
  150. }
  151. else {
  152. printf(" '%s':\n", sep->arg[2]);
  153. printf("===============================================================================\n");
  154. printf("| %10s | %62s |\n", "CharID", "Name");
  155. printf("===============================================================================\n");
  156. }
  157. }
  158. else {
  159. printf("Who's Online (Global):\n");
  160. printf("===============================================================================\n");
  161. printf("| %10s | %20s | %39s |\n", "CharID", "Name", "Zone");
  162. printf("===============================================================================\n");
  163. }
  164. printf("Not Implemented... yet :)\n");
  165. printf("===============================================================================\n");
  166. return true;
  167. }
  168. bool ConsoleGuildCommand(Seperator *sep)
  169. {
  170. if( strlen(sep->arg[1]) == 0 )
  171. return false;
  172. return true;
  173. }
  174. bool ConsolePlayerCommand(Seperator *sep)
  175. {
  176. if( strlen(sep->arg[1]) == 0 )
  177. return false;
  178. return true;
  179. }
  180. bool ConsoleWorldCommand(Seperator *sep)
  181. {
  182. if( strlen(sep->arg[1]) == 0 )
  183. return false;
  184. return true;
  185. }
  186. bool ConsoleZoneCommand(Seperator *sep)
  187. {
  188. if( strlen(sep->arg[1]) == 0 ) // has to be at least 1 arg (command)
  189. return false;
  190. ZoneServer* zone = 0;
  191. if( strlen(sep->arg[2]) == 0 )
  192. {
  193. // process commands without values
  194. if (!strcasecmp(sep->arg[1], "active") )
  195. {
  196. // not correct, but somehow need to access the Private zlist from World.h ???
  197. list<ZoneServer*> zlist;
  198. list<ZoneServer*>::iterator zone_iter;
  199. ZoneServer* tmp = 0;
  200. int zonesListed = 0;
  201. printf("> List Active Zones...\n");
  202. printf("======================================================================================================\n");
  203. printf("| %7s | %30s | %10s | %42s |\n", "ID", "Name", "Instance", "Description");
  204. printf("======================================================================================================\n");
  205. for(zone_iter=zlist.begin(); zone_iter!=zlist.end(); zone_iter++){
  206. tmp = *zone_iter;
  207. zonesListed++;
  208. printf("| %7d | %30s | %10d | %42s |\n", tmp->GetZoneID(), tmp->GetZoneName(), tmp->GetInstanceID(),tmp->GetZoneDescription());
  209. }
  210. return true;
  211. }
  212. else if (!strcasecmp(sep->arg[1], "help") || sep->arg[1][0] == '?')
  213. {
  214. printf("======================================================================================================\n");
  215. printf("| %10s | %30s | %52s |\n", "Command", "Value", "Description");
  216. printf("======================================================================================================\n");
  217. printf("| %10s | %30s | %52s |\n", "active", "n/a", "List currently active zones");
  218. printf("| %10s | %30s | %52s |\n", "list", "[name]", "Lookup zone by name");
  219. printf("| %10s | %30s | %52s |\n", "status", "[zone_id | name | ALL]", "List zone stats");
  220. printf("| %10s | %30s | %52s |\n", "lock", "[zone_id | name]", "Locks a zone");
  221. printf("| %10s | %30s | %52s |\n", "unlock", "[zone_id | name]", "Unlocks a zone");
  222. printf("| %10s | %30s | %52s |\n", "shutdown", "[zone_id | name | ALL]", "Gracefully shuts down a zone");
  223. printf("| %10s | %30s | %52s |\n", "kill", "[zone_id | name | ALL]", "Terminates a zone");
  224. printf("======================================================================================================\n");
  225. return true;
  226. }
  227. else
  228. return false;
  229. }
  230. else
  231. {
  232. if( !strcasecmp(sep->arg[1], "list") )
  233. {
  234. const char* name = 0;
  235. name = sep->argplus[2];
  236. map<int32, string>* zone_names = database.GetZoneList(name);
  237. if(!zone_names)
  238. {
  239. printf("> No zones found.\n");
  240. }
  241. else
  242. {
  243. printf("> List zones matching '%s'...\n", sep->arg[2]);
  244. printf("====================================================\n");
  245. printf("| %3s | %42s |\n", "ID", "Name");
  246. printf("====================================================\n");
  247. map<int32, string>::iterator itr;
  248. for(itr = zone_names->begin(); itr != zone_names->end(); itr++)
  249. printf("| %3u | %42s |\n", itr->first, itr->second.c_str());
  250. safe_delete(zone_names);
  251. printf("====================================================\n");
  252. }
  253. return true;
  254. }
  255. if( !strcasecmp(sep->arg[1], "lock") )
  256. {
  257. if( sep->IsNumber(2) )
  258. printf("> Locking zone ID %i...\n", atoul(sep->arg[2]));
  259. else
  260. printf("> Locking zone '%s'...\n", sep->arg[2]);
  261. return true;
  262. }
  263. if( !strcasecmp(sep->arg[1], "unlock") )
  264. {
  265. if( strlen(sep->arg[2]) > 0 && sep->IsNumber(2) )
  266. printf("> Unlocking zone ID %i...\n", atoi(sep->arg[2]));
  267. else
  268. printf("> Unlocking zone '%s'...\n", sep->arg[2]);
  269. return true;
  270. }
  271. if( !strcasecmp(sep->arg[1], "status") )
  272. {
  273. if( sep->IsNumber(2) )
  274. {
  275. zone = zone_list.Get(atoi(sep->arg[2]), false);
  276. if( zone )
  277. {
  278. printf("> Zone status for zone ID %i...\n", atoi(sep->arg[2]));
  279. printf("============================================================================================\n");
  280. printf("| %30s | %10s | %42s |\n", "Zone", "Param", "Value");
  281. printf("============================================================================================\n");
  282. printf("| %30s | %10s | %42s |\n", zone->GetZoneName(), "locked", zone->GetZoneLockState() ? "true" : "false");
  283. }
  284. else
  285. {
  286. printf("> Zone ID %i not running, so not locked.\n", atoi(sep->arg[2]));
  287. }
  288. }
  289. else if( !strcasecmp(sep->arg[2], "ALL") )
  290. {
  291. printf("> Zone status for ALL active zones...\n");
  292. }
  293. else
  294. {
  295. printf("> Zone status for zone '%s'...\n", sep->arg[2]);
  296. }
  297. return true;
  298. }
  299. if( !strcasecmp(sep->arg[1], "shutdown") )
  300. {
  301. if( sep->IsNumber(2) )
  302. printf("> Shutdown zone ID %i...\n", atoi(sep->arg[2]));
  303. else if( !strcasecmp(sep->arg[2], "ALL") )
  304. printf("> Shutdown ALL active zones...\n");
  305. else
  306. printf("> Shutdown zone '%s'...\n", sep->arg[2]);
  307. return true;
  308. }
  309. if( !strcasecmp(sep->arg[1], "kill") )
  310. {
  311. if( sep->IsNumber(2) )
  312. printf("> Kill zone ID %i...\n", atoi(sep->arg[2]));
  313. else if( !strcasecmp(sep->arg[2], "ALL") )
  314. printf("> Kill ALL active zones...\n");
  315. else
  316. printf("> Kill zone '%s'...\n", sep->arg[2]);
  317. return true;
  318. }
  319. }
  320. return false;
  321. }
  322. bool ConsoleGetMOTDCommand(Seperator *sep)
  323. {
  324. const char* motd = 0;
  325. Variable* var = variables.FindVariable("motd");
  326. if( var == NULL || strlen (var->GetValue()) == 0){
  327. printf("No MOTD.");
  328. }
  329. else{
  330. motd = var->GetValue();
  331. printf("%s\n", motd);
  332. }
  333. return true;
  334. }
  335. bool ConsoleSetMOTDCommand(Seperator *sep)
  336. {
  337. if( strlen(sep->arg[1]) == 0 )
  338. return false;
  339. return true;
  340. }
  341. bool ConsoleReloadCommand(Seperator *sep)
  342. {
  343. #ifdef _WIN32
  344. HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
  345. SetConsoleTextAttribute(console, FOREGROUND_YELLOW_BOLD);
  346. #else
  347. printf("\033[1;33m");
  348. #endif
  349. printf("Usage: ");
  350. #ifdef _WIN32
  351. SetConsoleTextAttribute(console, FOREGROUND_WHITE_BOLD);
  352. #else
  353. printf("\033[1;37m");
  354. #endif
  355. printf("reload [type]\n");
  356. #ifdef _WIN32
  357. SetConsoleTextAttribute(console, 8);
  358. #else
  359. printf("\033[0m");
  360. #endif
  361. printf("Valid [type] paramters are:\n");
  362. printf("===============================================================================\n");
  363. printf("| %21s | %51s |\n", "all", "Reloads all systems (why not just restart?)");
  364. printf("| %21s | %51s |\n", "structs", "Reloads structs (XMLs)");
  365. printf("| %21s | %51s |\n", "items", "Reload Items data");
  366. printf("| %21s | %51s |\n", "luasystem", "Reload LUA System Scripts");
  367. printf("| %21s | %51s |\n", "spawnscripts", "Reload SpawnScripts");
  368. printf("| %21s | %51s |\n", "quests", "Reload Quest Data and Scripts");
  369. printf("| %21s | %51s |\n", "spawns", "Reload ALL Spawns from DB");
  370. printf("| %21s | %51s |\n", "groundspawn_items", "Reload Groundspawn Items lists");
  371. printf("| %21s | %51s |\n", "zonescripts", "Reload Zone Scripts");
  372. printf("| %21s | %51s |\n", "entity_commands", "Reload Entity Commands");
  373. printf("| %21s | %51s |\n", "factions", "Reload Factions");
  374. printf("| %21s | %51s |\n", "mail", "Reload in-game Mail data");
  375. printf("| %21s | %51s |\n", "guilds", "Reload Guilds");
  376. printf("| %21s | %51s |\n", "locations", "Reload Locations data");
  377. printf("===============================================================================\n");
  378. if( strlen(sep->arg[1]) > 0 ) {
  379. // handle reloads here
  380. if (!strcasecmp(sep->arg[1], "spawns"))
  381. zone_list.ReloadSpawns();
  382. }
  383. return true;
  384. }
  385. bool ConsoleShutdownCommand(Seperator *sep)
  386. {
  387. if ( IsNumber(sep->arg[1]) ) {
  388. int8 shutdown_delay = atoi(sep->arg[1]);
  389. printf("Shutdown World in %i second(s)...\n", shutdown_delay);
  390. // shutting down gracefully, warn players.
  391. char message[4096];
  392. snprintf(message, sizeof(message), "BROADCAST: Server is shutting down in %s second(s)", sep->arg[1]);
  393. zone_list.HandleGlobalBroadcast(message);
  394. Sleep(shutdown_delay * 1000);
  395. }
  396. else {
  397. printf("Shutdown World immediately... you probably won't even see this message, huh!\n");
  398. }
  399. if( !ContinueLoops )
  400. RunLoops = false;
  401. return true;
  402. }
  403. bool ConsoleCancelShutdownCommand(Seperator *sep)
  404. {
  405. printf("Cancel World Shutdown...\n");
  406. ContinueLoops = true;
  407. return true;
  408. }
  409. bool ConsoleExitCommand(Seperator *sep)
  410. {
  411. // I wanted this to be a little more Terminate-y... killkillkill
  412. printf("Terminate World immediately...\n");
  413. RunLoops = false;
  414. return true;
  415. }
  416. bool ConsoleRulesCommand(Seperator *sep)
  417. {
  418. /*if( strlen(sep->arg[1]) == 0 )
  419. return false;*/
  420. printf("Current Active Ruleset");
  421. if (!strcasecmp(sep->arg[1], "zone"))
  422. {
  423. if (sep->IsNumber(2)) {
  424. printf(" in Zone ID: %s\n", sep->arg[2]);
  425. }
  426. else
  427. return false;
  428. }
  429. else
  430. {
  431. printf(" (global):\n");
  432. }
  433. printf("===============================================================================\n");
  434. printf("| %20s | %20s | %29s |\n", "Category", "Type", "Value");
  435. printf("===============================================================================\n");
  436. return true;
  437. }
  438. bool ConsoleTestCommand(Seperator *sep)
  439. {
  440. // devs put whatever test code in here
  441. printf("Testing Server Guild Rules values:\n");
  442. printf("AutoJoin: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoin)->GetInt8());
  443. printf("Guild ID: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoinID)->GetInt32());
  444. printf("Rank: %i\n", rule_manager.GetGlobalRule(R_World, GuildAutoJoinDefaultRankID)->GetInt8());
  445. return true;
  446. }