summaryrefslogtreecommitdiff
path: root/src/map/atcommand.c
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-10-29 09:16:39 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-10-29 09:16:39 +0000
commit8f36123ac4f0dad6a9c2428b0b01a3ffd81017a4 (patch)
tree844de2f22a0f03953031d1baaf3ffdc426ad48cd /src/map/atcommand.c
parentccbcf5a85c209341e6471269abef23b58633d083 (diff)
downloadhercules-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.c1569
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;
+}