From 984c6f97589a190be8bf6fc9095c3bd024bb0b90 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 21 May 2016 22:02:50 +0200 Subject: [PATCH] Added the ability to overload the default command parent. Implements #923. --- evennia/__init__.py | 1 + evennia/commands/cmdsethandler.py | 1 + evennia/commands/default/admin.py | 22 +- evennia/commands/default/batchprocess.py | 40 +-- evennia/commands/default/building.py | 31 +-- evennia/commands/default/cmdset_character.py | 1 - evennia/commands/default/comms.py | 77 ++++-- evennia/commands/default/general.py | 24 +- evennia/commands/default/help.py | 7 +- evennia/commands/default/muxcommand.py | 15 ++ evennia/commands/default/player.py | 72 +++-- evennia/commands/default/syscommands.py | 12 +- evennia/commands/default/system.py | 31 +-- evennia/commands/default/unloggedin.py | 17 +- evennia/game_template/commands/command.py | 266 +++++++++++-------- evennia/settings_default.py | 3 + 16 files changed, 383 insertions(+), 237 deletions(-) diff --git a/evennia/__init__.py b/evennia/__init__.py index b7b4b50f55..558eae9bb7 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -265,6 +265,7 @@ def _init(): add_cmds(help) add_cmds(system) add_cmds(unloggedin) + default_cmds = DefaultCmds() del DefaultCmds diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index 14445cf171..9ecc397b57 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -225,6 +225,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False): err_cmdset.errmessage = errstring return err_cmdset + # classes diff --git a/evennia/commands/default/admin.py b/evennia/commands/default/admin.py index d2afd52324..56d2fa5cdb 100644 --- a/evennia/commands/default/admin.py +++ b/evennia/commands/default/admin.py @@ -9,8 +9,9 @@ import re from django.conf import settings from evennia.server.sessionhandler import SESSIONS from evennia.server.models import ServerConfig -from evennia.utils import prettytable, search -from evennia.commands.default.muxcommand import MuxCommand +from evennia.utils import prettytable, search, class_from_module + +COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] @@ -19,7 +20,7 @@ __all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer", "CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall") -class CmdBoot(MuxCommand): +class CmdBoot(COMMAND_DEFAULT_CLASS): """ kick a player from the server. @@ -116,7 +117,7 @@ def list_bans(banlist): return string -class CmdBan(MuxCommand): +class CmdBan(COMMAND_DEFAULT_CLASS): """ ban a player from the server @@ -204,7 +205,7 @@ class CmdBan(MuxCommand): self.caller.msg("%s-Ban {w%s{n was added." % (typ, ban)) -class CmdUnban(MuxCommand): +class CmdUnban(COMMAND_DEFAULT_CLASS): """ remove a ban from a player @@ -249,7 +250,7 @@ class CmdUnban(MuxCommand): (num, " ".join([s for s in ban[:2]]))) -class CmdDelPlayer(MuxCommand): +class CmdDelPlayer(COMMAND_DEFAULT_CLASS): """ delete a player from the server @@ -319,7 +320,7 @@ class CmdDelPlayer(MuxCommand): self.msg("Player %s was successfully deleted." % uname) -class CmdEmit(MuxCommand): +class CmdEmit(COMMAND_DEFAULT_CLASS): """ admin command for emitting message to multiple objects @@ -398,7 +399,7 @@ class CmdEmit(MuxCommand): caller.msg("You are not allowed to emit to %s." % objname) -class CmdNewPassword(MuxCommand): +class CmdNewPassword(COMMAND_DEFAULT_CLASS): """ change the password of a player @@ -433,7 +434,7 @@ class CmdNewPassword(MuxCommand): self.rhs)) -class CmdPerm(MuxCommand): +class CmdPerm(COMMAND_DEFAULT_CLASS): """ set the permissions of a player/object @@ -534,7 +535,8 @@ class CmdPerm(MuxCommand): if tstring: obj.msg(tstring.strip()) -class CmdWall(MuxCommand): + +class CmdWall(COMMAND_DEFAULT_CLASS): """ make an announcement to all diff --git a/evennia/commands/default/batchprocess.py b/evennia/commands/default/batchprocess.py index 7f8e8469c5..1a0f74e9b3 100644 --- a/evennia/commands/default/batchprocess.py +++ b/evennia/commands/default/batchprocess.py @@ -22,9 +22,11 @@ from builtins import range from django.conf import settings from evennia.utils.batchprocessors import BATCHCMD, BATCHCODE from evennia.commands.cmdset import CmdSet -from evennia.commands.default.muxcommand import MuxCommand from evennia.utils import logger, utils +COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) +#from evennia.commands.default.muxcommand import COMMAND_DEFAULT_CLASS + # limit symbols for API inclusion __all__ = ("CmdBatchCommands", "CmdBatchCode") @@ -205,7 +207,7 @@ def purge_processor(caller): #------------------------------------------------------------ -class CmdBatchCommands(MuxCommand): +class CmdBatchCommands(COMMAND_DEFAULT_CLASS): """ build from batch-command file @@ -308,7 +310,7 @@ class CmdBatchCommands(MuxCommand): purge_processor(caller) -class CmdBatchCode(MuxCommand): +class CmdBatchCode(COMMAND_DEFAULT_CLASS): """ build from batch-code file @@ -419,7 +421,7 @@ class CmdBatchCode(MuxCommand): # (these are the same for both processors) #------------------------------------------------------------ -class CmdStateAbort(MuxCommand): +class CmdStateAbort(COMMAND_DEFAULT_CLASS): """ @abort @@ -437,7 +439,7 @@ class CmdStateAbort(MuxCommand): self.caller.msg("Exited processor and reset out active cmdset back to the default one.") -class CmdStateLL(MuxCommand): +class CmdStateLL(COMMAND_DEFAULT_CLASS): """ ll @@ -451,7 +453,7 @@ class CmdStateLL(MuxCommand): def func(self): show_curr(self.caller, showall=True) -class CmdStatePP(MuxCommand): +class CmdStatePP(COMMAND_DEFAULT_CLASS): """ pp @@ -472,7 +474,7 @@ class CmdStatePP(MuxCommand): batch_cmd_exec(caller) -class CmdStateRR(MuxCommand): +class CmdStateRR(COMMAND_DEFAULT_CLASS): """ rr @@ -494,7 +496,7 @@ class CmdStateRR(MuxCommand): show_curr(caller) -class CmdStateRRR(MuxCommand): +class CmdStateRRR(COMMAND_DEFAULT_CLASS): """ rrr @@ -516,7 +518,7 @@ class CmdStateRRR(MuxCommand): show_curr(caller) -class CmdStateNN(MuxCommand): +class CmdStateNN(COMMAND_DEFAULT_CLASS): """ nn @@ -537,7 +539,7 @@ class CmdStateNN(MuxCommand): show_curr(caller) -class CmdStateNL(MuxCommand): +class CmdStateNL(COMMAND_DEFAULT_CLASS): """ nl @@ -559,7 +561,7 @@ class CmdStateNL(MuxCommand): show_curr(caller, showall=True) -class CmdStateBB(MuxCommand): +class CmdStateBB(COMMAND_DEFAULT_CLASS): """ bb @@ -581,7 +583,7 @@ class CmdStateBB(MuxCommand): show_curr(caller) -class CmdStateBL(MuxCommand): +class CmdStateBL(COMMAND_DEFAULT_CLASS): """ bl @@ -603,7 +605,7 @@ class CmdStateBL(MuxCommand): show_curr(caller, showall=True) -class CmdStateSS(MuxCommand): +class CmdStateSS(COMMAND_DEFAULT_CLASS): """ ss [steps] @@ -632,7 +634,7 @@ class CmdStateSS(MuxCommand): show_curr(caller) -class CmdStateSL(MuxCommand): +class CmdStateSL(COMMAND_DEFAULT_CLASS): """ sl [steps] @@ -661,7 +663,7 @@ class CmdStateSL(MuxCommand): show_curr(caller) -class CmdStateCC(MuxCommand): +class CmdStateCC(COMMAND_DEFAULT_CLASS): """ cc @@ -693,7 +695,7 @@ class CmdStateCC(MuxCommand): caller.msg(format_code("Finished processing batch file.")) -class CmdStateJJ(MuxCommand): +class CmdStateJJ(COMMAND_DEFAULT_CLASS): """ jj @@ -717,7 +719,7 @@ class CmdStateJJ(MuxCommand): show_curr(caller) -class CmdStateJL(MuxCommand): +class CmdStateJL(COMMAND_DEFAULT_CLASS): """ jl @@ -741,7 +743,7 @@ class CmdStateJL(MuxCommand): show_curr(caller, showall=True) -class CmdStateQQ(MuxCommand): +class CmdStateQQ(COMMAND_DEFAULT_CLASS): """ qq @@ -756,7 +758,7 @@ class CmdStateQQ(MuxCommand): self.caller.msg("Aborted interactive batch mode.") -class CmdStateHH(MuxCommand): +class CmdStateHH(COMMAND_DEFAULT_CLASS): "Help command" key = "hh" diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index f955c989ec..c8f01a7501 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -8,14 +8,15 @@ from django.conf import settings from django.db.models import Q from evennia.objects.models import ObjectDB from evennia.locks.lockhandler import LockException -from evennia.commands.default.muxcommand import MuxCommand from evennia.commands.cmdhandler import get_and_merge_cmdsets from evennia.utils import create, utils, search -from evennia.utils.utils import inherits_from +from evennia.utils.utils import inherits_from, class_from_module from evennia.utils.eveditor import EvEditor from evennia.utils.spawner import spawn from evennia.utils.ansi import raw +COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) + # limit symbol import for API __all__ = ("ObjManipCommand", "CmdSetObjAlias", "CmdCopy", "CmdCpAttr", "CmdMvAttr", "CmdCreate", @@ -40,7 +41,7 @@ _DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH _PROTOTYPE_PARENTS = None -class ObjManipCommand(MuxCommand): +class ObjManipCommand(COMMAND_DEFAULT_CLASS): """ This is a parent class for some of the defining objmanip commands since they tend to have some more variables to define new objects. @@ -97,7 +98,7 @@ class ObjManipCommand(MuxCommand): self.rhs_objattr = obj_attrs[1] -class CmdSetObjAlias(MuxCommand): +class CmdSetObjAlias(COMMAND_DEFAULT_CLASS): """ adding permanent aliases for object @@ -528,7 +529,7 @@ def _desc_quit(caller): caller.attributes.remove("evmenu_target") caller.msg("Exited editor.") -class CmdDesc(MuxCommand): +class CmdDesc(COMMAND_DEFAULT_CLASS): """ describe an object @@ -607,7 +608,7 @@ class CmdDesc(MuxCommand): caller.msg("The description was set on %s." % obj.get_display_name(caller)) -class CmdDestroy(MuxCommand): +class CmdDestroy(COMMAND_DEFAULT_CLASS): """ permanently delete objects @@ -823,7 +824,7 @@ class CmdDig(ObjManipCommand): if new_room and ('teleport' in self.switches or "tel" in self.switches): caller.move_to(new_room) -class CmdTunnel(MuxCommand): +class CmdTunnel(COMMAND_DEFAULT_CLASS): """ create new rooms in cardinal directions only @@ -903,7 +904,7 @@ class CmdTunnel(MuxCommand): self.caller.execute_cmd(digstring) -class CmdLink(MuxCommand): +class CmdLink(COMMAND_DEFAULT_CLASS): """ link existing rooms together with exits @@ -1077,7 +1078,7 @@ class CmdSetHome(CmdLink): self.caller.msg(string) -class CmdListCmdSets(MuxCommand): +class CmdListCmdSets(COMMAND_DEFAULT_CLASS): """ list command sets defined on an object @@ -1552,7 +1553,7 @@ class CmdSetAttribute(ObjManipCommand): caller.msg(string.strip('\n')) -class CmdTypeclass(MuxCommand): +class CmdTypeclass(COMMAND_DEFAULT_CLASS): """ set or change an object's typeclass @@ -2070,7 +2071,7 @@ class CmdExamine(ObjManipCommand): get_and_merge_cmdsets(obj, self.session, self.player, obj, mergemode).addCallback(get_cmdset_callback) -class CmdFind(MuxCommand): +class CmdFind(COMMAND_DEFAULT_CLASS): """ search the database for objects @@ -2196,7 +2197,7 @@ class CmdFind(MuxCommand): caller.msg(string.strip()) -class CmdTeleport(MuxCommand): +class CmdTeleport(COMMAND_DEFAULT_CLASS): """ teleport object to another location @@ -2297,7 +2298,7 @@ class CmdTeleport(MuxCommand): destination)) -class CmdScript(MuxCommand): +class CmdScript(COMMAND_DEFAULT_CLASS): """ attach a script to an object @@ -2397,7 +2398,7 @@ class CmdScript(MuxCommand): caller.msg(string.strip()) -class CmdTag(MuxCommand): +class CmdTag(COMMAND_DEFAULT_CLASS): """ handles the tags of an object @@ -2510,7 +2511,7 @@ class CmdTag(MuxCommand): # Reload the server and the prototypes should be available. # -class CmdSpawn(MuxCommand): +class CmdSpawn(COMMAND_DEFAULT_CLASS): """ spawn objects from prototype diff --git a/evennia/commands/default/cmdset_character.py b/evennia/commands/default/cmdset_character.py index 7aa9ed84d3..a8216db73b 100644 --- a/evennia/commands/default/cmdset_character.py +++ b/evennia/commands/default/cmdset_character.py @@ -9,7 +9,6 @@ from evennia.commands.default import general, help, admin, system from evennia.commands.default import building from evennia.commands.default import batchprocess - class CharacterCmdSet(CmdSet): """ Implements the default command set. diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index 0c30f47ffb..b2f9b7535b 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -15,8 +15,9 @@ from evennia.players.models import PlayerDB from evennia.players import bots from evennia.comms.channelhandler import CHANNELHANDLER from evennia.utils import create, utils, evtable -from evennia.utils.utils import make_iter -from evennia.commands.default.muxcommand import MuxCommand, MuxPlayerCommand +from evennia.utils.utils import make_iter, class_from_module + +COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) # limit symbol import for API __all__ = ("CmdAddCom", "CmdDelCom", "CmdAllCom", @@ -50,7 +51,7 @@ def find_channel(caller, channelname, silent=False, noaliases=False): return channels[0] -class CmdAddCom(MuxPlayerCommand): +class CmdAddCom(COMMAND_DEFAULT_CLASS): """ add a channel alias and/or subscribe to a channel @@ -68,6 +69,9 @@ class CmdAddCom(MuxPlayerCommand): help_category = "Comms" locks = "cmd:not pperm(channel_banned)" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implement the command" @@ -119,7 +123,7 @@ class CmdAddCom(MuxPlayerCommand): self.msg(string) -class CmdDelCom(MuxPlayerCommand): +class CmdDelCom(COMMAND_DEFAULT_CLASS): """ remove a channel alias and/or unsubscribe from channel @@ -136,6 +140,9 @@ class CmdDelCom(MuxPlayerCommand): help_category = "Comms" locks = "cmd:not perm(channel_banned)" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implementing the command. " @@ -176,7 +183,7 @@ class CmdDelCom(MuxPlayerCommand): self.msg("You had no such alias defined for this channel.") -class CmdAllCom(MuxPlayerCommand): +class CmdAllCom(COMMAND_DEFAULT_CLASS): """ perform admin operations on all channels @@ -194,6 +201,9 @@ class CmdAllCom(MuxPlayerCommand): locks = "cmd: not pperm(channel_banned)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Runs the function" @@ -242,7 +252,7 @@ class CmdAllCom(MuxPlayerCommand): self.msg("Usage: allcom on | off | who | clear") -class CmdChannels(MuxPlayerCommand): +class CmdChannels(COMMAND_DEFAULT_CLASS): """ list all channels available to you @@ -260,6 +270,9 @@ class CmdChannels(MuxPlayerCommand): help_category = "Comms" locks = "cmd: not pperm(channel_banned)" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implement function" @@ -305,7 +318,7 @@ class CmdChannels(MuxPlayerCommand): caller.msg("\n{wAvailable channels{n (use {wcomlist{n,{waddcom{n and {wdelcom{n to manage subscriptions):\n%s" % comtable) -class CmdCdestroy(MuxPlayerCommand): +class CmdCdestroy(COMMAND_DEFAULT_CLASS): """ destroy a channel you created @@ -319,6 +332,9 @@ class CmdCdestroy(MuxPlayerCommand): help_category = "Comms" locks = "cmd: not pperm(channel_banned)" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Destroy objects cleanly." caller = self.caller @@ -342,7 +358,7 @@ class CmdCdestroy(MuxPlayerCommand): self.msg("Channel '%s' was destroyed." % channel_key) -class CmdCBoot(MuxPlayerCommand): +class CmdCBoot(COMMAND_DEFAULT_CLASS): """ kick a player from a channel you control @@ -360,6 +376,9 @@ class CmdCBoot(MuxPlayerCommand): locks = "cmd: not pperm(channel_banned)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "implement the function" @@ -403,7 +422,7 @@ class CmdCBoot(MuxPlayerCommand): CHANNELHANDLER.update() -class CmdCemit(MuxPlayerCommand): +class CmdCemit(COMMAND_DEFAULT_CLASS): """ send an admin message to a channel you control @@ -425,6 +444,9 @@ class CmdCemit(MuxPlayerCommand): locks = "cmd: not pperm(channel_banned) and pperm(Players)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implement function" @@ -448,7 +470,7 @@ class CmdCemit(MuxPlayerCommand): self.msg(string) -class CmdCWho(MuxPlayerCommand): +class CmdCWho(COMMAND_DEFAULT_CLASS): """ show who is listening to a channel @@ -461,6 +483,9 @@ class CmdCWho(MuxPlayerCommand): locks = "cmd: not pperm(channel_banned)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "implement function" @@ -486,7 +511,7 @@ class CmdCWho(MuxPlayerCommand): self.msg(string.strip()) -class CmdChannelCreate(MuxPlayerCommand): +class CmdChannelCreate(COMMAND_DEFAULT_CLASS): """ create a new channel @@ -501,6 +526,9 @@ class CmdChannelCreate(MuxPlayerCommand): locks = "cmd:not pperm(channel_banned) and pperm(Players)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implement the command" @@ -535,7 +563,7 @@ class CmdChannelCreate(MuxPlayerCommand): self.msg("Created channel %s and connected to it." % new_chan.key) -class CmdClock(MuxPlayerCommand): +class CmdClock(COMMAND_DEFAULT_CLASS): """ change channel locks of a channel you control @@ -551,6 +579,9 @@ class CmdClock(MuxPlayerCommand): aliases = ["@clock"] help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "run the function" @@ -581,7 +612,7 @@ class CmdClock(MuxPlayerCommand): self.msg(string) -class CmdCdesc(MuxPlayerCommand): +class CmdCdesc(COMMAND_DEFAULT_CLASS): """ describe a channel you control @@ -596,6 +627,9 @@ class CmdCdesc(MuxPlayerCommand): locks = "cmd:not pperm(channel_banned)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implement command" @@ -619,7 +653,7 @@ class CmdCdesc(MuxPlayerCommand): self.rhs)) -class CmdPage(MuxPlayerCommand): +class CmdPage(COMMAND_DEFAULT_CLASS): """ send a private message to another player @@ -641,10 +675,13 @@ class CmdPage(MuxPlayerCommand): locks = "cmd:not pperm(page_banned)" help_category = "Comms" + # this is used by the COMMAND_DEFAULT_CLASS parent + player_caller = True + def func(self): "Implement function using the Msg methods" - # this is a MuxPlayerCommand, which means caller will be a Player. + # Since player_caller is set above, this will be a Player. caller = self.caller # get the messages we've sent (not to channels) @@ -750,7 +787,7 @@ class CmdPage(MuxPlayerCommand): self.msg("You paged %s with: '%s'." % (", ".join(received), message)) -class CmdIRC2Chan(MuxCommand): +class CmdIRC2Chan(COMMAND_DEFAULT_CLASS): """ link an evennia channel to an external IRC channel @@ -853,7 +890,7 @@ class CmdIRC2Chan(MuxCommand): self.msg("Connection created. Starting IRC bot.") # RSS connection -class CmdRSS2Chan(MuxCommand): +class CmdRSS2Chan(COMMAND_DEFAULT_CLASS): """ link an evennia channel to an external RSS feed @@ -949,7 +986,7 @@ class CmdRSS2Chan(MuxCommand): self.msg("RSS reporter created. Fetching RSS.") -#class CmdIMC2Chan(MuxCommand): +#class CmdIMC2Chan(COMMAND_DEFAULT_CLASS): # """ # link an evennia channel to an external IMC2 channel # @@ -1027,7 +1064,7 @@ class CmdRSS2Chan(MuxCommand): # self.msg("Created connection channel %s <-> IMC channel %s." % (channel.key, imc2_channel)) # # -#class CmdIMCInfo(MuxCommand): +#class CmdIMCInfo(COMMAND_DEFAULT_CLASS): # """ # get various IMC2 information # @@ -1127,7 +1164,7 @@ class CmdRSS2Chan(MuxCommand): # # ## unclear if this is working ... -#class CmdIMCTell(MuxCommand): +#class CmdIMCTell(COMMAND_DEFAULT_CLASS): # """ # send a page to a remote IMC player # diff --git a/evennia/commands/default/general.py b/evennia/commands/default/general.py index 892461ee0f..9f9c173cf4 100644 --- a/evennia/commands/default/general.py +++ b/evennia/commands/default/general.py @@ -3,8 +3,8 @@ General Character commands usually availabe to all characters """ from django.conf import settings from evennia.utils import utils, prettytable -from evennia.commands.default.muxcommand import MuxCommand +COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) # limit symbol import for API __all__ = ("CmdHome", "CmdLook", "CmdNick", @@ -12,7 +12,7 @@ __all__ = ("CmdHome", "CmdLook", "CmdNick", "CmdSay", "CmdPose", "CmdAccess") -class CmdHome(MuxCommand): +class CmdHome(COMMAND_DEFAULT_CLASS): """ move to your character's home location @@ -38,7 +38,7 @@ class CmdHome(MuxCommand): caller.move_to(home) caller.msg("There's no place like home ...") -class CmdLook(MuxCommand): +class CmdLook(COMMAND_DEFAULT_CLASS): """ look at location or object @@ -70,7 +70,7 @@ class CmdLook(MuxCommand): self.msg(self.caller.at_look(target)) -class CmdNick(MuxCommand): +class CmdNick(COMMAND_DEFAULT_CLASS): """ define a personal alias/nick @@ -170,7 +170,7 @@ class CmdNick(MuxCommand): caller.msg(string) -class CmdInventory(MuxCommand): +class CmdInventory(COMMAND_DEFAULT_CLASS): """ view inventory @@ -200,7 +200,7 @@ class CmdInventory(MuxCommand): self.caller.msg(string) -class CmdGet(MuxCommand): +class CmdGet(COMMAND_DEFAULT_CLASS): """ pick up something @@ -246,7 +246,7 @@ class CmdGet(MuxCommand): obj.at_get(caller) -class CmdDrop(MuxCommand): +class CmdDrop(COMMAND_DEFAULT_CLASS): """ drop something @@ -286,7 +286,7 @@ class CmdDrop(MuxCommand): obj.at_drop(caller) -class CmdGive(MuxCommand): +class CmdGive(COMMAND_DEFAULT_CLASS): """ give away something to someone @@ -325,7 +325,7 @@ class CmdGive(MuxCommand): target.msg("%s gives you %s." % (caller.key, to_give.key)) -class CmdDesc(MuxCommand): +class CmdDesc(COMMAND_DEFAULT_CLASS): """ describe yourself @@ -350,7 +350,7 @@ class CmdDesc(MuxCommand): self.caller.db.desc = self.args.strip() self.caller.msg("You set your description.") -class CmdSay(MuxCommand): +class CmdSay(COMMAND_DEFAULT_CLASS): """ speak as your character @@ -388,7 +388,7 @@ class CmdSay(MuxCommand): exclude=caller) -class CmdPose(MuxCommand): +class CmdPose(COMMAND_DEFAULT_CLASS): """ strike a pose @@ -431,7 +431,7 @@ class CmdPose(MuxCommand): self.caller.location.msg_contents(msg) -class CmdAccess(MuxCommand): +class CmdAccess(COMMAND_DEFAULT_CLASS): """ show your current game access diff --git a/evennia/commands/default/help.py b/evennia/commands/default/help.py index 77ca63f5c8..7637280096 100644 --- a/evennia/commands/default/help.py +++ b/evennia/commands/default/help.py @@ -12,8 +12,9 @@ from evennia.utils.utils import fill, dedent from evennia.commands.command import Command from evennia.help.models import HelpEntry from evennia.utils import create -from evennia.utils.utils import string_suggestions -from evennia.commands.default.muxcommand import MuxCommand +from evennia.utils.utils import string_suggestions, class_from_module + +COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) # limit symbol import for API __all__ = ("CmdHelp", "CmdSetHelp") @@ -157,7 +158,7 @@ class CmdHelp(Command): self.msg(format_help_entry("", "No help entry found for '%s'" % query, None, suggested=suggestions)) -class CmdSetHelp(MuxCommand): +class CmdSetHelp(COMMAND_DEFAULT_CLASS): """ edit the help database diff --git a/evennia/commands/default/muxcommand.py b/evennia/commands/default/muxcommand.py index f159c4bbc8..854f8032b2 100644 --- a/evennia/commands/default/muxcommand.py +++ b/evennia/commands/default/muxcommand.py @@ -127,6 +127,21 @@ class MuxCommand(Command): self.rhs = rhs self.rhslist = rhslist + # if the class has the player_caller property set on itself, we make + # sure that self.caller is always the player if possible. We also create + # a special property "character" for the puppeted object, if any. This + # is convenient for commands defined on the Player only. + if hasattr(self, "player_caller") and self.player_caller: + if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"): + # caller is an Object/Character + self.character = self.caller + self.caller = self.caller.player + elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"): + # caller was already a Player + self.character = self.caller.get_puppet(self.session) + else: + self.character = None + def func(self): """ This is the hook function that actually does all the work. It is called diff --git a/evennia/commands/default/player.py b/evennia/commands/default/player.py index d95d42142b..a7eb35ec00 100644 --- a/evennia/commands/default/player.py +++ b/evennia/commands/default/player.py @@ -5,14 +5,13 @@ and self.caller is thus always a Player, not an Object/Character. These commands go in the PlayerCmdset and are accessible also when puppeting a Character (although with lower priority) -These commands use the MuxCommandOOC parent that makes sure -to setup caller correctly. They use self.player to make sure -to always use the player object rather than self.caller (which -change depending on the level you are calling from) -The property self.character can be used to -access the character when these commands are triggered with -a connected character (such as the case of the @ooc command), it -is None if we are OOC. +These commands use the player_caller property which tells the command +parent (MuxCommand, usually) to setup caller correctly. They use +self.player to make sure to always use the player object rather than +self.caller (which change depending on the level you are calling from) +The property self.character can be used to access the character when +these commands are triggered with a connected character (such as the +case of the @ooc command), it is None if we are OOC. Note that under MULTISESSION_MODE > 2, Player- commands should use self.msg() and similar methods to reroute returns to the correct @@ -24,9 +23,10 @@ from builtins import range import time from django.conf import settings from evennia.server.sessionhandler import SESSIONS -from evennia.commands.default.muxcommand import MuxPlayerCommand from evennia.utils import utils, create, search, prettytable, evtable +COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) + _MAX_NR_CHARACTERS = settings.MAX_NR_CHARACTERS _MULTISESSION_MODE = settings.MULTISESSION_MODE @@ -36,12 +36,13 @@ __all__ = ("CmdOOCLook", "CmdIC", "CmdOOC", "CmdPassword", "CmdQuit", "CmdColorTest", "CmdQuell") -class MuxPlayerLookCommand(MuxPlayerCommand): +class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS): """ Custom parent (only) parsing for OOC looking, sets a "playable" property on the command based on the parsing. """ + def parse(self): "Custom parsing" @@ -92,6 +93,9 @@ class CmdOOCLook(MuxPlayerLookCommand): locks = "cmd:all()" help_category = "General" + # this is used by the parent + player_caller = True + def func(self): "implement the ooc look command" @@ -104,7 +108,7 @@ class CmdOOCLook(MuxPlayerLookCommand): self.msg(self.player.at_look(target=self.playable, session=self.session)) -class CmdCharCreate(MuxPlayerCommand): +class CmdCharCreate(COMMAND_DEFAULT_CLASS): """ create a new character @@ -120,6 +124,9 @@ class CmdCharCreate(MuxPlayerCommand): locks = "cmd:pperm(Players)" help_category = "General" + # this is used by the parent + player_caller = True + def func(self): "create the new character" player = self.player @@ -167,7 +174,7 @@ class CmdCharCreate(MuxPlayerCommand): self.msg("Created new character %s. Use {w@ic %s{n to enter the game as this character." % (new_character.key, new_character.key)) -class CmdIC(MuxPlayerCommand): +class CmdIC(COMMAND_DEFAULT_CLASS): """ control an object you have permission to puppet @@ -191,6 +198,9 @@ class CmdIC(MuxPlayerCommand): aliases = "@puppet" help_category = "General" + # this is used by the parent + player_caller = True + def func(self): """ Main puppet method @@ -238,6 +248,9 @@ class CmdOOC(MuxPlayerLookCommand): aliases = "@unpuppet" help_category = "General" + # this is used by the parent + player_caller = True + def func(self): "Implement function" @@ -267,7 +280,7 @@ class CmdOOC(MuxPlayerLookCommand): except RuntimeError as exc: self.msg("{rCould not unpuppet from {c%s{n: %s" % (old_char, exc)) -class CmdSessions(MuxPlayerCommand): +class CmdSessions(COMMAND_DEFAULT_CLASS): """ check your connected session(s) @@ -281,6 +294,9 @@ class CmdSessions(MuxPlayerCommand): locks = "cmd:all()" help_category = "General" + # this is used by the parent + player_caller = True + def func(self): "Implement function" player = self.player @@ -301,7 +317,7 @@ class CmdSessions(MuxPlayerCommand): self.msg(string) -class CmdWho(MuxPlayerCommand): +class CmdWho(COMMAND_DEFAULT_CLASS): """ list who is currently online @@ -317,6 +333,9 @@ class CmdWho(MuxPlayerCommand): aliases = "doing" locks = "cmd:all()" + # this is used by the parent + player_caller = True + def func(self): """ Get all connected players by polling session. @@ -376,7 +395,7 @@ class CmdWho(MuxPlayerCommand): self.msg(string) -class CmdOption(MuxPlayerCommand): +class CmdOption(COMMAND_DEFAULT_CLASS): """ Set an account option @@ -397,6 +416,9 @@ class CmdOption(MuxPlayerCommand): aliases = "@options" locks = "cmd:all()" + # this is used by the parent + player_caller = True + def func(self): """ Implements the command @@ -521,7 +543,7 @@ class CmdOption(MuxPlayerCommand): self.session.update_flags(**optiondict) -class CmdPassword(MuxPlayerCommand): +class CmdPassword(COMMAND_DEFAULT_CLASS): """ change your password @@ -533,6 +555,9 @@ class CmdPassword(MuxPlayerCommand): key = "@password" locks = "cmd:pperm(Players)" + # this is used by the parent + player_caller = True + def func(self): "hook function." @@ -552,7 +577,7 @@ class CmdPassword(MuxPlayerCommand): self.msg("Password changed.") -class CmdQuit(MuxPlayerCommand): +class CmdQuit(COMMAND_DEFAULT_CLASS): """ quit the game @@ -569,6 +594,9 @@ class CmdQuit(MuxPlayerCommand): aliases = "quit" locks = "cmd:all()" + # this is used by the parent + player_caller = True + def func(self): "hook function" player = self.player @@ -590,7 +618,7 @@ class CmdQuit(MuxPlayerCommand): -class CmdColorTest(MuxPlayerCommand): +class CmdColorTest(COMMAND_DEFAULT_CLASS): """ testing which colors your client support @@ -608,6 +636,9 @@ class CmdColorTest(MuxPlayerCommand): locks = "cmd:all()" help_category = "General" + # this is used by the parent + player_caller = True + def table_format(self, table): """ Helper method to format the ansi/xterm256 tables. @@ -668,7 +699,7 @@ class CmdColorTest(MuxPlayerCommand): self.msg("Usage: @color ansi||xterm256") -class CmdQuell(MuxPlayerCommand): +class CmdQuell(COMMAND_DEFAULT_CLASS): """ use character's permissions instead of player's @@ -690,6 +721,9 @@ class CmdQuell(MuxPlayerCommand): locks = "cmd:pperm(Players)" help_category = "General" + # this is used by the parent + player_caller = True + def _recache_locks(self, player): "Helper method to reset the lockhandler on an already puppeted object" if self.session: diff --git a/evennia/commands/default/syscommands.py b/evennia/commands/default/syscommands.py index 29953f7d7a..2763a093b0 100644 --- a/evennia/commands/default/syscommands.py +++ b/evennia/commands/default/syscommands.py @@ -27,14 +27,16 @@ from evennia.commands.cmdhandler import CMD_NOINPUT from evennia.commands.cmdhandler import CMD_NOMATCH from evennia.commands.cmdhandler import CMD_MULTIMATCH from evennia.commands.cmdhandler import CMD_CHANNEL +from evennia.utils import utils -from evennia.commands.default.muxcommand import MuxCommand +from django.conf import settings +COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) # Command called when there is no input at line # (i.e. an lone return key) -class SystemNoInput(MuxCommand): +class SystemNoInput(COMMAND_DEFAULT_CLASS): """ This is called when there is no input given """ @@ -50,7 +52,7 @@ class SystemNoInput(MuxCommand): # Command called when there was no match to the # command name # -class SystemNoMatch(MuxCommand): +class SystemNoMatch(COMMAND_DEFAULT_CLASS): """ No command was found matching the given input. """ @@ -67,7 +69,7 @@ class SystemNoMatch(MuxCommand): # # Command called when there were mulitple matches to the command. # -class SystemMultimatch(MuxCommand): +class SystemMultimatch(COMMAND_DEFAULT_CLASS): """ Multiple command matches. @@ -132,7 +134,7 @@ class SystemMultimatch(MuxCommand): # channel named 'ooc' and the user wrote # > ooc Hello! -class SystemSendToChannel(MuxCommand): +class SystemSendToChannel(COMMAND_DEFAULT_CLASS): """ This is a special command that the cmdhandler calls when it detects that the command given matches diff --git a/evennia/commands/default/system.py b/evennia/commands/default/system.py index ef87f6d37a..83564071f4 100644 --- a/evennia/commands/default/system.py +++ b/evennia/commands/default/system.py @@ -18,10 +18,11 @@ from evennia.server.sessionhandler import SESSIONS from evennia.scripts.models import ScriptDB from evennia.objects.models import ObjectDB from evennia.players.models import PlayerDB -from evennia.utils import logger, utils, gametime, create, is_pypy, prettytable +from evennia.utils import logger, utils, gametime, create, prettytable from evennia.utils.evtable import EvTable -from evennia.utils.utils import crop -from evennia.commands.default.muxcommand import MuxCommand +from evennia.utils.utils import crop, class_from_module + +COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) # delayed imports _RESOURCE = None @@ -33,7 +34,7 @@ __all__ = ("CmdReload", "CmdReset", "CmdShutdown", "CmdPy", "CmdTime", "CmdServerLoad") -class CmdReload(MuxCommand): +class CmdReload(COMMAND_DEFAULT_CLASS): """ reload the server @@ -59,7 +60,7 @@ class CmdReload(MuxCommand): SESSIONS.server.shutdown(mode='reload') -class CmdReset(MuxCommand): +class CmdReset(COMMAND_DEFAULT_CLASS): """ reset and reboot the server @@ -92,7 +93,7 @@ class CmdReset(MuxCommand): SESSIONS.server.shutdown(mode='reset') -class CmdShutdown(MuxCommand): +class CmdShutdown(COMMAND_DEFAULT_CLASS): """ stop the server completely @@ -121,7 +122,7 @@ class CmdShutdown(MuxCommand): SESSIONS.portal_shutdown() -class CmdPy(MuxCommand): +class CmdPy(COMMAND_DEFAULT_CLASS): """ execute a snippet of python code @@ -248,7 +249,7 @@ def format_script_list(scripts): return "%s" % table -class CmdScripts(MuxCommand): +class CmdScripts(COMMAND_DEFAULT_CLASS): """ list and manage all running scripts @@ -344,7 +345,7 @@ class CmdScripts(MuxCommand): caller.msg(string) -class CmdObjects(MuxCommand): +class CmdObjects(COMMAND_DEFAULT_CLASS): """ statistics on objects in the database @@ -408,7 +409,7 @@ class CmdObjects(MuxCommand): caller.msg(string) -class CmdPlayers(MuxCommand): +class CmdPlayers(COMMAND_DEFAULT_CLASS): """ list all registered players @@ -451,7 +452,7 @@ class CmdPlayers(MuxCommand): caller.msg(string) -class CmdService(MuxCommand): +class CmdService(COMMAND_DEFAULT_CLASS): """ manage system services @@ -545,7 +546,7 @@ class CmdService(MuxCommand): service.startService() -class CmdAbout(MuxCommand): +class CmdAbout(COMMAND_DEFAULT_CLASS): """ show Evennia info @@ -586,7 +587,7 @@ class CmdAbout(MuxCommand): self.caller.msg(string) -class CmdTime(MuxCommand): +class CmdTime(COMMAND_DEFAULT_CLASS): """ show server time statistics @@ -612,7 +613,7 @@ class CmdTime(MuxCommand): self.caller.msg(str(table)) -class CmdServerLoad(MuxCommand): +class CmdServerLoad(COMMAND_DEFAULT_CLASS): """ show server load and memory statistics @@ -754,7 +755,7 @@ class CmdServerLoad(MuxCommand): # return to caller self.caller.msg(string) -class CmdTickers(MuxCommand): +class CmdTickers(COMMAND_DEFAULT_CLASS): """ View running tickers diff --git a/evennia/commands/default/unloggedin.py b/evennia/commands/default/unloggedin.py index 429c962629..0c5d487051 100644 --- a/evennia/commands/default/unloggedin.py +++ b/evennia/commands/default/unloggedin.py @@ -12,9 +12,10 @@ from evennia.server.models import ServerConfig from evennia.comms.models import ChannelDB from evennia.utils import create, logger, utils, ansi -from evennia.commands.default.muxcommand import MuxCommand from evennia.commands.cmdhandler import CMD_LOGINSTART +COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) + # limit symbol import for API __all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate", "CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp") @@ -178,7 +179,7 @@ def create_normal_player(session, name, password): return player -class CmdUnconnectedConnect(MuxCommand): +class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS): """ connect to the game @@ -241,7 +242,7 @@ class CmdUnconnectedConnect(MuxCommand): session.sessionhandler.login(session, player) -class CmdUnconnectedCreate(MuxCommand): +class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS): """ create a new player account @@ -340,7 +341,7 @@ class CmdUnconnectedCreate(MuxCommand): logger.log_trace() -class CmdUnconnectedQuit(MuxCommand): +class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS): """ quit when in unlogged-in state @@ -361,7 +362,7 @@ class CmdUnconnectedQuit(MuxCommand): session.sessionhandler.disconnect(session, "Good bye! Disconnecting.") -class CmdUnconnectedLook(MuxCommand): +class CmdUnconnectedLook(COMMAND_DEFAULT_CLASS): """ look when in unlogged-in state @@ -385,7 +386,7 @@ class CmdUnconnectedLook(MuxCommand): self.caller.msg(connection_screen) -class CmdUnconnectedHelp(MuxCommand): +class CmdUnconnectedHelp(COMMAND_DEFAULT_CLASS): """ get help when in unconnected-in state @@ -424,7 +425,7 @@ You can use the {wlook{n command if you want to see the connect screen again. self.caller.msg(string) -class CmdUnconnectedEncoding(MuxCommand): +class CmdUnconnectedEncoding(COMMAND_DEFAULT_CLASS): """ set which text encoding to use in unconnected-in state @@ -496,7 +497,7 @@ class CmdUnconnectedEncoding(MuxCommand): self.session.sessionhandler.session_portal_sync(self.session) self.caller.msg(string.strip()) -class CmdUnconnectedScreenreader(MuxCommand): +class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS): """ Activate screenreader mode. diff --git a/evennia/game_template/commands/command.py b/evennia/game_template/commands/command.py index 9d850d3823..6efb174391 100644 --- a/evennia/game_template/commands/command.py +++ b/evennia/game_template/commands/command.py @@ -6,21 +6,21 @@ Commands describe the input the player can do to the game. """ from evennia import Command as BaseCommand -from evennia import default_cmds +# from evennia import default_cmds class Command(BaseCommand): """ - Inherit from this if you want to create your own - command styles. Note that Evennia's default commands - use MuxCommand instead (next in this module). + Inherit from this if you want to create your own command styles + from scratch. Note that Evennia's default commands inherits from + MuxCommand instead. Note that the class's `__doc__` string (this text) is used by Evennia to create the automatic help entry for the command, so make sure to document consistently here. Each Command implements the following methods, called - in this order: + in this order (only func() is actually required): - at_pre_command(): If this returns True, execution is aborted. - parse(): Should perform any extra parsing needed on self.args and store the result on self. @@ -29,110 +29,156 @@ class Command(BaseCommand): every command, like prompts. """ - # these need to be specified + pass - key = "MyCommand" - aliases = [] - locks = "cmd:all()" - help_category = "General" +#------------------------------------------------------------ +# +# The default commands inherit from +# +# evennia.commands.default.muxcommand.MuxCommand. +# +# If you want to make sweeping changes to default commands you can +# uncomment this copy of the MuxCommand parent and add +# +# COMMAND_DEFAULT_CLASS = "commands.command.MuxCommand" +# +# to your settings file. Be warned that the default commands expect +# the functionality implemented in the parse() method, so be +# careful with what you change. +# +#------------------------------------------------------------ - # optional - # auto_help = False # uncomment to deactive auto-help for this command. - # arg_regex = r"\s.*?|$" # optional regex detailing how the part after - # the cmdname must look to match this command. - - # (we don't implement hook method access() here, you don't need to - # modify that unless you want to change how the lock system works - # (in that case see evennia.commands.command.Command)) - - def at_pre_cmd(self): - """ - This hook is called before `self.parse()` on all commands. - """ - pass - - def parse(self): - """ - This method is called by the `cmdhandler` once the command name - has been identified. It creates a new set of member variables - that can be later accessed from `self.func()` (see below). - - The following variables are available to us: - # class variables: - - self.key - the name of this command ('mycommand') - self.aliases - the aliases of this cmd ('mycmd','myc') - self.locks - lock string for this command ("cmd:all()") - self.help_category - overall category of command ("General") - - # added at run-time by `cmdhandler`: - - self.caller - the object calling this command - self.cmdstring - the actual command name used to call this - (this allows you to know which alias was used, - for example) - self.args - the raw input; everything following `self.cmdstring`. - self.cmdset - the `cmdset` from which this command was picked. Not - often used (useful for commands like `help` or to - list all available commands etc). - self.obj - the object on which this command was defined. It is often - the same as `self.caller`. - """ - pass - - def func(self): - """ - This is the hook function that actually does all the work. It is called - by the `cmdhandler` right after `self.parser()` finishes, and so has access - to all the variables defined therein. - """ - self.caller.msg("Command called!") - - def at_post_cmd(self): - """ - This hook is called after `self.func()`. - """ - pass - - -class MuxCommand(default_cmds.MuxCommand): - """ - This sets up the basis for Evennia's 'MUX-like' command style. - The idea is that most other Mux-related commands should - just inherit from this and don't have to implement parsing of - their own unless they do something particularly advanced. - - A MUXCommand command understands the following possible syntax: - - name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]] - - The `name[ with several words]` part is already dealt with by the - `cmdhandler` at this point, and stored in `self.cmdname`. The rest is stored - in `self.args`. - - The MuxCommand parser breaks `self.args` into its constituents and stores them - in the following variables: - self.switches = optional list of /switches (without the /). - self.raw = This is the raw argument input, including switches. - self.args = This is re-defined to be everything *except* the switches. - self.lhs = Everything to the left of `=` (lhs:'left-hand side'). If - no `=` is found, this is identical to `self.args`. - self.rhs: Everything to the right of `=` (rhs:'right-hand side'). - If no `=` is found, this is `None`. - self.lhslist - `self.lhs` split into a list by comma. - self.rhslist - list of `self.rhs` split into a list by comma. - self.arglist = list of space-separated args (including `=` if it exists). - - All args and list members are stripped of excess whitespace around the - strings, but case is preserved. - """ - - def func(self): - """ - This is the hook function that actually does all the work. It is called - by the `cmdhandler` right after `self.parser()` finishes, and so has access - to all the variables defined therein. - """ - # this can be removed in your child class, it's just - # printing the ingoing variables as a demo. - super(MuxCommand, self).func() +#from evennia.utils import utils +#class MuxCommand(Command): +# """ +# This sets up the basis for a MUX command. The idea +# is that most other Mux-related commands should just +# inherit from this and don't have to implement much +# parsing of their own unless they do something particularly +# advanced. +# +# Note that the class's __doc__ string (this text) is +# used by Evennia to create the automatic help entry for +# the command, so make sure to document consistently here. +# """ +# def has_perm(self, srcobj): +# """ +# This is called by the cmdhandler to determine +# if srcobj is allowed to execute this command. +# We just show it here for completeness - we +# are satisfied using the default check in Command. +# """ +# return super(MuxCommand, self).has_perm(srcobj) +# +# def at_pre_cmd(self): +# """ +# This hook is called before self.parse() on all commands +# """ +# pass +# +# def at_post_cmd(self): +# """ +# This hook is called after the command has finished executing +# (after self.func()). +# """ +# pass +# +# def parse(self): +# """ +# This method is called by the cmdhandler once the command name +# has been identified. It creates a new set of member variables +# that can be later accessed from self.func() (see below) +# +# The following variables are available for our use when entering this +# method (from the command definition, and assigned on the fly by the +# cmdhandler): +# self.key - the name of this command ('look') +# self.aliases - the aliases of this cmd ('l') +# self.permissions - permission string for this command +# self.help_category - overall category of command +# +# self.caller - the object calling this command +# self.cmdstring - the actual command name used to call this +# (this allows you to know which alias was used, +# for example) +# self.args - the raw input; everything following self.cmdstring. +# self.cmdset - the cmdset from which this command was picked. Not +# often used (useful for commands like 'help' or to +# list all available commands etc) +# self.obj - the object on which this command was defined. It is often +# the same as self.caller. +# +# A MUX command has the following possible syntax: +# +# name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]] +# +# The 'name[ with several words]' part is already dealt with by the +# cmdhandler at this point, and stored in self.cmdname (we don't use +# it here). The rest of the command is stored in self.args, which can +# start with the switch indicator /. +# +# This parser breaks self.args into its constituents and stores them in the +# following variables: +# self.switches = [list of /switches (without the /)] +# self.raw = This is the raw argument input, including switches +# self.args = This is re-defined to be everything *except* the switches +# self.lhs = Everything to the left of = (lhs:'left-hand side'). If +# no = is found, this is identical to self.args. +# self.rhs: Everything to the right of = (rhs:'right-hand side'). +# If no '=' is found, this is None. +# self.lhslist - [self.lhs split into a list by comma] +# self.rhslist - [list of self.rhs split into a list by comma] +# self.arglist = [list of space-separated args (stripped, including '=' if it exists)] +# +# All args and list members are stripped of excess whitespace around the +# strings, but case is preserved. +# """ +# raw = self.args +# args = raw.strip() +# +# # split out switches +# switches = [] +# if args and len(args) > 1 and args[0] == "/": +# # we have a switch, or a set of switches. These end with a space. +# switches = args[1:].split(None, 1) +# if len(switches) > 1: +# switches, args = switches +# switches = switches.split('/') +# else: +# args = "" +# switches = switches[0].split('/') +# arglist = [arg.strip() for arg in args.split()] +# +# # check for arg1, arg2, ... = argA, argB, ... constructs +# lhs, rhs = args, None +# lhslist, rhslist = [arg.strip() for arg in args.split(',')], [] +# if args and '=' in args: +# lhs, rhs = [arg.strip() for arg in args.split('=', 1)] +# lhslist = [arg.strip() for arg in lhs.split(',')] +# rhslist = [arg.strip() for arg in rhs.split(',')] +# +# # save to object properties: +# self.raw = raw +# self.switches = switches +# self.args = args.strip() +# self.arglist = arglist +# self.lhs = lhs +# self.lhslist = lhslist +# self.rhs = rhs +# self.rhslist = rhslist +# +# # if the class has the player_caller property set on itself, we make +# # sure that self.caller is always the player if possible. We also create +# # a special property "character" for the puppeted object, if any. This +# # is convenient for commands defined on the Player only. +# if hasattr(self, "player_caller") and self.player_caller: +# if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"): +# # caller is an Object/Character +# self.character = self.caller +# self.caller = self.caller.player +# elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"): +# # caller was already a Player +# self.character = self.caller.get_puppet(self.session) +# else: +# self.character = None +# diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 193de9e0c9..33e6d17685 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -321,6 +321,9 @@ CMDSET_CHARACTER = "commands.default_cmdsets.CharacterCmdSet" CMDSET_PLAYER = "commands.default_cmdsets.PlayerCmdSet" # Location to search for cmdsets if full path not given CMDSET_PATHS = ["commands", "evennia", "contribs"] +# Parent class for all default commands. Changing this class will +# modify all default commands, so do so carefully. +COMMAND_DEFAULT_CLASS = "evennia.commands.default.muxcommand.MuxCommand" ###################################################################### # Typeclasses and other paths