Przeglądaj źródła

Added new @/# command aliases pattern, all aliases can now be modified/added/removed in the front-end within atcommand_conf (no longer hardcoded). The aliases pattern was defined in this topic: tid:56343 atcommand_conf file rewrite/update belongs to Jguy and BrianL

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@15343 54d463be-8e91-2dee-dedb-b68131a5f0ec
shennetsind 13 lat temu
rodzic
commit
7aaf9b5a25
7 zmienionych plików z 717 dodań i 535 usunięć
  1. 319 141
      conf/atcommand_athena.conf
  2. 375 370
      src/map/atcommand.c
  3. 1 1
      src/map/atcommand.h
  4. 20 20
      src/map/clif.c
  5. 1 1
      src/map/mail.c
  6. 0 1
      src/map/map.c
  7. 1 1
      src/map/pc.c

+ 319 - 141
conf/atcommand_athena.conf

@@ -1,15 +1,16 @@
+//--------------------------------------------------------------
+// rAthena atcommand/charcommand Configuration File
 //--------------------------------------------------------------
-// rAthena atcommand configuration file.
-// Originally translated by Peter Kieser <pfak@telus.net>
-//--------------------------------------------------------------
+
 
 // The symbol that will be used to recognize commands.
 // You can set any one character except control-characters (0x00-0x1f),
 // '%', '$' (party/guild chat speaking) and '/' (standard client commands).
 // command_symbol represents @commands used locally
 // char_symbol represents #commands used on other players.
-command_symbol: @
-char_symbol: #
+command_symbol:@
+char_symbol:#
+
 
 // The following settings in this file use the format "<command name>: level(@),level(#)".
 // They define the minimum GM level required to execute the associated command.
@@ -19,6 +20,7 @@ char_symbol: #
 // (GM level 0), you also need to change the 'atcommand_gm_only' option to 'no'.
 // To completely disable a command, set its required GM level to 100.
 
+
 // Default levels were chosen so that they form the following hierarchy:
 // 0: Normal player
 //    -> no commands accessible
@@ -42,81 +44,107 @@ char_symbol: #
 //    -> commands that will not be available to anyone
 
 
+// Syntax of file:
+// command: @level,#level [<alias commands seperated by commas>]
+
+
+// Example:
+// command: 40,40 [alias,command2,alias2] 
+
+
+
+
 //--------------------------
 // 0: normal player commands
 // None for security purposes.
 
+
 //-------------------------
 // 1: Super player commands
 
+
 // Displays a list of @ commands available to the player.
 commands: 1,1
 
+
 // Displays a list of # commands available to the player.
 charcommands: 1,1
 
+
 // Displays the server rates.
 rates: 1,1
 
-// Show server uptime
+
+// Show server uptime since last map server restart
 uptime: 1,1
 
+
 // Shows/Hides the "there is a delay after a skill" message.
 showdelay: 1,1
 
+
 // Displays current levels and % progress.
 exp: 1,40
 
-// To change your (own) email (characters protection)
+
+// To change your (own) email
 // note: this command doesn't check email itself, but check structure of the email (xxx@xxx)
 //       if you want be sure of each e-mail disable this option (value: 100)
-email: 1,1
+email: 1,60
+
 
 // Show Monster info (rates, stats, drops, MVP stuff)
-mobinfo: 1,1
-monsterinfo: 1,1
-mi: 1,1
+monsterinfo: 1,1 [mobinfo, mi]
+
 
 // Show Item info (type, price, etc)
-iteminfo: 1,1
-ii: 1,1
+iteminfo: 1,1 [ii]
+
 
 // Show who drops an item (mobs with highest drop rate)
 whodrops: 1,1
 
+
 // Syncs the player's position on the client with the one stored on the server.
 refresh: 1,40
 
-// Give server time. (6 same commands)
-time: 1,1
-date: 1,1
-serverdate: 1,1
-servertime: 1,1
+
+// Give server time. (4 same commands)
+time: 1,1 [date,serverdate,servertime]
+
 
 // Displays SVN version of the server.
 version: 1,1
 
+
 // Suicide your character.
 die: 1,1
 
+
 // Enables you to rename your pet.
 petrename: 1,50
 
-// Organize a new party, with you as the party leader.
+
+// Organize a new party, with you as the party leader
 party: 1,1
 
-// Brings up your personal storage wherever you are.
+
+// Opens your Kafra storage wherever you are
 storage: 1,1
 
-// Opens your mailbox.
+
+// Opens your mailbox
 mail: 1,1
 
-// Opens auctions window.
+
+// Opens auctions window
 auction: 1,1
 
+
 // Locate someone on a map, returns your coordinates if the person isn't on.
 where: 1,1
 
+
 // Duel organizing commands
 duel: 1,1
 invite: 1,1
@@ -124,62 +152,80 @@ accept: 1,1
 reject: 1,1
 leave: 1,1
 
+
 // Main chat
 main: 1,1
 
+
 // Autorejecting Deals/Invites
 noask: 1,1
 
+
 // Displays remaining jail time
 jailtime: 1,40
 
+
 // Homunculus commands for players
 hominfo: 1,40
 homstats: 1,40
 
+
 // Kill Steal Protection
 noks: 1,1
 
+
 // Set Font
 font: 1,1
 
+
 //---------------------------
 // 10: Super player+ commands
 
-// Displays/Hides Experience gained
+
+// Displays/Hides Experience gained messages
 showexp: 10,10
 
-// Displays/Hides Zeny gained
+
+// Displays/Hides Zeny gained messages
 showzeny: 10,10
 
+
 // Warps you to predefined locations in major cities.
 go: 10,10
 
+
 // Enables/disables autolooting from killed mobs.
 autoloot: 10,10
 
+
 // Enables/disables autolooting an item.
 alootid: 10,10
 
+
 // Allows you continue vending offline.
-autotrade: 10,10
-at: 10,10
+autotrade: 10,10 [at]
+
 
 // Change Guild Master of your Guild
 changegm: 10,10
 
+
 // Change the leader of your party.
 changeleader: 10,10
 
+
 // Change the party exp- and item share rules.
 partyoption: 10,10
 
+
 // Command what the player's pet will say.
 pettalk: 10,10
 
+
 // Command what the player's homunculus will say.
 homtalk: 10,10
 
+
 // Locates and displays the position of a certain mob on the current map.
 mobsearch: 10,10
 // Locates and displays the position of a certain mob on your mini-map
@@ -187,95 +233,115 @@ showmobs: 10,10
 // Prints out in which maps a monster normally spawns at (does not count script-invoked mobs)
 whereis: 10,10
 
+
 // Resets a Star Gladiator's marked maps
 feelreset: 10,60
 
+
 //----------------------
 // 20: Mediator commands
 
+
 // Displays helpfile in rAthena base directory (2 same commands).
-help: 20,20
-h: 20,20
-help2: 20,20
-h2: 20,20
+help: 20,20 [h]
+help2: 20,20 [h2]
+
 
 // Warp yourself to a person (3 same commands + /shift).
-jumpto: 20,20
-goto: 20,20
-warpto: 20,20
+goto: 20,20 [jumpto,warpto]
+
 
 // Displays the motd file to all players
 gmotd: 20,20
 
+
 // Follow a player (including warping to them)
 follow: 20,20
 
+
 // Sends a request to all connected GMs (via the gm whisper system)
 request: 20,100
 
+
 // Disconnects a user from the server (1 command + right click menu for GM "(name) force to quit").
 kick: 20,20
 
+
 // Changes your appearance.
 model: 20,50
 
+
 // To get a peco to (un)ride (2 same commands).
-mountpeco: 20,50
-mount: 20,50
+mount: 20,50 [mountpeco]
+
 
 // Returns list of logged in characters with their position (2 same commands).
-who: 20,20
-whois: 20,20
+who: 20,20 [whois]
+
 
 // Returns list of logged in characters with their job.
 who2: 20,20
 
+
 // Returns list of logged in characters with their party/guild.
 who3: 20,20
 
+
 // Returns list of logged in characters with their position in a specifical map.
 whomap: 20,20
 
+
 // Returns list of logged in characters with their job in a specifical map.
 whomap2: 20,20
 
+
 // Returns list of logged in characters with their party/guild in a specifical map.
 whomap3: 20,20
 
+
 // Displays GMs online. For those who are higher GM level than yourself,
 // only the name is shown, for the rest, it displays the same info of
 // @who+@who2+who3
 whogm: 20,20
 
+
 // Change your appearence to other players to a mob.
 disguise: 20,60
 
+
 // Restore your normal appearance.
 undisguise: 20,20
 
+
 // Displays the text as a normal message with the format "*name message*" 
 // instead of "name : message" (Like the /me command in IRC)
 me: 20,20
 
+
 // Changes your name to your choice temporarily.
 fakename: 20,50
 
+
 // Changes your size.
 size: 20,50
 
+
 // Can command what other npcs (by name) can say.
-npctalk: 20,100
-npctalkc: 20,100
+npctalk: 20,100 [npctalkc]
+
 
 //--------------------
 // 40: Sub-GM commands
 
+
 // Broadcast to the whole server. Using (1 command + /nb, /b).
 broadcast: 40,40
 
+
 // Broadcast to the map you are on (1 command + /lb, /nlb).
 localbroadcast: 40,40
 
+
 // Broadcast (with or without name)
 kami: 40,40
 // Same as kami but with blue color
@@ -283,267 +349,326 @@ kamib: 40,40
 // Same as kami but you can choose the color (uses different packet)
 kamic: 40,40
 
+
 // Enables GvG on a map (2 same commands).
-gvgon: 40,100
-gpvpon: 40,100
+gvgon: 40,100 [gpvpon]
+
 
 // Turns GvG (Guild vs. Guild) off on a map (2 same commands).
-gvgoff: 40,100
-gpvpoff: 40,100
+gvgoff: 40,100 [gpvpoff]
+
 
 // Activate/Deactivate kill steal protection on a map
 allowks: 40,100
 
+
 // Modifies your HP/SP.
 heal: 40,60
 
+
 // GM Hide (total invisibility to characters and monsters) (1 command + /hide).
 hide: 40,60
 
+
 // Changes your job to one you specify (2 same commands).
-job: 40,60
-jobchange: 40,60
+job: 40,60 [jobchange]
+
 
 // Enables you to to jump randomly on a map (that you are already on).
 jump: 40,40
 
+
 // Warps you to your last save point (2 same commands).
-load: 40,60
-return: 40,60
+load: 40,60 [return]
+
 
 // Warps you to a specific npc
 tonpc: 40,40
 
+
 // Saves a warp point.
 memo: 40,40
 
+
 // Set your character display options. (Visual effects of your character)
 option: 40,60
 
+
 // Sets the level of intemecy of your pet.
 petfriendly: 40,50
 
+
 // Sets hunger level of your pet.
 pethungry: 40,50
 
+
 // Turns PvP (Person vs. Person) off on a map.
 pvpoff: 40,100
 
+
 // Enables PvP on a map.
 pvpon: 40,100
 
-// Permanently adds/removes a quest skill
+
+// Permanently adds a quest skill
 questskill: 40,60
+
+
+// Permanently removes a quest skill
 lostskill: 40,60
 
+
 // Sets the speed you can walk/attack at. Default is 150.
 speed: 40,60
 
+
 // Summons spirit spheres around you.
 spiritball: 40,60
 
-// Warp yourself to a certain map, at (x,y) coordinates (2 same commands).
-mapmove: 40,60 // (also /mm or /mapmove)
-rura: 40,60
-warp: 40,60
+
+// Warp yourself to a certain map, at (x,y) coordinates (2 same commands) + also /mm or /mapmove.
+warp: 40,60 [rura,mapmove]
+
 
 // Changes GM clothes color (2 same commands)
-dye: 40,50
-ccolor: 40,50
+dye: 40,50 [ccolor]
+
 
 // Changes GM hair style (2 same commands)
-hairstyle: 40,40
-hstyle: 40,40
+hairstyle: 40,40 [hstyle]
+
 
 // Changes GM hair color (2 same commands)
-haircolor: 40,50
-hcolor: 40,50
+haircolor: 40,50 [hcolor]
+
 
 // Deletes all your items.
 itemreset: 40,60
 
+
 // Does a skill/stat reset.
 reset: 40,60
 
+
 // Displays distribution of players on the server per map (% on each map which has players)
 users: 40,40
 
+
 // Deletes floor items in your range of sight
 cleanmap: 40,40
 
+
 // Kill all monsters in map (without drops)
 killmonster2: 40,40
 
+
 // Sets your spawn point (aka save point).
 save: 40,60
 
+
 // Do some visual effect on your character
 effect: 40,40
 
+
 // Do some visual effect on your character (misceffect)
 misceffect: 40,40
 
+
 // GM's magnifier
 identify: 40,40
 
+
 // Drop all your items
 dropall: 40,60
 
+
 // Store all your items
 storeall: 40,60
 
+
 // Allow other players to hit you out of PvP
 killable: 40,60
 
+
 // Look up a skill by name
 skillid: 40,40
 
+
 // Use a skill by id
 useskill: 40,40
 
+
 // What skills are required to get this skill
 skilltree: 40,40
 
+
 // Marriage commands
 marry: 40,40
 divorce: 40,40
 
+
 // Adopt a novice into a family
 adopt: 40,40
 
+
 // Play a Sound!
 sound: 40,40
 
+
 // Displays a player's storage
 storagelist: 40,40
 
+
 // Displays a player's cart contents
 cartlist: 40,40
 
+
 // Displays a player's items
 itemlist: 40,40
 
+
 // Displays a player's stats
 stats: 40,40
 
+
 //---------------------
 // 50: Sub-GM+ commands
 
+
 // Creates a new guild, with you as the guildmaster.
 guild: 50,50
 
+
 // Brings up your guild storage wherever you are.
 gstorage: 50,60
 
+
 // Spawns a monster, and a certain amount (2 same commands + /monster).
-monster: 50,50
-spawn: 50,50
+monster: 50,50 [spawn]
+
 
 // Spawns a smaller sized version of a monster.
 monstersmall: 50,50
 
+
 // Spawns a larger sized version of a monster.
 monsterbig: 50,50
 
+
 // Spawns mobs that treat you as their master (they disappear after some time)
 summon: 50,50
 
+
 // It will spawn a supportive clone of the given player.
 clone: 50,50
 
+
 // It will spawn a supportive clone of the given player that follows the creator around.
 slaveclone: 50,50
 
+
 // It will spawn an aggresive clone of the given player.
 evilclone: 50,50
 
 
+
+
 //----------------
 // 60: GM commands
 
-// Add or Remove Cash/Kafra points to yourself
+
+// Add or Remove Cash Points to/from yourself
 cash: 60,60
+
+
+// Add or Remove Kafra Points to/from yourself
 points: 60,60
 
+
 // Starts Guild Wars
 agitstart: 60,100
 
+
 // Ends Guild Wars
 agitend: 60,100
 
+
 // Resurects yourself.
 alive: 60,60
 
-// Levels your character to specified level (adds to your level) (7 same commands).
-blvl: 60,60
-lvup: 60,60
-blevel: 60,60
-baselvl: 60,60
-baselvup: 60,60
-baselevel: 60,60
-baselvlup: 60,60
-
-// Raises your job level (6 same commands).
-jlvl: 60,60
-jlevel: 60,60
-joblvl: 60,60
-joblvup: 60,60
-joblevel: 60,60
-joblvlup: 60,60
+
+// Raises your base level by specified amount (7 same commands).
+blvl: 60,60 [lvup,blevel,baselvl,baselvup,baselevel,baselvlup]
+
+
+// Raises your job level by specified amount (6 same commands).
+jlvl: 60,60 [jlevel,joblvl,joblvup,joblevel,joblvlup]
+
 
 // Changes the sex of yourself
 changesex: 60,60
 
-// Levels your guild to specified level (2 same commands).
-glvl: 60,60
-glevel: 60,60
-guildlvl: 60,60
-guildlvup: 60,60
-guildlevel: 60,60
-guildlvlup: 60,60
+
+// Raises your guild level by specified amount (6 same commands).
+glvl: 60,60 [glevel,guildlvl,guildlvup,guildlevel,guildlvlup]
+
 
 // Find an itemID based on item name
 idsearch: 60,60
 
+
 // Creates an item of your choosing, either Item ID or Name (1 command + /item).
 item: 60,60
 
+
 // Creates a complet item (card, etc...) of your choosing, either Item ID or Name.
 item2: 60,60
 
+
 // Deletes an item of your choosing, either Item ID or Name.
 delitem: 60,60
 
+
 // Kill another character without hitting them.
 kill: 60,60
 
+
 // Kill all monsters in map (with drops)
 killmonster: 60,60
 
+
 // Creates yourself a pet egg.
 makeegg: 60,60
 
+
 // Hatches an egg
 hatch: 60,60
 
+
 // Instantly kills player whose name is entered and deals insane damage to everything around
 nuke: 60,60
 
+
 // Enable hitting a player even when not in PvP
 killer: 60,60
 
+
 // Creates weapon of desired element.
 produce: 60,60
 
+
 // Warps a character to you (1 command + /recall).
 recall: 60,60
 
+
 // Refines all weapons in your items list.
 refine: 60,80
 
+
 // Will repair all broken items in inventory.
 repairall: 60,60
 
+
 // Change Status of your character
 str: 60,60
 agi: 60,60
@@ -552,260 +677,313 @@ int: 60,60
 dex: 60,60
 luk: 60,60
 
-// Gets all skills (4 same commands)
-allskill: 60,60
-allskills: 60,60
-skillall: 60,60
-skillsall: 60,60
 
-// Sets GM stats to maximum (4 same commands)
-statall: 60,60
-statsall: 60,60
-allstats: 60,60
-allstat: 60,60
+// Gives all skills
+allskill: 60,60 [allskills,skillall,skillsall]
+
+
+// Sets GM stats to maximum
+allstats: 60,60 [allstat,statall,statsall]
+
 
-// Gives you job points.
+// Gives you stat points.
 stpoint: 60,60
 
+
 // Gives you skill points of desired amount.
 skpoint: 60,60
 
+
 // Warps all online character of a guild to you. (at least one member of that guild must be on.)
 guildrecall: 60,60
 
-// Warps all online character of a party to you. (at least one party member must be online.)
+
+// Warps all online character of a party to you. 
+// (at least one party member must be online.)
 partyrecall: 60,60
 
-// Allows you to spy on any Guilds Guild chat. (at least one member of that guild must be on.)
+
+// Allows you to spy on any Guilds Guild chat. 
+// (at least one member of that guild must be on.)
 // NOTE: map server needs to be configured to enable spying to use this command (enable_spy: yes)
 guildspy: 60,60
 
-// Allows you to spy on any party's party chat. (at least one party member must be online.)
+
+// Allows you to spy on any party's party chat. 
+// (at least one party member must be online.)
 // NOTE: map server needs to be configured to enable spying to use this command (enable_spy: yes)
 partyspy: 60,60
 
-// Gives you money (zeny) of desired amount.
+
+// Gives you zeny (or subtracts, if amount is negative)
 zeny: 60,80
 
-// To block definitively a player (2 same commands)
-block: 60,100
-charblock: 60,100
 
-// To unblock a player (2 same commands)
-unblock: 60,100
-charunblock: 60,100
+// Block a player indefinitely
+block: 60,100 [charblock]
+
+
+// Unblock a player
+unblock: 60,100 [charunblock]
 
-// To ban a player for a limited time (4 same commands)
-ban: 60,100
-banish: 60,100
-charban: 60,100
-charbanish: 60,100
 
-// To unban a player (4 same commands)
-unban: 60,100
-unbanish: 60,100
-charunban: 60,100
-charunbanish: 60,100
+// Ban a player for a limited time
+ban: 60,100 [banish,charban,charbanish]
+
+
+// Unban a player
+unban: 60,100 [unbanish,charunban,charunbanish]
+
 
 // To send specified character in jails
 jail: 60,100
 
-// To discharge a prisoner (2 same commands)
-unjail: 60,100
-discharge: 60,100
+
+// To discharge a jailed character (2 same commands)
+unjail: 60,100 [discharge]
+
 
 // Timed jailing
 jailfor: 60,60
 
+
 // Create a static warp portal that lasts until the next reboot
 addwarp: 60,60
 
+
 // Open a trade window with any player
 trade: 60,60
 
+
 // Changes the player's appearance (headgear)
 changelook: 60,60
 
+
 // Homunculus commands for GMs
-hlvl: 60,60
-hlevel: 60,60
-homlvl: 60,60
-homlvup: 60,60
-homlevel: 60,60
-homevolve: 60,60
-homevolution: 60,60
+hlvl: 60,60 [homlevel,hlevel,homlvl,homlvup]
+
+
+homevolve: 60,60 [homevolution]
+
+
 makehomun: 60,60
+
+
 homfriendly: 60,60
+
+
 homhungry: 60,60
 
+
 // Re-calculates stats, as if the homun was sent back to level 1 and re-leveled
 homshuffle: 60,60
 
+
 // WoE 2 start/stop commands
 agitstart2: 60,100
 agitend2: 60,100
 
+
 // Resets player stats
 streset: 60,60
 
+
 // Resets player skills
 skreset: 60,60
 
 
+
+
 //----------------------
 // 80: GM Chief commands
 
+
 // Set the server to day.
 day: 80,100
 
+
+// Set the server to night.
+night: 80,100
+
+
 // Kills everyone on the server.
 doom: 80,100
 
+
 // Kills everyone on the map you are on.
 doommap: 80,80
 
-// Set the server to night.
-night: 80,100
 
 // Recalls Everyone To Your Coordinates
 recallall: 80,80
 
+
 // Revives all players on the map.
 raisemap: 80,80
 
+
 // Revives all players on the server.
 raise: 80,100
 
+
 // Hides a NPC.
 hidenpc: 80,100
 
+
 // Unhides a NPC.
 shownpc: 80,100
 
-// Loads a Script
+
+// Loads an NPC script by path
 loadnpc: 80,100
 
+
 // Unloads a NPC
 unloadnpc: 80,100
 
+
 // Move a NPC
 npcmove: 80,100
 
+
 // turn skills on for a map
 skillon: 80,100
 
+
 // turn skills off for a map
 skilloff: 80,100
 
+
 // Mute a player (prevents talking, usage of skills and commands)
 mute: 80,100
 
+
 // Unmute a player
 unmute: 80,100
 
+
 //---------------------------
 // 99: Administrator commands
 
+
 // Disconnect all users from the server
 kickall: 99,100
 
+
 // Closes Map-Server
 mapexit: 99,100
 
+
 // Used for testing packet sends from the client (debug function)
 send: 99,100
 
+
 // Give information about terrain/area (debug function)
 gat: 99,100
 
+
 // Displays a status change without really applying it (debug function)
 displaystatus: 99,100
 
+
 // Displays the animation of a skill without really using it (debug function)
 displayskill: 99,100
 
+
 // Shows information about the map
 mapinfo: 99,100
 
-// Set Map Flags (WIP)
+
+// Set Map Flags
 mapflag: 99,100
 
+
 // Re-load item database (admin command)
 reloaditemdb: 99,100
 
+
 // Re-load monsters database (admin command)
 reloadmobdb: 99,100
 
+
 // Re-load skills database (admin command)
 reloadskilldb: 99,100
 
+
 // Re-load scripts (admin command)
 reloadscript: 99,100
 
+
 // Change a battle_config flag without rebooting server
 setbattleflag: 99,100
 
+
 // Re-load gm command config (admin command)
 reloadatcommand: 99,100
 
+
 // Re-load battle config (admin command)
 // Note that some player config settings won't take effect until relog
 // (display exp, display zeny, display skill delay fail, ...)
 reloadbattleconf: 99,100
 
+
 // Re-load status database (admin command)
 reloadstatusdb: 99,100
 
+
 // Re-load player info database (admin command)
 reloadpcdb: 99,100
 
+
 // Re-load the Message of the Day (admin command)
 reloadmotd: 99,100
 
+
 // Changes the GM level of another character
 // (lasts until reboot, or gm list reload)
 adjgmlvl: 99,100
 
+
 // Changes the required GM level of an @ command
 // (effect lasts until restart or command reload)
 adjcmdlvl: 99,100
 
+
 // [Un]Disguise All Players (admin command)
 disguiseall: 99,100
 undisguiseall: 99,100
 
+
 // Mutes every player on screen (admin command)
-mutearea: 99,100
-stfu: 99,100
+mutearea: 99,100 [stfu]
+
 
 // Makes you immune to attacks (monsters/players/skills cannot target/hit you, admin command)
-monsterignore: 99,100
-battleignore: 99,100
+battleignore: 99,100 [monsterignore]
+
 
 //---------------------------------------------------------------
 // 99: Weather effects
-
 snow: 99,100
-
 clouds: 99,100
-
 clouds2: 99,100
-
 fog: 99,100
-
 fireworks: 99,100
-
 sakura: 99,100
+leaves: 99,100
 
-leaves:99,100
 
 // Stop all weather effects
 clearweather: 99,100
 
+
 //---------------------------------------------------------------
 // 100: Disabled commands
 
+
 //---------------------
 // OTHER: not a command
 
-import: conf/import/atcommand_conf.txt
+
+import:conf/import/atcommand_conf.txt

+ 375 - 370
src/map/atcommand.c

@@ -53,6 +53,8 @@ char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 50
 // local declarations
 #define ACMD_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
 
+DBMap* atcommand_db = NULL;//name -> AtCommandInfo
+
 typedef struct AtCommandInfo
 {
 	const char* command;
@@ -62,7 +64,6 @@ typedef struct AtCommandInfo
 } AtCommandInfo;
 
 static AtCommandInfo* get_atcommandinfo_byname(const char* name);
-static AtCommandInfo* get_atcommandinfo_byfunc(const AtCommandFunc func);
 
 ACMD_FUNC(commands);
 
@@ -4268,9 +4269,9 @@ ACMD_FUNC(reloadskilldb)
 /*==========================================
  * @reloadatcommand - reloads atcommand_athena.conf
  *------------------------------------------*/
-ACMD_FUNC(reloadatcommand)
-{
-	atcommand_config_read(ATCOMMAND_CONF_FILENAME);
+void atcommand_doload();
+ACMD_FUNC(reloadatcommand) {
+	atcommand_doload();
 	clif_displaymessage(fd, msg_txt(254));
 	return 0;
 }
@@ -8800,340 +8801,289 @@ ACMD_FUNC(new_mount) {
 	}
 	return 0;
 }
-/*==========================================
- * atcommand_info[] structure definition
- *------------------------------------------*/
-
-AtCommandInfo atcommand_info[] = {
-	{ "rura",              40,40,     atcommand_mapmove },
-	{ "warp",              40,40,     atcommand_mapmove },
-	{ "mapmove",           40,40,     atcommand_mapmove }, // + /mm
-	{ "where",              1,1,      atcommand_where },
-	{ "jumpto",            20,20,     atcommand_jumpto }, // + /shift
-	{ "warpto",            20,20,     atcommand_jumpto },
-	{ "goto",              20,20,     atcommand_jumpto },
-	{ "jump",              40,40,     atcommand_jump },
-	{ "who",               20,20,     atcommand_who },
-	{ "whois",             20,20,     atcommand_who },
-	{ "who2",              20,20,     atcommand_who2 },
-	{ "who3",              20,20,     atcommand_who3 },
-	{ "whomap",            20,20,     atcommand_whomap },
-	{ "whomap2",           20,20,     atcommand_whomap2 },
-	{ "whomap3",           20,20,     atcommand_whomap3 },
-	{ "whogm",             20,20,     atcommand_whogm },
-	{ "save",              40,40,     atcommand_save },
-	{ "return",            40,40,     atcommand_load },
-	{ "load",              40,40,     atcommand_load },
-	{ "speed",             40,40,     atcommand_speed },
-	{ "storage",            1,1,      atcommand_storage },
-	{ "gstorage",          50,50,     atcommand_guildstorage },
-	{ "option",            40,40,     atcommand_option },
-	{ "hide",              40,40,     atcommand_hide }, // + /hide
-	{ "jobchange",         40,40,     atcommand_jobchange },
-	{ "job",               40,40,     atcommand_jobchange },
-	{ "die",                1,1,      atcommand_die },
-	{ "kill",              60,60,     atcommand_kill },
-	{ "alive",             60,60,     atcommand_alive },
-	{ "kami",              40,40,     atcommand_kami },
-	{ "kamib",             40,40,     atcommand_kami },
-	{ "kamic",             40,40,     atcommand_kami },
-	{ "heal",              40,60,     atcommand_heal },
-	{ "item",              60,60,     atcommand_item },
-	{ "item2",             60,60,     atcommand_item2 },
-	{ "itemreset",         40,40,     atcommand_itemreset },
-	{ "blvl",              60,60,     atcommand_baselevelup },
-	{ "lvup",              60,60,     atcommand_baselevelup },
-	{ "blevel",            60,60,     atcommand_baselevelup },
-	{ "baselvl",           60,60,     atcommand_baselevelup },
-	{ "baselvup",          60,60,     atcommand_baselevelup },
-	{ "baselevel",         60,60,     atcommand_baselevelup },
-	{ "baselvlup",         60,60,     atcommand_baselevelup },
-	{ "jlvl",              60,60,     atcommand_joblevelup },
-	{ "jlevel",            60,60,     atcommand_joblevelup },
-	{ "joblvl",            60,60,     atcommand_joblevelup },
-	{ "joblevel",          60,60,     atcommand_joblevelup },
-	{ "joblvup",           60,60,     atcommand_joblevelup },
-	{ "joblvlup",          60,60,     atcommand_joblevelup },
-	{ "h",                 20,20,     atcommand_help },
-	{ "help",              20,20,     atcommand_help },
-	{ "h2",                20,20,     atcommand_help2 },
-	{ "help2",             20,20,     atcommand_help2 },
-	{ "pvpoff",            40,40,     atcommand_pvpoff },
-	{ "pvpon",             40,40,     atcommand_pvpon },
-	{ "gvgoff",            40,40,     atcommand_gvgoff },
-	{ "gpvpoff",           40,40,     atcommand_gvgoff },
-	{ "gvgon",             40,40,     atcommand_gvgon },
-	{ "gpvpon",            40,40,     atcommand_gvgon },
-	{ "model",             20,20,     atcommand_model },
-	{ "go",                10,10,     atcommand_go },
-	{ "monster",           50,50,     atcommand_monster },
-	{ "spawn",             50,50,     atcommand_monster },
-	{ "monstersmall",      50,50,     atcommand_monstersmall },
-	{ "monsterbig",        50,50,     atcommand_monsterbig },
-	{ "killmonster",       60,60,     atcommand_killmonster },
-	{ "killmonster2",      40,40,     atcommand_killmonster2 },
-	{ "refine",            60,60,     atcommand_refine },
-	{ "produce",           60,60,     atcommand_produce },
-	{ "memo",              40,40,     atcommand_memo },
-	{ "gat",               99,99,     atcommand_gat },
-	{ "displaystatus",     99,99,     atcommand_displaystatus },
-	{ "stpoint",           60,60,     atcommand_statuspoint },
-	{ "skpoint",           60,60,     atcommand_skillpoint },
-	{ "zeny",              60,60,     atcommand_zeny },
-	{ "str",               60,60,     atcommand_param },
-	{ "agi",               60,60,     atcommand_param },
-	{ "vit",               60,60,     atcommand_param },
-	{ "int",               60,60,     atcommand_param },
-	{ "dex",               60,60,     atcommand_param },
-	{ "luk",               60,60,     atcommand_param },
-	{ "glvl",              60,60,     atcommand_guildlevelup },
-	{ "glevel",            60,60,     atcommand_guildlevelup },
-	{ "guildlvl",          60,60,     atcommand_guildlevelup },
-	{ "guildlvup",         60,60,     atcommand_guildlevelup },
-	{ "guildlevel",        60,60,     atcommand_guildlevelup },
-	{ "guildlvlup",        60,60,     atcommand_guildlevelup },
-	{ "makeegg",           60,60,     atcommand_makeegg },
-	{ "hatch",             60,60,     atcommand_hatch },
-	{ "petfriendly",       40,40,     atcommand_petfriendly },
-	{ "pethungry",         40,40,     atcommand_pethungry },
-	{ "petrename",          1,1,      atcommand_petrename },
-	{ "recall",            60,60,     atcommand_recall }, // + /recall
-	{ "night",             80,80,     atcommand_night },
-	{ "day",               80,80,     atcommand_day },
-	{ "doom",              80,80,     atcommand_doom },
-	{ "doommap",           80,80,     atcommand_doommap },
-	{ "raise",             80,80,     atcommand_raise },
-	{ "raisemap",          80,80,     atcommand_raisemap },
-	{ "kick",              20,20,     atcommand_kick }, // + right click menu for GM "(name) force to quit"
-	{ "kickall",           99,99,     atcommand_kickall },
-	{ "allskill",          60,60,     atcommand_allskill },
-	{ "allskills",         60,60,     atcommand_allskill },
-	{ "skillall",          60,60,     atcommand_allskill },
-	{ "skillsall",         60,60,     atcommand_allskill },
-	{ "questskill",        40,40,     atcommand_questskill },
-	{ "lostskill",         40,40,     atcommand_lostskill },
-	{ "spiritball",        40,40,     atcommand_spiritball },
-	{ "party",              1,1,      atcommand_party },
-	{ "guild",             50,50,     atcommand_guild },
-	{ "agitstart",         60,60,     atcommand_agitstart },
-	{ "agitend",           60,60,     atcommand_agitend },
-	{ "mapexit",           99,99,     atcommand_mapexit },
-	{ "idsearch",          60,60,     atcommand_idsearch },
-	{ "broadcast",         40,40,     atcommand_broadcast }, // + /b and /nb
-	{ "localbroadcast",    40,40,     atcommand_localbroadcast }, // + /lb and /nlb
-	{ "recallall",         80,80,     atcommand_recallall },
-	{ "reloaditemdb",      99,99,     atcommand_reloaditemdb },
-	{ "reloadmobdb",       99,99,     atcommand_reloadmobdb },
-	{ "reloadskilldb",     99,99,     atcommand_reloadskilldb },
-	{ "reloadscript",      99,99,     atcommand_reloadscript },
-	{ "reloadatcommand",   99,99,     atcommand_reloadatcommand },
-	{ "reloadbattleconf",  99,99,     atcommand_reloadbattleconf },
-	{ "reloadstatusdb",    99,99,     atcommand_reloadstatusdb },
-	{ "reloadpcdb",        99,99,     atcommand_reloadpcdb },
-	{ "reloadmotd",        99,99,     atcommand_reloadmotd },
-	{ "mapinfo",           99,99,     atcommand_mapinfo },
-	{ "dye",               40,40,     atcommand_dye },
-	{ "ccolor",            40,40,     atcommand_dye },
-	{ "hairstyle",         40,40,     atcommand_hair_style },
-	{ "hstyle",            40,40,     atcommand_hair_style },
-	{ "haircolor",         40,40,     atcommand_hair_color },
-	{ "hcolor",            40,40,     atcommand_hair_color },
-	{ "statall",           60,60,     atcommand_stat_all },
-	{ "statsall",          60,60,     atcommand_stat_all },
-	{ "allstats",          60,60,     atcommand_stat_all },
-	{ "allstat",           60,60,     atcommand_stat_all },
-	{ "block",             60,60,     atcommand_char_block },
-	{ "charblock",         60,60,     atcommand_char_block },
-	{ "ban",               60,60,     atcommand_char_ban },
-	{ "banish",            60,60,     atcommand_char_ban },
-	{ "charban",           60,60,     atcommand_char_ban },
-	{ "charbanish",        60,60,     atcommand_char_ban },
-	{ "unblock",           60,60,     atcommand_char_unblock },
-	{ "charunblock",       60,60,     atcommand_char_unblock },
-	{ "unban",             60,60,     atcommand_char_unban },
-	{ "unbanish",          60,60,     atcommand_char_unban },
-	{ "charunban",         60,60,     atcommand_char_unban },
-	{ "charunbanish",      60,60,     atcommand_char_unban },
-	{ "mount",             20,20,     atcommand_mount_peco },
-	{ "mountpeco",         20,20,     atcommand_mount_peco },
-	{ "guildspy",          60,60,     atcommand_guildspy },
-	{ "partyspy",          60,60,     atcommand_partyspy },
-	{ "repairall",         60,60,     atcommand_repairall },
-	{ "guildrecall",       60,60,     atcommand_guildrecall },
-	{ "partyrecall",       60,60,     atcommand_partyrecall },
-	{ "nuke",              60,60,     atcommand_nuke },
-	{ "shownpc",           80,80,     atcommand_shownpc },
-	{ "hidenpc",           80,80,     atcommand_hidenpc },
-	{ "loadnpc",           80,80,     atcommand_loadnpc },
-	{ "unloadnpc",         80,80,     atcommand_unloadnpc },
-	{ "time",               1,1,      atcommand_servertime },
-	{ "date",               1,1,      atcommand_servertime },
-	{ "serverdate",         1,1,      atcommand_servertime },
-	{ "servertime",         1,1,      atcommand_servertime },
-	{ "jail",              60,60,     atcommand_jail },
-	{ "unjail",            60,60,     atcommand_unjail },
-	{ "discharge",         60,60,     atcommand_unjail },
-	{ "jailfor",           60,60,     atcommand_jailfor },
-	{ "jailtime",           1,1,      atcommand_jailtime },
-	{ "disguise",          20,20,     atcommand_disguise },
-	{ "undisguise",        20,20,     atcommand_undisguise },
-	{ "email",              1,1,      atcommand_email },
-	{ "effect",            40,40,     atcommand_effect },
-	{ "follow",            20,20,     atcommand_follow },
-	{ "addwarp",           60,60,     atcommand_addwarp },
-	{ "skillon",           80,80,     atcommand_skillon },
-	{ "skilloff",          80,80,     atcommand_skilloff },
-	{ "killer",            60,60,     atcommand_killer },
-	{ "npcmove",           80,80,     atcommand_npcmove },
-	{ "killable",          40,40,     atcommand_killable },
-	{ "dropall",           40,40,     atcommand_dropall },
-	{ "storeall",          40,40,     atcommand_storeall },
-	{ "skillid",           40,40,     atcommand_skillid },
-	{ "useskill",          40,40,     atcommand_useskill },
-	{ "displayskill",      99,99,     atcommand_displayskill },
-	{ "snow",              99,99,     atcommand_snow },
-	{ "sakura",            99,99,     atcommand_sakura },
-	{ "clouds",            99,99,     atcommand_clouds },
-	{ "clouds2",           99,99,     atcommand_clouds2 },
-	{ "fog",               99,99,     atcommand_fog },
-	{ "fireworks",         99,99,     atcommand_fireworks },
-	{ "leaves",            99,99,     atcommand_leaves },
-	{ "summon",            60,60,     atcommand_summon },
-	{ "adjgmlvl",          99,99,     atcommand_adjgmlvl },
-	{ "adjcmdlvl",         99,99,     atcommand_adjcmdlvl },
-	{ "trade",             60,60,     atcommand_trade },
-	{ "send",              99,99,     atcommand_send },
-	{ "setbattleflag",     99,99,     atcommand_setbattleflag },
-	{ "unmute",            80,80,     atcommand_unmute },
-	{ "clearweather",      99,99,     atcommand_clearweather },
-	{ "uptime",             1,1,      atcommand_uptime },
-	{ "changesex",         60,60,     atcommand_changesex },
-	{ "mute",              80,80,     atcommand_mute },
-	{ "refresh",            1,1,      atcommand_refresh },
-	{ "identify",          40,40,     atcommand_identify },
-	{ "gmotd",             20,20,     atcommand_gmotd },
-	{ "misceffect",        50,50,     atcommand_misceffect },
-	{ "mobsearch",         10,10,     atcommand_mobsearch },
-	{ "cleanmap",          40,40,     atcommand_cleanmap },
-	{ "npctalk",           20,20,     atcommand_npctalk },
-	{ "npctalkc",          20,20,     atcommand_npctalk },
-	{ "pettalk",           10,10,     atcommand_pettalk },
-	{ "users",             40,40,     atcommand_users },
-	{ "reset",             40,40,     atcommand_reset },
-	{ "skilltree",         40,40,     atcommand_skilltree },
-	{ "marry",             40,40,     atcommand_marry },
-	{ "divorce",           40,40,     atcommand_divorce },
-	{ "sound",             40,40,     atcommand_sound },
-	{ "undisguiseall",     99,99,     atcommand_undisguiseall },
-	{ "disguiseall",       99,99,     atcommand_disguiseall },
-	{ "changelook",        60,60,     atcommand_changelook },
-	{ "autoloot",          10,10,     atcommand_autoloot },
-	{ "alootid",           10,10,     atcommand_autolootitem },
-	{ "mobinfo",            1,1,      atcommand_mobinfo },
-	{ "monsterinfo",        1,1,      atcommand_mobinfo },
-	{ "mi",                 1,1,      atcommand_mobinfo },
-	{ "exp",                1,1,      atcommand_exp },
-	{ "adopt",             40,40,     atcommand_adopt },
-	{ "version",            1,1,      atcommand_version },
-	{ "mutearea",          99,99,     atcommand_mutearea },
-	{ "stfu",              99,99,     atcommand_mutearea },
-	{ "rates",              1,1,      atcommand_rates },
-	{ "iteminfo",           1,1,      atcommand_iteminfo },
-	{ "ii",                 1,1,      atcommand_iteminfo },
-	{ "whodrops",           1,1,      atcommand_whodrops },
-	{ "whereis",           10,10,     atcommand_whereis },
-	{ "mapflag",           99,99,     atcommand_mapflag },
-	{ "me",                20,20,     atcommand_me },
-	{ "monsterignore",     99,99,     atcommand_monsterignore },
-	{ "battleignore",      99,99,     atcommand_monsterignore },
-	{ "fakename",          20,20,     atcommand_fakename },
-	{ "size",              20,20,     atcommand_size },
-	{ "showexp",           10,10,     atcommand_showexp},
-	{ "showzeny",          10,10,     atcommand_showzeny},
-	{ "showdelay",          1,1,      atcommand_showdelay},
-	{ "autotrade",         10,10,     atcommand_autotrade },
-	{ "at",                10,10,     atcommand_autotrade },
-	{ "changegm",          10,10,     atcommand_changegm },
-	{ "changeleader",      10,10,     atcommand_changeleader },
-	{ "partyoption",       10,10,     atcommand_partyoption},
-	{ "invite",             1,1,      atcommand_invite },
-	{ "duel",               1,1,      atcommand_duel },
-	{ "leave",              1,1,      atcommand_leave },
-	{ "accept",             1,1,      atcommand_accept },
-	{ "reject",             1,1,      atcommand_reject },
-	{ "main",               1,1,      atcommand_main },
-	{ "clone",             50,50,     atcommand_clone },
-	{ "slaveclone",        50,50,     atcommand_clone },
-	{ "evilclone",         50,50,     atcommand_clone },
-	{ "tonpc",             40,40,     atcommand_tonpc },
-	{ "commands",           1,1,      atcommand_commands },
-	{ "noask",              1,1,      atcommand_noask },
-	{ "request",           20,20,     atcommand_request },
-	{ "hlvl",              60,60,     atcommand_homlevel },
-	{ "hlevel",            60,60,     atcommand_homlevel },
-	{ "homlvl",            60,60,     atcommand_homlevel },
-	{ "homlvup",           60,60,     atcommand_homlevel },
-	{ "homlevel",          60,60,     atcommand_homlevel },
-	{ "homevolve",         60,60,     atcommand_homevolution },
-	{ "homevolution",      60,60,     atcommand_homevolution },
-	{ "makehomun",         60,60,     atcommand_makehomun },
-	{ "homfriendly",       60,60,     atcommand_homfriendly },
-	{ "homhungry",         60,60,     atcommand_homhungry },
-	{ "homtalk",           10,10,     atcommand_homtalk },
-	{ "hominfo",            1,1,      atcommand_hominfo },
-	{ "homstats",           1,1,      atcommand_homstats },
-	{ "homshuffle",        60,60,     atcommand_homshuffle },
-	{ "showmobs",          10,10,     atcommand_showmobs },
-	{ "feelreset",         10,10,     atcommand_feelreset },
-	{ "auction",            1,1,      atcommand_auction },
-	{ "mail",               1,1,      atcommand_mail },
-	{ "noks",               1,1,      atcommand_ksprotection },
-	{ "allowks",           40,40,     atcommand_allowks },
-	{ "cash",              60,60,     atcommand_cash },
-	{ "points",            60,60,     atcommand_cash },
-	{ "agitstart2",        60,60,     atcommand_agitstart2 },
-	{ "agitend2",          60,60,     atcommand_agitend2 },
-	{ "skreset",           60,60,     atcommand_resetskill },
-	{ "streset",           60,60,     atcommand_resetstat },
-	{ "storagelist",       40,40,     atcommand_itemlist },
-	{ "cartlist",          40,40,     atcommand_itemlist },
-	{ "itemlist",          40,40,     atcommand_itemlist },
-	{ "stats",             40,40,     atcommand_stats },
-	{ "delitem",           60,60,     atcommand_delitem },
-	{ "charcommands",       1,1,      atcommand_commands },
-	{ "font",               1,1,      atcommand_font },
+
+/**
+ * Fills the reference of available commands in atcommand DBMap
+ **/
+void atcommand_basecommands(void) {
 	/**
-	 * For Testing Purposes, not going to be here after we're done.
+	 * Command reference list, place the base of your commands here
+	 * Dev note: I'd love to get rid of this, if you have a better idea on this please share with the poor mortals
 	 **/
-	{ "newmount",           0,99,     atcommand_new_mount },
-};
+	AtCommandInfo atcommand_base[] = {
+		{ "warp",              40,40,     atcommand_mapmove }, // + /mm
+		{ "where",              1,1,      atcommand_where },
+		{ "goto",              20,20,     atcommand_jumpto }, // + /shift
+		{ "jump",              40,40,     atcommand_jump },
+		{ "who",               20,20,     atcommand_who },
+		{ "who2",              20,20,     atcommand_who2 },
+		{ "who3",              20,20,     atcommand_who3 },
+		{ "whomap",            20,20,     atcommand_whomap },
+		{ "whomap2",           20,20,     atcommand_whomap2 },
+		{ "whomap3",           20,20,     atcommand_whomap3 },
+		{ "whogm",             20,20,     atcommand_whogm },
+		{ "save",              40,40,     atcommand_save },
+		{ "load",              40,40,     atcommand_load },
+		{ "speed",             40,40,     atcommand_speed },
+		{ "storage",            1,1,      atcommand_storage },
+		{ "gstorage",          50,50,     atcommand_guildstorage },
+		{ "option",            40,40,     atcommand_option },
+		{ "hide",              40,40,     atcommand_hide }, // + /hide
+		{ "job",               40,40,     atcommand_jobchange },
+		{ "die",                1,1,      atcommand_die },
+		{ "kill",              60,60,     atcommand_kill },
+		{ "alive",             60,60,     atcommand_alive },
+		{ "kami",              40,40,     atcommand_kami },
+		{ "kamib",             40,40,     atcommand_kami },
+		{ "kamic",             40,40,     atcommand_kami },
+		{ "heal",              40,60,     atcommand_heal },
+		{ "item",              60,60,     atcommand_item },
+		{ "item2",             60,60,     atcommand_item2 },
+		{ "itemreset",         40,40,     atcommand_itemreset },
+		{ "blvl",              60,60,     atcommand_baselevelup },
+		{ "jlvl",              60,60,     atcommand_joblevelup },
+		{ "help",              20,20,     atcommand_help },
+		{ "help2",             20,20,     atcommand_help2 },
+		{ "pvpoff",            40,40,     atcommand_pvpoff },
+		{ "pvpon",             40,40,     atcommand_pvpon },
+		{ "gvgoff",            40,40,     atcommand_gvgoff },
+		{ "gvgon",             40,40,     atcommand_gvgon },
+		{ "model",             20,20,     atcommand_model },
+		{ "go",                10,10,     atcommand_go },
+		{ "monster",           50,50,     atcommand_monster },
+		{ "monstersmall",      50,50,     atcommand_monstersmall },
+		{ "monsterbig",        50,50,     atcommand_monsterbig },
+		{ "killmonster",       60,60,     atcommand_killmonster },
+		{ "killmonster2",      40,40,     atcommand_killmonster2 },
+		{ "refine",            60,60,     atcommand_refine },
+		{ "produce",           60,60,     atcommand_produce },
+		{ "memo",              40,40,     atcommand_memo },
+		{ "gat",               99,99,     atcommand_gat },
+		{ "displaystatus",     99,99,     atcommand_displaystatus },
+		{ "stpoint",           60,60,     atcommand_statuspoint },
+		{ "skpoint",           60,60,     atcommand_skillpoint },
+		{ "zeny",              60,60,     atcommand_zeny },
+		{ "str",               60,60,     atcommand_param },
+		{ "agi",               60,60,     atcommand_param },
+		{ "vit",               60,60,     atcommand_param },
+		{ "int",               60,60,     atcommand_param },
+		{ "dex",               60,60,     atcommand_param },
+		{ "luk",               60,60,     atcommand_param },
+		{ "glvl",              60,60,     atcommand_guildlevelup },
+		{ "makeegg",           60,60,     atcommand_makeegg },
+		{ "hatch",             60,60,     atcommand_hatch },
+		{ "petfriendly",       40,40,     atcommand_petfriendly },
+		{ "pethungry",         40,40,     atcommand_pethungry },
+		{ "petrename",          1,1,      atcommand_petrename },
+		{ "recall",            60,60,     atcommand_recall }, // + /recall
+		{ "night",             80,80,     atcommand_night },
+		{ "day",               80,80,     atcommand_day },
+		{ "doom",              80,80,     atcommand_doom },
+		{ "doommap",           80,80,     atcommand_doommap },
+		{ "raise",             80,80,     atcommand_raise },
+		{ "raisemap",          80,80,     atcommand_raisemap },
+		{ "kick",              20,20,     atcommand_kick }, // + right click menu for GM "(name) force to quit"
+		{ "kickall",           99,99,     atcommand_kickall },
+		{ "allskill",          60,60,     atcommand_allskill },
+		{ "questskill",        40,40,     atcommand_questskill },
+		{ "lostskill",         40,40,     atcommand_lostskill },
+		{ "spiritball",        40,40,     atcommand_spiritball },
+		{ "party",              1,1,      atcommand_party },
+		{ "guild",             50,50,     atcommand_guild },
+		{ "agitstart",         60,60,     atcommand_agitstart },
+		{ "agitend",           60,60,     atcommand_agitend },
+		{ "mapexit",           99,99,     atcommand_mapexit },
+		{ "idsearch",          60,60,     atcommand_idsearch },
+		{ "broadcast",         40,40,     atcommand_broadcast }, // + /b and /nb
+		{ "localbroadcast",    40,40,     atcommand_localbroadcast }, // + /lb and /nlb
+		{ "recallall",         80,80,     atcommand_recallall },
+		{ "reloaditemdb",      99,99,     atcommand_reloaditemdb },
+		{ "reloadmobdb",       99,99,     atcommand_reloadmobdb },
+		{ "reloadskilldb",     99,99,     atcommand_reloadskilldb },
+		{ "reloadscript",      99,99,     atcommand_reloadscript },
+		{ "reloadatcommand",   99,99,     atcommand_reloadatcommand },
+		{ "reloadbattleconf",  99,99,     atcommand_reloadbattleconf },
+		{ "reloadstatusdb",    99,99,     atcommand_reloadstatusdb },
+		{ "reloadpcdb",        99,99,     atcommand_reloadpcdb },
+		{ "reloadmotd",        99,99,     atcommand_reloadmotd },
+		{ "mapinfo",           99,99,     atcommand_mapinfo },
+		{ "dye",               40,40,     atcommand_dye },
+		{ "hairstyle",         40,40,     atcommand_hair_style },
+		{ "haircolor",         40,40,     atcommand_hair_color },
+		{ "allstats",          60,60,     atcommand_stat_all },
+		{ "block",             60,60,     atcommand_char_block },
+		{ "ban",               60,60,     atcommand_char_ban },
+		{ "unblock",           60,60,     atcommand_char_unblock },
+		{ "unban",             60,60,     atcommand_char_unban },
+		{ "mount",             20,20,     atcommand_mount_peco },
+		{ "guildspy",          60,60,     atcommand_guildspy },
+		{ "partyspy",          60,60,     atcommand_partyspy },
+		{ "repairall",         60,60,     atcommand_repairall },
+		{ "guildrecall",       60,60,     atcommand_guildrecall },
+		{ "partyrecall",       60,60,     atcommand_partyrecall },
+		{ "nuke",              60,60,     atcommand_nuke },
+		{ "shownpc",           80,80,     atcommand_shownpc },
+		{ "hidenpc",           80,80,     atcommand_hidenpc },
+		{ "loadnpc",           80,80,     atcommand_loadnpc },
+		{ "unloadnpc",         80,80,     atcommand_unloadnpc },
+		{ "time",               1,1,      atcommand_servertime },
+		{ "jail",              60,60,     atcommand_jail },
+		{ "unjail",            60,60,     atcommand_unjail },
+		{ "jailfor",           60,60,     atcommand_jailfor },
+		{ "jailtime",           1,1,      atcommand_jailtime },
+		{ "disguise",          20,20,     atcommand_disguise },
+		{ "undisguise",        20,20,     atcommand_undisguise },
+		{ "email",              1,1,      atcommand_email },
+		{ "effect",            40,40,     atcommand_effect },
+		{ "follow",            20,20,     atcommand_follow },
+		{ "addwarp",           60,60,     atcommand_addwarp },
+		{ "skillon",           80,80,     atcommand_skillon },
+		{ "skilloff",          80,80,     atcommand_skilloff },
+		{ "killer",            60,60,     atcommand_killer },
+		{ "npcmove",           80,80,     atcommand_npcmove },
+		{ "killable",          40,40,     atcommand_killable },
+		{ "dropall",           40,40,     atcommand_dropall },
+		{ "storeall",          40,40,     atcommand_storeall },
+		{ "skillid",           40,40,     atcommand_skillid },
+		{ "useskill",          40,40,     atcommand_useskill },
+		{ "displayskill",      99,99,     atcommand_displayskill },
+		{ "snow",              99,99,     atcommand_snow },
+		{ "sakura",            99,99,     atcommand_sakura },
+		{ "clouds",            99,99,     atcommand_clouds },
+		{ "clouds2",           99,99,     atcommand_clouds2 },
+		{ "fog",               99,99,     atcommand_fog },
+		{ "fireworks",         99,99,     atcommand_fireworks },
+		{ "leaves",            99,99,     atcommand_leaves },
+		{ "summon",            60,60,     atcommand_summon },
+		{ "adjgmlvl",          99,99,     atcommand_adjgmlvl },
+		{ "adjcmdlvl",         99,99,     atcommand_adjcmdlvl },
+		{ "trade",             60,60,     atcommand_trade },
+		{ "send",              99,99,     atcommand_send },
+		{ "setbattleflag",     99,99,     atcommand_setbattleflag },
+		{ "unmute",            80,80,     atcommand_unmute },
+		{ "clearweather",      99,99,     atcommand_clearweather },
+		{ "uptime",             1,1,      atcommand_uptime },
+		{ "changesex",         60,60,     atcommand_changesex },
+		{ "mute",              80,80,     atcommand_mute },
+		{ "refresh",            1,1,      atcommand_refresh },
+		{ "identify",          40,40,     atcommand_identify },
+		{ "gmotd",             20,20,     atcommand_gmotd },
+		{ "misceffect",        50,50,     atcommand_misceffect },
+		{ "mobsearch",         10,10,     atcommand_mobsearch },
+		{ "cleanmap",          40,40,     atcommand_cleanmap },
+		{ "npctalk",           20,20,     atcommand_npctalk },
+		{ "pettalk",           10,10,     atcommand_pettalk },
+		{ "users",             40,40,     atcommand_users },
+		{ "reset",             40,40,     atcommand_reset },
+		{ "skilltree",         40,40,     atcommand_skilltree },
+		{ "marry",             40,40,     atcommand_marry },
+		{ "divorce",           40,40,     atcommand_divorce },
+		{ "sound",             40,40,     atcommand_sound },
+		{ "undisguiseall",     99,99,     atcommand_undisguiseall },
+		{ "disguiseall",       99,99,     atcommand_disguiseall },
+		{ "changelook",        60,60,     atcommand_changelook },
+		{ "autoloot",          10,10,     atcommand_autoloot },
+		{ "alootid",           10,10,     atcommand_autolootitem },
+		{ "monsterinfo",        1,1,      atcommand_mobinfo },
+		{ "exp",                1,1,      atcommand_exp },
+		{ "adopt",             40,40,     atcommand_adopt },
+		{ "version",            1,1,      atcommand_version },
+		{ "mutearea",          99,99,     atcommand_mutearea },
+		{ "rates",              1,1,      atcommand_rates },
+		{ "iteminfo",           1,1,      atcommand_iteminfo },
+		{ "whodrops",           1,1,      atcommand_whodrops },
+		{ "whereis",           10,10,     atcommand_whereis },
+		{ "mapflag",           99,99,     atcommand_mapflag },
+		{ "me",                20,20,     atcommand_me },
+		{ "battleignore",      99,99,     atcommand_monsterignore },
+		{ "fakename",          20,20,     atcommand_fakename },
+		{ "size",              20,20,     atcommand_size },
+		{ "showexp",           10,10,     atcommand_showexp},
+		{ "showzeny",          10,10,     atcommand_showzeny},
+		{ "showdelay",          1,1,      atcommand_showdelay},
+		{ "autotrade",         10,10,     atcommand_autotrade },
+		{ "changegm",          10,10,     atcommand_changegm },
+		{ "changeleader",      10,10,     atcommand_changeleader },
+		{ "partyoption",       10,10,     atcommand_partyoption},
+		{ "invite",             1,1,      atcommand_invite },
+		{ "duel",               1,1,      atcommand_duel },
+		{ "leave",              1,1,      atcommand_leave },
+		{ "accept",             1,1,      atcommand_accept },
+		{ "reject",             1,1,      atcommand_reject },
+		{ "main",               1,1,      atcommand_main },
+		{ "clone",             50,50,     atcommand_clone },
+		{ "slaveclone",        50,50,     atcommand_clone },
+		{ "evilclone",         50,50,     atcommand_clone },
+		{ "tonpc",             40,40,     atcommand_tonpc },
+		{ "commands",           1,1,      atcommand_commands },
+		{ "noask",              1,1,      atcommand_noask },
+		{ "request",           20,20,     atcommand_request },
+		{ "hlvl",              60,60,     atcommand_homlevel },
+		{ "homevolve",         60,60,     atcommand_homevolution },
+		{ "makehomun",         60,60,     atcommand_makehomun },
+		{ "homfriendly",       60,60,     atcommand_homfriendly },
+		{ "homhungry",         60,60,     atcommand_homhungry },
+		{ "homtalk",           10,10,     atcommand_homtalk },
+		{ "hominfo",            1,1,      atcommand_hominfo },
+		{ "homstats",           1,1,      atcommand_homstats },
+		{ "homshuffle",        60,60,     atcommand_homshuffle },
+		{ "showmobs",          10,10,     atcommand_showmobs },
+		{ "feelreset",         10,10,     atcommand_feelreset },
+		{ "auction",            1,1,      atcommand_auction },
+		{ "mail",               1,1,      atcommand_mail },
+		{ "noks",               1,1,      atcommand_ksprotection },
+		{ "allowks",           40,40,     atcommand_allowks },
+		{ "cash",              60,60,     atcommand_cash },
+		{ "points",            60,60,     atcommand_cash },
+		{ "agitstart2",        60,60,     atcommand_agitstart2 },
+		{ "agitend2",          60,60,     atcommand_agitend2 },
+		{ "skreset",           60,60,     atcommand_resetskill },
+		{ "streset",           60,60,     atcommand_resetstat },
+		{ "storagelist",       40,40,     atcommand_itemlist },
+		{ "cartlist",          40,40,     atcommand_itemlist },
+		{ "itemlist",          40,40,     atcommand_itemlist },
+		{ "stats",             40,40,     atcommand_stats },
+		{ "delitem",           60,60,     atcommand_delitem },
+		{ "charcommands",       1,1,      atcommand_commands },
+		{ "font",               1,1,      atcommand_font },
+		/**
+		 * For Testing Purposes, not going to be here after we're done.
+		 **/
+		{ "newmount",           0,99,     atcommand_new_mount },
+	};
+	AtCommandInfo* atcommand;
+	int i;
+
+	for( i = 0; i < ARRAYLENGTH(atcommand_base); i++ ) {
 
+		CREATE(atcommand, AtCommandInfo, 1);
+
+		atcommand->command = atcommand_base[i].command;
+		atcommand->level = atcommand_base[i].level;
+		atcommand->level2 = atcommand_base[i].level2;
+		atcommand->func = atcommand_base[i].func;
+
+		strdb_put(atcommand_db, atcommand->command, atcommand);
+	}
+	return;
+}
 
 /*==========================================
  * Command lookup functions
  *------------------------------------------*/
-static AtCommandInfo* get_atcommandinfo_byname(const char* name)
-{
-	int i;
+static AtCommandInfo* get_atcommandinfo_byname(const char* name) {
 	if( *name == atcommand_symbol || *name == charcommand_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;
+	if( strdb_exists(atcommand_db,name) )
+		return (AtCommandInfo*)strdb_get(atcommand_db, name);
+	return NULL;
 }
 
 
 /*==========================================
  * Retrieve the command's required gm level
  *------------------------------------------*/
-int get_atcommand_level(const AtCommandFunc func)
-{
-	AtCommandInfo* info = get_atcommandinfo_byfunc(func);
+int get_atcommand_level(const char* name) {
+	AtCommandInfo* info = (AtCommandInfo*)strdb_get(atcommand_db, name);
 	return ( info != NULL ) ? info->level : 100; // 100: command can not be used
 }
 
@@ -9247,8 +9197,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
 		params[0] = '\0';
 	
 	//Grab the command information and check for the proper GM level required to use it or if the command exists
-	info = get_atcommandinfo_byname(command);
-	if( info == NULL || info->func == NULL || ( type && ((*atcmd_msg == atcommand_symbol && pc_isGM(sd) < info->level) || (*atcmd_msg == charcommand_symbol && pc_isGM(sd) < info->level2)) ) )
+	if( (info = (AtCommandInfo*)strdb_get(atcommand_db, command+1)) == NULL || info->func == NULL || ( type && ((*atcmd_msg == atcommand_symbol && pc_isGM(sd) < info->level) || (*atcmd_msg == charcommand_symbol && pc_isGM(sd) < info->level2)) ) )
 	{
 		if( pc_isGM(sd) ) {
 			sprintf(output, msg_txt(153), command); // "%s is Unknown Command."
@@ -9260,10 +9209,9 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
 	
 	//Log atcommands
 	if( *atcmd_msg == atcommand_symbol )
-		log_atcommand(sd, info->level, atcmd_msg);
-		
+		log_atcommand(sd, info->level, atcmd_msg);	
 	//Log Charcommands
-	if( *atcmd_msg == charcommand_symbol && ssd != NULL )
+	else if( *atcmd_msg == charcommand_symbol && ssd != NULL )
 		log_atcommand(sd, info->level2, message);
 	
 	//Attempt to use the command
@@ -9277,61 +9225,97 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
 	
 	return true;
 }
+/**
+ * Splits and parses command aliases field
+ * Note: I'm not good (at all) with string manipulation, if you think you can improve, please do. I beg you.
+ **/
+void atcommand_parse_aliases(char aliases[1024],AtCommandInfo* base) {
+	char *str[99], *p;
+	int i, max = 0;
+
+	p = aliases;
+	while( ISSPACE(*p) )//trim
+		++p;
+
+	//I assume nobody is getting over 98 alises in the same command lol
+	for( i = 0; i < 99; i++ ) {
+		str[i] = p;
+		p = strchr(p,',');
+		if( p == NULL ) {
+			max = i+1;
+			break;// comma not found
+		}
+		*p = '\0';
+		++p;
+	}
 
+	if( !str[0] )//no aliases at all
+		return;
+
+	for(i = 0; i < max;i++) {
+		AtCommandInfo* atcommand;
+
+		if( strdb_exists(atcommand_db, str[i]) ) {
+			ShowError("atcommand_conf: duplicate alises error: %s (from %s)\n",str[i],base->command);
+			continue;
+		}
+
+		CREATE(atcommand, AtCommandInfo, 1);
+
+		atcommand->command = str[i];
+		atcommand->level = base->level;
+		atcommand->level2 = base->level2;
+		atcommand->func = base->func;
+
+		strdb_put(atcommand_db, atcommand->command, atcommand);
+	}
 
+	return;
+}
 /*==========================================
  *
  *------------------------------------------*/
 int atcommand_config_read(const char* cfgName)
 {
-	char line[1024], w1[1024], w2[1024], w3[1024];
+	char line[1024], w1[1024], w2[1024], w3[1024], w4[1024];
 	AtCommandInfo* p;
 	FILE* fp;
-	
-	if( (fp = fopen(cfgName, "r")) == NULL )
-	{
+
+	if( (fp = fopen(cfgName, "r")) == NULL ) {
 		ShowError("AtCommand configuration file not found: %s\n", cfgName);
 		return 1;
 	}
 	
-	while( fgets(line, sizeof(line), fp) )
-	{
+	while( fgets(line, sizeof(line), fp) ) {
 		if( line[0] == '/' && line[1] == '/' )
 			continue;
-		
-		if( (sscanf(line, "%1023[^:]:%1023[^,],%1023s", w1, w2, w3)) != 3 && ( sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2 
-		&& strcmpi(w1, "import") != 0 ) && strcmpi(w1, "command_symbol") != 0 && strcmpi(w1, "char_symbol") != 0 )
-			continue;
 
-		p = get_atcommandinfo_byname(w1);
-		if( p != NULL )
-		{
-			p->level = atoi(w2);
-			p->level = cap_value(p->level, 0, 100);
-			if( (sscanf(line, "%1023[^:]:%1023s", w1, w2) == 2) && (sscanf(line, "%1023[^:]:%1023[^,],%1023s", w1, w2, w3)) != 3 )
-			{	
-				ShowWarning("atcommand_conf: setting %s:%d is deprecated! Please see atcommand_athena.conf for the new setting format.\n",w1,atoi(w2));
-				ShowWarning("atcommand_conf: defaulting %s charcommand level to %d.\n",w1,atoi(w2));
-				p->level2 = atoi(w2);
+		if( ( sscanf(line,"%1023[^:]:%1023[^,],%1023[^[][%1023[^]]",w1,w2,w3,w4) ) == 4 ) {
+			if( ( p = (AtCommandInfo*)strdb_get(atcommand_db, w1) ) != NULL ) {
+				
+				p->level = atoi(w2);//update @level
+				p->level2 = atoi(w3);//update #level
+				
+				/**
+				 * Parse the alises
+				 **/
+				atcommand_parse_aliases(w4,p);
+
+				continue;//we're done move on
 			}
-			else {
-				p->level2 = atoi(w3);
-			}
-			p->level2 = cap_value(p->level2, 0, 100);
-		}
-		else
+		} else if( strcmpi(w1, "import") != 0 && strcmpi(w1, "command_symbol") != 0 && strcmpi(w1, "char_symbol") != 0 )
+			continue;
+
 		if( strcmpi(w1, "import") == 0 )
 			atcommand_config_read(w2);
-		else
-		if( strcmpi(w1, "command_symbol") == 0 &&
+		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] != '#' ) // remote symbol
 			atcommand_symbol = w2[0];
-		else 
-		if( strcmpi(w1, "char_symbol") == 0 &&
+		else  if( strcmpi(w1, "char_symbol") == 0 &&
 			w2[0] > 31   &&
 			w2[0] != '/' &&
 			w2[0] != '%' &&
@@ -9346,14 +9330,33 @@ int atcommand_config_read(const char* cfgName)
 	return 0;
 }
 
-void do_init_atcommand()
-{
+void atcommand_doload() {
+
+	if( atcommand_db != NULL )
+		db_destroy(atcommand_db);
+
+	atcommand_db = strdb_alloc(DB_OPT_DUP_KEY, 0);
+	atcommand_basecommands();//fills initial atcommand_db with known commands
+
+	atcommand_config_read(ATCOMMAND_CONF_FILENAME);
+	
+	return;
+}
+
+void do_init_atcommand() {
+	
+	atcommand_doload();
+
 	add_timer_func_list(atshowmobs_timer, "atshowmobs_timer");
+
 	return;
 }
 
-void do_final_atcommand()
-{
+void do_final_atcommand() {
+	
+	db_destroy(atcommand_db);
+
+	return;
 }
 
 
@@ -9365,24 +9368,25 @@ void do_final_atcommand()
 ACMD_FUNC(commands)
 {
 	char line_buff[CHATBOX_SIZE];
-	int i, gm_lvl = pc_isGM(sd), count = 0;
+	int gm_lvl = pc_isGM(sd), count = 0;
 	char* cur = line_buff;
+	AtCommandInfo* cmd;
+	DBIterator* iter = atcommand_db->iterator(atcommand_db);
 
 	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++ )
-	{
+	for( cmd = (AtCommandInfo*)iter->first(iter,NULL); iter->exists(iter); cmd = (AtCommandInfo*)iter->next(iter,NULL) ) {
 		unsigned int slen;
 
-		if( gm_lvl < atcommand_info[i].level && stristr(command,"commands") )
+		if( gm_lvl < cmd->level && stristr(command,"commands") )
 			continue;
-		if( gm_lvl < atcommand_info[i].level2 && stristr(command,"charcommands") )
+		if( gm_lvl < cmd->level2 && stristr(command,"charcommands") )
 			continue;
 
-		slen = strlen(atcommand_info[i].command);
+		slen = strlen(cmd->command);
 
 		// flush the text buffer if this command won't fit into it
 		if( slen + cur - line_buff >= CHATBOX_SIZE )
@@ -9393,11 +9397,12 @@ ACMD_FUNC(commands)
 			line_buff[CHATBOX_SIZE-1] = 0;
 		}
 
-		memcpy(cur,atcommand_info[i].command,slen);
+		memcpy(cur,cmd->command,slen);
 		cur += slen+(10-slen%10);
 
 		count++;
 	}
+	iter->destroy(iter);
 	clif_displaymessage(fd,line_buff);
 
 	sprintf(atcmd_output, msg_txt(274), count); // "%d commands found."

+ 1 - 1
src/map/atcommand.h

@@ -18,7 +18,7 @@ extern char charcommand_symbol;
 typedef int (*AtCommandFunc)(const int fd, struct map_session_data* sd, const char* command, const char* message);
 
 bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type);
-int get_atcommand_level(const AtCommandFunc func);
+int get_atcommand_level(const char* name);
 
 void do_init_atcommand(void);
 void do_final_atcommand(void);

+ 20 - 20
src/map/clif.c

@@ -9169,7 +9169,7 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd)
 
 	if (battle_config.atc_gmonly && !pc_isGM(sd))
 		return;
-	if(pc_isGM(sd) < get_atcommand_level(atcommand_mapmove))
+	if(pc_isGM(sd) < get_atcommand_level("warp"))
 		return;
 
 	map_name = (char*)RFIFOP(fd,2);
@@ -9177,7 +9177,7 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd)
 	sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20));
 	atcommand_mapmove(fd, sd, "@mapmove", output);
 	sprintf(message, "/mm %s", output);
-	log_atcommand(sd, get_atcommand_level(atcommand_mapmove), message);
+	log_atcommand(sd, get_atcommand_level("warp"), message);
 }
 
 /*==========================================
@@ -9534,7 +9534,7 @@ void clif_parse_Broadcast(int fd, struct map_session_data* sd)
 
 	if( battle_config.atc_gmonly && !pc_isGM(sd) )
 		return;
-	if( pc_isGM(sd) < (lv=get_atcommand_level(atcommand_broadcast)) )
+	if( pc_isGM(sd) < (lv=get_atcommand_level("broadcast")) )
 		return;
 
 	// as the length varies depending on the command used, just block unreasonably long strings
@@ -10628,7 +10628,7 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd)
 	if( battle_config.atc_gmonly && !pc_isGM(sd) )
 		return;
 
-	if( pc_isGM(sd) < get_atcommand_level(atcommand_reset) )
+	if( pc_isGM(sd) < get_atcommand_level("reset") )
 		return;
 
 	if( RFIFOW(fd,2) )
@@ -10636,7 +10636,7 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd)
 	else
 		pc_resetstate(sd);
 
-	log_atcommand(sd, get_atcommand_level(atcommand_reset), RFIFOW(fd,2) ? "/resetskill" : "/resetstate");
+	log_atcommand(sd, get_atcommand_level("reset"), RFIFOW(fd,2) ? "/resetskill" : "/resetstate");
 }
 
 /*==========================================
@@ -10652,7 +10652,7 @@ void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd)
 	if( battle_config.atc_gmonly && !pc_isGM(sd) )
 		return;
 
-	if( pc_isGM(sd) < (lv=get_atcommand_level(atcommand_localbroadcast)) )
+	if( pc_isGM(sd) < (lv=get_atcommand_level("localbroadcast")) )
 		return;
 
 	// as the length varies depending on the command used, just block unreasonably long strings
@@ -11613,7 +11613,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd)
 			return;
 		}
 
-		lv = get_atcommand_level(atcommand_kick);
+		lv = get_atcommand_level("kick");
 		if( pc_isGM(sd) < lv )
 		{
 			clif_GM_kickack(sd, 0);
@@ -11631,7 +11631,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd)
 	break;
 	case BL_MOB:
 	{
-		lv = get_atcommand_level(atcommand_killmonster);
+		lv = get_atcommand_level("killmonster");
 		if( pc_isGM(sd) < lv )
 		{
 			clif_GM_kickack(sd, 0);
@@ -11650,7 +11650,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd)
 	case BL_NPC:
 	{
 		struct npc_data* nd = (struct npc_data *)target;
-		lv = get_atcommand_level(atcommand_unloadnpc);
+		lv = get_atcommand_level("unloadnpc");
 		if( pc_isGM(sd) < lv )
 		{
 			clif_GM_kickack(sd, 0);
@@ -11693,7 +11693,7 @@ void clif_parse_GMShift(int fd, struct map_session_data *sd)
 
 	if( battle_config.atc_gmonly && !pc_isGM(sd) )
 		return;
-	if( pc_isGM(sd) < (lv=get_atcommand_level(atcommand_jumpto)) )
+	if( pc_isGM(sd) < (lv=get_atcommand_level("goto")) )
 		return;
 
 	player_name = (char*)RFIFOP(fd,2);
@@ -11719,7 +11719,7 @@ void clif_parse_GMRemove2(int fd, struct map_session_data* sd)
 		return;
 	}
 
-	if( pc_isGM(sd) < ( lv = get_atcommand_level(atcommand_jumpto) ) )
+	if( pc_isGM(sd) < ( lv = get_atcommand_level("goto") ) )
 	{
 		return;
 	}
@@ -11752,7 +11752,7 @@ void clif_parse_GMRecall(int fd, struct map_session_data *sd)
 	if( battle_config.atc_gmonly && !pc_isGM(sd) )
 		return;
 
-	if( pc_isGM(sd) < (lv=get_atcommand_level(atcommand_recall)) )
+	if( pc_isGM(sd) < (lv=get_atcommand_level("recall")) )
 		return;
 
 	player_name = (char*)RFIFOP(fd,2);
@@ -11778,7 +11778,7 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd)
 		return;
 	}
 
-	if( pc_isGM(sd) < ( lv = get_atcommand_level(atcommand_recall) ) )
+	if( pc_isGM(sd) < ( lv = get_atcommand_level("recall") ) )
 	{
 		return;
 	}
@@ -11816,18 +11816,18 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
 	monster_item_name[NAME_LENGTH-1] = '\0';
 
 	if( mobdb_searchname(monster_item_name) ) {
-		if( pc_isGM(sd) < (level=get_atcommand_level(atcommand_monster)) )
+		if( pc_isGM(sd) < (level=get_atcommand_level("monster")) )
 			return;
 		atcommand_monster(fd, sd, "@monster", monster_item_name); // as @monster
 		{	//Log action. [Skotlex]
-			snprintf(message, sizeof(message)-1, "@spawn %s", monster_item_name);
+			snprintf(message, sizeof(message)-1, "@monster %s", monster_item_name);
 			log_atcommand(sd, level, message);
 		}
 		return;
 	}
 	if( itemdb_searchname(monster_item_name) == NULL )
 		return;
-	if( pc_isGM(sd) < (level = get_atcommand_level(atcommand_item)) )
+	if( pc_isGM(sd) < (level = get_atcommand_level("item")) )
 		return;
 	atcommand_item(fd, sd, "@item", monster_item_name); // as @item
 	{	//Log action. [Skotlex]
@@ -11844,7 +11844,7 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd)
 	if( battle_config.atc_gmonly && !pc_isGM(sd) )
 		return;
 
-	if( pc_isGM(sd) < get_atcommand_level(atcommand_hide) )
+	if( pc_isGM(sd) < get_atcommand_level("hide") )
 		return;
 
 	if( sd->sc.option & OPTION_INVISIBLE ) {
@@ -11858,7 +11858,7 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd)
 		sd->sc.option |= OPTION_INVISIBLE;
 		sd->vd.class_ = INVISIBLE_CLASS;
 		clif_displaymessage(fd, "Invisible: On.");
-		log_atcommand(sd, get_atcommand_level(atcommand_hide), "/hide");
+		log_atcommand(sd, get_atcommand_level("hide"), "/hide");
 	}
 	clif_changeoption(&sd->bl);
 }
@@ -11891,7 +11891,7 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
 	if( dstsd == NULL )
 		return;
 
-	if( (level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level(atcommand_mute) )
+	if( (level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level("mute") )
 	{
 		clif_manner_message(sd, 0);
 		clif_manner_message(dstsd, 5);
@@ -11923,7 +11923,7 @@ void clif_parse_GMRc(int fd, struct map_session_data* sd)
 	if( dstsd == NULL )
 		return;
 
-	if( pc_isGM(sd) > pc_isGM(dstsd) && pc_isGM(sd) >= get_atcommand_level(atcommand_mute) )
+	if( pc_isGM(sd) > pc_isGM(dstsd) && pc_isGM(sd) >= get_atcommand_level("mute") )
 	{
 		clif_manner_message(sd, 0);
 		clif_manner_message(dstsd, 3);

+ 1 - 1
src/map/mail.c

@@ -195,7 +195,7 @@ void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg)
 // This function only check if the mail operations are valid
 bool mail_invalid_operation(struct map_session_data *sd)
 {
-	if( !map[sd->bl.m].flag.town && pc_isGM(sd) < get_atcommand_level(atcommand_mail) )
+	if( !map[sd->bl.m].flag.town && pc_isGM(sd) < get_atcommand_level("mail") )
 	{
 		ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name);
 		return true;

+ 0 - 1
src/map/map.c

@@ -3740,7 +3740,6 @@ int do_init(int argc, char *argv[])
 
 	battle_config_read(BATTLE_CONF_FILENAME);
 	msg_config_read(MSG_CONF_NAME);
-	atcommand_config_read(ATCOMMAND_CONF_FILENAME);
 	script_config_read(SCRIPT_CONF_NAME);
 	inter_config_read(INTER_CONF_NAME);
 	log_config_read(LOG_CONF_NAME);

+ 1 - 1
src/map/pc.c

@@ -871,7 +871,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	pc_setequipindex(sd);
 
 	status_change_init(&sd->bl);
-	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level(atcommand_hide)))
+	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level("hide")))
 		sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
 	else
 		sd->status.option &= OPTION_MASK;