00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sstream>
00023
00024 #include "defines.h"
00025
00026 #include "game-server/commandhandler.hpp"
00027 #include "game-server/accountconnection.hpp"
00028 #include "game-server/character.hpp"
00029 #include "game-server/gamehandler.hpp"
00030 #include "game-server/inventory.hpp"
00031 #include "game-server/item.hpp"
00032 #include "game-server/itemmanager.hpp"
00033 #include "game-server/mapmanager.hpp"
00034 #include "game-server/monster.hpp"
00035 #include "game-server/monstermanager.hpp"
00036 #include "game-server/state.hpp"
00037
00038 #include "common/transaction.hpp"
00039
00040 #include "utils/string.hpp"
00041
00042 static void say(const std::string error, Character *player)
00043 {
00044 GameState::sayTo(player, NULL, error);
00045 }
00046
00047 static bool checkPermission(Character *player, unsigned int permissions)
00048 {
00049 if (player->getAccountLevel() & permissions)
00050 {
00051 return true;
00052 }
00053
00054 say("Invalid permissions", player);
00055
00056 return false;
00057 }
00058
00059 static std::string getArgument(std::string &args)
00060 {
00061 std::string argument = "";
00062 std::string::size_type pos = args.find(' ');
00063 if (pos != std::string::npos)
00064 {
00065 argument = args.substr(0, pos);
00066 args = args.substr(pos+1);
00067 }
00068 else
00069 {
00070 argument = args.substr(0);
00071 args = "";
00072 }
00073
00074 return argument;
00075 }
00076
00077 static Character* getPlayer(const std::string &player)
00078 {
00079
00080
00081 GameClient *client = gameHandler->getClientByNameSlow(player);
00082 if (!client)
00083 {
00084 return NULL;
00085 }
00086
00087 if (client->status != CLIENT_CONNECTED)
00088 {
00089 return NULL;
00090 }
00091
00092 return client->character;
00093 }
00094
00095 static void handleHelp(Character *player, std::string &args)
00096 {
00097 if (args == "")
00098 {
00099 if (player->getAccountLevel() & AL_PLAYER)
00100 {
00101 say("=General Commands=", player);
00102 say("@help [command]", player);
00103 say("@report <bug>", player);
00104 say("@where", player);
00105 say("@rights", player);
00106 }
00107
00108 if (player->getAccountLevel() & AL_TESTER)
00109 {
00110 say("=Tester Commands=", player);
00111 say("@warp <character> <map> <x> <y>", player);
00112 say("@goto <character>", player);
00113 }
00114
00115 if (player->getAccountLevel() & AL_GM)
00116 {
00117 say("=Game Master Commands=", player);
00118 say("@recall <character>", player);
00119 say("@ban <character> <length of time>", player);
00120 }
00121
00122 if (player->getAccountLevel() & AL_DEV)
00123 {
00124 say("=Developer Commands=", player);
00125 say("@item <character> <item id> <amount>", player);
00126 say("@drop <item id> <amount>", player);
00127 say("@money <character> <amount>", player);
00128 say("@spawn <monster id> <number>", player);
00129 say("@attribute <character> <attribute> <value>", player);
00130 }
00131
00132 if (player->getAccountLevel() & AL_ADMIN)
00133 {
00134 say("=Administrator Commands=", player);
00135 say("@reload", player);
00136 say("@setgroup <character> <AL level>", player);
00137 say("@announce <message>", player);
00138 say("@history <number of transactions>", player);
00139 }
00140 }
00141 else
00142 {
00143
00144 }
00145 }
00146
00147 static void handleWarp(Character *player, std::string &args)
00148 {
00149 int x, y;
00150 MapComposite *map;
00151 Character *other;
00152
00153
00154 std::string character = getArgument(args);
00155 std::string mapstr = getArgument(args);
00156 std::string xstr = getArgument(args);
00157 std::string ystr = getArgument(args);
00158
00159
00160 if (character == "" || mapstr == "" || xstr == "" || ystr == "")
00161 {
00162 say("Invalid number of arguments given.", player);
00163 say("Usage: @warp <character> <map> <x> <y>", player);
00164 return;
00165 }
00166
00167
00168 if (character == "#")
00169 {
00170 other = player;
00171 }
00172 else
00173 {
00174
00175 other = getPlayer(character);
00176 if (!other)
00177 {
00178 say("Invalid character, or they are offline", player);
00179 return;
00180 }
00181 }
00182
00183
00184 if (mapstr == "#")
00185 {
00186 map = player->getMap();
00187 }
00188 else
00189 {
00190
00191 int id;
00192 if (!utils::isNumeric(mapstr))
00193 {
00194 say("Invalid map", player);
00195 return;
00196 }
00197
00198 id = utils::stringToInt(mapstr);
00199
00200
00201 map = MapManager::getMap(id);
00202 if (!map)
00203 {
00204 say("Invalid map", player);
00205 return;
00206 }
00207 }
00208
00209 if (!utils::isNumeric(xstr))
00210 {
00211 say("Invalid x", player);
00212 return;
00213 }
00214
00215 if (!utils::isNumeric(ystr))
00216 {
00217 say("Invalid y", player);
00218 return;
00219 }
00220
00221
00222 x = utils::stringToInt(xstr);
00223 y = utils::stringToInt(ystr);
00224
00225
00226 GameState::warp(other, map, x, y);
00227
00228
00229 std::string msg = "User warped to " + xstr + "x" + ystr;
00230 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_WARP, msg);
00231 }
00232
00233 static void handleItem(Character *player, std::string &args)
00234 {
00235 Character *other;
00236 ItemClass *ic;
00237 int value;
00238 int id;
00239
00240
00241 std::string character = getArgument(args);
00242 std::string itemclass = getArgument(args);
00243 std::string valuestr = getArgument(args);
00244
00245
00246 if (character == "" || itemclass == "" || valuestr == "")
00247 {
00248 say("Invalid number of arguments given.", player);
00249 say("Usage: @item <character> <itemID> <amount>", player);
00250 return;
00251 }
00252
00253
00254 if (character == "#")
00255 {
00256 other = player;
00257 }
00258 else
00259 {
00260
00261 other = getPlayer(character);
00262 if (!other)
00263 {
00264 say("Invalid character or they are offline", player);
00265 return;
00266 }
00267 }
00268
00269
00270 if (!utils::isNumeric(itemclass))
00271 {
00272 say("Invalid item", player);
00273 return;
00274 }
00275
00276
00277 id = utils::stringToInt(itemclass);
00278
00279
00280 ic = ItemManager::getItem(id);
00281
00282 if (!ic)
00283 {
00284 say("Invalid item", player);
00285 return;
00286 }
00287
00288 if (!utils::isNumeric(valuestr))
00289 {
00290 say("Invalid value", player);
00291 return;
00292 }
00293
00294 value = utils::stringToInt(valuestr);
00295
00296 if (value < 0)
00297 {
00298 say("Invalid amount", player);
00299 return;
00300 }
00301
00302
00303 Inventory(other).insert(ic->getDatabaseID(), value);
00304
00305
00306 std::stringstream str;
00307 str << "User created item " << ic->getDatabaseID();
00308 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_ITEM, str.str());
00309 }
00310
00311 static void handleDrop(Character *player, std::string &args)
00312 {
00313 ItemClass *ic;
00314 int value, id;
00315
00316
00317 std::string itemclass = getArgument(args);
00318 std::string valuestr = getArgument(args);
00319
00320
00321 if (itemclass == "" || valuestr == "")
00322 {
00323 say("Invalid number of arguments given.", player);
00324 say("Usage: @drop <itemID> <amount]>", player);
00325 return;
00326 }
00327
00328
00329 if (!utils::isNumeric(itemclass) || !utils::isNumeric(valuestr))
00330 {
00331 say("Invalid arguments passed.", player);
00332 return;
00333 }
00334
00335
00336 id = utils::stringToInt(itemclass);
00337
00338
00339 ic = ItemManager::getItem(id);
00340 if (!ic)
00341 {
00342 say("Invalid item", player);
00343 return;
00344 }
00345
00346
00347 value = utils::stringToInt(valuestr);
00348
00349 if (value < 0)
00350 {
00351 say("Invalid amount", player);
00352 return;
00353 }
00354
00355
00356 Item *item = new Item(ic, value);
00357 item->setMap(player->getMap());
00358 item->setPosition(player->getPosition());
00359 GameState::insertSafe(item);
00360
00361
00362 std::stringstream str;
00363 str << "User created item " << ic->getDatabaseID();
00364 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_DROP, str.str());
00365 }
00366
00367 static void handleMoney(Character *player, std::string &args)
00368 {
00369 Character *other;
00370 int value;
00371
00372
00373 std::string character = getArgument(args);
00374 std::string valuestr = getArgument(args);
00375
00376
00377 if (character == "" || valuestr == "")
00378 {
00379 say("Invalid number of arguments given", player);
00380 say("Usage: @money <character> <amount>", player);
00381 return;
00382 }
00383
00384
00385 if (character == "#")
00386 {
00387 other = player;
00388 }
00389 else
00390 {
00391
00392 other = getPlayer(character);
00393 if (!other)
00394 {
00395 say("Invalid character or they are offline", player);
00396 return;
00397 }
00398 }
00399
00400
00401 if (!utils::isNumeric(valuestr))
00402 {
00403 say("Invalid argument", player);
00404 return;
00405 }
00406
00407
00408 value = utils::stringToInt(valuestr);
00409
00410
00411 Inventory(other).changeMoney(value);
00412
00413
00414 std::string msg = "User created " + valuestr + " money";
00415 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_MONEY, msg);
00416 }
00417
00418 static void handleSpawn(Character *player, std::string &args)
00419 {
00420 MonsterClass *mc;
00421 MapComposite *map = player->getMap();
00422 const Point &pos = player->getPosition();
00423 int value, id;
00424
00425
00426 std::string monsterclass = getArgument(args);
00427 std::string valuestr = getArgument(args);
00428
00429
00430 if (monsterclass == "" || valuestr == "")
00431 {
00432 say("Invalid amount of arguments given.", player);
00433 say("Usage: @spawn <monsterID> <number>", player);
00434 return;
00435 }
00436
00437
00438 if (!utils::isNumeric(monsterclass) || !utils::isNumeric(valuestr))
00439 {
00440 say("Invalid arguments", player);
00441 return;
00442 }
00443
00444
00445 id = utils::stringToInt(monsterclass);
00446
00447
00448 mc = MonsterManager::getMonster(id);
00449 if (!mc)
00450 {
00451 say("Invalid monster", player);
00452 return;
00453 }
00454
00455
00456 value = utils::stringToInt(valuestr);
00457
00458 if (value < 0)
00459 {
00460 say("Invalid amount", player);
00461 return;
00462 }
00463
00464
00465 for (int i = 0; i < value; ++i)
00466 {
00467 Being *monster = new Monster(mc);
00468 monster->setMap(map);
00469 monster->setPosition(pos);
00470 monster->clearDestination();
00471 if (!GameState::insertSafe(monster))
00472 {
00473
00474 break;
00475 }
00476
00477
00478 std::string msg = "User created monster " + monster->getName();
00479 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_SPAWN, msg);
00480 }
00481 }
00482
00483 static void handleGoto(Character *player, std::string &args)
00484 {
00485 Character *other;
00486
00487
00488 std::string character = getArgument(args);
00489
00490
00491 if (character == "")
00492 {
00493 say("Invalid amount of arguments given.", player);
00494 say("Usage: @goto <character>", player);
00495 return;
00496 }
00497
00498
00499 other = getPlayer(character);
00500 if (!other)
00501 {
00502 say("Invalid character, or they are offline.", player);
00503 return;
00504 }
00505
00506
00507 MapComposite *map = other->getMap();
00508 const Point &pos = other->getPosition();
00509 GameState::warp(player, map, pos.x, pos.y);
00510 }
00511
00512 static void handleRecall(Character *player, std::string &args)
00513 {
00514 Character *other;
00515
00516
00517 std::string character = getArgument(args);
00518
00519
00520 if (character == "")
00521 {
00522 say("Invalid amount of arguments given.", player);
00523 say("Usage: @recall <character>", player);
00524 return;
00525 }
00526
00527
00528 other = getPlayer(character);
00529 if (!other)
00530 {
00531 say("Invalid character, or they are offline.", player);
00532 return;
00533 }
00534
00535
00536 MapComposite *map = player->getMap();
00537 const Point &pos = player->getPosition();
00538 GameState::warp(other, map, pos.x, pos.y);
00539 }
00540
00541 static void handleReload(Character *player)
00542 {
00543
00544 ItemManager::reload();
00545 MonsterManager::reload();
00546 }
00547
00548 static void handleBan(Character *player, std::string &args)
00549 {
00550 Character *other;
00551 int length;
00552
00553
00554 std::string character = getArgument(args);
00555 std::string valuestr = getArgument(args);
00556
00557
00558 if (character == "" || valuestr == "")
00559 {
00560 say("Invalid number of arguments given.", player);
00561 say("Usage: @ban <character> <duration>", player);
00562 return;
00563 }
00564
00565
00566 other = getPlayer(character);
00567 if (!other)
00568 {
00569 say("Invalid character", player);
00570 return;
00571 }
00572
00573
00574 if (!utils::isNumeric(valuestr))
00575 {
00576 say("Invalid argument", player);
00577 return;
00578 }
00579
00580
00581 length = utils::stringToInt(valuestr);
00582
00583 if (length < 0)
00584 {
00585 say("Invalid length", player);
00586 return;
00587 }
00588
00589
00590 accountHandler->banCharacter(other, length);
00591
00592
00593 std::string msg = "User banned " + other->getName();
00594 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_BAN, msg);
00595 }
00596
00597 static void handleSetGroup(Character *player, std::string &args)
00598 {
00599 Character *other;
00600 int level = 0;
00601
00602
00603 std::string character = getArgument(args);
00604 std::string levelstr = getArgument(args);
00605
00606
00607 if (character == "" || levelstr == "")
00608 {
00609 say("Invalid number of arguments given.", player);
00610 say("Usage: @setgroup <character> <level>", player);
00611 return;
00612 }
00613
00614
00615 if (character == "#")
00616 {
00617 other = player;
00618 }
00619 else
00620 {
00621
00622 other = getPlayer(character);
00623 if (!other)
00624 {
00625 say("Invalid character", player);
00626 return;
00627 }
00628 }
00629
00630
00631
00632 if (levelstr == "AL_PLAYER")
00633 {
00634 level = AL_PLAYER;
00635 }
00636 else if (levelstr == "AL_TESTER")
00637 {
00638 level = AL_PLAYER | AL_TESTER;
00639 }
00640 else if (levelstr == "AL_GM")
00641 {
00642 level = AL_PLAYER | AL_TESTER | AL_GM;
00643 }
00644 else if (levelstr == "AL_DEV")
00645 {
00646 level = AL_PLAYER | AL_TESTER | AL_DEV;
00647 }
00648 else if (levelstr == "AL_ADMIN")
00649 {
00650 level = 255;
00651 }
00652
00653 if (level == 0)
00654 {
00655 say("Invalid group", player);
00656 return;
00657 }
00658
00659
00660 accountHandler->changeAccountLevel(other, level);
00661
00662
00663 std::string msg = "User changed account level of " + other->getName() + " to " + levelstr;
00664 accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_SETGROUP, msg);
00665 }
00666
00667 static void handleAttribute(Character *player, std::string &args)
00668 {
00669 Character *other;
00670 int attr, value;
00671
00672
00673 std::string character = getArgument(args);
00674 std::string attrstr = getArgument(args);
00675 std::string valuestr = getArgument(args);
00676
00677
00678 if (character == "" || valuestr == "" || attrstr == "")
00679 {
00680 say("Invalid number of arguments given.", player);
00681 say("Usage: @attribute <character> <attribute> <value>", player);
00682 return;
00683 }
00684
00685
00686 if (character == "#")
00687 {
00688 other = player;
00689 }
00690 else
00691 {
00692
00693 other = getPlayer(character);
00694 if (!other)
00695 {
00696 say("Invalid character", player);
00697 return;
00698 }
00699 }
00700
00701
00702 if (!utils::isNumeric(valuestr) || !utils::isNumeric(attrstr))
00703 {
00704 say("Invalid argument", player);
00705 return;
00706 }
00707
00708
00709 attr = utils::stringToInt(attrstr);
00710
00711 if (attr < 0)
00712 {
00713 say("Invalid Attribute", player);
00714 return;
00715 }
00716
00717
00718 value = utils::stringToInt(valuestr);
00719
00720 if (value < 0)
00721 {
00722 say("Invalid amount", player);
00723 return;
00724 }
00725
00726
00727 other->setAttribute(attr, value);
00728 }
00729
00730 static void handleReport(Character *player, std::string &args)
00731 {
00732 std::string bugReport = getArgument(args);
00733
00734 if (bugReport == "")
00735 {
00736 say("Invalid number of arguments given.", player);
00737 say("Usage: @report <message>", player);
00738 return;
00739 }
00740
00741
00742 }
00743
00744 static void handleAnnounce(Character *player, std::string &args)
00745 {
00746 std::string msg = getArgument(args);
00747
00748 if (msg == "")
00749 {
00750 say("Invalid number of arguments given.", player);
00751 say("Usage: @announce <message>", player);
00752 return;
00753 }
00754
00755 GameState::sayToAll(msg);
00756 }
00757
00758 static void handleWhere(Character *player)
00759 {
00760 std::stringstream str;
00761 str << "Your current location is map "
00762 << player->getMapId()
00763 << " ["
00764 << player->getPosition().x
00765 << ":"
00766 << player->getPosition().y
00767 << "]";
00768 say (str.str(), player);
00769 }
00770
00771 static void handleRights(Character *player)
00772 {
00773 std::stringstream str;
00774 str << "Your rights level is: "
00775 << player->getAccountLevel()
00776 << " (AL_PLAYER";
00777 if (player->getAccountLevel() & AL_TESTER)
00778 str << ", AL_TESTER";
00779 if (player->getAccountLevel() & AL_GM)
00780 str << ", AL_GM";
00781 if (player->getAccountLevel() & AL_ADMIN)
00782 str << ", AL_ADMIN";
00783 str << ")";
00784 say(str.str(), player);
00785 }
00786
00787 static void handleHistory(Character *player, std::string args)
00788 {
00789
00790 }
00791
00792 void CommandHandler::handleCommand(Character *player,
00793 const std::string &command)
00794 {
00795
00796
00797 std::string::size_type pos = command.find(' ');
00798 std::string type(command, 1, pos == std::string::npos ? pos : pos - 1);
00799 std::string args(command, pos == std::string::npos ? command.size() : pos + 1);
00800
00801
00802 if (type == "help")
00803 {
00804 if (checkPermission(player, AL_PLAYER))
00805 handleHelp(player, args);
00806 }
00807 else if (type == "where" || type == "location")
00808 {
00809 if (checkPermission(player, AL_PLAYER))
00810 handleWhere(player);
00811 }
00812 else if (type == "rights" || type == "right" || type == "permission")
00813 {
00814 if (checkPermission(player, AL_PLAYER))
00815 handleRights(player);
00816 }
00817 else if (type == "warp")
00818 {
00819 if (checkPermission(player, AL_TESTER))
00820 handleWarp(player, args);
00821 }
00822 else if (type == "item")
00823 {
00824 if (checkPermission(player, AL_DEV))
00825 handleItem(player, args);
00826 }
00827 else if (type == "drop")
00828 {
00829 if (checkPermission(player, AL_DEV))
00830 handleDrop(player, args);
00831 }
00832 else if (type == "money")
00833 {
00834 if (checkPermission(player, AL_DEV))
00835 handleMoney(player, args);
00836 }
00837 else if (type == "spawn")
00838 {
00839 if (checkPermission(player, AL_DEV))
00840 handleSpawn(player, args);
00841 }
00842 else if (type == "goto")
00843 {
00844 if (checkPermission(player, AL_TESTER))
00845 handleGoto(player, args);
00846 }
00847 else if (type == "recall")
00848 {
00849 if (checkPermission(player, AL_GM))
00850 handleRecall(player, args);
00851 }
00852 else if (type == "reload")
00853 {
00854 if (checkPermission(player, AL_ADMIN))
00855 handleReload(player);
00856 }
00857 else if (type == "ban")
00858 {
00859 if (checkPermission(player, AL_GM))
00860 handleBan(player, args);
00861 }
00862 else if (type == "setgroup")
00863 {
00864 if (checkPermission(player, AL_ADMIN))
00865 handleSetGroup(player, args);
00866 }
00867 else if (type == "attribute")
00868 {
00869 if (checkPermission(player, AL_DEV))
00870 handleAttribute(player, args);
00871 }
00872 else if (type == "report")
00873 {
00874 if (checkPermission(player, AL_PLAYER))
00875 handleReport(player, args);
00876 }
00877 else if (type == "announce")
00878 {
00879 if (checkPermission(player, AL_ADMIN))
00880 handleAnnounce(player, args);
00881 }
00882 else if (type == "history")
00883 {
00884 if (checkPermission(player, AL_ADMIN))
00885 handleHistory(player, args);
00886 }
00887 else
00888 {
00889 say("Command not found. Enter @help to view the list of available commands.", player);
00890 }
00891 }