Atrinik Server 2.5
commands/commands.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00033 CommArray_s Commands[] =
00034 {
00035     {"stay",           command_stay,           1.0f, 0},
00036     {"n",              command_north,          1.0f, 0},
00037     {"e",              command_east,           1.0f, 0},
00038     {"s",              command_south,          1.0f, 0},
00039     {"w",              command_west,           1.0f, 0},
00040     {"ne",             command_northeast,      1.0f, 0},
00041     {"se",             command_southeast,      1.0f, 0},
00042     {"sw",             command_southwest,      1.0f, 0},
00043     {"nw",             command_northwest,      1.0f, 0},
00044     {"apply",          command_apply,          1.0f, 0},
00045     {"target",         command_target,         0.1f, 0},
00046     {"combat",         command_combat,         0.1f, 0},
00047     {"pray",           command_praying,        0.2f, 0},
00048     {"run",            command_run,            1.0f, 0},
00049     {"run_stop",       command_run_stop,       0.1f, 0},
00050     {"cast",           command_cast_spell,     0.0f, 0},
00051     {"say",            command_say,            1.0f, 0},
00052     {"shout",          command_shout,          1.0f, 0},
00053     {"tell",           command_tell,           1.0f, 0},
00054     {"t_tell",         command_t_tell,         1.0f, 0},
00055     {"who",            command_who,            1.0f, 0},
00056     {"mapinfo",        command_mapinfo,        1.0f, 0},
00057     {"motd",           command_motd,           1.0f, 0},
00058     {"dm",             command_dm,             1.0f, 0},
00059     {"time",           command_time,           1.0f, 0},
00060     {"version",        command_version,        1.0f, 0},
00061     {"save",           command_save,           1.0f, 0},
00062     {"use_skill",      command_uskill,         0.1f, 0},
00063     {"ready_skill",    command_rskill,         0.1f, 0},
00064     {"hiscore",        command_hiscore,        1.0f, 0},
00065     {"afk",            command_afk,            1.0f, 0},
00066     {"drop",           command_drop,           1.0f, 0},
00067     {"take",           command_take,           1.0f, 0},
00068     {"get",            command_take,           1.0f, 0},
00069     {"party",          command_party,          0.0f, 0},
00070     {"gsay",           command_gsay,           1.0f, 0},
00071     {"push",           command_push_object,    1.0f, 0},
00072     {"left",           command_turn_left,      1.0f, 0},
00073     {"right",          command_turn_right,     1.0f, 0},
00074     {"whereami",       command_whereami,       1.0f, 0},
00075     {"ms_privacy",     command_ms_privacy,     1.0f, 0},
00076     {"statistics",     command_statistics,     1.0f, 0},
00077     {"rename",         command_rename_item,    1.0f, 0},
00078     {"region_map", command_region_map, 1.0f, 0},
00079 };
00080 
00082 const int CommandsSize = sizeof(Commands) / sizeof(CommArray_s);
00083 
00085 CommArray_s CommunicationCommands [] =
00086 {
00087     {"nod",           command_nod,           1.0, 0},
00088     {"dance",         command_dance,         1.0, 0},
00089     {"kiss",          command_kiss,          1.0, 0},
00090     {"bounce",        command_bounce,        1.0, 0},
00091     {"smile",         command_smile,         1.0, 0},
00092     {"cackle",        command_cackle,        1.0, 0},
00093     {"laugh",         command_laugh,         1.0, 0},
00094     {"giggle",        command_giggle,        1.0, 0},
00095     {"shake",         command_shake,         1.0, 0},
00096     {"puke",          command_puke,          1.0, 0},
00097     {"growl",         command_growl,         1.0, 0},
00098     {"scream",        command_scream,        1.0, 0},
00099     {"sigh",          command_sigh,          1.0, 0},
00100     {"sulk",          command_sulk,          1.0, 0},
00101     {"hug",           command_hug,           1.0, 0},
00102     {"cry",           command_cry,           1.0, 0},
00103     {"poke",          command_poke,          1.0, 0},
00104     {"accuse",        command_accuse,        1.0, 0},
00105     {"grin",          command_grin,          1.0, 0},
00106     {"bow",           command_bow,           1.0, 0},
00107     {"clap",          command_clap,          1.0, 0},
00108     {"blush",         command_blush,         1.0, 0},
00109     {"burp",          command_burp,          1.0, 0},
00110     {"chuckle",       command_chuckle,       1.0, 0},
00111     {"cough",         command_cough,         1.0, 0},
00112     {"flip",          command_flip,          1.0, 0},
00113     {"frown",         command_frown,         1.0, 0},
00114     {"gasp",          command_gasp,          1.0, 0},
00115     {"glare",         command_glare,         1.0, 0},
00116     {"groan",         command_groan,         1.0, 0},
00117     {"hiccup",        command_hiccup,        1.0, 0},
00118     {"lick",          command_lick,          1.0, 0},
00119     {"pout",          command_pout,          1.0, 0},
00120     {"shiver",        command_shiver,        1.0, 0},
00121     {"shrug",         command_shrug,         1.0, 0},
00122     {"slap",          command_slap,          1.0, 0},
00123     {"smirk",         command_smirk,         1.0, 0},
00124     {"snap",          command_snap,          1.0, 0},
00125     {"sneeze",        command_sneeze,        1.0, 0},
00126     {"snicker",       command_snicker,       1.0, 0},
00127     {"sniff",         command_sniff,         1.0, 0},
00128     {"snore",         command_snore,         1.0, 0},
00129     {"spit",          command_spit,          1.0, 0},
00130     {"strut",         command_strut,         1.0, 0},
00131     {"thank",         command_thank,         1.0, 0},
00132     {"twiddle",       command_twiddle,       1.0, 0},
00133     {"wave",          command_wave,          1.0, 0},
00134     {"whistle",       command_whistle,       1.0, 0},
00135     {"wink",          command_wink,          1.0, 0},
00136     {"yawn",          command_yawn,          1.0, 0},
00137     {"beg",           command_beg,           1.0, 0},
00138     {"bleed",         command_bleed,         1.0, 0},
00139     {"cringe",        command_cringe,        1.0, 0},
00140     {"think",         command_think,         1.0, 0},
00141     {"me",            command_me,            1.0, 0},
00142     {"stare",         command_stare,         1.0, 0},
00143     {"sneer",         command_sneer,         1.0, 0},
00144     {"wince",         command_wince,         1.0, 0},
00145     {"facepalm",      command_facepalm,      1.0, 0},
00146     {"my",            command_my,            1.0, 0}
00147 };
00148 
00150 const int CommunicationCommandSize = sizeof(CommunicationCommands)/ sizeof(CommArray_s);
00151 
00153 CommArray_s WizCommands [] =
00154 {
00155     {"dmsay",          command_dmsay,                  0.0, 0},
00156     {"summon",         command_summon,                 0.0, 0},
00157     {"kick",           command_kick,                   0.0, 0},
00158     {"inventory",      command_inventory,              0.0, 0},
00159     {"plugin",         command_loadplugin,             0.0, 0},
00160     {"pluglist",       command_listplugins,            0.0, 0},
00161     {"motd_set",       command_motd_set,               0.0, 0},
00162     {"ban",            command_ban,                    0.0, 0},
00163     {"teleport",       command_teleport,               0.0, 0},
00164     {"goto",           command_goto,                   0.0, 0},
00165     {"shutdown",       command_shutdown,               0.0, 0},
00166     {"shutdown_now",   command_shutdown_now,           0.0, 0},
00167     {"resetmap",       command_resetmap,               0.0, 0},
00168     {"plugout",        command_unloadplugin,           0.0, 0},
00169     {"create",         command_create,                 0.0, 0},
00170     {"addexp",         command_addexp,                 0.0, 0},
00171     {"malloc",         command_malloc,                 0.0, 0},
00172     {"maps",           command_maps,                   0.0, 0},
00173     {"dump",           command_dump,                   0.0, 0},
00174     {"dm_stealth",     command_dm_stealth,             0.0, 0},
00175     {"dm_light",       command_dm_light,               0.0, 0},
00176     {"d_active",       command_dumpactivelist,         0.0, 0},
00177     {"d_arches",       command_dumpallarchetypes,      0.0, 0},
00178     {"d_maps",         command_dumpallmaps,            0.0, 0},
00179     {"d_map",          command_dumpmap,                0.0, 0},
00180     {"d_belowfull",    command_dumpbelowfull,          0.0, 0},
00181     {"d_below",        command_dumpbelow,              0.0, 0},
00182     {"set_map_light",  command_setmaplight,            0.0, 0},
00183     {"wizpass",        command_wizpass,                0.0, 0},
00184     {"learn_spell",    command_learn_spell,            0.0, 0},
00185     {"learn_prayer",   command_learn_special_prayer,   0.0, 0},
00186     {"ssdumptable",    command_ssdumptable,            0.0, 0},
00187     {"patch",          command_patch,                  0.0, 0},
00188     {"speed",          command_speed,                  0.0, 0},
00189     {"strings",        command_strings,                0.0, 0},
00190     {"debug",          command_debug,                  0.0, 0},
00191     {"freeze",         command_freeze,                 0.0, 0},
00192     {"remove",         command_remove,                 0.0, 0},
00193     {"stats",          command_stats,                  0.0, 0},
00194     {"forget_spell",   command_forget_spell,           0.0, 0},
00195     {"set_god",        command_setgod,                 0.0, 0},
00196     {"dm_password",    command_dm_password,            0.0, 0},
00197     {"follow",         command_follow,                 0.0, 0},
00198     {"insert_into",    command_insert_into,            0.0, 0},
00199     {"arrest",         command_arrest,                 0.0, 0},
00200     {"cmd_permission", command_cmd_permission,         0.0, 0},
00201     {"map_save",       command_map_save,               0.0, 0},
00202     {"map_reset",      command_map_reset,              0.0, 0},
00203     {"map_patch",      command_map_patch,              0.0, 0},
00204     {"no_shout",       command_no_shout,               0.0, 0},
00205     {"dmtake",         command_dmtake,                 0.0, 0},
00206     {"server_shout", command_server_shout, 0.0, 0},
00207     {"mod_shout", command_mod_shout, 0.0, 0}
00208 };
00209 
00211 const int WizCommandsSize = sizeof(WizCommands) / sizeof(CommArray_s);
00212 
00219 static int compare_A(const void *a, const void *b)
00220 {
00221     return strcmp(((CommArray_s *) a)->name, ((CommArray_s *) b)->name);
00222 }
00223 
00228 void init_commands()
00229 {
00230     qsort((char *) Commands, CommandsSize, sizeof(CommArray_s), compare_A);
00231     qsort((char *) CommunicationCommands, CommunicationCommandSize, sizeof(CommArray_s), compare_A);
00232     qsort((char *) WizCommands, WizCommandsSize, sizeof(CommArray_s), compare_A);
00233 }
00234 
00241 CommArray_s *find_command_element(char *cmd, CommArray_s *commarray, int commsize)
00242 {
00243     CommArray_s *asp, dummy;
00244     char *cp;
00245 
00246     for (cp = cmd; *cp; cp++)
00247     {
00248         *cp = tolower(*cp);
00249     }
00250 
00251     dummy.name = cmd;
00252     asp = (CommArray_s *) bsearch((void *) &dummy, (void *) commarray, commsize, sizeof(CommArray_s), compare_A);
00253 
00254     return asp;
00255 }
00256 
00262 int can_do_wiz_command(player *pl, const char *command)
00263 {
00264     int i;
00265 
00266     /* We are the wizard. */
00267     if (QUERY_FLAG(pl->ob, FLAG_WIZ))
00268     {
00269         return 1;
00270     }
00271 
00272     /* No permission? */
00273     if (!pl->cmd_permissions)
00274     {
00275         return 0;
00276     }
00277 
00278     /* Check inside command permissions for this command. */
00279     for (i = 0; i < pl->num_cmd_permissions; i++)
00280     {
00281         if (pl->cmd_permissions[i] && !strcmp(command, pl->cmd_permissions[i]))
00282         {
00283             return 1;
00284         }
00285     }
00286 
00287     return 0;
00288 }
00289 
00296 int execute_newserver_command(object *pl, char *command)
00297 {
00298     CommArray_s *csp;
00299     char *cp;
00300 
00301     /* Sanity check: all commands must begin with a slash, and there must be
00302      * something else after the slash. */
00303     if (command[0] != '/' || !command[1])
00304     {
00305         new_draw_info_format(0, COLOR_WHITE, pl, "'%s' is not a valid command.", command);
00306         return 0;
00307     }
00308 
00309     /* Jump over the slash. */
00310     command++;
00311 
00312     /* Remove the command from the parameters. */
00313     cp = strchr(command, ' ');
00314 
00315     if (cp)
00316     {
00317         *(cp++) = '\0';
00318         cp = cleanup_string(cp);
00319 
00320         if (cp && *cp == '\0')
00321         {
00322             cp = NULL;
00323         }
00324     }
00325 
00326     /* First look in the normal commands. */
00327     csp = find_command_element(command, Commands, CommandsSize);
00328 
00329     /* Not found? Try the emote commands. */
00330     if (!csp)
00331     {
00332         csp = find_command_element(command, CommunicationCommands, CommunicationCommandSize);
00333     }
00334 
00335     /* If still not found and we're a DM or have permission for the command,
00336      * look in DM commands. */
00337     if (!csp && can_do_wiz_command(CONTR(pl), command))
00338     {
00339         csp = find_command_element(command, WizCommands, WizCommandsSize);
00340 
00341         if (csp)
00342         {
00343             LOG(llevSystem, "WIZ: %s: /%s %s\n", pl->name, command, STRING_SAFE(cp));
00344         }
00345     }
00346 
00347     /* Still not found? Maybe a plugin has registered this command. */
00348     if (!csp)
00349     {
00350         csp = find_plugin_command(command);
00351     }
00352 
00353     /* We didn't find the command anywhere. */
00354     if (!csp)
00355     {
00356         new_draw_info_format(0, COLOR_WHITE, pl, "'/%s' is not a valid command.", command);
00357         return 0;
00358     }
00359 
00360     pl->speed_left -= csp->time;
00361 
00362     return csp->func(pl, cp);
00363 }