diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-10-29 09:16:39 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-10-29 09:16:39 +0000 |
commit | 8f36123ac4f0dad6a9c2428b0b01a3ffd81017a4 (patch) | |
tree | 844de2f22a0f03953031d1baaf3ffdc426ad48cd /src/map/atcommand.c | |
parent | ccbcf5a85c209341e6471269abef23b58633d083 (diff) | |
download | hercules-8f36123ac4f0dad6a9c2428b0b01a3ffd81017a4.tar.gz hercules-8f36123ac4f0dad6a9c2428b0b01a3ffd81017a4.tar.bz2 hercules-8f36123ac4f0dad6a9c2428b0b01a3ffd81017a4.tar.xz hercules-8f36123ac4f0dad6a9c2428b0b01a3ffd81017a4.zip |
Command code cleaning (refer to topic:169759)
* separated the execution part of command code into interface part and internal part to better see which checks are done and when (fixes problem where 'nocommand' mapflag blocked server npcs)
* moved the internal commands list (array) to the end of the file, this let me discard that long block of ACMD_FUNC() declarations
* removed enum AtCommandType from command headers and commands array; its purpose was perhaps to identify aliased commands, but apparently it was never finished because the rest of the code doesn't use it (also doing aliases like this is not a very good idea)
* internally, commands are now referenced to using their function name
* removed the @/# symbols from the command lists; all lookup functions will now properly deal with strings with- and without a command symbol (commands interface still requires the symbol tho', so TODO for later)
* removed several unneeded commands (*id2 code, dmalloc debug commands)
* reverted atcommand config from alphabetically-sorted to how it was before (with additional fixes; see /conf changelog)
* added missing code for #dropall / #storeall
* added a warning when trying to set gm level of an undefined command
The structure of the commands table has changed, please adjust docs/guides to match the new format (sorry for the inconvenience).
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11607 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/atcommand.c')
-rw-r--r-- | src/map/atcommand.c | 1569 |
1 files changed, 551 insertions, 1018 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 8a23c9d05..a93bddb3d 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -13,11 +13,12 @@ #include "../common/utils.h" #include "atcommand.h" -#include "log.h" +#include "battle.h" #include "clif.h" #include "chrif.h" #include "intif.h" #include "itemdb.h" +#include "log.h" #include "map.h" #include "pc.h" #include "status.h" @@ -25,12 +26,10 @@ #include "mob.h" #include "npc.h" #include "pet.h" -#include "mercenary.h" //[orn] -#include "battle.h" +#include "mercenary.h" #include "party.h" #include "guild.h" #include "script.h" -#include "npc.h" #include "trade.h" #include "unit.h" @@ -43,539 +42,25 @@ #include <string.h> #include <math.h> -char atcommand_symbol = '@'; // first char of the commands (by [Yor]) - -char *msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) +// extern variables +char atcommand_symbol = '@'; // first char of the commands +char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) +// local declarations #define ACMD_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message) -ACMD_FUNC(broadcast); -ACMD_FUNC(localbroadcast); -ACMD_FUNC(rura); -ACMD_FUNC(where); -ACMD_FUNC(jumpto); -ACMD_FUNC(jump); -ACMD_FUNC(who); -ACMD_FUNC(who2); -ACMD_FUNC(who3); -ACMD_FUNC(whomap); -ACMD_FUNC(whomap2); -ACMD_FUNC(whomap3); -ACMD_FUNC(whogm); // by Yor -ACMD_FUNC(whozeny); // [Valaris] -ACMD_FUNC(save); -ACMD_FUNC(load); -ACMD_FUNC(speed); -ACMD_FUNC(storage); -ACMD_FUNC(guildstorage); -ACMD_FUNC(option); -ACMD_FUNC(hide); -ACMD_FUNC(jobchange); -ACMD_FUNC(die); -ACMD_FUNC(kill); -ACMD_FUNC(alive); -ACMD_FUNC(kami); -ACMD_FUNC(heal); -ACMD_FUNC(item); -ACMD_FUNC(item2); -ACMD_FUNC(itemreset); -ACMD_FUNC(baselevelup); -ACMD_FUNC(joblevelup); -ACMD_FUNC(help); -ACMD_FUNC(help2); -ACMD_FUNC(gm); -ACMD_FUNC(pvpoff); -ACMD_FUNC(pvpon); -ACMD_FUNC(gvgoff); -ACMD_FUNC(gvgon); -ACMD_FUNC(model); -ACMD_FUNC(go); -ACMD_FUNC(monster); -ACMD_FUNC(monstersmall); -ACMD_FUNC(monsterbig); -ACMD_FUNC(spawn); -ACMD_FUNC(killmonster); -ACMD_FUNC(killmonster2); -ACMD_FUNC(refine); -ACMD_FUNC(produce); -ACMD_FUNC(memo); -ACMD_FUNC(gat); -ACMD_FUNC(displaystatus); -ACMD_FUNC(statuspoint); -ACMD_FUNC(skillpoint); -ACMD_FUNC(zeny); -ACMD_FUNC(param); -ACMD_FUNC(guildlevelup); -ACMD_FUNC(makeegg); -ACMD_FUNC(hatch); -ACMD_FUNC(petfriendly); -ACMD_FUNC(pethungry); -ACMD_FUNC(petrename); -ACMD_FUNC(recall); -ACMD_FUNC(recallall); -ACMD_FUNC(night); -ACMD_FUNC(day); -ACMD_FUNC(doom); -ACMD_FUNC(doommap); -ACMD_FUNC(raise); -ACMD_FUNC(raisemap); -ACMD_FUNC(kick); -ACMD_FUNC(kickall); -ACMD_FUNC(allskill); -ACMD_FUNC(questskill); -ACMD_FUNC(lostskill); -ACMD_FUNC(spiritball); -ACMD_FUNC(party); -ACMD_FUNC(guild); -ACMD_FUNC(agitstart); -ACMD_FUNC(agitend); -ACMD_FUNC(reloaditemdb); -ACMD_FUNC(reloadmobdb); -ACMD_FUNC(reloadskilldb); -ACMD_FUNC(reloadscript); -ACMD_FUNC(reloadgmdb); // by Yor -ACMD_FUNC(reloadatcommand); -ACMD_FUNC(reloadbattleconf); -ACMD_FUNC(reloadstatusdb); -ACMD_FUNC(reloadpcdb); -ACMD_FUNC(reloadmotd); // [Valaris] -ACMD_FUNC(mapexit); -ACMD_FUNC(idsearch); -ACMD_FUNC(mapinfo); -ACMD_FUNC(dye); //** by fritz -ACMD_FUNC(hair_style); //** by fritz -ACMD_FUNC(hair_color); //** by fritz -ACMD_FUNC(stat_all); //** by fritz -ACMD_FUNC(char_block); // by Yor -ACMD_FUNC(char_ban); // by Yor -ACMD_FUNC(char_unblock); // by Yor -ACMD_FUNC(char_unban); // by Yor -ACMD_FUNC(mount_peco); // by Valaris -ACMD_FUNC(guildspy); // [Syrus22] -ACMD_FUNC(partyspy); // [Syrus22] -ACMD_FUNC(repairall); // [Valaris] -ACMD_FUNC(guildrecall); // by Yor -ACMD_FUNC(partyrecall); // by Yor -ACMD_FUNC(nuke); // [Valaris] -ACMD_FUNC(shownpc); -ACMD_FUNC(hidenpc); -ACMD_FUNC(loadnpc); -ACMD_FUNC(unloadnpc); -ACMD_FUNC(servertime); // by Yor -ACMD_FUNC(jail); // by Yor -ACMD_FUNC(unjail); // by Yor -ACMD_FUNC(jailfor); // Alias Meruru -ACMD_FUNC(jailtime); // Coltaro -ACMD_FUNC(disguise); // [Valaris] -ACMD_FUNC(undisguise); // by Yor -ACMD_FUNC(email); // by Yor -ACMD_FUNC(effect);//by Apple -ACMD_FUNC(addwarp); // by MouseJstr -ACMD_FUNC(follow); // by MouseJstr -ACMD_FUNC(skillon); // by MouseJstr -ACMD_FUNC(skilloff); // by MouseJstr -ACMD_FUNC(killer); // by MouseJstr -ACMD_FUNC(npcmove); // by MouseJstr -ACMD_FUNC(killable); // by MouseJstr -ACMD_FUNC(dropall); // by MouseJstr -ACMD_FUNC(storeall); // by MouseJstr -ACMD_FUNC(skillid); // by MouseJstr -ACMD_FUNC(useskill); // by MouseJstr -ACMD_FUNC(displayskill); //[Skotlex] -ACMD_FUNC(summon); -ACMD_FUNC(rain); -ACMD_FUNC(snow); -ACMD_FUNC(sakura); -ACMD_FUNC(clouds); -ACMD_FUNC(clouds2); // [Valaris] -ACMD_FUNC(fog); -ACMD_FUNC(fireworks); -ACMD_FUNC(leaves); -ACMD_FUNC(adjgmlvl); // by MouseJstr -ACMD_FUNC(adjcmdlvl); // by MouseJstr -ACMD_FUNC(trade); // by MouseJstr -ACMD_FUNC(send); // by davidsiaw -ACMD_FUNC(setbattleflag); // by MouseJstr -ACMD_FUNC(unmute); // [Valaris] -ACMD_FUNC(clearweather); // Dexity -ACMD_FUNC(uptime); // by MC Cameri -ACMD_FUNC(changesex); // by MC Cameri -ACMD_FUNC(mute); // celest -ACMD_FUNC(refresh); // by MC Cameri -ACMD_FUNC(identify); // by MC Cameri -ACMD_FUNC(gmotd); // Added by MC Cameri, created by davidsiaw -ACMD_FUNC(misceffect); // by MC Cameri -ACMD_FUNC(mobsearch); -ACMD_FUNC(cleanmap); -ACMD_FUNC(npctalk); -ACMD_FUNC(pettalk); -ACMD_FUNC(users); -ACMD_FUNC(reset); -ACMD_FUNC(autoloot); // Improved version imported from Freya. -ACMD_FUNC(skilltree); // by MouseJstr -ACMD_FUNC(marry); // by MouseJstr -ACMD_FUNC(divorce); // by MouseJstr -ACMD_FUNC(jumptoid2); // by Dino9021 -ACMD_FUNC(recallid2); // by Dino9021 -ACMD_FUNC(kickid2); // by Dino9021 -ACMD_FUNC(reviveid2); // by Dino9021 -ACMD_FUNC(killid2); // by Dino9021 -ACMD_FUNC(sound); -ACMD_FUNC(undisguiseall); -ACMD_FUNC(disguiseall); -ACMD_FUNC(changelook); -ACMD_FUNC(mobinfo); //by Lupus -ACMD_FUNC(exp); // by Skotlex -ACMD_FUNC(adopt); // by Veider -ACMD_FUNC(version); // by Ancyker -ACMD_FUNC(mutearea); // by MouseJstr -ACMD_FUNC(rates); // by MouseJstr -ACMD_FUNC(iteminfo); // Lupus -ACMD_FUNC(whodrops); //Skotlex -ACMD_FUNC(whereis); //Skotlex -ACMD_FUNC(mapflag); // Lupus -ACMD_FUNC(me); //added by massdriller, code by lordalfa -ACMD_FUNC(monsterignore); // [Valaris] -ACMD_FUNC(fakename); //[Valaris] -ACMD_FUNC(size); //[Valaris] -ACMD_FUNC(showexp); //moved from charcommand [Kevin] -ACMD_FUNC(showzeny); -ACMD_FUNC(showdelay); //moved from charcommand [Kevin] -ACMD_FUNC(autotrade);// durf -ACMD_FUNC(changeleader);// [Skotlex] -ACMD_FUNC(partyoption);// [Skotlex] -ACMD_FUNC(changegm);// durf -// Duel [LuzZza] -ACMD_FUNC(invite); -ACMD_FUNC(duel); -ACMD_FUNC(leave); -ACMD_FUNC(accept); -ACMD_FUNC(reject); -ACMD_FUNC(away); // LuzZza -ACMD_FUNC(main); // LuzZza -ACMD_FUNC(clone); // [Valaris] -ACMD_FUNC(tonpc); // LuzZza -ACMD_FUNC(commands); // [Skotlex] -ACMD_FUNC(noask); //LuzZza -ACMD_FUNC(request); //[Skotlex] -ACMD_FUNC(homlevel); //[orn] -ACMD_FUNC(homevolution); //[orn] -ACMD_FUNC(makehomun); //[orn] -ACMD_FUNC(homfriendly); //[orn] -ACMD_FUNC(homhungry); //[orn] -ACMD_FUNC(homtalk); //[orn] -ACMD_FUNC(hominfo); //[Toms] -ACMD_FUNC(homstats); //[Skotlex] -ACMD_FUNC(homshuffle); //[Skotlex] -ACMD_FUNC(showmobs); //KarLaeda -ACMD_FUNC(feelreset); //[HiddenDragon] -#ifndef TXT_ONLY -ACMD_FUNC(mail); // [MAIL SYSTEM] -ACMD_FUNC(refreshonline); // [Valaris] -#endif -#ifdef DMALLOC -ACMD_FUNC(dmstart); // by MouseJstr -ACMD_FUNC(dmtick); // by MouseJstr -#endif -/*========================================== - *AtCommandInfo atcommand_info[] structure definition - *------------------------------------------*/ - -// First char of commands is configured in atcommand_athena.conf. Leave @ in this list for default value. -// to set default level, read atcommand_athena.conf first please. -static AtCommandInfo atcommand_info[] = { - { AtCommand_Rura, "@rura", 40, atcommand_rura }, - { AtCommand_Warp, "@warp", 40, atcommand_rura }, - { AtCommand_MapMove, "@mapmove", 40, atcommand_rura }, // /mm command - { AtCommand_Where, "@where", 1, atcommand_where }, - { AtCommand_JumpTo, "@jumpto", 20, atcommand_jumpto }, // + /shift - { AtCommand_JumpTo, "@warpto", 20, atcommand_jumpto }, - { AtCommand_JumpTo, "@goto", 20, atcommand_jumpto }, - { AtCommand_Jump, "@jump", 40, atcommand_jump }, - { AtCommand_Who, "@who", 20, atcommand_who }, - { AtCommand_Who, "@whois", 20, atcommand_who }, - { AtCommand_Who2, "@who2", 20, atcommand_who2 }, - { AtCommand_Who3, "@who3", 20, atcommand_who3 }, - { AtCommand_WhoMap, "@whomap", 20, atcommand_whomap }, - { AtCommand_WhoMap2, "@whomap2", 20, atcommand_whomap2 }, - { AtCommand_WhoMap3, "@whomap3", 20, atcommand_whomap3 }, - { AtCommand_WhoGM, "@whogm", 20, atcommand_whogm }, // by Yor - { AtCommand_Save, "@save", 40, atcommand_save }, - { AtCommand_Load, "@return", 40, atcommand_load }, - { AtCommand_Load, "@load", 40, atcommand_load }, - { AtCommand_Speed, "@speed", 40, atcommand_speed }, - { AtCommand_Storage, "@storage", 1, atcommand_storage }, - { AtCommand_GuildStorage, "@gstorage", 50, atcommand_guildstorage }, - { AtCommand_Option, "@option", 40, atcommand_option }, - { AtCommand_Hide, "@hide", 40, atcommand_hide }, // + /hide - { AtCommand_JobChange, "@jobchange", 40, atcommand_jobchange }, - { AtCommand_JobChange, "@job", 40, atcommand_jobchange }, - { AtCommand_Die, "@die", 1, atcommand_die }, - { AtCommand_Kill, "@kill", 60, atcommand_kill }, - { AtCommand_Alive, "@alive", 60, atcommand_alive }, - { AtCommand_Kami, "@kami", 40, atcommand_kami }, - { AtCommand_KamiB, "@kamib", 40, atcommand_kami }, - { AtCommand_KamiC, "@kamic", 40, atcommand_kami }, //[LuzZza] - { AtCommand_Heal, "@heal", 40, atcommand_heal }, - { AtCommand_Item, "@item", 60, atcommand_item }, - { AtCommand_Item2, "@item2", 60, atcommand_item2 }, - { AtCommand_ItemReset, "@itemreset", 40, atcommand_itemreset }, - { AtCommand_BaseLevelUp, "@baselvl", 60, atcommand_baselevelup }, - { AtCommand_BaseLevelUp, "@baselevel", 60, atcommand_baselevelup }, - { AtCommand_BaseLevelUp, "@blevel", 60, atcommand_baselevelup }, - { AtCommand_BaseLevelUp, "@blvl", 60, atcommand_baselevelup }, - { AtCommand_JobLevelUp, "@jlvl", 60, atcommand_joblevelup }, - { AtCommand_JobLevelUp, "@jlevel", 60, atcommand_joblevelup }, - { AtCommand_JobLevelUp, "@joblvl", 60, atcommand_joblevelup }, - { AtCommand_JobLevelUp, "@joblevel", 60, atcommand_joblevelup }, - { AtCommand_H, "@h", 20, atcommand_help }, - { AtCommand_Help, "@help", 20, atcommand_help }, - { AtCommand_H2, "@h2", 20, atcommand_help2 }, - { AtCommand_Help2, "@help2", 20, atcommand_help2 }, - { AtCommand_GM, "@gm", 100,atcommand_gm }, - { AtCommand_PvPOff, "@pvpoff", 40, atcommand_pvpoff }, - { AtCommand_PvPOn, "@pvpon", 40, atcommand_pvpon }, - { AtCommand_GvGOff, "@gvgoff", 40, atcommand_gvgoff }, - { AtCommand_GvGOff, "@gpvpoff", 40, atcommand_gvgoff }, - { AtCommand_GvGOn, "@gvgon", 40, atcommand_gvgon }, - { AtCommand_GvGOn, "@gpvpon", 40, atcommand_gvgon }, - { AtCommand_Model, "@model", 20, atcommand_model }, - { AtCommand_Go, "@go", 10, atcommand_go }, - { AtCommand_Spawn, "@monster", 50, atcommand_monster }, - { AtCommand_Spawn, "@spawn", 50, atcommand_monster }, - { AtCommand_MonsterSmall, "@monstersmall", 50, atcommand_monstersmall }, - { AtCommand_MonsterBig, "@monsterbig", 50, atcommand_monsterbig }, - { AtCommand_KillMonster, "@killmonster", 60, atcommand_killmonster }, - { AtCommand_KillMonster2, "@killmonster2", 40, atcommand_killmonster2 }, - { AtCommand_Refine, "@refine", 60, atcommand_refine }, - { AtCommand_Produce, "@produce", 60, atcommand_produce }, - { AtCommand_Memo, "@memo", 40, atcommand_memo }, - { AtCommand_GAT, "@gat", 99, atcommand_gat }, - { AtCommand_DisplayStatus, "@displaystatus", 99, atcommand_displaystatus }, - { AtCommand_StatusPoint, "@stpoint", 60, atcommand_statuspoint }, - { AtCommand_SkillPoint, "@skpoint", 60, atcommand_skillpoint }, - { AtCommand_Zeny, "@zeny", 60, atcommand_zeny }, - { AtCommand_Strength, "@str", 60, atcommand_param }, - { AtCommand_Agility, "@agi", 60, atcommand_param }, - { AtCommand_Vitality, "@vit", 60, atcommand_param }, - { AtCommand_Intelligence, "@int", 60, atcommand_param }, - { AtCommand_Dexterity, "@dex", 60, atcommand_param }, - { AtCommand_Luck, "@luk", 60, atcommand_param }, - { AtCommand_GuildLevelUp, "@glvl", 60, atcommand_guildlevelup }, - { AtCommand_GuildLevelUp, "@glevel", 60, atcommand_guildlevelup }, - { AtCommand_GuildLevelUp, "@guildlvl", 60, atcommand_guildlevelup }, - { AtCommand_GuildLevelUp, "@guildlevel", 60, atcommand_guildlevelup }, - { AtCommand_MakeEgg, "@makeegg", 60, atcommand_makeegg }, - { AtCommand_Hatch, "@hatch", 60, atcommand_hatch }, - { AtCommand_PetFriendly, "@petfriendly", 40, atcommand_petfriendly }, - { AtCommand_PetHungry, "@pethungry", 40, atcommand_pethungry }, - { AtCommand_PetRename, "@petrename", 1, atcommand_petrename }, - { AtCommand_Recall, "@recall", 60, atcommand_recall }, // + /recall - { AtCommand_Night, "@night", 80, atcommand_night }, - { AtCommand_Day, "@day", 80, atcommand_day }, - { AtCommand_Doom, "@doom", 80, atcommand_doom }, - { AtCommand_DoomMap, "@doommap", 80, atcommand_doommap }, - { AtCommand_Raise, "@raise", 80, atcommand_raise }, - { AtCommand_RaiseMap, "@raisemap", 80, atcommand_raisemap }, - { AtCommand_Kick, "@kick", 20, atcommand_kick }, // + right click menu for GM "(name) force to quit" - { AtCommand_KickAll, "@kickall", 99, atcommand_kickall }, - { AtCommand_AllSkill, "@allskill", 60, atcommand_allskill }, - { AtCommand_AllSkill, "@allskills", 60, atcommand_allskill }, - { AtCommand_AllSkill, "@skillall", 60, atcommand_allskill }, - { AtCommand_AllSkill, "@skillsall", 60, atcommand_allskill }, - { AtCommand_QuestSkill, "@questskill", 40, atcommand_questskill }, - { AtCommand_LostSkill, "@lostskill", 40, atcommand_lostskill }, - { AtCommand_SpiritBall, "@spiritball", 40, atcommand_spiritball }, - { AtCommand_Party, "@party", 1, atcommand_party }, - { AtCommand_Guild, "@guild", 50, atcommand_guild }, - { AtCommand_AgitStart, "@agitstart", 60, atcommand_agitstart }, - { AtCommand_AgitEnd, "@agitend", 60, atcommand_agitend }, - { AtCommand_MapExit, "@mapexit", 99, atcommand_mapexit }, - { AtCommand_IDSearch, "@idsearch", 60, atcommand_idsearch }, - { AtCommand_Broadcast, "@broadcast", 40, atcommand_broadcast }, // /b and /nb command - { AtCommand_LocalBroadcast, "@localbroadcast", 40, atcommand_localbroadcast }, // /lb and /nlb command - { AtCommand_RecallAll, "@recallall", 80, atcommand_recallall }, - { AtCommand_ReloadItemDB, "@reloaditemdb", 99, atcommand_reloaditemdb }, // admin command - { AtCommand_ReloadMobDB, "@reloadmobdb", 99, atcommand_reloadmobdb }, // admin command - { AtCommand_ReloadSkillDB, "@reloadskilldb", 99, atcommand_reloadskilldb }, // admin command - { AtCommand_ReloadScript, "@reloadscript", 99, atcommand_reloadscript }, // admin command - { AtCommand_ReloadGMDB, "@reloadgmdb", 99, atcommand_reloadgmdb }, // admin command - { AtCommand_ReloadAtcommand, "@reloadatcommand", 99, atcommand_reloadatcommand }, - { AtCommand_ReloadBattleConf, "@reloadbattleconf",99, atcommand_reloadbattleconf }, - { AtCommand_ReloadStatusDB, "@reloadstatusdb", 99, atcommand_reloadstatusdb }, - { AtCommand_ReloadPcDB, "@reloadpcdb", 99, atcommand_reloadpcdb }, - { AtCommand_ReloadMOTD, "@reloadmotd", 99, atcommand_reloadmotd }, // [Valaris] - { AtCommand_MapInfo, "@mapinfo", 99, atcommand_mapinfo }, - { AtCommand_Dye, "@dye", 40, atcommand_dye }, // by fritz - { AtCommand_Dye, "@ccolor", 40, atcommand_dye }, // by fritz - { AtCommand_Hstyle, "@hairstyle", 40, atcommand_hair_style }, // by fritz - { AtCommand_Hstyle, "@hstyle", 40, atcommand_hair_style }, // by fritz - { AtCommand_Hcolor, "@haircolor", 40, atcommand_hair_color }, // by fritz - { AtCommand_Hcolor, "@hcolor", 40, atcommand_hair_color }, // by fritz - { AtCommand_StatAll, "@statall", 60, atcommand_stat_all }, // by fritz - { AtCommand_StatAll, "@statsall", 60, atcommand_stat_all }, - { AtCommand_StatAll, "@allstats", 60, atcommand_stat_all }, // by fritz - { AtCommand_StatAll, "@allstat", 60, atcommand_stat_all }, // by fritz - { AtCommand_CharBlock, "@block", 60, atcommand_char_block }, // by Yor - { AtCommand_CharBlock, "@charblock", 60, atcommand_char_block }, // by Yor - { AtCommand_CharBan, "@ban", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharBan, "@banish", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharBan, "@charban", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharBan, "@charbanish", 60, atcommand_char_ban }, // by Yor - { AtCommand_CharUnBlock, "@unblock", 60, atcommand_char_unblock }, // by Yor - { AtCommand_CharUnBlock, "@charunblock", 60, atcommand_char_unblock }, // by Yor - { AtCommand_CharUnBan, "@unban", 60, atcommand_char_unban }, // by Yor - { AtCommand_CharUnBan, "@unbanish", 60, atcommand_char_unban }, // by Yor - { AtCommand_CharUnBan, "@charunban", 60, atcommand_char_unban }, // by Yor - { AtCommand_CharUnBan, "@charunbanish", 60, atcommand_char_unban }, // by Yor - { AtCommand_MountPeco, "@mount", 20, atcommand_mount_peco }, // by Valaris - { AtCommand_MountPeco, "@mountpeco", 20, atcommand_mount_peco }, // by Valaris - { AtCommand_GuildSpy, "@guildspy", 60, atcommand_guildspy }, // [Syrus22] - { AtCommand_PartySpy, "@partyspy", 60, atcommand_partyspy }, // [Syrus22] - { AtCommand_RepairAll, "@repairall", 60, atcommand_repairall }, // [Valaris] - { AtCommand_GuildRecall, "@guildrecall", 60, atcommand_guildrecall }, // by Yor - { AtCommand_PartyRecall, "@partyrecall", 60, atcommand_partyrecall }, // by Yor - { AtCommand_Nuke, "@nuke", 60, atcommand_nuke }, // [Valaris] - { AtCommand_Shownpc, "@shownpc", 80, atcommand_shownpc }, // [] - { AtCommand_Hidenpc, "@hidenpc", 80, atcommand_hidenpc }, // [] - { AtCommand_Loadnpc, "@loadnpc", 80, atcommand_loadnpc }, // [] - { AtCommand_Unloadnpc, "@unloadnpc", 80, atcommand_unloadnpc }, // [] - { AtCommand_ServerTime, "@time", 1, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@date", 1, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@serverdate", 1, atcommand_servertime }, // by Yor - { AtCommand_ServerTime, "@servertime", 1, atcommand_servertime }, // by Yor - { AtCommand_Jail, "@jail", 60, atcommand_jail }, // by Yor - { AtCommand_UnJail, "@unjail", 60, atcommand_unjail }, // by Yor - { AtCommand_UnJail, "@discharge", 60, atcommand_unjail }, // by Yor - { AtCommand_JailFor, "@jailfor", 60, atcommand_jailfor }, //Meruru - { AtCommand_JailTime, "@jailtime", 1, atcommand_jailtime }, //Change this to 0 in atcommand_conf.txt if you want it accessible to players (you most likely will ;)) - { AtCommand_Disguise, "@disguise", 20, atcommand_disguise }, // [Valaris] - { AtCommand_UnDisguise, "@undisguise", 20, atcommand_undisguise }, // by Yor - { AtCommand_EMail, "@email", 1, atcommand_email }, // by Yor - { AtCommand_Effect, "@effect", 40, atcommand_effect }, // by Apple - { AtCommand_Follow, "@follow", 20, atcommand_follow }, // by MouseJstr - { AtCommand_AddWarp, "@addwarp", 60, atcommand_addwarp }, // by MouseJstr - { AtCommand_SkillOn, "@skillon", 80, atcommand_skillon }, // by MouseJstr - { AtCommand_SkillOff, "@skilloff", 80, atcommand_skilloff }, // by MouseJstr - { AtCommand_Killer, "@killer", 60, atcommand_killer }, // by MouseJstr - { AtCommand_NpcMove, "@npcmove", 80, atcommand_npcmove }, // by MouseJstr - { AtCommand_Killable, "@killable", 40, atcommand_killable }, // by MouseJstr - { AtCommand_Dropall, "@dropall", 40, atcommand_dropall }, // MouseJstr - { AtCommand_Storeall, "@storeall", 40, atcommand_storeall }, // MouseJstr - { AtCommand_Skillid, "@skillid", 40, atcommand_skillid }, // MouseJstr - { AtCommand_Useskill, "@useskill", 40, atcommand_useskill }, // MouseJstr - { AtCommand_DisplaySkill, "@displayskill", 99, atcommand_displayskill }, // Skotlex - { AtCommand_Snow, "@snow", 99, atcommand_snow }, - { AtCommand_Sakura, "@sakura", 99, atcommand_sakura }, - { AtCommand_Clouds, "@clouds", 99, atcommand_clouds }, - { AtCommand_Clouds2, "@clouds2", 99, atcommand_clouds2 }, - { AtCommand_Fog, "@fog", 99, atcommand_fog }, - { AtCommand_Fireworks, "@fireworks", 99, atcommand_fireworks }, - { AtCommand_Leaves, "@leaves", 99, atcommand_leaves }, - { AtCommand_Summon, "@summon", 60, atcommand_summon }, - { AtCommand_AdjGmLvl, "@adjgmlvl", 99, atcommand_adjgmlvl }, - { AtCommand_AdjCmdLvl, "@adjcmdlvl", 99, atcommand_adjcmdlvl }, - { AtCommand_Trade, "@trade", 60, atcommand_trade }, - { AtCommand_Send, "@send", 99, atcommand_send }, - { AtCommand_SetBattleFlag, "@setbattleflag", 99, atcommand_setbattleflag }, - { AtCommand_UnMute, "@unmute", 80, atcommand_unmute }, // [Valaris] - { AtCommand_Clearweather, "@clearweather", 99, atcommand_clearweather }, // Dexity - { AtCommand_UpTime, "@uptime", 1, atcommand_uptime }, // by MC Cameri - { AtCommand_ChangeSex, "@changesex", 60, atcommand_changesex }, // by MC Cameri <- do we still need this? [Foruken] <- why not? [Skotlex] - { AtCommand_Mute, "@mute", 80, atcommand_mute }, // [celest] - { AtCommand_WhoZeny, "@whozeny", 20, atcommand_whozeny }, // [Valaris] - { AtCommand_Refresh, "@refresh", 1, atcommand_refresh }, // by MC Cameri - { AtCommand_Identify, "@identify", 40, atcommand_identify }, // by MC Cameri - { AtCommand_Gmotd, "@gmotd", 20, atcommand_gmotd }, // Added by MC Cameri, created by davidsiaw - { AtCommand_MiscEffect, "@misceffect", 50, atcommand_misceffect }, // by MC Cameri - { AtCommand_MobSearch, "@mobsearch", 10, atcommand_mobsearch }, - { AtCommand_CleanMap, "@cleanmap", 40, atcommand_cleanmap }, - { AtCommand_NpcTalk, "@npctalk", 20, atcommand_npctalk }, - { AtCommand_PetTalk, "@pettalk", 10, atcommand_pettalk }, - { AtCommand_Users, "@users", 40, atcommand_users }, - { AtCommand_ResetState, "@reset", 40, atcommand_reset }, - { AtCommand_SkillTree, "@skilltree", 40, atcommand_skilltree }, // [MouseJstr] - { AtCommand_Marry, "@marry", 40, atcommand_marry }, // [MouseJstr] - { AtCommand_Divorce, "@divorce", 40, atcommand_divorce }, // [MouseJstr] - { AtCommand_JumpToId2, "@jumptoid2", 20, atcommand_jumptoid2 }, // [Dino9021] - { AtCommand_JumpToId2, "@warptoid2", 20, atcommand_jumptoid2 }, // [Dino9021] - { AtCommand_JumpToId2, "@gotoid2", 20, atcommand_jumptoid2 }, // [Dino9021] - { AtCommand_RecallId2, "@recallid2", 60, atcommand_recallid2 }, // [Dino9021] - { AtCommand_KickId2, "@kickid2", 99, atcommand_kickid2 }, // [Dino9021] - { AtCommand_ReviveId2, "@reviveid2", 60, atcommand_reviveid2 }, // [Dino9021] - { AtCommand_KillId2, "@killid2", 60, atcommand_killid2 }, // [Dino9021] - { AtCommand_Sound, "@sound", 40, atcommand_sound }, - { AtCommand_UndisguiseAll, "@undisguiseall", 99, atcommand_undisguiseall }, - { AtCommand_DisguiseAll, "@disguiseall", 99, atcommand_disguiseall }, - { AtCommand_ChangeLook, "@changelook", 60, atcommand_changelook }, - { AtCommand_AutoLoot, "@autoloot", 10, atcommand_autoloot }, // Upa-Kun - { AtCommand_MobInfo, "@mobinfo", 1, atcommand_mobinfo }, // [Lupus] - { AtCommand_MobInfo, "@monsterinfo", 1, atcommand_mobinfo }, // [Lupus] - { AtCommand_MobInfo, "@mi", 1, atcommand_mobinfo }, // [Lupus] - { AtCommand_Exp, "@exp", 1, atcommand_exp }, // [Skotlex] - { AtCommand_Adopt, "@adopt", 40, atcommand_adopt }, // [Veider] - { AtCommand_Version, "@version", 1, atcommand_version }, - { AtCommand_MuteArea, "@mutearea", 99, atcommand_mutearea }, // MouseJstr - { AtCommand_MuteArea, "@stfu", 99, atcommand_mutearea }, // MouseJstr - { AtCommand_Rates, "@rates", 1, atcommand_rates }, // MouseJstr - { AtCommand_ItemInfo, "@iteminfo", 1, atcommand_iteminfo }, // [Lupus] - { AtCommand_ItemInfo, "@ii", 1, atcommand_iteminfo }, // [Lupus] - { AtCommand_WhoDrops, "@whodrops", 1, atcommand_whodrops }, // [Skotlex] - { AtCommand_WhereIs, "@whereis", 10, atcommand_whereis }, // [Skotlex] - { AtCommand_MapFlag, "@mapflag", 99, atcommand_mapflag }, // [Lupus] - { AtCommand_Me, "@me", 20, atcommand_me }, //added by massdriller, code by lordalfa - { AtCommand_MonsterIgnore, "@monsterignore", 99, atcommand_monsterignore }, // [Valaris] - { AtCommand_MonsterIgnore, "@battleignore", 99, atcommand_monsterignore }, - { AtCommand_FakeName, "@fakename", 20, atcommand_fakename }, // [Valaris] - { AtCommand_Size, "@size", 20, atcommand_size }, - { AtCommand_ShowExp, "@showexp", 10, atcommand_showexp}, - { AtCommand_ShowZeny, "@showzeny", 10, atcommand_showzeny}, - { AtCommand_ShowDelay, "@showdelay", 1, atcommand_showdelay}, - { AtCommand_AutoTrade, "@autotrade", 10, atcommand_autotrade }, // durf - { AtCommand_AutoTrade, "@at", 10, atcommand_autotrade }, - { AtCommand_ChangeGM, "@changegm", 10, atcommand_changegm }, // durf - { AtCommand_ChangeLeader, "@changeleader", 10, atcommand_changeleader }, // durf - { AtCommand_PartyOption, "@partyoption", 10, atcommand_partyoption}, // durf - { AtCommand_Invite, "@invite", 1, atcommand_invite }, // By LuzZza - { AtCommand_Duel, "@duel", 1, atcommand_duel }, // By LuzZza - { AtCommand_Leave, "@leave", 1, atcommand_leave }, // By LuzZza - { AtCommand_Accept, "@accept", 1, atcommand_accept }, // By LuzZza - { AtCommand_Reject, "@reject", 1, atcommand_reject }, // By LuzZza - { AtCommand_Away, "@away", 1, atcommand_away }, // [LuzZza] - { AtCommand_Away, "@aw", 1, atcommand_away }, // [LuzZza] - { AtCommand_Main, "@main", 1, atcommand_main }, // [LuzZza] - { AtCommand_Clone, "@clone", 50, atcommand_clone }, - { AtCommand_Clone, "@slaveclone", 50, atcommand_clone }, - { AtCommand_Clone, "@evilclone", 50, atcommand_clone }, // [Valaris] - { AtCommand_ToNPC, "@tonpc", 40, atcommand_tonpc }, // LuzZza - { AtCommand_Commands, "@commands", 1, atcommand_commands }, // [Skotlex] - { AtCommand_NoAsk, "@noask", 1, atcommand_noask }, // [LuzZza] - { AtCommand_Request, "@request", 20, atcommand_request }, // [Skotlex] - { AtCommand_HomLevel, "@hlvl", 60, atcommand_homlevel }, - { AtCommand_HomLevel, "@hlevel", 60, atcommand_homlevel }, - { AtCommand_HomLevel, "@homlvl", 60, atcommand_homlevel }, - { AtCommand_HomLevel, "@homlevel", 60, atcommand_homlevel }, - { AtCommand_HomEvolution, "@homevolution", 60, atcommand_homevolution }, - { AtCommand_MakeHomun, "@makehomun", 60, atcommand_makehomun }, - { AtCommand_HomFriendly, "@homfriendly", 60, atcommand_homfriendly }, - { AtCommand_HomHungry, "@homhungry", 60, atcommand_homhungry }, - { AtCommand_HomTalk, "@homtalk", 10, atcommand_homtalk }, - { AtCommand_HomInfo, "@hominfo", 1, atcommand_hominfo }, - { AtCommand_HomStats, "@homstats", 1, atcommand_homstats }, - { AtCommand_HomShuffle, "@homshuffle", 60, atcommand_homshuffle }, - { AtCommand_ShowMobs, "@showmobs", 10, atcommand_showmobs }, //KarLaeda - { AtCommand_FeelReset, "@feelreset", 10, atcommand_feelreset }, //[HiddenDragon] -#ifndef TXT_ONLY // sql-only commands - { AtCommand_Mail, "@mail", 1, atcommand_mail }, // [Mail System] - { AtCommand_RefreshOnline, "@refreshonline", 99, atcommand_refreshonline }, // [Valaris] -#endif -#ifdef DMALLOC - { AtCommand_DMStart, "@dmstart", 99, atcommand_dmstart }, // [MouseJstr] - { AtCommand_DMTick, "@dmtick", 99, atcommand_dmtick }, // [MouseJstr] -#endif -// add new commands before this line - { AtCommand_Unknown, NULL, 1, NULL } -}; +typedef struct AtCommandInfo +{ + const char* command; + int level; + AtCommandFunc func; +} AtCommandInfo; + +static AtCommandInfo* get_atcommandinfo_byname(const char* name); +static AtCommandInfo* get_atcommandinfo_byfunc(const AtCommandFunc func); + +int atcommand_commands(const int fd, struct map_session_data* sd, const char* command, const char* message); + /*========================================= * Generic variables @@ -627,151 +112,6 @@ static char* player_title_txt(int level) return atcmd_temp; } -/*========================================== - * Retrieve the atcommand's required gm level - *------------------------------------------*/ -int get_atcommand_level(const AtCommandType type) -{ - int i; - - for (i = 0; atcommand_info[i].type != AtCommand_None; i++) - if (atcommand_info[i].type == type) - return atcommand_info[i].level; - - return 100; // 100: command can not be used -} - -AtCommandType is_atcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl) -{ - AtCommandInfo info; - AtCommandType type; - - memset(&info, 0, sizeof(info)); - - type = atcommand(sd, gmlvl, str, &info); - if (type != AtCommand_None) { - char command[100]; - const char* p = str; - - if (map[sd->bl.m].nocommand && - gmlvl < map[sd->bl.m].nocommand) - { //Command not allowed on this map. - sprintf(atcmd_output, msg_txt(143)); - clif_displaymessage(fd, atcmd_output); - return AtCommand_None; - } - - memset(command, '\0', sizeof(command)); - memset(atcmd_output, '\0', sizeof(atcmd_output)); - while (*p && !ISSPACE(*p)) - p++; - if (p - str >= sizeof(command)) // too long - return AtCommand_Unknown; - strncpy(command, str, p - str); - while (ISSPACE(*p)) - p++; - - if (type == AtCommand_Unknown || info.proc == NULL) { - sprintf(atcmd_output, msg_txt(153), command); // %s is Unknown Command. - clif_displaymessage(fd, atcmd_output); - } else { - if (info.proc(fd, sd, command, p) != 0) { - // Command can not be executed - sprintf(atcmd_output, msg_txt(154), command); // %s failed. - clif_displaymessage(fd, atcmd_output); - } - } - - return info.type; - } - - return AtCommand_None; -} - -/*========================================== - * - *------------------------------------------*/ -AtCommandType is_atcommand(const int fd, struct map_session_data* sd, const char* message) -{ - const char* str = message; - int s_flag = 0; - - nullpo_retr(AtCommand_None, sd); - - if (sd->sc.count && sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCOMMAND) { - return AtCommand_Unknown; - } - - if (!message || !*message) - return AtCommand_None; - - // temporary compatibility layer for previous implementation - if( *message != atcommand_symbol ) - { - str += strlen(sd->status.name); - while (*str && (ISSPACE(*str) || (s_flag == 0 && *str == ':'))) { - if (*str == ':') - s_flag = 1; - str++; - } - } - - if (!*str) - return AtCommand_None; - - if(str[0] == '|' && strlen(str) >= 4 && str[3] == atcommand_symbol) - str += 3; // skip 10/11-langtype's codepage indicator, if detected - - return is_atcommand_sub(fd,sd,str,pc_isGM(sd)); -} - -/*========================================== - * - *------------------------------------------*/ -AtCommandType atcommand(struct map_session_data* sd, const int level, const char* message, struct AtCommandInfo* info) -{ - char* p = (char *)message; // it's 'char' and not 'const char' to have possibility to modify the first character if necessary - - if (!info) - return AtCommand_None; - if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd) - return AtCommand_None; - if (!p || !*p) { - ShowError("at command message is empty\n"); - return AtCommand_None; - } - - if (*p == atcommand_symbol) { // check first char - char command[101]; - int i = 0; - memset(info, 0, sizeof(AtCommandInfo)); - sscanf(p, "%100s", command); - command[100] = '\0'; - - while (atcommand_info[i].type != AtCommand_Unknown) { - if (strcmpi(command+1, atcommand_info[i].command+1) == 0 && level >= atcommand_info[i].level) { - p[0] = atcommand_info[i].command[0]; // set correct first symbol for after. - break; - } - i++; - } - - if (atcommand_info[i].type == AtCommand_Unknown) { - // doesn't return Unknown if player is normal player (display the text, not display: unknown command) - if (level == 0) - return AtCommand_None; - else - return AtCommand_Unknown; - } else if((log_config.gm) && (atcommand_info[i].level >= log_config.gm)) { - log_atcommand(sd, message); - } - memcpy(info, &atcommand_info[i], sizeof atcommand_info[i]); - } else { - return AtCommand_None; - } - - return info->type; -} /*========================================== * Read Message Data @@ -826,114 +166,8 @@ void do_final_msg(void) int i; for (i = 0; i < MAX_MSG; i++) aFree(msg_table[i]); - return; } -/*========================================== - * - *------------------------------------------*/ -static AtCommandInfo* get_atcommandinfo_byname(const char* name) -{ - int i; - - for (i = 0; atcommand_info[i].type != AtCommand_Unknown; i++) - if (strcmpi(atcommand_info[i].command + 1, name) == 0) - return &atcommand_info[i]; - - return NULL; -} - -/*========================================== - * - *------------------------------------------*/ -int atcommand_config_read(const char *cfgName) -{ - char line[1024], w1[1024], w2[1024]; - AtCommandInfo* p; - FILE* fp; - - if ((fp = fopen(cfgName, "r")) == NULL) { - ShowError("At commands configuration file not found: %s\n", cfgName); - return 1; - } - - while(fgets(line, sizeof(line), fp)) - { - if (line[0] == '/' && line[1] == '/') - continue; - - if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2) - continue; - p = get_atcommandinfo_byname(w1); - if (p != NULL) { - p->level = atoi(w2); - if (p->level > 100) - p->level = 100; - else if (p->level < 0) - p->level = 0; - } - - if (strcmpi(w1, "import") == 0) - atcommand_config_read(w2); - else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 && - w2[0] != '/' && // symbol of standard ragnarok GM commands - w2[0] != '%' && // symbol of party chat speaking - w2[0] != '$' && // symbol of guild chat - w2[0] != '#') // symbol of charcommand - atcommand_symbol = w2[0]; - } - fclose(fp); - - return 0; -} - -/*========================================== -// @ command processing functions - *------------------------------------------*/ - -/*========================================== - * @commands Lists available @ commands to you (code 98% from Meruru) - *------------------------------------------*/ -int atcommand_commands(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - char cz_line_buff[CHATBOX_SIZE]; - - register char *lpcz_cur = cz_line_buff; - register unsigned int ui_slen; - - int i_cur_cmd,gm_lvl = pc_isGM(sd), count = 0; - - memset(cz_line_buff,' ',CHATBOX_SIZE); - cz_line_buff[CHATBOX_SIZE-1] = 0; - - clif_displaymessage(fd, msg_txt(273)); - - for (i_cur_cmd = 0;atcommand_info[i_cur_cmd].type != AtCommand_Unknown;i_cur_cmd++) - { - if(gm_lvl < atcommand_info[i_cur_cmd].level) - continue; - - count++; - ui_slen = (unsigned int)strlen(atcommand_info[i_cur_cmd].command); - - //remember not <= bc we need null terminator - if(((CHATBOX_SIZE+(int)cz_line_buff)-(int)lpcz_cur) < (int)ui_slen) - { - clif_displaymessage(fd,(char*)cz_line_buff); - lpcz_cur = cz_line_buff; - memset(cz_line_buff,' ',CHATBOX_SIZE); - cz_line_buff[CHATBOX_SIZE-1] = 0; - } - - memcpy(lpcz_cur,atcommand_info[i_cur_cmd].command,ui_slen); - lpcz_cur += ui_slen+(10-ui_slen%10); - } - - clif_displaymessage(fd,(char*)cz_line_buff); - sprintf(atcmd_output, msg_txt(274), count); //There will always be at least 1 command (@commands) - clif_displaymessage(fd, atcmd_output); - return 0; -} /*========================================== * @send (used for testing packet sends from the client) @@ -1171,9 +405,9 @@ int atcommand_send(const int fd, struct map_session_data* sd, const char* comman } /*========================================== - * @rura + * @rura, @warp, @mapmove *------------------------------------------*/ -int atcommand_rura( const int fd, struct map_session_data* sd, const char* command, const char* message) +int atcommand_mapmove(const int fd, struct map_session_data* sd, const char* command, const char* message) { char map_name[MAP_NAME_LENGTH_EXT]; unsigned short mapindex; @@ -3984,13 +3218,16 @@ int atcommand_makeegg(const int fd, struct map_session_data* sd, const char* com nullpo_retr(-1, sd); if (!message || !*message) { - clif_displaymessage(fd, "Please, enter a monster/egg name/id (usage: @makeegg <pet_id>)."); + clif_displaymessage(fd, "Please, enter a monster/egg name/id (usage: @makeegg <pet>)."); return -1; } if ((item_data = itemdb_searchname(message)) != NULL) // for egg name id = item_data->nameid; - else if ((id = mobdb_searchname(message)) == 0) // for monster name + else + if ((id = mobdb_searchname(message)) != 0) // for monster name + ; + else id = atoi(message); pet_id = search_petDB_index(id, PET_CLASS); @@ -4531,12 +3768,12 @@ int atcommand_questskill(const int fd, struct map_session_data* sd, const char* if (!(skill_get_inf2(skill_id) & INF2_QUEST_SKILL)) { clif_displaymessage(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill. return -1; - } + } if (pc_checkskill(sd, skill_id) > 0) { clif_displaymessage(fd, msg_txt(196)); // You already have this quest skill. return -1; } - + pc_skill(sd, skill_id, 1, 0); clif_displaymessage(fd, msg_txt(70)); // You have learned the skill. @@ -6272,9 +5509,6 @@ int atcommand_npcmove(const int fd, struct map_session_data* sd, const char* com return -1; } - //Who's idea was this? nullpo's are meant to check pointers that SHOULDN'T be null unless there's a bug... [Skotlex] -// nullpo_retr(-1, (nd = npc_name2id(atcmd_player_name))); - if ((nd = npc_name2id(atcmd_player_name)) == NULL) { clif_displaymessage(fd, msg_txt(111)); // This NPC doesn't exist. @@ -6308,13 +5542,13 @@ int atcommand_addwarp(const int fd, struct map_session_data* sd, const char* com nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%23s %d %d[^\n]", atcmd_player_name, &x, &y) < 3) { - clif_displaymessage(fd, "usage: @addwarp <mapname (without .gat)> <X> <Y>."); + clif_displaymessage(fd, "usage: @addwarp <mapname> <X> <Y>."); return -1; } sprintf(w1,"%s,%d,%d", mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y); sprintf(w3,"%s%d%d%d%d", atcmd_player_name,sd->bl.x, sd->bl.y, x, y); - sprintf(w4,"1,1,%s.gat,%d,%d", atcmd_player_name, x, y); + sprintf(w4,"1,1,%s,%d,%d", atcmd_player_name, x, y); // FIXME check if it failed [FlavioJS] npc_parse_warp(w1, "warp", w3, w4, NULL, NULL, "console"); @@ -6677,28 +5911,6 @@ int atcommand_divorce(const int fd, struct map_session_data* sd, const char* com return 0; } - -#ifdef DMALLOC -unsigned long dmark_; -int atcommand_dmstart(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - dmark_ = dmalloc_mark(); - - clif_displaymessage(fd, "debug mark set"); - - return 0; -} - -int atcommand_dmtick(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - dmalloc_log_changed ( dmark_, 1, 0, 1 ) ; - dmark_ = dmalloc_mark(); - clif_displaymessage(fd, "malloc changes logged"); - - return 0; -} -#endif - /*========================================== * @changelook by [Celest] *------------------------------------------*/ @@ -7369,38 +6581,40 @@ int atcommand_summon(const int fd, struct map_session_data* sd, const char* comm *------------------------------------------*/ int atcommand_adjcmdlvl(const int fd, struct map_session_data* sd, const char* command, const char* message) { - int i, newlev; - char cmd[100]; + int newlev; + char name[100]; + AtCommandInfo* cmd; + nullpo_retr(-1, sd); - if (!message || !*message || sscanf(message, "%d %99s", &newlev, cmd) != 2) + if (!message || !*message || sscanf(message, "%d %99s", &newlev, name) != 2) { clif_displaymessage(fd, "Usage: @adjcmdlvl <lvl> <command>."); return -1; } - if (newlev > pc_isGM(sd)) + cmd = get_atcommandinfo_byname(name); + if (cmd == NULL) + { + clif_displaymessage(fd, "@command not found."); + return -1; + } + else if (newlev > pc_isGM(sd)) { clif_displaymessage(fd, "You can't make a command require higher GM level than your own."); return -1; } - - for (i = 0; atcommand_info[i].command && atcommand_info[i].type != AtCommand_None; i++) + else if (cmd->level > pc_isGM(sd)) { - if (strcmpi(cmd, atcommand_info[i].command+1) != 0) - continue; - if (atcommand_info[i].level > pc_isGM(sd)) - { - clif_displaymessage(fd, "You can't adjust the level of a command which's level is above your own."); - return -1; - } - atcommand_info[i].level = newlev; + clif_displaymessage(fd, "You can't adjust the level of a command which's level is above your own."); + return -1; + } + else + { + cmd->level = newlev; clif_displaymessage(fd, "@command level changed."); return 0; } - - clif_displaymessage(fd, "@command not found."); - return -1; } /*========================================== @@ -7653,185 +6867,6 @@ int atcommand_misceffect(const int fd, struct map_session_data* sd, const char* return 0; } -/*========================================== - * Jump to a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------*/ -int atcommand_jumptoid2(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int aid=0; - struct map_session_data *pl_sd; - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || (aid = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @jumptoid/@warptoid/@gotoid <account id>)."); - return -1; - } - - pl_sd = map_id2sd(aid); - if (!pl_sd) { - clif_displaymessage(fd, msg_txt(154)); // Character not found. - return -1; - } - - if (map[pl_sd->bl.m].flag.nowarpto && - battle_config.any_warp_GM_min_level > pc_isGM(sd)) - { - clif_displaymessage(fd, msg_txt(247)); - return -1; - } - if (map[sd->bl.m].flag.nowarp && - battle_config.any_warp_GM_min_level > pc_isGM(sd)) - { - clif_displaymessage(fd, msg_txt(248)); - return -1; - } - pc_setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, 3); - sprintf(atcmd_output, msg_txt(4), pl_sd->status.name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - return 0; -} - -/*========================================== - * Recall a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------*/ -int atcommand_recallid2(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int aid=0; - struct map_session_data *pl_sd; - - memset(atcmd_output, '\0', sizeof(atcmd_output)); - - if (!message || (aid = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @recallid2 <account id>)."); - return -1; - } - - pl_sd = map_id2sd(aid); - if (!pl_sd) { - clif_displaymessage(fd, msg_txt(154)); // Character not found. - return -1; - } - if (pc_isGM(sd) < pc_isGM(pl_sd)) - { // you can recall only lower or same level - clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. - return -1; - } - - if (map[pl_sd->bl.m].flag.nowarpto && - battle_config.any_warp_GM_min_level > pc_isGM(sd)) - { - clif_displaymessage(fd, msg_txt(247)); - return -1; - } - if (map[sd->bl.m].flag.nowarp && - battle_config.any_warp_GM_min_level > pc_isGM(sd)) - { - clif_displaymessage(fd, msg_txt(248)); - return -1; - } - - pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, 2); - sprintf(atcmd_output, msg_txt(46), pl_sd->status.name); // Jump to %s - clif_displaymessage(fd, atcmd_output); - return 0; -} - -/*========================================== - * Kick a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------*/ -int atcommand_kickid2(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - struct map_session_data *pl_sd; - int aid=0; - - if (!message || (aid = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @kickid2 <account id>)."); - return -1; - } - - pl_sd = map_id2sd(aid); - if (!pl_sd) { - clif_displaymessage(fd, msg_txt(3)); // Character not found. - return -1; - } - if (pc_isGM(sd) < pc_isGM(pl_sd)) - { // you can kick only lower or same gm level - clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. - return -1; - } - clif_GM_kick(sd, pl_sd, 1); - return 0; -} - -/*========================================== - * Revive a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------*/ -int atcommand_reviveid2(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int aid=0; - struct map_session_data *pl_sd; - - if (!message || (aid = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @reviveid2 <account id>)."); - return -1; - } - - pl_sd = map_id2sd(aid); - - if(!pl_sd) { - clif_displaymessage(fd, msg_txt(3)); // Character not found. - return -1; - } - - if(!status_revive(&pl_sd->bl, 100, 100)) - return -1; - - clif_skill_nodamage(&pl_sd->bl,&pl_sd->bl,ALL_RESURRECTION,4,1); - clif_displaymessage(fd, msg_txt(51)); // Character revived. - return 0; -} - -/*========================================== - * Kill a player by PID number - * Original by Dino9021 - * Added in by nsstrunks - *------------------------------------------*/ -int atcommand_killid2(const int fd, struct map_session_data* sd, const char* command, const char* message) -{ - int aid=0; - struct map_session_data *pl_sd; - - if (!message || (aid = atoi(message)) == 0) { - clif_displaymessage(fd, "Please, enter a player AID (usage: @killid2 <account id>)."); - return -1; - } - - pl_sd = map_id2sd(aid); - if (!pl_sd) { - clif_displaymessage(fd, msg_txt(3)); // Character not found. - return -1; - } - - if (pc_isGM(sd) < pc_isGM(pl_sd)) - { // you can kill only lower or same level - clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. - return -1; - } - - status_kill(&pl_sd->bl); - clif_displaymessage(fd, msg_txt(14)); // Character killed. - return 0; -} - #ifndef TXT_ONLY /* Begin SQL-Only commands */ /*========================================== @@ -8089,7 +7124,7 @@ int atcommand_homlevel(const int fd, struct map_session_data* sd, const char* co int atcommand_homevolution(const int fd, struct map_session_data* sd, const char* command, const char* message) { nullpo_retr(-1, sd); - + if ( !merc_is_hom_active(sd->hd) ) { clif_displaymessage(fd, "You do not have a homunculus."); return -1; @@ -8099,7 +7134,7 @@ int atcommand_homevolution(const int fd, struct map_session_data* sd, const char clif_displaymessage(fd, "Your homunculus doesn't evolve."); return -1; } - + return 0; } @@ -8110,7 +7145,7 @@ int atcommand_makehomun(const int fd, struct map_session_data* sd, const char* c { int homunid; nullpo_retr(-1, sd); - + if ( merc_is_hom_active(sd->hd) ) { clif_displaymessage(fd, msg_txt(450)); return -1; @@ -8120,7 +7155,7 @@ int atcommand_makehomun(const int fd, struct map_session_data* sd, const char* c clif_displaymessage(fd, "Please, enter a homunculus id: (usage: @makehomun <homunculus id>."); return -1; } - + homunid = atoi(message); if( homunid < HM_CLASS_BASE || homunid > HM_CLASS_BASE + MAX_HOMUNCULUS_CLASS - 1 ) { @@ -9117,6 +8152,456 @@ int atcommand_feelreset(const int fd, struct map_session_data* sd, const char* c return 0; } + + + +/*========================================== + * atcommand_info[] structure definition + *------------------------------------------*/ + +AtCommandInfo atcommand_info[] = { + { "rura", 40, atcommand_mapmove }, + { "warp", 40, atcommand_mapmove }, + { "mapmove", 40, atcommand_mapmove }, // + /mm + { "where", 1, atcommand_where }, + { "jumpto", 20, atcommand_jumpto }, // + /shift + { "warpto", 20, atcommand_jumpto }, + { "goto", 20, atcommand_jumpto }, + { "jump", 40, atcommand_jump }, + { "who", 20, atcommand_who }, + { "whois", 20, atcommand_who }, + { "who2", 20, atcommand_who2 }, + { "who3", 20, atcommand_who3 }, + { "whomap", 20, atcommand_whomap }, + { "whomap2", 20, atcommand_whomap2 }, + { "whomap3", 20, atcommand_whomap3 }, + { "whogm", 20, atcommand_whogm }, + { "save", 40, atcommand_save }, + { "return", 40, atcommand_load }, + { "load", 40, atcommand_load }, + { "speed", 40, atcommand_speed }, + { "storage", 1, atcommand_storage }, + { "gstorage", 50, atcommand_guildstorage }, + { "option", 40, atcommand_option }, + { "hide", 40, atcommand_hide }, // + /hide + { "jobchange", 40, atcommand_jobchange }, + { "job", 40, atcommand_jobchange }, + { "die", 1, atcommand_die }, + { "kill", 60, atcommand_kill }, + { "alive", 60, atcommand_alive }, + { "kami", 40, atcommand_kami }, + { "kamib", 40, atcommand_kami }, + { "kamic", 40, atcommand_kami }, + { "heal", 40, atcommand_heal }, + { "item", 60, atcommand_item }, + { "item2", 60, atcommand_item2 }, + { "itemreset", 40, atcommand_itemreset }, + { "blvl", 60, atcommand_baselevelup }, + { "lvup", 60, atcommand_baselevelup }, + { "blevel", 60, atcommand_baselevelup }, + { "baselvl", 60, atcommand_baselevelup }, + { "baselvup", 60, atcommand_baselevelup }, + { "baselevel", 60, atcommand_baselevelup }, + { "baselvlup", 60, atcommand_baselevelup }, + { "jlvl", 60, atcommand_joblevelup }, + { "jlevel", 60, atcommand_joblevelup }, + { "joblvl", 60, atcommand_joblevelup }, + { "joblevel", 60, atcommand_joblevelup }, + { "joblvup", 60, atcommand_joblevelup }, + { "joblvlup", 60, atcommand_joblevelup }, + { "h", 20, atcommand_help }, + { "help", 20, atcommand_help }, + { "h2", 20, atcommand_help2 }, + { "help2", 20, atcommand_help2 }, + { "gm", 100, atcommand_gm }, + { "pvpoff", 40, atcommand_pvpoff }, + { "pvpon", 40, atcommand_pvpon }, + { "gvgoff", 40, atcommand_gvgoff }, + { "gpvpoff", 40, atcommand_gvgoff }, + { "gvgon", 40, atcommand_gvgon }, + { "gpvpon", 40, atcommand_gvgon }, + { "model", 20, atcommand_model }, + { "go", 10, atcommand_go }, + { "monster", 50, atcommand_monster }, + { "spawn", 50, atcommand_monster }, + { "monstersmall", 50, atcommand_monstersmall }, + { "monsterbig", 50, atcommand_monsterbig }, + { "killmonster", 60, atcommand_killmonster }, + { "killmonster2", 40, atcommand_killmonster2 }, + { "refine", 60, atcommand_refine }, + { "produce", 60, atcommand_produce }, + { "memo", 40, atcommand_memo }, + { "gat", 99, atcommand_gat }, + { "displaystatus", 99, atcommand_displaystatus }, + { "stpoint", 60, atcommand_statuspoint }, + { "skpoint", 60, atcommand_skillpoint }, + { "zeny", 60, atcommand_zeny }, + { "str", 60, atcommand_param }, + { "agi", 60, atcommand_param }, + { "vit", 60, atcommand_param }, + { "int", 60, atcommand_param }, + { "dex", 60, atcommand_param }, + { "luk", 60, atcommand_param }, + { "glvl", 60, atcommand_guildlevelup }, + { "glevel", 60, atcommand_guildlevelup }, + { "guildlvl", 60, atcommand_guildlevelup }, + { "guildlvup", 60, atcommand_guildlevelup }, + { "guildlevel", 60, atcommand_guildlevelup }, + { "guildlvlup", 60, atcommand_guildlevelup }, + { "makeegg", 60, atcommand_makeegg }, + { "hatch", 60, atcommand_hatch }, + { "petfriendly", 40, atcommand_petfriendly }, + { "pethungry", 40, atcommand_pethungry }, + { "petrename", 1, atcommand_petrename }, + { "recall", 60, atcommand_recall }, // + /recall + { "night", 80, atcommand_night }, + { "day", 80, atcommand_day }, + { "doom", 80, atcommand_doom }, + { "doommap", 80, atcommand_doommap }, + { "raise", 80, atcommand_raise }, + { "raisemap", 80, atcommand_raisemap }, + { "kick", 20, atcommand_kick }, // + right click menu for GM "(name) force to quit" + { "kickall", 99, atcommand_kickall }, + { "allskill", 60, atcommand_allskill }, + { "allskills", 60, atcommand_allskill }, + { "skillall", 60, atcommand_allskill }, + { "skillsall", 60, atcommand_allskill }, + { "questskill", 40, atcommand_questskill }, + { "lostskill", 40, atcommand_lostskill }, + { "spiritball", 40, atcommand_spiritball }, + { "party", 1, atcommand_party }, + { "guild", 50, atcommand_guild }, + { "agitstart", 60, atcommand_agitstart }, + { "agitend", 60, atcommand_agitend }, + { "mapexit", 99, atcommand_mapexit }, + { "idsearch", 60, atcommand_idsearch }, + { "broadcast", 40, atcommand_broadcast }, // + /b and /nb + { "localbroadcast", 40, atcommand_localbroadcast }, // + /lb and /nlb + { "recallall", 80, atcommand_recallall }, + { "reloaditemdb", 99, atcommand_reloaditemdb }, + { "reloadmobdb", 99, atcommand_reloadmobdb }, + { "reloadskilldb", 99, atcommand_reloadskilldb }, + { "reloadscript", 99, atcommand_reloadscript }, + { "reloadgmdb", 99, atcommand_reloadgmdb }, + { "reloadatcommand", 99, atcommand_reloadatcommand }, + { "reloadbattleconf", 99, atcommand_reloadbattleconf }, + { "reloadstatusdb", 99, atcommand_reloadstatusdb }, + { "reloadpcdb", 99, atcommand_reloadpcdb }, + { "reloadmotd", 99, atcommand_reloadmotd }, + { "mapinfo", 99, atcommand_mapinfo }, + { "dye", 40, atcommand_dye }, + { "ccolor", 40, atcommand_dye }, + { "hairstyle", 40, atcommand_hair_style }, + { "hstyle", 40, atcommand_hair_style }, + { "haircolor", 40, atcommand_hair_color }, + { "hcolor", 40, atcommand_hair_color }, + { "statall", 60, atcommand_stat_all }, + { "statsall", 60, atcommand_stat_all }, + { "allstats", 60, atcommand_stat_all }, + { "allstat", 60, atcommand_stat_all }, + { "block", 60, atcommand_char_block }, + { "charblock", 60, atcommand_char_block }, + { "ban", 60, atcommand_char_ban }, + { "banish", 60, atcommand_char_ban }, + { "charban", 60, atcommand_char_ban }, + { "charbanish", 60, atcommand_char_ban }, + { "unblock", 60, atcommand_char_unblock }, + { "charunblock", 60, atcommand_char_unblock }, + { "unban", 60, atcommand_char_unban }, + { "unbanish", 60, atcommand_char_unban }, + { "charunban", 60, atcommand_char_unban }, + { "charunbanish", 60, atcommand_char_unban }, + { "mount", 20, atcommand_mount_peco }, + { "mountpeco", 20, atcommand_mount_peco }, + { "guildspy", 60, atcommand_guildspy }, + { "partyspy", 60, atcommand_partyspy }, + { "repairall", 60, atcommand_repairall }, + { "guildrecall", 60, atcommand_guildrecall }, + { "partyrecall", 60, atcommand_partyrecall }, + { "nuke", 60, atcommand_nuke }, + { "shownpc", 80, atcommand_shownpc }, + { "hidenpc", 80, atcommand_hidenpc }, + { "loadnpc", 80, atcommand_loadnpc }, + { "unloadnpc", 80, atcommand_unloadnpc }, + { "time", 1, atcommand_servertime }, + { "date", 1, atcommand_servertime }, + { "serverdate", 1, atcommand_servertime }, + { "servertime", 1, atcommand_servertime }, + { "jail", 60, atcommand_jail }, + { "unjail", 60, atcommand_unjail }, + { "discharge", 60, atcommand_unjail }, + { "jailfor", 60, atcommand_jailfor }, + { "jailtime", 1, atcommand_jailtime }, + { "disguise", 20, atcommand_disguise }, + { "undisguise", 20, atcommand_undisguise }, + { "email", 1, atcommand_email }, + { "effect", 40, atcommand_effect }, + { "follow", 20, atcommand_follow }, + { "addwarp", 60, atcommand_addwarp }, + { "skillon", 80, atcommand_skillon }, + { "skilloff", 80, atcommand_skilloff }, + { "killer", 60, atcommand_killer }, + { "npcmove", 80, atcommand_npcmove }, + { "killable", 40, atcommand_killable }, + { "dropall", 40, atcommand_dropall }, + { "storeall", 40, atcommand_storeall }, + { "skillid", 40, atcommand_skillid }, + { "useskill", 40, atcommand_useskill }, + { "displayskill", 99, atcommand_displayskill }, + { "snow", 99, atcommand_snow }, + { "sakura", 99, atcommand_sakura }, + { "clouds", 99, atcommand_clouds }, + { "clouds2", 99, atcommand_clouds2 }, + { "fog", 99, atcommand_fog }, + { "fireworks", 99, atcommand_fireworks }, + { "leaves", 99, atcommand_leaves }, + { "summon", 60, atcommand_summon }, + { "adjgmlvl", 99, atcommand_adjgmlvl }, + { "adjcmdlvl", 99, atcommand_adjcmdlvl }, + { "trade", 60, atcommand_trade }, + { "send", 99, atcommand_send }, + { "setbattleflag", 99, atcommand_setbattleflag }, + { "unmute", 80, atcommand_unmute }, + { "clearweather", 99, atcommand_clearweather }, + { "uptime", 1, atcommand_uptime }, + { "changesex", 60, atcommand_changesex }, + { "mute", 80, atcommand_mute }, + { "whozeny", 20, atcommand_whozeny }, + { "refresh", 1, atcommand_refresh }, + { "identify", 40, atcommand_identify }, + { "gmotd", 20, atcommand_gmotd }, + { "misceffect", 50, atcommand_misceffect }, + { "mobsearch", 10, atcommand_mobsearch }, + { "cleanmap", 40, atcommand_cleanmap }, + { "npctalk", 20, atcommand_npctalk }, + { "pettalk", 10, atcommand_pettalk }, + { "users", 40, atcommand_users }, + { "reset", 40, atcommand_reset }, + { "skilltree", 40, atcommand_skilltree }, + { "marry", 40, atcommand_marry }, + { "divorce", 40, atcommand_divorce }, + { "sound", 40, atcommand_sound }, + { "undisguiseall", 99, atcommand_undisguiseall }, + { "disguiseall", 99, atcommand_disguiseall }, + { "changelook", 60, atcommand_changelook }, + { "autoloot", 10, atcommand_autoloot }, + { "mobinfo", 1, atcommand_mobinfo }, + { "monsterinfo", 1, atcommand_mobinfo }, + { "mi", 1, atcommand_mobinfo }, + { "exp", 1, atcommand_exp }, + { "adopt", 40, atcommand_adopt }, + { "version", 1, atcommand_version }, + { "mutearea", 99, atcommand_mutearea }, + { "stfu", 99, atcommand_mutearea }, + { "rates", 1, atcommand_rates }, + { "iteminfo", 1, atcommand_iteminfo }, + { "ii", 1, atcommand_iteminfo }, + { "whodrops", 1, atcommand_whodrops }, + { "whereis", 10, atcommand_whereis }, + { "mapflag", 99, atcommand_mapflag }, + { "me", 20, atcommand_me }, + { "monsterignore", 99, atcommand_monsterignore }, + { "battleignore", 99, atcommand_monsterignore }, + { "fakename", 20, atcommand_fakename }, + { "size", 20, atcommand_size }, + { "showexp", 10, atcommand_showexp}, + { "showzeny", 10, atcommand_showzeny}, + { "showdelay", 1, atcommand_showdelay}, + { "autotrade", 10, atcommand_autotrade }, + { "at", 10, atcommand_autotrade }, + { "changegm", 10, atcommand_changegm }, + { "changeleader", 10, atcommand_changeleader }, + { "partyoption", 10, atcommand_partyoption}, + { "invite", 1, atcommand_invite }, + { "duel", 1, atcommand_duel }, + { "leave", 1, atcommand_leave }, + { "accept", 1, atcommand_accept }, + { "reject", 1, atcommand_reject }, + { "away", 1, atcommand_away }, + { "aw", 1, atcommand_away }, + { "main", 1, atcommand_main }, + { "clone", 50, atcommand_clone }, + { "slaveclone", 50, atcommand_clone }, + { "evilclone", 50, atcommand_clone }, + { "tonpc", 40, atcommand_tonpc }, + { "commands", 1, atcommand_commands }, + { "noask", 1, atcommand_noask }, + { "request", 20, atcommand_request }, + { "hlvl", 60, atcommand_homlevel }, + { "hlevel", 60, atcommand_homlevel }, + { "homlvl", 60, atcommand_homlevel }, + { "homlvup", 60, atcommand_homlevel }, + { "homlevel", 60, atcommand_homlevel }, + { "homevolve", 60, atcommand_homevolution }, + { "homevolution", 60, atcommand_homevolution }, + { "makehomun", 60, atcommand_makehomun }, + { "homfriendly", 60, atcommand_homfriendly }, + { "homhungry", 60, atcommand_homhungry }, + { "homtalk", 10, atcommand_homtalk }, + { "hominfo", 1, atcommand_hominfo }, + { "homstats", 1, atcommand_homstats }, + { "homshuffle", 60, atcommand_homshuffle }, + { "showmobs", 10, atcommand_showmobs }, + { "feelreset", 10, atcommand_feelreset }, +#ifndef TXT_ONLY + { "mail", 1, atcommand_mail }, + { "refreshonline", 99, atcommand_refreshonline }, +#endif +}; + + +/*========================================== + * Command lookup functions + *------------------------------------------*/ +static AtCommandInfo* get_atcommandinfo_byname(const char* name) +{ + int i; + if( *name == atcommand_symbol ) name++; // for backwards compatibility + ARR_FIND( 0, ARRAYLENGTH(atcommand_info), i, strcmpi(atcommand_info[i].command, name) == 0 ); + return ( i != ARRAYLENGTH(atcommand_info) ) ? &atcommand_info[i] : NULL; +} + +static AtCommandInfo* get_atcommandinfo_byfunc(const AtCommandFunc func) +{ + int i; + ARR_FIND( 0, ARRAYLENGTH(atcommand_info), i, atcommand_info[i].func == func ); + return ( i != ARRAYLENGTH(atcommand_info) ) ? &atcommand_info[i] : NULL; +} + + +/*========================================== + * Retrieve the command's required gm level + *------------------------------------------*/ +int get_atcommand_level(const AtCommandFunc func) +{ + AtCommandInfo* info = get_atcommandinfo_byfunc(func); + return ( info != NULL ) ? info->level : 100; // 100: command can not be used +} + + +/// Executes an at-command. +/// To be called by internal server code (bypasses various restrictions). +bool is_atcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl) +{ + AtCommandInfo* info; + char command[100]; + char args[100]; + char output[200]; + + if( !str || !*str ) + return false; + + if( *str != atcommand_symbol ) // check first char + return false; + + if( sscanf(str, "%99s %99[^\n]", command, args) < 2 ) + args[0] = '\0'; + + info = get_atcommandinfo_byname(command); + if( info == NULL || info->func == NULL || gmlvl < info->level ) + { + if( gmlvl == 0 ) + return false; // will just display as normal text + else + { + sprintf(output, msg_txt(153), command); // "%s is Unknown Command." + clif_displaymessage(fd, output); + return true; + } + } + + if( log_config.gm && info->level >= log_config.gm ) + log_atcommand(sd, str); + + if( info->func(fd, sd, command, args) != 0 ) + { + sprintf(output, msg_txt(154), command); // "%s failed." + clif_displaymessage(fd, output); + } + + return true; +} + +/// Executes an at-command. +/// To be used by player-invoked code (restrictions will be applied). +bool is_atcommand(const int fd, struct map_session_data* sd, const char* message) +{ + int gmlvl = pc_isGM(sd); + int s_flag = 0; + + nullpo_retr(false, sd); + + if( !message || !*message ) + return false; // shouldn't happen + + if( sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCOMMAND ) + return true; // so that it won't display as normal message + + if( battle_config.atc_gmonly != 0 && gmlvl == 0 ) + return false; + + if( map[sd->bl.m].nocommand && gmlvl < map[sd->bl.m].nocommand ) + { + clif_displaymessage(fd, msg_txt(143)); // "Commands are disabled on this map." + return false; + } + + // skip 10/11-langtype's codepage indicator, if detected + if( message[0] == '|' && strlen(message) >= 4 && message[3] == atcommand_symbol ) + message += 3; + + return is_atcommand_sub(fd,sd,message,gmlvl); +} + + +/*========================================== + * + *------------------------------------------*/ +int atcommand_config_read(const char* cfgName) +{ + char line[1024], w1[1024], w2[1024]; + AtCommandInfo* p; + FILE* fp; + + if( (fp = fopen(cfgName, "r")) == NULL ) + { + ShowError("AtCommand configuration file not found: %s\n", cfgName); + return 1; + } + + while( fgets(line, sizeof(line), fp) ) + { + if( line[0] == '/' && line[1] == '/' ) + continue; + + if( sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2 ) + continue; + + p = get_atcommandinfo_byname(w1); + if( p != NULL ) + { + p->level = atoi(w2); + p->level = cap_value(p->level, 0, 100); + } + else + if( strcmpi(w1, "import") == 0 ) + atcommand_config_read(w2); + else + if( strcmpi(w1, "command_symbol") == 0 && + w2[0] > 31 && // control characters + w2[0] != '/' && // symbol of standard ragnarok GM commands + w2[0] != '%' && // symbol of party chat speaking + w2[0] != '$' && // symbol of guild chat speaking + w2[0] != '#' ) // symbol of charcommand + atcommand_symbol = w2[0]; + else + ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName); + } + fclose(fp); + + return 0; +} + void do_init_atcommand() { users_db = db_alloc(__FILE__,__LINE__,DB_UINT,DB_OPT_BASE,sizeof(int)); @@ -9130,3 +8615,51 @@ void do_final_atcommand() { users_db->destroy(users_db,NULL); } + + +// commands that need to go _after_ the commands table + +/*========================================== + * @commands Lists available @ commands to you + *------------------------------------------*/ +int atcommand_commands(const int fd, struct map_session_data* sd, const char* command, const char* message) +{ + char line_buff[CHATBOX_SIZE]; + int i, gm_lvl = pc_isGM(sd), count = 0; + char* cur = line_buff; + + memset(line_buff,' ',CHATBOX_SIZE); + line_buff[CHATBOX_SIZE-1] = 0; + + clif_displaymessage(fd, msg_txt(273)); // "Commands available:" + + for( i = 0; i < ARRAYLENGTH(atcommand_info); i++ ) + { + unsigned int slen; + + if( gm_lvl < atcommand_info[i].level ) + continue; + + slen = (unsigned int)strlen(atcommand_info[i].command); + + // flush the text buffer if this command won't fit into it + if( ((CHATBOX_SIZE-1+(int)line_buff)-(int)cur) < (int)slen ) + { + clif_displaymessage(fd,line_buff); + cur = line_buff; + memset(line_buff,' ',CHATBOX_SIZE); + line_buff[CHATBOX_SIZE-1] = 0; + } + + memcpy(cur,atcommand_info[i].command,slen); + cur += slen+(10-slen%10); + + count++; + } + clif_displaymessage(fd,line_buff); + + sprintf(atcmd_output, msg_txt(274), count); // "%d commands found." + clif_displaymessage(fd, atcmd_output); + + return 0; +} |