summaryrefslogtreecommitdiff
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
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
-rw-r--r--Changelog-Trunk.txt22
-rw-r--r--conf/Changelog.txt8
-rw-r--r--conf/atcommand_athena.conf764
-rw-r--r--conf/charcommand_athena.conf19
-rw-r--r--src/map/atcommand.c1569
-rw-r--r--src/map/atcommand.h299
-rw-r--r--src/map/charcommand.c732
-rw-r--r--src/map/charcommand.h101
-rw-r--r--src/map/clif.c85
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/pc.c2
-rw-r--r--src/map/script.c94
12 files changed, 1464 insertions, 2233 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 8bae71d38..bc418daf2 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -3,6 +3,28 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
+2007/10/29
+ * command code cleaning (refer to topic:169759) [ultramage]
+ - 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)
2007/10/28
* Minor adjustment to take into account the end of line.
* Fixed the line count in the new error message of npc_parse_function.
diff --git a/conf/Changelog.txt b/conf/Changelog.txt
index 16f89f004..b9da37380 100644
--- a/conf/Changelog.txt
+++ b/conf/Changelog.txt
@@ -1,5 +1,13 @@
Date Added
+2007/10/29
+ * Removed petid command (not needed because commands understand names)
+ * Removed *id2 commands (messy, useless and redundant)
+ * Added missing @misceffect, @feelreset and #dropall/#storeall setting
+ * AGAIN added conf entries for @whozeny, @kamic, @tonpc, @identify,
+ @adopt, @trade, @changelook, @send, @displayskill
+ * Reverted atcommand conf (alphabetically-sorted = failure) [ultramage]
+
2007/10/26
* Removed the config setting firewall_hits_on_undead setting. The code
handles this now using the delay defined in skill_unit_db. [Skotlex]
diff --git a/conf/atcommand_athena.conf b/conf/atcommand_athena.conf
index 06fec590e..92ecf2bf5 100644
--- a/conf/atcommand_athena.conf
+++ b/conf/atcommand_athena.conf
@@ -1,41 +1,41 @@
-// Athena atcommand Configuration file.
-// Translated by Peter Kieser <pfak@telus.net>
-
-// Set here the symbol that you want to use for your commands
-// Only 1 character is get (default is character_savecharacter_save'@'). You can set any character,
-// except control-character (0x00-0x1f), '%' (party chat speaking) and '/' (standard ragnarok GM commands)
-// With default character, all commands begin by a '@': <example> @revive
+//--------------------------------------------------------------
+// eAthena 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).
+// The symbol must also be different from from the GM charcommand symbol.
command_symbol: @
+// The following settings in this file use the format "<command name>: level".
+// They define the minimum GM level required to execute the associated command.
+// Adjust values as you like. Note that to activate commands for normal players,
+// (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.
-// Sets the level of the users that can use the GM commands.
-// <command name>: level
-// When battle_athena.conf has atcommand_gm_only set to no,
-// normal players (gm level 0) can use GM commands if you set 0 to the command level.
-// Max GM level is 99. If you want forbid a command to all people, set it with level 100.
-
-// Default values are set to define different GM levels like follow:
-// 0: normal player
-// -> no special advantage (only @time to know time and if at_command_gm_only is disabled)
+// Default levels were chosen so that they form the following hierarchy:
+// 0: Normal player
+// -> no commands accessible
// 1: Super player
-// -> some (very) little advantages: storage, petrename, etc...
+// -> some minor advantage: storage, petrename, etc...
// 10: Super player+
-// -> same of Super player with !go (very super player)
+// -> more powerful commands, like mobsearch and changegm
// 20: Mediator
-// -> it's a GM that only need to know people, and move to their to speak with them (they can access to any command about wisps)
+// -> GM commands for finding players and moving to them (also kicking them)
// 40: Sub-GM
-// -> This GM can help a GM, and can not create item or zeny or modify a character (can have some information commands)
+// -> GM commands for basic tasks, no significant impact on other players
// 50: Sub-GM+
-// -> This GM can change some non-important things on a character
+// -> GM commands to spawn mobs and create guilds
// 60: GM
-// -> can do almost anything (excep administration, and mass commands)
-// GM is the first level where we can modify a character with important value, create items or create zenys
+// -> almost all commands available (except administration and mass commands)
// 80: GM Chief
// -> can do anything, except administration commands
// 99: Administrator
// -> can do anything!
// 100: Disabled
-// -> Commands that aren't used. Note: You must use command level 100 to disable command. Commenting doesn't enough.
+// -> commands that will not be available to anyone
//--------------------------
@@ -45,222 +45,168 @@ command_symbol: @
//-------------------------
// 1: Super player commands
-// Enables/disables autolooting from killed mobs.
-autoloot: 1
-
-// Allows you continue vending offline.
-autotrade: 1
-at: 1
-
-// Away messsage
-away: 1
-aw: 1
+// Displays a list of @ commands available to the player.
+commands: 1
-// Change Guild Master of your Guild
-changegm: 1
+// Displays the server rates.
+rates: 1
-// Change the leader of your party.
-changeleader: 1
+// Show server uptime
+uptime: 1
-//Displays a list of @ commands available to the player.
-commands: 1
+// Shows/Hides the "there is a delay after a skill" message.
+showdelay: 1
-// Duel organizing commands
-duel: 1
-invite: 1
-accept: 1
-reject: 1
-leave: 1
+// Displays current levels and % progress.
+exp: 1
// To change your (own) email (characters protection)
// 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
-//Displays current levels and % progress.
-exp: 1
-
-//Homunculus commands for players
-homtalk: 1
-hominfo: 1
+// Show Monster info (rates, stats, drops, MVP stuff)
+mobinfo: 1
+monsterinfo: 1
+mi: 1
// Show Item info (type, price, etc)
iteminfo: 1
ii: 1
-// Displays remaining jail time
-jailtime: 1
-
-// Main chat
-main: 1
-
-// Displays the text as a normal message with the format "*name message*"
-// instead of "name : message" (Like the /me command in IRC)
-me: 1
-
-// Saves a warp point.
-memo: 1
+// Show who drops an item (mobs with highest drop rate)
+whodrops: 1
-// Show Monster info (rates, stats, drops, MVP stuff)
-mobinfo: 1
-monsterinfo: 1
-mi: 1
+// Syncs the player's position on the client with the one stored on the server.
+refresh: 1
-// Autorejecting Deals/Invites
-noask: 1
+// Give server time. (6 same commands)
+time: 1
+date: 1
+serverdate: 1
+servertime: 1
-//Create a party
-party: 1
+// Displays SVN version of the server.
+version: 1
-// Change the party item share rules.
-partyoption: 1
+// Suicide your character.
+die: 1
// Enables you to rename your pet.
petrename: 1
-// Command what the player's pet will say.
-pettalk: 1
-
-//Displays the server rates.
-rates: 1
-
-// Syncs the position of the player on the client with the one stored in the server.
-refresh: 1
-
-// Sends a request to all connected GMs (via the gm whisper system)
-request: 1
+// Organize a new party, with you as the party leader.
+party: 1
-//Shows/Hides the "there is a delay after a skill" message.
-showdelay: 1
+// Brings up your personal storage wherever you are.
+storage: 1
-//Displays/Hides Experience gained
-showexp: 1
+// Opens your mailbox.
+mail: 1
-//Displays/Hides Zeny gained
-showzeny: 1
+// Locate someone on a map, returns your coordinates if the person isn't on.
+where: 1
-// Give server time. (6 same commands)
-time: 1
-date: 1
-server_date: 1
-serverdate: 1
-server_time: 1
-servertime: 1
+// Duel organizing commands
+duel: 1
+invite: 1
+accept: 1
+reject: 1
+leave: 1
-// Show server uptime
-uptime: 1
+// Away messsage
+away: 1
+aw: 1
-// Displays SVN version of the server.
-version: 1
+// Main chat
+main: 1
-// Show who drops an item (mobs with highest drop rate)
-whodrops: 1
+// Autorejecting Deals/Invites
+noask: 1
-//---------------------------------------------------------------
-// 0: Mail System - SQL Only commands
+// Displays remaining jail time
+jailtime: 1
-// Opens mail Window.
-mail: 1
+// Homunculus commands for players
+hominfo: 1
+homstats: 1
//---------------------------
// 10: Super player+ commands
-// Suicide your character.
-die: 10
+// Displays/Hides Experience gained
+showexp: 10
-// Spawns you to set points in major cities.
+// Displays/Hides Zeny gained
+showzeny: 10
+
+// Warps you to predefined locations in major cities.
go: 10
-// Brings up your guild storage wherever you are.
-gstorage: 10
+// Enables/disables autolooting from killed mobs.
+autoloot: 10
-// Create a guild
-guild: 10
+// Allows you continue vending offline.
+autotrade: 10
+at: 10
-// Brings up your personal storage wherever you are.
-storage: 10
+// Change Guild Master of your Guild
+changegm: 10
-// Locate someone on a map, returns your coordinates if the person isn't on.
-where: 10
+// Change the leader of your party.
+changeleader: 10
-// Locates and displays the position of a certain mob on the current map.
-mobsearch: 10
+// Change the party exp- and item share rules.
+partyoption: 10
-// Changes your apperance.
-model: 10
+// Command what the player's pet will say.
+pettalk: 10
+
+// Command what the player's homunculus will say.
+homtalk: 10
+// Locates and displays the position of a certain mob on the current map.
+mobsearch: 10
// Locates and displays the position of a certain mob on your mini-map
showmobs: 10
-
// Prints out in which maps a monster normally spawns at (does not count script-invoked mobs)
whereis: 10
-// Changes your size.
-size: 10
+// Resets a Star Gladiator's marked maps
+feelreset: 10
//----------------------
// 20: Mediator commands
-// Change your appearence to other players to a mob.
-disguise: 20
-
-// Changes GM clothes color (2 same commands)
-dye: 20
-ccolor: 20
-
-// Do some visual effect on your character
-effect: 20
-
-// Changes your name to your choice temporarly.
-fakename: 20
-
-// follow a player (including warping to them)
-follow: 20
-
-// Displays the motd file to all players
-gmotd: 20
-
-// Displays helpfile in Athena base directory (2 same commands).
+// Displays helpfile in eAthena base directory (2 same commands).
help: 20
h: 20
help2: 20
h2: 20
-// Changes GM hair color (2 same commands)
-haircolor: 20
-hcolor: 20
-
-// Changes GM hair style (2 same commands)
-hairstyle: 20
-hstyle: 20
-
// Warp yourself to a person (3 same commands + /shift).
jumpto: 20
goto: 20
warpto: 20
-// Warp yourself to a person by PID (similar to above, cept you us the PID)
-jumptoid2: 20
-gotoid2: 20
-warptoid2: 20
-
-// allow other players to hit you out of pvp
-killable: 20
+// Displays the motd file to all players
+gmotd: 20
-// To get a peco to (un)ride
-mountpeco: 20
+// Follow a player (including warping to them)
+follow: 20
-// Can command what other npcs (by name) can say.
-npctalk: 20
+// Sends a request to all connected GMs (via the gm whisper system)
+request: 20
-// Sets the speed you can walk/attack at. Default is 150.
-speed: 20
+// Disconnects a user from the server (1 command + right click menu for GM "(name) force to quit").
+kick: 20
-//Restore your normal appearance.
-undisguise: 20
+// Changes your appearance.
+model: 20
-// Displays distribution of players on the server per map (% on each map which has players)
-users: 20
+// To get a peco to (un)ride (2 same commands).
+mountpeco: 20
+mount: 20
// Returns list of logged in characters with their position (2 same commands).
who: 20
@@ -286,50 +232,58 @@ whomap3: 20
// @who+@who2+who3
whogm: 20
-//--------------------
-// 40: Sub-GM commands
+// Displays a sorted list of the ammount of zeny each conected player has at hand.
+whozeny: 20
+// Change your appearence to other players to a mob.
+disguise: 20
-// Resurects yourself.
-alive: 40
+// Restore your normal appearance.
+undisguise: 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
+
+// Changes your name to your choice temporarily.
+fakename: 20
+
+// Changes your size.
+size: 20
-// Levels your character to specified level (adds to your level) (3 same commands).
-blvl: 40
-blevel: 40
-baselvl: 40
-baselevel: 40
+// Can command what other npcs (by name) can say.
+npctalk: 20
+
+//--------------------
+// 40: Sub-GM commands
// Broadcast to the whole server. Using (1 command + /nb, /b).
broadcast: 40
-// Changes the sex of yourself
-changesex: 40
+// Broadcast to the map you are on (1 command + /lb, /nlb).
+localbroadcast: 40
-// Deletes floor items in your range of sight
-cleanmap: 40
+// Broadcast (with or without name)
+kami: 40
+// Same as kami but with blue color
+kamib: 40
+// Same as kami but you can choose the color (uses different packet)
+kamic: 40
-// drop all your items
-dropall: 40
+// Enables GvG on a map (2 same commands).
+gvgon: 40
+gpvpon: 40
-//Hatches an egg
-hatch: 60
+// Turns GvG (Guild vs. Guild) off on a map (2 same commands).
+gvgoff: 40
+gpvpoff: 40
-// Heals yourself to full HP/SP.
+// Modifies your HP/SP.
heal: 40
-// GM Hide (enables you to be invisible to characters, and most monsters) (1 command + /hide).
+// GM Hide (total invisibility to characters and monsters) (1 command + /hide).
hide: 40
-//Homunculus commands for gms
-homlvup: 40
-homevolution: 40
-makehomun: 40
-homfriendly: 40
-homhungry: 40
-
-// Deletes all your items.
-itemreset: 40
-
// Changes your job to one you specify (2 same commands).
job: 40
jobchange: 40
@@ -337,53 +291,15 @@ jobchange: 40
// Enables you to to jump randomly on a map (that you are already on).
jump: 40
-// Broadcast (with or without name).
-kami: 40
-kamib: 40
-
-// Disconnects a user from the server (1 command + right click menu for GM "(name) force to quit").
-kick: 40
-
-// Disconnects a user from the server using their PID.
-kickid2: 40
-
-// Kill all monsters in map (without drops)
-killmonster2: 40
-
// Warps you to your last save point (2 same commands).
load: 40
return: 40
-// Broadcast to the map you are on (1 command + /lb, /nlb).
-localbroadcast: 40
-
-// To send specified character in jails
-jail: 40
-
-// To discharge a prisoner (2 same commands)
-unjail: 40
-discharge: 40
-
-// Timed jailing
-jailfor: 40
-
-// Raises your job level (3 same commands).
-jlvl: 40
-jlevel: 40
-joblvl: 40
-joblevel: 40
-
-// Creates yourself a pet egg, have to use Pet ID.
-makeegg: 60
+// Warps you to a specific npc
+tonpc: 40
-// Warp yourself to a certain map, at (x,y) coordinates (2 same commands). /mm or /mapmove
-mapmove: 40
-rura: 40
-warp: 40
-
-// Marriage skills
-marry: 40
-divorce: 40
+// Saves a warp point.
+memo: 40
// Set your character display options. (Visual effects of your character)
option: 40
@@ -394,67 +310,106 @@ petfriendly: 40
// Sets hunger level of your pet.
pethungry: 40
+// Turns PvP (Person vs. Person) off on a map.
+pvpoff: 40
+
+// Enables PvP on a map.
+pvpon: 40
+
// Permanently adds/removes a quest skill
questskill: 40
lostskill: 40
+// Sets the speed you can walk/attack at. Default is 150.
+speed: 40
+
+// Summons spirit spheres around you.
+spiritball: 40
+
+// Warp yourself to a certain map, at (x,y) coordinates (2 same commands).
+mapmove: 40 // (also /mm or /mapmove)
+rura: 40
+warp: 40
+
+// Changes GM clothes color (2 same commands)
+dye: 40
+ccolor: 40
+
+// Changes GM hair style (2 same commands)
+hairstyle: 40
+hstyle: 40
+
+// Changes GM hair color (2 same commands)
+haircolor: 40
+hcolor: 40
+
+// Deletes all your items.
+itemreset: 40
+
// Does a skill/stat reset.
reset: 40
+// Displays distribution of players on the server per map (% on each map which has players)
+users: 40
+
+// Deletes floor items in your range of sight
+cleanmap: 40
+
+// Kill all monsters in map (without drops)
+killmonster2: 40
+
// Sets your spawn point (aka save point).
save: 40
-// look up a skill by name
-skillid: 40
+// Do some visual effect on your character
+effect: 40
-// What skills are required to get this skill
-skilltree: 40
+// Do some visual effect on your character (misceffect)
+misceffect: 40
-// Play a Sound!
-sound: 40
+// GM's magnifier
+identify: 40
-// Enables spirit sphere balls.
-spiritball: 40
+// Drop all your items
+dropall: 40
-// Change Status of your character
-str: 40
-agi: 40
-vit: 40
-int: 40
-dex: 40
-luk: 40
+// Store all your items
+storeall: 40
-// Gets all skills (4 same commands)
-allskill: 40
-allskills: 40
-skillall: 40
-skillsall: 40
+// Allow other players to hit you out of PvP
+killable: 40
-// sets GM stats to maximum (4 same commands)
-statall: 40
-statsall: 40
-allstats: 40
-allstat: 40
+// Look up a skill by name
+skillid: 40
-// Gives you job points.
-stpoint: 40
+// Use a skill by id
+useskill: 40
-// Gives you skill points of desired amount.
-skpoint: 40
+// What skills are required to get this skill
+skilltree: 40
-// store all your items
-storeall: 40
+// Marriage commands
+marry: 40
+divorce: 40
-// use a skill by id
-useskill: 40
+// Adopt a novice into a family
+adopt: 40
+
+// Play a Sound!
+sound: 40
//---------------------
// 50: Sub-GM+ commands
-// Spawns a monster, and a certain amount (3 same commands + /monster).
-spawn: 50
+// Creates a new guild, with you as the guildmaster.
+guild: 50
+
+// Brings up your guild storage wherever you are.
+gstorage: 50
+
+// Spawns a monster, and a certain amount (2 same commands + /monster).
monster: 50
-summon: 50
+spawn: 50
// Spawns a smaller sized version of a monster.
monstersmall: 50
@@ -462,6 +417,9 @@ monstersmall: 50
// Spawns a larger sized version of a monster.
monsterbig: 50
+// Spawns mobs that treat you as their master (they disappear after some time)
+summon: 50
+
// It will spawn a supportive clone of the given player.
clone: 50
@@ -475,40 +433,43 @@ evilclone: 50
//----------------
// 60: GM commands
-// Create a static warp portal that lasts until the next reboot
-addwarp: 60
-
-// To block definitively a player (only administrator can unblock the account) (2 same commands)
-block: 60
-charblock: 60
+// Starts Guild Wars
+agitstart: 60
-// To unblock a player (2 same commands)
-unblock: 60
-charunblock: 60
+// Ends Guild Wars
+agitend: 60
-// To ban a player for a limited time (only administrator can unban the account) (4 same commands)
-ban: 60
-banish: 60
-charban: 60
-charbanish: 60
+// Resurects yourself.
+alive: 60
+
+// Levels your character to specified level (adds to your level) (7 same commands).
+blvl: 60
+lvup: 60
+blevel: 60
+baselvl: 60
+baselvup: 60
+baselevel: 60
+baselvlup: 60
+
+// Raises your job level (6 same commands).
+jlvl: 60
+jlevel: 60
+joblvl: 60
+joblvup: 60
+joblevel: 60
+joblvlup: 60
-// To unban a player (4 same commands)
-unban: 60
-unbanish: 60
-charunban: 60
-charunbanish: 60
+// Changes the sex of yourself
+changesex: 60
// Levels your guild to specified level (2 same commands).
+glvl: 60
+glevel: 60
+guildlvl: 60
guildlvup: 60
+guildlevel: 60
guildlvlup: 60
-// Warps all online character of a guild to you. (at least one member of that guild must be on.)
-guildrecall: 60
-
-// 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
-
// Find an itemID based on item name
idsearch: 60
@@ -521,85 +482,142 @@ item2: 60
// Kill another character without hitting them.
kill: 60
-// Same as above, cept uses PID.
-killid2: 60
-
// Kill all monsters in map (with drops)
killmonster: 60
-// Enable hitting a player even when not in pvp
-killer: 60
+// Creates yourself a pet egg.
+makeegg: 60
-// Mute a player (prevents talking, usage of skills and commands)
-mute: 80
+// Hatches an egg
+hatch: 60
-// Warps all online character of a party to you. (at least one party member must be online.)
-partyrecall: 60
+// Instantly kills player whose name is entered and deals insane damage to everything around
+nuke: 60
-//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
+// Enable hitting a player even when not in PvP
+killer: 60
// Creates weapon of desired element.
produce: 60
-// Turns PVP (Person v. Person) off on a map.
-pvpoff: 60
-
-// Enables PVP on a map.
-pvpon: 60
-
// Warps a character to you (1 command + /recall).
recall: 60
-// Warps a character to you using their PID.
-recallid2: 60
-
// Refines all weapons in your items list.
refine: 60
// Will repair all broken items in inventory.
repairall: 60
-// Revives a character using their PID.
-reviveid2: 60
+// Change Status of your character
+str: 60
+agi: 60
+vit: 60
+int: 60
+dex: 60
+luk: 60
-// Unmute a player
-unmute: 60
+// Gets all skills (4 same commands)
+allskill: 60
+allskills: 60
+skillall: 60
+skillsall: 60
+
+// Sets GM stats to maximum (4 same commands)
+statall: 60
+statsall: 60
+allstats: 60
+allstat: 60
+
+// Gives you job points.
+stpoint: 60
+
+// Gives you skill points of desired amount.
+skpoint: 60
+
+// Warps all online character of a guild to you. (at least one member of that guild must be on.)
+guildrecall: 60
+
+// Warps all online character of a party to you. (at least one party member must be online.)
+partyrecall: 60
+
+// 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
+
+// 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
// Gives you money (zeny) of desired amount.
zeny: 60
-//----------------------
-// 80: GM Chief commands
+// To block definitively a player (2 same commands)
+block: 60
+charblock: 60
-// Starts Guild Wars
-agitstart: 60
+// To unblock a player (2 same commands)
+unblock: 60
+charunblock: 60
-// Ends Guild Wars
-agitend: 60
+// To ban a player for a limited time (4 same commands)
+ban: 60
+banish: 60
+charban: 60
+charbanish: 60
+
+// To unban a player (4 same commands)
+unban: 60
+unbanish: 60
+charunban: 60
+charunbanish: 60
+
+// To send specified character in jails
+jail: 60
+
+// To discharge a prisoner (2 same commands)
+unjail: 60
+discharge: 60
+
+// Timed jailing
+jailfor: 60
+
+// Create a static warp portal that lasts until the next reboot
+addwarp: 60
+
+// Open a trade window with any player
+trade: 60
+
+// Changes the player's appearance (headgear)
+changelook: 60
+
+// Homunculus commands for GMs
+hlvl: 60
+hlevel: 60
+homlvl: 60
+homlvup: 60
+homlevel: 60
+homevolve: 60
+homevolution: 60
+makehomun: 60
+homfriendly: 60
+homhungry: 60
+
+// Re-calculates stats, as if the homun was sent back to level 1 and re-leveled
+homshuffle: 60
+
+//----------------------
+// 80: GM Chief commands
// Set the map you are on to day.
day: 80
-// [Un]Disguise All Players (admin command)
-disguiseall: 99
-undisguiseall: 99
-
// Kills everyone on the server.
doom: 80
// Kills everyone on the map you are on.
doommap: 80
-// Enables GVG on a map (2 same commands).
-gvgon: 40
-gpvpon: 40
-
-// Turns GVG (Guild v. Guild) off on a map (2 same commands).
-gvgoff: 40
-gpvpoff: 40
-
// Set the map you are currently on to night.
night: 80
@@ -633,19 +651,14 @@ skillon: 80
// turn skills off for a map
skilloff: 80
-//---------------------------
-// 99: Administrator commands
-
-// Changes the required GM level of an @ command
-// (effect lasts until restart or command reload)
-adjcmdlvl: 99
+// Mute a player (prevents talking, usage of skills and commands)
+mute: 80
-// Changes the GM level of another character
-// (lasts until reboot, or gm list reload)
-adjgmlvl: 99
+// Unmute a player
+unmute: 80
-// Give information about terrain/area (debug function)
-gat: 99
+//---------------------------
+// 99: Administrator commands
// Disconnect all users from the server
kickall: 99
@@ -653,6 +666,12 @@ kickall: 99
// Closes Map-Server
mapexit: 99
+// Used for testing packet sends from the client (debug function)
+send: 99
+
+// Give information about terrain/area (debug function)
+gat: 99
+
// Displays a status change without really applying it (debug function)
displaystatus: 99
@@ -665,10 +684,6 @@ mapinfo: 99
// Set Map Flags (WIP)
mapflag: 99
-// Mutes every player on screen (admin command)
-mutearea: 99
-stfu: 99
-
// Re-load item database (admin command)
reloaditemdb: 99
@@ -684,7 +699,10 @@ reloadscript: 99
// Re-load GM level (admin command)
reloadgmdb: 99
-// Refresh online status of players - SQL Only
+// Change a battle_config flag without rebooting server
+setbattleflag: 99
+
+// Refresh only status of players - SQL Only
refreshonline: 99
// Re-load gm command config (admin command)
@@ -704,11 +722,21 @@ reloadpcdb: 99
// Re-load the Message of the Day (admin command)
reloadmotd: 99
-// Used for testing packet sends from the client (debug function)
-send: 99
+// Changes the GM level of another character
+// (lasts until reboot, or gm list reload)
+adjgmlvl: 99
-// change a battle_config flag without rebooting server
-setbattleflag: 99
+// Changes the required GM level of an @ command
+// (effect lasts until restart or command reload)
+adjcmdlvl: 99
+
+// [Un]Disguise All Players (admin command)
+disguiseall: 99
+undisguiseall: 99
+
+// Mutes every player on screen (admin command)
+mutearea: 99
+stfu: 99
// Makes you immune to attacks (monsters/players/skills cannot target/hit you, admin command)
monsterignore: 99
@@ -737,8 +765,6 @@ clearweather: 99
//---------------------------------------------------------------
// 100: Disabled commands
gm: 100
-nuke: 100
-
//---------------------
// OTHER: not a command
diff --git a/conf/charcommand_athena.conf b/conf/charcommand_athena.conf
index acd89779a..20e0c2427 100644
--- a/conf/charcommand_athena.conf
+++ b/conf/charcommand_athena.conf
@@ -1,10 +1,12 @@
-// Athena charcommand Configuration file.
-// Translated by Peter Kieser <pfak@telus.net>
+//--------------------------------------------------------------
+// eAthena charcommand 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),
+// You can set any one character except control-characters (0x00-0x1f),
// '%', '$' (party/guild chat speaking) and '/' (standard client commands).
-// The symbol must be different from from the standard GM command symbol.
+// The symbol must also be different from from the GM atcommand symbol.
command_symbol: #
@@ -21,6 +23,9 @@ command_symbol: #
//----------------------
// 20: Mediator commands
+// Displays helpfile in eAthena base directory
+help: 20
+
//--------------------
// 40: Sub-GM commands
@@ -120,6 +125,12 @@ delitem: 60
disguise: 60
undisguise: 60
+// Drop a players possessions on the ground
+dropall: 60
+
+// Put a players possessions in storage
+storeall: 60
+
// Resets another character's designated maps
feelreset: 60
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;
+}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index d2532fda7..c8823b38e 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -4,297 +4,42 @@
#ifndef _ATCOMMAND_H_
#define _ATCOMMAND_H_
+//#include "map.h"
+struct map_session_data;
+
//This is the distance at which @autoloot works,
//if the item drops farther from the player than this,
//it will not be autolooted. [Skotlex]
//Note: The range is unlimited unless this define is set.
//#define AUTOLOOT_DISTANCE AREA_SIZE
-//#include "map.h"
-struct map_session_data;
-
-enum AtCommandType {
- AtCommand_None = -1,
- AtCommand_Broadcast = 0,
- AtCommand_LocalBroadcast,
- AtCommand_MapMove,
- AtCommand_ResetState,
- AtCommand_RuraP,
- AtCommand_Rura,
- AtCommand_Warp,
- AtCommand_Where,
- AtCommand_JumpTo,
- AtCommand_Jump,
- AtCommand_Who,
- AtCommand_Who2,
- AtCommand_Who3,
- AtCommand_WhoMap,
- AtCommand_WhoMap2,
- AtCommand_WhoMap3,
- AtCommand_WhoGM,
- AtCommand_Save,
- AtCommand_Load,
- AtCommand_Speed,
- AtCommand_CharSpeed,
- AtCommand_Storage,
- AtCommand_GuildStorage,
- AtCommand_Option,
- AtCommand_Hide,
- AtCommand_JobChange,
- AtCommand_JobChange2,
- AtCommand_JobChange3,
- AtCommand_Die,
- AtCommand_Kill,
- AtCommand_Alive,
- AtCommand_Kami,
- AtCommand_KamiB,
- AtCommand_KamiC, //LuzZza
- AtCommand_Heal,
- AtCommand_Item,
- AtCommand_Item2,
- AtCommand_ItemReset,
- AtCommand_BaseLevelUp,
- AtCommand_JobLevelUp,
- AtCommand_H,
- AtCommand_Help,
- AtCommand_H2,
- AtCommand_Help2,
- AtCommand_GM,
- AtCommand_PvPOff,
- AtCommand_PvPOn,
- AtCommand_GvGOff,
- AtCommand_GvGOn,
- AtCommand_Model,
- AtCommand_Go,
- AtCommand_Spawn,
- AtCommand_MonsterSmall,
- AtCommand_MonsterBig,
- AtCommand_KillMonster,
- AtCommand_KillMonster2,
- AtCommand_Refine,
- AtCommand_Produce,
- AtCommand_Memo,
- AtCommand_GAT,
- AtCommand_DisplayStatus,
- AtCommand_StatusPoint,
- AtCommand_SkillPoint,
- AtCommand_Zeny,
- AtCommand_Param,
- AtCommand_Strength,
- AtCommand_Agility,
- AtCommand_Vitality,
- AtCommand_Intelligence,
- AtCommand_Dexterity,
- AtCommand_Luck,
- AtCommand_GuildLevelUp,
- AtCommand_MakeEgg,
- AtCommand_PetFriendly,
- AtCommand_PetHungry,
- AtCommand_PetRename,
- AtCommand_Recall,
- AtCommand_Night,
- AtCommand_Day,
- AtCommand_Doom,
- AtCommand_DoomMap,
- AtCommand_Raise,
- AtCommand_RaiseMap,
- AtCommand_Kick,
- AtCommand_KickAll,
- AtCommand_AllSkill,
- AtCommand_QuestSkill,
- AtCommand_LostSkill,
- AtCommand_SpiritBall,
- AtCommand_Party,
- AtCommand_Guild,
- AtCommand_AgitStart,
- AtCommand_AgitEnd,
- AtCommand_MapExit,
- AtCommand_IDSearch,
- AtCommand_RecallAll,
- AtCommand_ReloadItemDB,
- AtCommand_ReloadMobDB,
- AtCommand_ReloadSkillDB,
- AtCommand_ReloadScript,
- AtCommand_ReloadGMDB,
- AtCommand_ReloadAtcommand,
- AtCommand_ReloadBattleConf,
- AtCommand_ReloadStatusDB,
- AtCommand_ReloadPcDB,
- AtCommand_ReloadMOTD, // [Valaris]
- AtCommand_MapInfo,
- AtCommand_Dye,
- AtCommand_Hstyle,
- AtCommand_Hcolor,
- AtCommand_StatAll,
- AtCommand_CharBlock, // by Yor
- AtCommand_CharBan, // by Yor
- AtCommand_CharUnBlock, // by Yor
- AtCommand_CharUnBan, // by Yor
- AtCommand_MountPeco, // by Valaris
- AtCommand_GuildSpy, // [Syrus22]
- AtCommand_PartySpy, // [Syrus22]
- AtCommand_RepairAll, // [Valaris]
- AtCommand_GuildRecall, // by Yor
- AtCommand_PartyRecall, // by Yor
- AtCommand_Nuke, // [Valaris]
- AtCommand_Shownpc,
- AtCommand_Hidenpc,
- AtCommand_Loadnpc,
- AtCommand_Unloadnpc,
- AtCommand_ServerTime, // by Yor
- AtCommand_Jail, // by Yor
- AtCommand_UnJail, // by Yor
- AtCommand_JailFor, // Meruru
- AtCommand_JailTime, // Coltaro
- AtCommand_Disguise, // [Valaris]
- AtCommand_UnDisguise, // by Yor
- AtCommand_EMail, // by Yor
- AtCommand_Hatch,
- AtCommand_Effect, // by Apple
- AtCommand_AddWarp, // by MouseJstr
- AtCommand_Follow, // by MouseJstr
- AtCommand_SkillOn, // by MouseJstr
- AtCommand_SkillOff, // by MouseJstr
- AtCommand_Killer, // by MouseJstr
- AtCommand_NpcMove, // by MouseJstr
- AtCommand_Killable, // by MouseJstr
- AtCommand_Dropall, // by MouseJstr
- AtCommand_Storeall, // by MouseJstr
- AtCommand_Skillid, // by MouseJstr
- AtCommand_Useskill, // by MouseJstr
- AtCommand_DisplaySkill,
- AtCommand_Summon,
- AtCommand_Rain,
- AtCommand_Snow,
- AtCommand_Sakura,
- AtCommand_Clouds,
- AtCommand_Clouds2, // [Valaris]
- AtCommand_Fog,
- AtCommand_Fireworks,
- AtCommand_Leaves,
- AtCommand_AdjGmLvl, // MouseJstr
- AtCommand_AdjCmdLvl, // MouseJstr
- AtCommand_Trade, // MouseJstr
- AtCommand_Send,
- AtCommand_SetBattleFlag,
- AtCommand_UnMute,
- AtCommand_Clearweather, // by Dexity
- AtCommand_UpTime, // by MC Cameri
- AtCommand_ChangeSex, // by MC Cameri
- AtCommand_Mute, // [celest]
- AtCommand_WhoZeny, // [Valaris] <-- LOL...(MC Cameri) worth it.
- AtCommand_Refresh, // by MC Cameri
- AtCommand_PetId, // by MC Cameri
- AtCommand_Identify, // by MC Cameri
- AtCommand_Gmotd, // Added by MC Cameri, created by davidsiaw
- AtCommand_MiscEffect, // by MC Cameri
- AtCommand_MobSearch,
- AtCommand_CleanMap,
- AtCommand_NpcTalk,
- AtCommand_PetTalk,
- AtCommand_Users,
- AtCommand_SkillTree, // by MouseJstr
- AtCommand_Marry, // by MouseJstr
- AtCommand_Divorce, // by MouseJstr
- AtCommand_Me, //added by massdriller, code by lordalfa
- AtCommand_DMStart, // by MouseJstr
- AtCommand_DMTick, // by MouseJstr
- AtCommand_JumpToId2, // by Dino9021
- AtCommand_RecallId2, // by Dino9021
- AtCommand_KickId2, // by Dino9021
- AtCommand_ReviveId2, // by Dino9021
- AtCommand_KillId2, // by Dino9021
- AtCommand_Sound,
- AtCommand_UndisguiseAll,
- AtCommand_DisguiseAll,
- AtCommand_ChangeLook,
- AtCommand_AutoLoot, //by Upa-Kun
- AtCommand_MobInfo, //by Lupus
- AtCommand_Exp, // by Skotlex
- AtCommand_Adopt, // by Veider
- AtCommand_Version, // by Ancyker
- AtCommand_MuteArea, // MouseJstr
- AtCommand_Rates, // MouseJstr
- AtCommand_ItemInfo, // Lupus
- AtCommand_WhoDrops, // Skotlex
- AtCommand_WhereIs, // Skotlex
- AtCommand_MapFlag, // Lupus
- AtCommand_MonsterIgnore, // [Valaris]
- AtCommand_FakeName, // [Valaris]
- AtCommand_Size, // [Valaris]
- AtCommand_ShowDelay,
- AtCommand_ShowExp,
- AtCommand_ShowZeny,
- AtCommand_AutoTrade,//durf
- AtCommand_ChangeGM,//durf
- AtCommand_ChangeLeader,
- AtCommand_PartyOption,
- AtCommand_Invite, // By LuzZza
- AtCommand_Duel, // By LuzZza
- AtCommand_Leave, // By LuzZza
- AtCommand_Accept, // By LuzZza
- AtCommand_Reject, // By LuzZza
- AtCommand_Away, // LuzZza
- AtCommand_Main, // LuzZza
- AtCommand_Clone, // [Valaris]
- AtCommand_ToNPC, // LuzZza
- AtCommand_Commands, // [Skotlex]
- AtCommand_NoAsk, // [LuzZza]
- AtCommand_Request, // [Skotlex]
- AtCommand_HomLevel, //[orn]
- AtCommand_HomEvolution, //[orn]
- AtCommand_MakeHomun, //[orn]
- AtCommand_HomFriendly, //[orn]
- AtCommand_HomHungry, //[orn]
- AtCommand_HomTalk, //[orn]
- AtCommand_HomInfo, //[Toms]
- AtCommand_HomStats, //[Skotlex]
- AtCommand_HomShuffle, //[Skotlex]
- AtCommand_ShowMobs, //KarLaeda
- AtCommand_FeelReset, //[HiddenDragon]
- AtCommand_HappyHappyJoyJoy,
- // SQL-only commands start
-#ifndef TXT_ONLY
- AtCommand_Mail, // [Mail System]
- AtCommand_RefreshOnline, // [Valaris]
- // SQL-only commands end
-#endif
- // No more commands after this line
- AtCommand_Unknown,
- AtCommand_MAX
-};
-
-typedef enum AtCommandType AtCommandType;
-
-typedef struct AtCommandInfo {
- AtCommandType type;
- const char* command;
- int level;
- int (*proc)(const int fd, struct map_session_data* sd, const char* command, const char* message);
-} AtCommandInfo;
-
-AtCommandType is_atcommand(const int fd, struct map_session_data* sd, const char* message);
-AtCommandType is_atcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl);
-AtCommandType atcommand(struct map_session_data *sd, const int level, const char* message, AtCommandInfo* info);
-int get_atcommand_level(const AtCommandType type);
+extern char atcommand_symbol;
+typedef int (*AtCommandFunc)(const int fd, struct map_session_data* sd, const char* command, const char* message);
-char* msg_txt(int msg_number); // [Yor]
+bool is_atcommand(const int fd, struct map_session_data* sd, const char* message);
+bool is_atcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl);
+int get_atcommand_level(const AtCommandFunc func);
void do_init_atcommand(void);
void do_final_atcommand(void);
+int atcommand_config_read(const char *cfgName);
-int atcommand_item(const int fd, struct map_session_data* sd,const char* command, const char* message); // [Valaris]
-int atcommand_rura(const int fd, struct map_session_data* sd,const char* command, const char* message); // [Yor]
-int atcommand_jumpto(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Yor]
-int atcommand_recall(const int fd, struct map_session_data* sd, const char* command, const char* message); // [Yor]
+int atcommand_item(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);
int atcommand_monster(const int fd, struct map_session_data* sd, const char* command, const char* message);
+int atcommand_jumpto(const int fd, struct map_session_data* sd, const char* command, const char* message);
+int atcommand_recall(const int fd, struct map_session_data* sd, const char* command, const char* message);
+int atcommand_hide(const int fd, struct map_session_data* sd, const char* command, const char* message);
+int atcommand_mute(const int fd, struct map_session_data* sd, const char* command, const char* message);
+int atcommand_kick(const int fd, struct map_session_data* sd, const char* command, const char* message);
+int atcommand_broadcast(const int fd, struct map_session_data* sd,const char* command, const char* message);
+int atcommand_localbroadcast(const int fd, struct map_session_data* sd,const char* command, const char* message);
+int atcommand_reset(const int fd, struct map_session_data* sd,const char* command, const char* message);
-int atcommand_config_read(const char *cfgName);
-int msg_config_read(const char *cfgName);
-void do_final_msg(void);
-
-extern char atcommand_symbol;
#define MAX_MSG 1000
extern char* msg_table[MAX_MSG];
+char* msg_txt(int msg_number);
+int msg_config_read(const char* cfgName);
+void do_final_msg(void);
#endif /* _ATCOMMAND_H_ */
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index c2689b8e8..d5746d379 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -1,32 +1,31 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#include "../common/cbasetypes.h"
-#include "../common/socket.h"
#include "../common/timer.h"
#include "../common/nullpo.h"
#include "../common/showmsg.h"
+#include "../common/strlib.h"
#include "../common/utils.h"
-#include "log.h"
+#include "atcommand.h" // msg_txt()
+#include "charcommand.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"
#include "skill.h"
#include "mob.h"
+#include "npc.h"
#include "pet.h"
-#include "mercenary.h" //[orn]
-#include "battle.h"
-#include "charcommand.h"
-#include "atcommand.h"
+#include "mercenary.h"
#include "party.h"
#include "guild.h"
#include "script.h"
-#include "npc.h"
#include "trade.h"
#include "unit.h"
@@ -40,379 +39,16 @@ char charcommand_symbol = '#';
extern char *msg_table[1000]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
#define CCMD_FUNC(x) int charcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
-CCMD_FUNC(jobchange);
-CCMD_FUNC(petrename);
-CCMD_FUNC(petfriendly);
-CCMD_FUNC(stats);
-CCMD_FUNC(option);
-CCMD_FUNC(save);
-CCMD_FUNC(stats_all);
-CCMD_FUNC(reset);
-CCMD_FUNC(spiritball);
-CCMD_FUNC(itemlist);
-CCMD_FUNC(effect);
-CCMD_FUNC(storagelist);
-CCMD_FUNC(item);
-CCMD_FUNC(warp);
-CCMD_FUNC(zeny);
-CCMD_FUNC(fakename);
-CCMD_FUNC(baselevel);
-CCMD_FUNC(joblevel);
-CCMD_FUNC(questskill);
-CCMD_FUNC(lostskill);
-CCMD_FUNC(skreset);
-CCMD_FUNC(streset);
-CCMD_FUNC(model);
-CCMD_FUNC(stpoint);
-CCMD_FUNC(skpoint);
-CCMD_FUNC(changesex);
-CCMD_FUNC(feelreset);
-CCMD_FUNC(help);
-CCMD_FUNC(load);
-CCMD_FUNC(speed);
-CCMD_FUNC(storage);
-CCMD_FUNC(guildstorage);
-CCMD_FUNC(hide);
-CCMD_FUNC(alive);
-CCMD_FUNC(heal);
-CCMD_FUNC(item2);
-CCMD_FUNC(itemreset);
-CCMD_FUNC(refine);
-CCMD_FUNC(produce);
-CCMD_FUNC(param);
-CCMD_FUNC(guildlevelup);
-CCMD_FUNC(hatch);
-CCMD_FUNC(pethungry);
-CCMD_FUNC(allskill);
-CCMD_FUNC(dye);
-CCMD_FUNC(hair_style);
-CCMD_FUNC(hair_color);
-CCMD_FUNC(allstats);
-CCMD_FUNC(mount_peco);
-CCMD_FUNC(delitem);
-CCMD_FUNC(jailtime);
-CCMD_FUNC(disguise);
-CCMD_FUNC(undisguise);
-CCMD_FUNC(cart_list);
-CCMD_FUNC(killer);
-CCMD_FUNC(killable);
-CCMD_FUNC(refresh);
-CCMD_FUNC(exp);
-CCMD_FUNC(monsterignore);
-CCMD_FUNC(size);
-CCMD_FUNC(homlevel);
-CCMD_FUNC(homevolution);
-CCMD_FUNC(homfriendly);
-CCMD_FUNC(homhungry);
-CCMD_FUNC(hominfo);
-
-/*==========================================
- *CharCommandInfo charcommand_info[]構造体の定義
- *------------------------------------------*/
-
-// First char of commands is configured in charcommand_athena.conf. Leave # in this list for default value.
-// to set default level, read charcommand_athena.conf first please.
-static CharCommandInfo charcommand_info[] = {
- { CharCommandJobChange, "#job", 60, charcommand_jobchange },
- { CharCommandJobChange, "#jobchange", 60, charcommand_jobchange },
- { CharCommandPetRename, "#petrename", 50, charcommand_petrename },
- { CharCommandPetFriendly, "#petfriendly", 50, charcommand_petfriendly },
- { CharCommandStats, "#stats", 40, charcommand_stats },
- { CharCommandOption, "#option", 60, charcommand_option },
- { CharCommandReset, "#reset", 60, charcommand_reset },
- { CharCommandSave, "#save", 60, charcommand_save },
- { CharCommandSpiritball, "#spiritball", 40, charcommand_spiritball },
- { CharCommandItemList, "#itemlist", 40, charcommand_itemlist },
- { CharCommandEffect, "#effect", 40, charcommand_effect },
- { CharCommandStorageList, "#storagelist", 40, charcommand_storagelist },
- { CharCommandItem, "#item", 60, charcommand_item },
- { CharCommandWarp, "#warp", 60, charcommand_warp },
- { CharCommandWarp, "#rura", 60, charcommand_warp },
- { CharCommandWarp, "#rura+", 60, charcommand_warp },
- { CharCommandZeny, "#zeny", 60, charcommand_zeny },
- { CharCommandFakeName, "#fakename", 50, charcommand_fakename},
- { CharCommandBaseLevel, "#baselvl", 60, charcommand_baselevel},
- { CharCommandBaseLevel, "#baselevel", 60, charcommand_baselevel},
- { CharCommandBaseLevel, "#blvl", 60, charcommand_baselevel},
- { CharCommandBaseLevel, "#blevel", 60, charcommand_baselevel},
- { CharCommandJobLevel, "#joblvl", 60, charcommand_joblevel},
- { CharCommandJobLevel, "#joblevel", 60, charcommand_joblevel},
- { CharCommandJobLevel, "#jlvl", 60, charcommand_joblevel},
- { CharCommandJobLevel, "#jlevel", 60, charcommand_joblevel},
- { CharCommandQuestSkill, "#questskill", 60, charcommand_questskill },
- { CharCommandLostSkill, "#lostskill", 60, charcommand_lostskill },
- { CharCommandSkReset, "#skreset", 60, charcommand_skreset },
- { CharCommandStReset, "#streset", 60, charcommand_streset },
- { CharCommandModel, "#model", 50, charcommand_model },
- { CharCommandSKPoint, "#skpoint", 60, charcommand_skpoint },
- { CharCommandSTPoint, "#stpoint", 60, charcommand_stpoint },
- { CharCommandChangeSex, "#changesex", 60, charcommand_changesex },
- { CharCommandFeelReset, "#feelreset", 60, charcommand_feelreset },
- { CharCommandHelp, "#help", 20, charcommand_help },
- { CharCommandLoad, "#load", 60, charcommand_load },
- { CharCommandSpeed, "#speed", 60, charcommand_speed },
- { CharCommandStorage, "#storage", 60, charcommand_storage },
- { CharCommandGStorage, "#gstorage", 60, charcommand_guildstorage },
- { CharCommandHide, "#hide", 60, charcommand_hide },
- { CharCommandAlive, "#alive", 60, charcommand_alive },
- { CharCommandHeal, "#heal", 60, charcommand_heal },
- { CharCommandItem2, "#item2", 60, charcommand_item2 },
- { CharCommandItemReset, "#itemreset", 60, charcommand_itemreset },
- { CharCommandRefine, "#refine", 60, charcommand_refine },
- { CharCommandProduce, "#produce", 60, charcommand_produce },
- { CharCommandStrength, "#str", 60, charcommand_param },
- { CharCommandAgility, "#agi", 60, charcommand_param },
- { CharCommandVitality, "#vit", 60, charcommand_param },
- { CharCommandIntelligence, "#int", 60, charcommand_param },
- { CharCommandDexterity, "#dex", 60, charcommand_param },
- { CharCommandLuck, "#luk", 60, charcommand_param },
- { CharCommandGuildLevelUp, "#glvl", 60, charcommand_guildlevelup },
- { CharCommandGuildLevelUp, "#glevel", 60, charcommand_guildlevelup },
- { CharCommandGuildLevelUp, "#guildlvl", 60, charcommand_guildlevelup },
- { CharCommandGuildLevelUp, "#guildlevel", 60, charcommand_guildlevelup },
- { CharCommandHatch, "#hatch", 50, charcommand_hatch },
- { CharCommandPetHungry, "#pethungry", 60, charcommand_pethungry },
- { CharCommandAllSkill, "#allskill", 60, charcommand_allskill },
- { CharCommandAllSkill, "#allskills", 60, charcommand_allskill },
- { CharCommandAllSkill, "#skillall", 60, charcommand_allskill },
- { CharCommandAllSkill, "#skillsall", 60, charcommand_allskill },
- { CharCommandDye, "#dye", 50, charcommand_dye },
- { CharCommandHStyle, "#hairstyle", 50, charcommand_hair_style },
- { CharCommandHStyle, "#hstyle", 50, charcommand_hair_style },
- { CharCommandHColor, "#haircolor", 50, charcommand_hair_color },
- { CharCommandHColor, "#hcolor", 50, charcommand_hair_color },
- { CharCommandAllStats, "#allstat", 60, charcommand_allstats },
- { CharCommandAllStats, "#allstats", 60, charcommand_allstats },
- { CharCommandAllStats, "#statall", 60, charcommand_allstats },
- { CharCommandAllStats, "#statsall", 60, charcommand_allstats },
- { CharCommandMountPeco, "#mount", 50, charcommand_mount_peco },
- { CharCommandMountPeco, "#mountpeco", 50, charcommand_mount_peco },
- { CharCommandDelItem, "#delitem", 60, charcommand_delitem },
- { CharCommandJailTime, "#jailtime", 40, charcommand_jailtime },
- { CharCommandDisguie, "#disguise", 60, charcommand_disguise },
- { CharCommandUnDisguise, "#undisguise", 60, charcommand_undisguise },
- { CharCommandCartList, "#cartlist", 40, charcommand_cart_list },
- { CharCommandKiller, "#killer", 60, charcommand_killer },
- { CharCommandKillable, "#killable", 60, charcommand_killable },
- { CharCommandRefresh, "#refresh", 40, charcommand_refresh },
- { CharCommandExp, "#exp", 1, charcommand_exp },
- { CharCommandMonsterIgnore, "#monsterignore", 60, charcommand_monsterignore },
- { CharCommandSize, "#size", 50, charcommand_size },
- { CharCommandHomLevel, "#hlvl", 60, charcommand_homlevel },
- { CharCommandHomLevel, "#hlevel", 60, charcommand_homlevel },
- { CharCommandHomLevel, "#homlvl", 60, charcommand_homlevel },
- { CharCommandHomLevel, "#homlevel", 60, charcommand_homlevel },
- { CharCommandHomEvolve, "#homevolve", 60, charcommand_homevolution },
- { CharCommandHomEvolve, "#homevolvution", 60, charcommand_homevolution },
- { CharCommandHomFriendly, "#homfriendly", 60, charcommand_homfriendly },
- { CharCommandHomHungry, "#homhungry", 60, charcommand_homhungry },
- { CharCommandHomInfo, "#hominfo", 40, charcommand_hominfo },
-
-// add new commands before this line
- { CharCommand_Unknown, NULL, 1, NULL }
-};
-
-int get_charcommand_level(const CharCommandType type)
-{
- int i;
-
- for (i = 0; charcommand_info[i].type != CharCommand_None; i++)
- if (charcommand_info[i].type == type)
- return charcommand_info[i].level;
-
- return 100; // 100: command can not be used
-}
-
-CharCommandType is_charcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl)
-{
- CharCommandInfo info;
- CharCommandType type;
-
- memset(&info, 0, sizeof(info));
-
- type = charcommand(sd, gmlvl, str, &info);
- if (type != CharCommand_None) {
- char command[100];
- char output[200];
- const char* p = str;
-
- if (map[sd->bl.m].nocommand &&
- gmlvl < map[sd->bl.m].nocommand)
- { //Command not allowed on this map.
- sprintf(output, msg_txt(143));
- clif_displaymessage(fd, output);
- return AtCommand_None;
- }
-
- memset(command, '\0', sizeof(command));
- memset(output, '\0', sizeof(output));
- while (*p && !ISSPACE(*p))
- p++;
- if (p - str >= sizeof(command)) // too long
- return CharCommand_Unknown;
- strncpy(command, str, p - str);
- while (ISSPACE(*p))
- p++;
-
- if (type == CharCommand_Unknown || info.proc == NULL) {
- snprintf(output, sizeof(output),msg_txt(153), command); // %s is Unknown Command.
- clif_displaymessage(fd, output);
- } else {
- if (info.proc(fd, sd, command, p) != 0) {
- // Command can not be executed
- snprintf(output, sizeof(output), msg_txt(154), command); // %s failed.
- clif_displaymessage(fd, output);
- }
- }
-
- return info.type;
- }
-
- return CharCommand_None;
-}
-
-/*==========================================
- *is_charcommand @コマンドに存在するかどうか確認する
- *------------------------------------------*/
-CharCommandType is_charcommand(const int fd, struct map_session_data* sd, const char* message)
-{
- const char* str = message;
- int s_flag = 0;
-
- nullpo_retr(CharCommand_None, sd);
-
- if (sd->sc.count && sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCOMMAND)
- return CharCommand_None;
-
- if (!message || !*message)
- return CharCommand_None;
-
- // temporary compatibility layer for previous implementation
- if( *message != charcommand_symbol )
- {
- str += strlen(sd->status.name);
- while (*str && (ISSPACE(*str) || (s_flag == 0 && *str == ':'))) {
- if (*str == ':')
- s_flag = 1;
- str++;
- }
- }
-
- if (!*str)
- return CharCommand_None;
-
- if(str[0] == '|' && strlen(str) >= 4 && str[3] == charcommand_symbol)
- str += 3; // skip 10/11-langtype's codepage indicator, if detected
-
- return is_charcommand_sub(fd,sd,str,pc_isGM(sd));
-}
-
-/*==========================================
- *
- *------------------------------------------*/
-CharCommandType charcommand(struct map_session_data* sd, const int level, const char* message, CharCommandInfo* info)
-{
- char* p = (char *)message;
-
- if (!info)
- return CharCommand_None;
- if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd)
- return CharCommand_None;
- if (!p || !*p) {
- ShowError("char command message is empty\n");
- return CharCommand_None;
- }
-
- if (*p == charcommand_symbol) { // check first char
- char command[101];
- int i = 0;
- memset(info, 0, sizeof(CharCommandInfo));
- sscanf(p, "%100s", command);
- command[100] = '\0';
-
- while (charcommand_info[i].type != CharCommand_Unknown) {
- if (strcmpi(command+1, charcommand_info[i].command+1) == 0 && level >= charcommand_info[i].level) {
- p[0] = charcommand_info[i].command[0]; // set correct first symbol for after.
- break;
- }
- i++;
- }
- if (charcommand_info[i].type == CharCommand_Unknown) {
- // doesn't return Unknown if player is normal player (display the text, not display: unknown command)
- if (level == 0)
- return CharCommand_None;
- else
- return CharCommand_Unknown;
- } else if((log_config.gm) && (charcommand_info[i].level >= log_config.gm)) {
- log_atcommand(sd, message);
- }
- memcpy(info, &charcommand_info[i], sizeof charcommand_info[i]);
- } else {
- return CharCommand_None;
- }
-
- return info->type;
-}
-
-
-/*==========================================
- *
- *------------------------------------------*/
-static CharCommandInfo* get_charcommandinfo_byname(const char* name)
-{
- int i;
-
- for (i = 0; charcommand_info[i].type != CharCommand_Unknown; i++)
- if (strcmpi(charcommand_info[i].command + 1, name) == 0)
- return &charcommand_info[i];
-
- return NULL;
-}
-
-/*==========================================
- *
- *------------------------------------------*/
-int charcommand_config_read(const char *cfgName)
-{
- char line[1024], w1[1024], w2[1024];
- CharCommandInfo* p;
- FILE* fp;
-
- if ((fp = fopen(cfgName, "r")) == NULL) {
- ShowError("CharCommands configuration file not found: %s\n", cfgName);
- return 1;
- }
-
- while (fgets(line, sizeof(line), fp))
- {
- if (line[0] == '/' && line[1] == '/')
- continue;
+typedef struct CharCommandInfo {
+ const char* command;
+ int level;
+ CharCommandFunc func;
+} CharCommandInfo;
- if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
- continue;
- p = get_charcommandinfo_byname(w1);
- if (p != NULL) {
- p->level = atoi(w2);
- if (p->level > 100)
- p->level = 100;
- else if (p->level < 0)
- p->level = 0;
- }
+static CharCommandInfo* get_charcommandinfo_byname(const char* name);
+static CharCommandInfo* get_charcommandinfo_byfunc(const CharCommandFunc func);
- if (strcmpi(w1, "import") == 0)
- charcommand_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 speaking
- w2[0] != '@') // symbol of atcommand
- charcommand_symbol = w2[0];
- }
- fclose(fp);
-
- return 0;
-}
/*==========================================
* 対象キャラクターを転職させる upper指定で転生や養子も可能
@@ -1558,9 +1194,9 @@ int charcommand_lostskill(const int fd, struct map_session_data* sd, const char*
}
if (skill_id < 0 && skill_id >= MAX_SKILL) {
- clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
- return -1;
- }
+ clif_displaymessage(fd, msg_txt(198)); // This skill number doesn't exist.
+ return -1;
+ }
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;
@@ -3498,6 +3134,78 @@ int charcommand_killable(const int fd, struct map_session_data* sd, const char*
}
/*==========================================
+ * Drop all of the target's possessions on the ground
+ *------------------------------------------*/
+int charcommand_dropall(const int fd, struct map_session_data* sd, const char* command, const char* message)
+{
+ int i;
+ struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message)
+ return -1;
+ if((pl_sd=map_nick2sd((char *) message)) == NULL)
+ return -1;
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if (pl_sd->status.inventory[i].amount) {
+ if(pl_sd->status.inventory[i].equip != 0)
+ pc_unequipitem(pl_sd, i, 3);
+ pc_dropitem(pl_sd, i, pl_sd->status.inventory[i].amount);
+ }
+ }
+
+ clif_displaymessage(pl_sd->fd, "All items dropped");
+ clif_displaymessage(fd, "It is done");
+
+ return 0;
+}
+
+/*==========================================
+ * Put all of the target's possessions into storage
+ *------------------------------------------*/
+int charcommand_storeall(const int fd, struct map_session_data* sd, const char* command, const char* message)
+{
+ int i;
+ struct map_session_data *pl_sd = NULL;
+ nullpo_retr(-1, sd);
+
+ if (!message || !*message)
+ return -1;
+ if((pl_sd=map_nick2sd((char *) message)) == NULL)
+ return -1;
+
+ if (pl_sd->state.storage_flag != 1)
+ { //Open storage.
+ switch (storage_storageopen(pl_sd)) {
+ case 2: //Try again
+ clif_displaymessage(fd, "Had to open the characters storage window...");
+ clif_displaymessage(fd, "run this command again..");
+ return 0;
+ case 1: //Failure
+ clif_displaymessage(fd, "The character currently can't use the storage.");
+ return 1;
+ }
+ }
+
+ for (i = 0; i < MAX_INVENTORY; i++) {
+ if (pl_sd->status.inventory[i].amount) {
+ if(pl_sd->status.inventory[i].equip != 0)
+ pc_unequipitem(pl_sd, i, 3);
+ storage_storageadd(pl_sd, i, sd->status.inventory[i].amount);
+ }
+ }
+ storage_storageclose(pl_sd);
+
+ clif_displaymessage(pl_sd->fd, "Everything you own has been put away for safe keeping.");
+ clif_displaymessage(pl_sd->fd, "go to the nearest kafka to retrieve it..");
+ clif_displaymessage(pl_sd->fd, " -- the management");
+
+ clif_displaymessage(fd, "It is done");
+
+ return 0;
+}
+
+/*==========================================
* Refreshes target [HiddenDragon]
*------------------------------------------*/
int charcommand_refresh(const int fd, struct map_session_data* sd, const char* command, const char* message)
@@ -3734,7 +3442,7 @@ int charcommand_homevolution(const int fd, struct map_session_data* sd, const ch
clif_displaymessage(fd, "Please, enter a player name (usage: #homevolution <player>).");
return -1;
}
-
+
if ( (pl_sd = map_nick2sd(character)) == NULL )
{
clif_displaymessage(fd, msg_txt(3)); // Character not found.
@@ -3746,7 +3454,7 @@ int charcommand_homevolution(const int fd, struct map_session_data* sd, const ch
clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
return -1;
}
-
+
if ( !merc_is_hom_active(pl_sd->hd) ) {
clif_displaymessage(fd, "Target player does not have a homunculus.");
return -1;
@@ -3961,3 +3669,261 @@ int charcommand_hominfo(const int fd, struct map_session_data* sd, const char* c
return 0;
}
+
+
+/*==========================================
+ * charcommand_info[] structure definition
+ *------------------------------------------*/
+
+CharCommandInfo charcommand_info[] = {
+ { "job", 60, charcommand_jobchange },
+ { "jobchange", 60, charcommand_jobchange },
+ { "petrename", 50, charcommand_petrename },
+ { "petfriendly", 50, charcommand_petfriendly },
+ { "stats", 40, charcommand_stats },
+ { "option", 60, charcommand_option },
+ { "reset", 60, charcommand_reset },
+ { "save", 60, charcommand_save },
+ { "spiritball", 40, charcommand_spiritball },
+ { "itemlist", 40, charcommand_itemlist },
+ { "effect", 40, charcommand_effect },
+ { "storagelist", 40, charcommand_storagelist },
+ { "item", 60, charcommand_item },
+ { "warp", 60, charcommand_warp },
+ { "rura", 60, charcommand_warp },
+ { "rura+", 60, charcommand_warp },
+ { "zeny", 60, charcommand_zeny },
+ { "fakename", 50, charcommand_fakename },
+ { "baselvl", 60, charcommand_baselevel },
+ { "baselevel", 60, charcommand_baselevel },
+ { "blvl", 60, charcommand_baselevel },
+ { "blevel", 60, charcommand_baselevel },
+ { "joblvl", 60, charcommand_joblevel },
+ { "joblevel", 60, charcommand_joblevel },
+ { "jlvl", 60, charcommand_joblevel },
+ { "jlevel", 60, charcommand_joblevel },
+ { "questskill", 60, charcommand_questskill },
+ { "lostskill", 60, charcommand_lostskill },
+ { "skreset", 60, charcommand_skreset },
+ { "streset", 60, charcommand_streset },
+ { "model", 50, charcommand_model },
+ { "skpoint", 60, charcommand_skpoint },
+ { "stpoint", 60, charcommand_stpoint },
+ { "changesex", 60, charcommand_changesex },
+ { "feelreset", 60, charcommand_feelreset },
+ { "help", 20, charcommand_help },
+ { "load", 60, charcommand_load },
+ { "speed", 60, charcommand_speed },
+ { "storage", 60, charcommand_storage },
+ { "gstorage", 60, charcommand_guildstorage },
+ { "hide", 60, charcommand_hide },
+ { "alive", 60, charcommand_alive },
+ { "revive", 60, charcommand_alive },
+ { "heal", 60, charcommand_heal },
+ { "item2", 60, charcommand_item2 },
+ { "itemreset", 60, charcommand_itemreset },
+ { "refine", 60, charcommand_refine },
+ { "produce", 60, charcommand_produce },
+ { "str", 60, charcommand_param },
+ { "agi", 60, charcommand_param },
+ { "vit", 60, charcommand_param },
+ { "int", 60, charcommand_param },
+ { "dex", 60, charcommand_param },
+ { "luk", 60, charcommand_param },
+ { "glvl", 60, charcommand_guildlevelup },
+ { "glevel", 60, charcommand_guildlevelup },
+ { "guildlvl", 60, charcommand_guildlevelup },
+ { "guildlevel", 60, charcommand_guildlevelup },
+ { "hatch", 50, charcommand_hatch },
+ { "pethungry", 60, charcommand_pethungry },
+ { "allskill", 60, charcommand_allskill },
+ { "allskills", 60, charcommand_allskill },
+ { "skillall", 60, charcommand_allskill },
+ { "skillsall", 60, charcommand_allskill },
+ { "dye", 50, charcommand_dye },
+ { "hairstyle", 50, charcommand_hair_style },
+ { "hstyle", 50, charcommand_hair_style },
+ { "haircolor", 50, charcommand_hair_color },
+ { "hcolor", 50, charcommand_hair_color },
+ { "allstat", 60, charcommand_allstats },
+ { "allstats", 60, charcommand_allstats },
+ { "statall", 60, charcommand_allstats },
+ { "statsall", 60, charcommand_allstats },
+ { "mount", 50, charcommand_mount_peco },
+ { "mountpeco", 50, charcommand_mount_peco },
+ { "delitem", 60, charcommand_delitem },
+ { "jailtime", 40, charcommand_jailtime },
+ { "disguise", 60, charcommand_disguise },
+ { "undisguise", 60, charcommand_undisguise },
+ { "cartlist", 40, charcommand_cart_list },
+ { "killer", 60, charcommand_killer },
+ { "killable", 60, charcommand_killable },
+ { "dropall", 60, charcommand_dropall },
+ { "storeall", 60, charcommand_storeall },
+ { "refresh", 40, charcommand_refresh },
+ { "exp", 1, charcommand_exp },
+ { "monsterignore", 60, charcommand_monsterignore },
+ { "size", 50, charcommand_size },
+ { "hlvl", 60, charcommand_homlevel },
+ { "hlevel", 60, charcommand_homlevel },
+ { "homlvl", 60, charcommand_homlevel },
+ { "homlevel", 60, charcommand_homlevel },
+ { "homevolve", 60, charcommand_homevolution },
+ { "homevolution", 60, charcommand_homevolution },
+ { "homfriendly", 60, charcommand_homfriendly },
+ { "homhungry", 60, charcommand_homhungry },
+ { "hominfo", 40, charcommand_hominfo },
+};
+
+
+/*==========================================
+ * Command lookup functions
+ *------------------------------------------*/
+static CharCommandInfo* get_charcommandinfo_byname(const char* name)
+{
+ int i;
+ if( *name == charcommand_symbol ) name++; // for backwards compatibility
+ ARR_FIND( 0, ARRAYLENGTH(charcommand_info), i, strcmpi(charcommand_info[i].command, name) == 0 );
+ return ( i != ARRAYLENGTH(charcommand_info) ) ? &charcommand_info[i] : NULL;
+}
+
+static CharCommandInfo* get_charcommandinfo_byfunc(const CharCommandFunc func)
+{
+ int i;
+ ARR_FIND( 0, ARRAYLENGTH(charcommand_info), i, charcommand_info[i].func == func );
+ return ( i != ARRAYLENGTH(charcommand_info) ) ? &charcommand_info[i] : NULL;
+}
+
+
+/*==========================================
+ * Retrieve the command's required gm level
+ *------------------------------------------*/
+int get_charcommand_level(const CharCommandFunc func)
+{
+ CharCommandInfo* info = get_charcommandinfo_byfunc(func);
+ return ( info != NULL ) ? info->level : 100; // 100: command can not be used
+}
+
+
+/// Executes a char-command.
+/// To be called by internal server code (bypasses various restrictions).
+bool is_charcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl)
+{
+ CharCommandInfo* info;
+ char command[100];
+ char args[100];
+ char output[200];
+
+ if( !str || !*str )
+ return false;
+
+ if( *str != charcommand_symbol ) // check first char
+ return false;
+
+ if( sscanf(str, "%99s %99[^\n]", command, args) < 2 )
+ args[0] = '\0';
+
+ info = get_charcommandinfo_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 a char-command.
+/// To be used by player-invoked code (restrictions will be applied)
+bool is_charcommand(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;
+
+ if( sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCOMMAND )
+ return true;
+
+ 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] == charcommand_symbol )
+ message += 3;
+
+ return is_atcommand_sub(fd,sd,message,gmlvl);
+}
+
+
+/*==========================================
+ *
+ *------------------------------------------*/
+int charcommand_config_read(const char* cfgName)
+{
+ char line[1024], w1[1024], w2[1024];
+ CharCommandInfo* p;
+ FILE* fp;
+
+ if( (fp = fopen(cfgName, "r")) == NULL )
+ {
+ ShowError("CharCommand 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_charcommandinfo_byname(w1);
+ if( p != NULL )
+ {
+ p->level = atoi(w2);
+ p->level = cap_value(p->level, 0, 100);
+ }
+ else
+ if( strcmpi(w1, "import") == 0 )
+ charcommand_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 atcommand
+ charcommand_symbol = w2[0];
+ else
+ ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ }
+ fclose(fp);
+
+ return 0;
+}
diff --git a/src/map/charcommand.h b/src/map/charcommand.h
index 754989d4b..25a27b732 100644
--- a/src/map/charcommand.h
+++ b/src/map/charcommand.h
@@ -4,101 +4,16 @@
#ifndef _CHARCOMMAND_H_
#define _CHARCOMMAND_H_
-enum CharCommandType {
- CharCommand_None = -1,
- CharCommandJobChange,
- CharCommandPetRename,
- CharCommandPetFriendly,
- CharCommandReset,
- CharCommandStats,
- CharCommandOption,
- CharCommandSave,
- CharCommandSpiritball,
- CharCommandItemList,
- CharCommandEffect,
- CharCommandStorageList,
- CharCommandItem, // by MC Cameri
- CharCommandWarp,
- CharCommandZeny,
- CharCommandFakeName,
- CharCommandBaseLevel,
- CharCommandJobLevel,
- CharCommandQuestSkill,
- CharCommandLostSkill,
- CharCommandSkReset,
- CharCommandStReset,
- CharCommandModel,
- CharCommandSKPoint,
- CharCommandSTPoint,
- CharCommandChangeSex,
- CharCommandFeelReset, // Komurka
- CharCommandHelp,
- CharCommandLoad,
- CharCommandSpeed,
- CharCommandStorage,
- CharCommandGStorage,
- CharCommandHide,
- CharCommandAlive,
- CharCommandHeal,
- CharCommandItem2,
- CharCommandItemReset,
- CharCommandRefine,
- CharCommandProduce,
- CharCommandStrength,
- CharCommandAgility,
- CharCommandVitality,
- CharCommandIntelligence,
- CharCommandDexterity,
- CharCommandLuck,
- CharCommandGuildLevelUp,
- CharCommandHatch,
- CharCommandPetHungry,
- CharCommandAllSkill,
- CharCommandDye,
- CharCommandHStyle,
- CharCommandHColor,
- CharCommandAllStats,
- CharCommandMountPeco,
- CharCommandDelItem,
- CharCommandJailTime,
- CharCommandDisguie,
- CharCommandUnDisguise,
- CharCommandCartList,
- CharCommandKiller,
- CharCommandKillable,
- CharCommandRefresh,
- CharCommandExp,
- CharCommandMonsterIgnore,
- CharCommandSize,
- CharCommandHomLevel,
- CharCommandHomEvolve,
- CharCommandHomFriendly,
- CharCommandHomHungry,
- CharCommandHomInfo,
- // No more commands after this line
- CharCommand_Unknown,
- CharCommand_MAX
-};
+//#include "map.h"
+struct map_session_data;
-typedef enum CharCommandType CharCommandType;
-typedef struct CharCommandInfo {
- CharCommandType type;
- const char* command;
- int level;
- int (*proc)(const int, struct map_session_data*,
- const char* command, const char* message);
-} CharCommandInfo;
-
-CharCommandType
-is_charcommand(const int fd, struct map_session_data* sd, const char* message);
-CharCommandType
-is_charcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl);
+extern char charcommand_symbol;
+typedef int (*CharCommandFunc)(const int fd, struct map_session_data* sd, const char* command, const char* message);
-CharCommandType charcommand(
- struct map_session_data* sd, const int level, const char* message, CharCommandInfo* info);
-int get_charcommand_level(const CharCommandType type);
+bool is_charcommand(const int fd, struct map_session_data* sd, const char* message);
+bool is_charcommand_sub(const int fd, struct map_session_data* sd, const char* str, int gmlvl);
+int get_charcommand_level(const CharCommandFunc func);
-int charcommand_config_read(const char *cfgName);
-extern char charcommand_symbol;
+int charcommand_config_read(const char* cfgName);
#endif /* _CHARCOMMAND_H_ */
diff --git a/src/map/clif.c b/src/map/clif.c
index c020d5760..8f86ddc6b 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -8248,7 +8248,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
return;
- if( is_atcommand(fd, sd, message) != AtCommand_None || is_charcommand(fd, sd, message) != CharCommand_None )
+ if( is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
if( sd->sc.data[SC_BERSERK].timer != -1 || (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) )
@@ -8331,14 +8331,14 @@ 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(atcommand_mapmove))
return;
map_name = (char*)RFIFOP(fd,2);
map_name[MAP_NAME_LENGTH_EXT-1]='\0';
sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20));
- atcommand_rura(fd, sd, "@rura", output);
- if(log_config.gm && get_atcommand_level(AtCommand_MapMove) >= log_config.gm)
+ atcommand_mapmove(fd, sd, "@mapmove", output);
+ if( log_config.gm && get_atcommand_level(atcommand_mapmove) >= log_config.gm )
{
sprintf(message, "/mm %s", output);
log_atcommand(sd, message);
@@ -8559,7 +8559,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
if( !clif_process_message(sd, 1, &target, &namelen, &message, &messagelen) )
return;
- if (is_atcommand(fd, sd, message) != AtCommand_None || is_charcommand(fd, sd, message) != CharCommand_None )
+ if (is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
if (sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT))
@@ -8694,9 +8694,9 @@ void clif_parse_GMmessage(int fd, struct map_session_data* sd)
unsigned int len = RFIFOW(fd,2)-4;
int lv;
- if (battle_config.atc_gmonly && !pc_isGM(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(atcommand_broadcast)) )
return;
// as the length varies depending on the command used, just block unreasonably long strings
@@ -9674,17 +9674,18 @@ void clif_parse_SolveCharName(int fd, struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_ResetChar(int fd, struct map_session_data *sd)
{
- if (battle_config.atc_gmonly && !pc_isGM(sd))
+ if( battle_config.atc_gmonly && !pc_isGM(sd) )
return;
- if (pc_isGM(sd) < get_atcommand_level(AtCommand_ResetState))
+
+ if( pc_isGM(sd) < get_atcommand_level(atcommand_reset) )
return;
- if (RFIFOW(fd,2))
+ if( RFIFOW(fd,2) )
pc_resetskill(sd,1);
else
pc_resetstate(sd);
- if(log_config.gm && get_atcommand_level(AtCommand_ResetState >= log_config.gm))
+ if( log_config.gm && get_atcommand_level(atcommand_reset) >= log_config.gm )
log_atcommand(sd, RFIFOW(fd,2) ? "/resetskill" : "/resetstate");
}
@@ -9698,9 +9699,10 @@ void clif_parse_LGMmessage(int fd, struct map_session_data* sd)
unsigned int len = RFIFOW(fd,2)-4;
int lv;
- if (battle_config.atc_gmonly && !pc_isGM(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(atcommand_localbroadcast)) )
return;
// as the length varies depending on the command used, just block unreasonably long strings
@@ -9708,7 +9710,7 @@ void clif_parse_LGMmessage(int fd, struct map_session_data* sd)
clif_GMmessage(&sd->bl, msg, len, 1);
- if(log_config.gm && lv >= log_config.gm) {
+ if( log_config.gm && lv >= log_config.gm ) {
char logmsg[CHAT_SIZE_MAX+5];
sprintf(logmsg, "/lb %s", msg);
log_atcommand(sd, logmsg);
@@ -9963,13 +9965,13 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
return;
- if (is_charcommand(fd, sd, message) != CharCommand_None || is_atcommand(fd, sd, message) != AtCommand_None)
+ if( is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
- if (sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT))
+ if( sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) )
return;
- if (battle_config.min_chat_delay)
+ if( battle_config.min_chat_delay )
{ //[Skotlex]
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
return;
@@ -10236,13 +10238,13 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
if( !clif_process_message(sd, 0, &name, &namelen, &message, &messagelen) )
return;
- if (is_charcommand(fd, sd, message) != CharCommand_None || is_atcommand(fd, sd, message) != AtCommand_None)
+ if( is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
- if (sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT))
+ if( sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) )
return;
- if (battle_config.min_chat_delay)
+ if( battle_config.min_chat_delay )
{ //[Skotlex]
if (DIFF_TICK(sd->cantalk_tick, gettick()) > 0)
return;
@@ -10379,10 +10381,10 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd)
struct block_list *target;
int tid,lv;
- if (battle_config.atc_gmonly && !pc_isGM(sd))
+ if( battle_config.atc_gmonly && !pc_isGM(sd) )
return;
- if (pc_isGM(sd) < (lv=get_atcommand_level(AtCommand_Kick)))
+ if( pc_isGM(sd) < (lv=get_atcommand_level(atcommand_kick)) )
return;
tid = RFIFOL(fd,2);
@@ -10429,15 +10431,15 @@ void clif_parse_Shift(int fd, struct map_session_data *sd)
char *player_name;
int lv;
- if (battle_config.atc_gmonly && !pc_isGM(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(atcommand_jumpto)) )
return;
player_name = (char*)RFIFOP(fd,2);
player_name[NAME_LENGTH-1] = '\0';
atcommand_jumpto(fd, sd, "@jumpto", player_name); // as @jumpto
- if(log_config.gm && lv >= log_config.gm) {
+ if( log_config.gm && lv >= log_config.gm ) {
char message[NAME_LENGTH+7];
sprintf(message, "/shift %s", player_name);
log_atcommand(sd, message);
@@ -10453,16 +10455,16 @@ void clif_parse_Recall(int fd, struct map_session_data *sd)
char *player_name;
int lv;
- if (battle_config.atc_gmonly && !pc_isGM(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(atcommand_recall)) )
return;
player_name = (char*)RFIFOP(fd,2);
player_name[NAME_LENGTH-1] = '\0';
atcommand_recall(fd, sd, "@recall", player_name); // as @recall
- if(log_config.gm && lv >= log_config.gm) {
+ if( log_config.gm && lv >= log_config.gm ) {
char message[NAME_LENGTH+8];
sprintf(message, "/recall %s", player_name);
log_atcommand(sd, message);
@@ -10479,29 +10481,29 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
char message[NAME_LENGTH+10]; //For logging.
int level;
- if (battle_config.atc_gmonly && !pc_isGM(sd))
+ if( battle_config.atc_gmonly && !pc_isGM(sd) )
return;
monster_item_name = (char*)RFIFOP(fd,2);
monster_item_name[NAME_LENGTH-1] = '\0';
- if (mobdb_searchname(monster_item_name)) {
- if (pc_isGM(sd) < (level=get_atcommand_level(AtCommand_Spawn)))
+ if( mobdb_searchname(monster_item_name) ) {
+ if( pc_isGM(sd) < (level=get_atcommand_level(atcommand_monster)) )
return;
- atcommand_monster(fd, sd, "@spawn", monster_item_name); // as @spawn
- if(log_config.gm && level >= log_config.gm)
+ atcommand_monster(fd, sd, "@monster", monster_item_name); // as @monster
+ if( log_config.gm && level >= log_config.gm )
{ //Log action. [Skotlex]
snprintf(message, sizeof(message)-1, "@spawn %s", monster_item_name);
log_atcommand(sd, message);
}
return;
}
- if (itemdb_searchname(monster_item_name) == NULL)
+ 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(atcommand_item)) )
return;
atcommand_item(fd, sd, "@item", monster_item_name); // as @item
- if(log_config.gm && level >= log_config.gm)
+ if( log_config.gm && level >= log_config.gm )
{ //Log action. [Skotlex]
sprintf(message, "@item %s", monster_item_name);
log_atcommand(sd, message);
@@ -10513,12 +10515,13 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_GMHide(int fd, struct map_session_data *sd)
{
- if (battle_config.atc_gmonly && !pc_isGM(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(atcommand_hide) )
return;
- if (sd->sc.option & OPTION_INVISIBLE) {
+ if( sd->sc.option & OPTION_INVISIBLE ) {
sd->sc.option &= ~OPTION_INVISIBLE;
if (sd->disguise)
status_set_viewdata(&sd->bl, sd->disguise);
@@ -10529,7 +10532,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.");
- if(log_config.gm && get_atcommand_level(AtCommand_Hide) >= log_config.gm)
+ if( log_config.gm && get_atcommand_level(atcommand_hide) >= log_config.gm )
log_atcommand(sd, "/hide");
}
clif_changeoption(&sd->bl);
@@ -10560,7 +10563,7 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
return;
if (
- ((level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level(AtCommand_Mute))
+ ((level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level(atcommand_mute))
|| (type == 2 && !level))
{
clif_GM_silence(sd, dstsd, ((type == 2) ? 1 : type));
diff --git a/src/map/map.c b/src/map/map.c
index fd50012e4..cc09132f5 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2691,7 +2691,7 @@ int parse_console(char* buf)
ShowInfo("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y);
if( n == 5 && strcmpi("admin",type) == 0 ){
- if( is_atcommand_sub(sd.fd,&sd,command,99) == AtCommand_None )
+ if( !is_atcommand_sub(sd.fd,&sd,command,99) )
printf("Console: not atcommand\n");
} else if( n == 2 && strcmpi("server",type) == 0 ){
if( strcmpi("shutdown",command) == 0 ||
diff --git a/src/map/pc.c b/src/map/pc.c
index 2b218586d..5db1502c1 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -666,7 +666,7 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
pc_checkitem(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(atcommand_hide)))
sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
else
sd->status.option &= OPTION_MASK;
diff --git a/src/map/script.c b/src/map/script.c
index 8b2464be4..28cb7ed7e 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -11006,80 +11006,82 @@ BUILDIN_FUNC(nude)
*------------------------------------------*/
BUILDIN_FUNC(atcommand)
{
- TBL_PC *sd=NULL;
- const char *cmd;
+ TBL_PC dummy_sd;
+ TBL_PC* sd;
+ int fd;
+ const char* cmd;
cmd = script_getstr(st,2);
- if (st->rid)
- sd = script_rid2sd(st);
- if (sd){
- if(cmd[0] != atcommand_symbol){
- cmd += strlen(sd->status.name);
- while(*cmd != atcommand_symbol && *cmd != 0)
- cmd++;
- }
- is_atcommand_sub(sd->fd, sd, cmd, 99);
+ if (st->rid) {
+ sd = script_rid2sd(st);
+ fd = sd->fd;
} else { //Use a dummy character.
- TBL_PC dummy_sd;
- struct block_list *bl = NULL;
+ sd = &dummy_sd;
+ fd = 0;
+
memset(&dummy_sd, 0, sizeof(TBL_PC));
- if (st->oid) bl = map_id2bl(st->oid);
- if (bl) {
+ if (st->oid)
+ {
+ struct block_list* bl = map_id2bl(st->oid);
memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
if (bl->type == BL_NPC)
- strncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
+ safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
}
- if(cmd[0] != atcommand_symbol){
- cmd += strlen(dummy_sd.status.name);
- while(*cmd != atcommand_symbol && *cmd != 0)
- cmd++;
- }
- is_atcommand_sub(0, &dummy_sd, cmd, 99);
}
+ // compatibility with previous implementation (deprecated!)
+ if(cmd[0] != atcommand_symbol)
+ {
+ cmd += strlen(sd->status.name);
+ while(*cmd != atcommand_symbol && *cmd != 0)
+ cmd++;
+ }
+
+ is_atcommand_sub(fd, sd, cmd, 99);
+
return 0;
}
BUILDIN_FUNC(charcommand)
{
- TBL_PC *sd=NULL;
- const char *cmd;
-
+ TBL_PC dummy_sd;
+ TBL_PC* sd;
+ int fd;
+ const char* cmd;
+
cmd = script_getstr(st,2);
- if (st->rid)
+ if (st->rid) {
sd = script_rid2sd(st);
-
- if (sd){
- if(cmd[0] != charcommand_symbol){
- cmd += strlen(sd->status.name);
- while(*cmd != charcommand_symbol && *cmd != 0)
- cmd++;
- }
- is_charcommand_sub(sd->fd, sd, cmd,99);
+ fd = sd->fd;
} else { //Use a dummy character.
- TBL_PC dummy_sd;
- struct block_list *bl = NULL;
+ sd = &dummy_sd;
+ fd = 0;
+
memset(&dummy_sd, 0, sizeof(TBL_PC));
- if (st->oid) bl = map_id2bl(st->oid);
- if (bl) {
+ if (st->oid)
+ {
+ struct block_list* bl = map_id2bl(st->oid);
memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
if (bl->type == BL_NPC)
- strncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
+ safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
}
- if(cmd[0] != charcommand_symbol){
- cmd += strlen(dummy_sd.status.name);
- while(*cmd != charcommand_symbol && *cmd != 0)
- cmd++;
- }
- is_charcommand_sub(0, &dummy_sd, cmd, 99);
}
+ // compatibility with previous implementation (deprecated!)
+ if(cmd[0] != charcommand_symbol)
+ {
+ cmd += strlen(sd->status.name);
+ while(*cmd != charcommand_symbol && *cmd != 0)
+ cmd++;
+ }
+
+ is_charcommand_sub(fd, sd, cmd, 99);
+
return 0;
}
-
/*==========================================
* Displays a message for the player only (like system messages like "you got an apple" )
*------------------------------------------*/