diff --git a/ev.py b/ev.py new file mode 100644 index 0000000000..b50e78f5c5 --- /dev/null +++ b/ev.py @@ -0,0 +1,96 @@ +""" + +Central API for Evennia MUD/MUX/MU* system. + +A simple way to explore Evennia's capabilities is to +import it in a python interpreter where all environment +variables have been set. Easiest is to do the following: + +game/manage.py shell +>>> import ev + +Using ipython is recommended since you will then have tab-completion +and the ability to view docstrings much easier than with the regular +python interpreter. + +In code, just import via ev. + +Philosophy is to keep the API as flat as possible, so as to not have +to remember which nested packages to traverse. Most of the important +stuff should be made visible from this module. + +One can of course still import from src/ directly should one prefer! + +""" + +# Stop erroneous direct run (would give a traceback since django is +# not yet initialized) + +if __name__ == "__main__": + print \ +""" + This module gives access to Evennia's programming API. + It should not be run on its own, but be imported and accessed as you develop your game. + To start the server, see game/manage.py and game/evennia.py. + More help can be found at http://www.evennia.com. +""" + import sys + sys.exit() + + +# Start Evennia API (easiest is to import this module interactively to explore it) + +# help entries +from src.help.models import HelpEntry +db_helpentries = HelpEntry.objects + +# players +from src.players.player import Player +from src.players.models import PlayerDB, PlayerAttribute, PlayerNick +db_players = PlayerDB.objects +db_playerattrs = PlayerAttribute.objects +db_playernicks = PlayerNick.objects +del PlayerDB, PlayerAttribute, PlayerNick + +# commands +from src.commands.command import Command +from src.commands.cmdset import CmdSet +from src.commands import default as default_cmds + +# locks +from src.locks import lockfuncs + +# scripts +from src.scripts.scripts import Script +from src.scripts.models import ScriptDB, ScriptAttribute +db_scripts = ScriptDB.objects +db_scriptattrs = ScriptAttribute.objects +del ScriptDB, ScriptAttribute + +# comms +from src.comms.models import Msg, Channel, PlayerChannelConnection, ExternalChannelConnection +db_msgs = Msg.objects +db_channels = Channel.objects +db_connections = PlayerChannelConnection.objects +db_externalconnections = ExternalChannelConnection.objects + +# objects +from src.objects.objects import Object, Character, Room, Exit +from src.objects.models import ObjAttribute, Alias, ObjectNick, ObjectDB +db_objects = ObjectDB.objects +db_aliases = Alias.objects +db_objnicks = ObjectNick.objects +db_objattrs = ObjAttribute.objects +del ObjAttribute, Alias, ObjectNick, ObjectDB + +# server +from src.server.models import ServerConfig +db_serverconfs = ServerConfig.objects +del ServerConfig + +# utils +from src.utils import search +from src.utils import logger +from src.utils import create +from src.utils import utils + diff --git a/game/gamesrc/objects/baseobjects.py b/game/gamesrc/objects/baseobjects.py index 5c2e6d5ccf..d9a2046cab 100644 --- a/game/gamesrc/objects/baseobjects.py +++ b/game/gamesrc/objects/baseobjects.py @@ -181,20 +181,60 @@ class Player(BasePlayer): Can be set using BASE_PLAYER_TYPECLASS. - The following hooks are called by the engine. Note that all of the following - are called on the character object too, and mostly at the same time. - at_player_creation() - This is called once, the very first time - the player is created (i.e. first time they - register with the game). It's a good place - to store attributes all players should have, - like configuration values etc. - at_pre_login() - called every time the user connects, after they have - identified, just before the system actually logs them in. - at_post_login() - called at the end of login, just before setting the - player loose in the world. - at_disconnect() - called just before the use is disconnected (this is also - called if the system determines the player lost their link) + * available properties + + key (string) - name of player + name (string)- wrapper for user.username + aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. + dbref (int, read-only) - unique #id-number. Also "id" can be used. + dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class + typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. + date_created (string) - time stamp of object creation + permissions (list of strings) - list of permission strings + + user (User, read-only) - django User authorization object + obj (Object) - game object controlled by player. 'character' can also be used. + sessions (list of Sessions) - sessions connected to this player + is_superuser (bool, read-only) - if the connected user is a superuser + + * Handlers + + locks - lock-handler: use locks.add() to add new lock strings + db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr + ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data + scripts - script-handler. Add new scripts to object with scripts.add() + cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object + nicks - nick-handler. New nicks with nicks.add(). + + * Helper methods + + msg(outgoing_string, from_obj=None, data=None) + swap_character(new_character, delete_old_character=False) + execute_cmd(raw_string) + search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False) + is_typeclass(typeclass, exact=False) + swap_typeclass(new_typeclass, clean_attributes=False, no_default=True) + access(accessing_obj, access_type='read', default=False) + check_permstring(permstring) + + * Hook methods (when re-implementation, remember methods need to have self as first arg) + + basetype_setup() + at_player_creation() + + - note that the following hooks are also found on Objects and are + usually handled on the character level: + + at_init() + at_cmdset_get() + at_first_login() + at_post_login() + at_disconnect() + at_message_receive() + at_message_send() + at_server_reload() + at_server_shutdown() """ pass diff --git a/game/manage.py b/game/manage.py index 122d4b7cc0..f93f9a7305 100755 --- a/game/manage.py +++ b/game/manage.py @@ -113,7 +113,10 @@ try: except Exception: import traceback string = "\n" + traceback.format_exc() - string += _("""\n + + # note - if this fails, ugettext will also fail, so we cannot translate this string. + + string += """\n Error: Couldn't import the file 'settings.py' in the directory containing %(file)r. There are usually two reasons for this: 1) You moved your settings.py elsewhere. In that case move it back or @@ -124,7 +127,7 @@ except Exception: set up django wrong in some way. If you run a virtual machine, it might be worth to restart it to see if this resolves the issue. Evennia should not require you to define any environment variables manually. - """) % {'file': __file__} + """ % {'file': __file__} print string sys.exit(1) diff --git a/src/commands/default/__init__.py b/src/commands/default/__init__.py index e69de29bb2..a9e174ce13 100644 --- a/src/commands/default/__init__.py +++ b/src/commands/default/__init__.py @@ -0,0 +1,19 @@ +""" +Central package for importing the default commands from the API. + +""" +from src.commands.default.cmdset_default import DefaultCmdSet +from src.commands.default.cmdset_ooc import OOCCmdSet +from src.commands.default.cmdset_unloggedin import UnloggedinCmdSet + +from src.commands.default.muxcommand import MuxCommand + +from src.commands.default.admin import * +from src.commands.default.batchprocess import * +from src.commands.default.building import * +from src.commands.default.comms import * +from src.commands.default.general import * +from src.commands.default.help import * +from src.commands.default import syscommands +from src.commands.default.system import * +from src.commands.default.unloggedin import * diff --git a/src/commands/default/admin.py b/src/commands/default/admin.py index 907246c079..72630d75cd 100644 --- a/src/commands/default/admin.py +++ b/src/commands/default/admin.py @@ -15,6 +15,11 @@ from src.commands.default.muxcommand import MuxCommand PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] +# limit members for API inclusion +__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer", "CmdEmit", "CmdNewPassword", + "CmdPerm", "CmdWall") + + class CmdBoot(MuxCommand): """ @boot diff --git a/src/commands/default/batchprocess.py b/src/commands/default/batchprocess.py index 7966f2313d..5aa6eddfb2 100644 --- a/src/commands/default/batchprocess.py +++ b/src/commands/default/batchprocess.py @@ -28,6 +28,9 @@ from src.commands.cmdset import CmdSet from src.commands.default.muxcommand import MuxCommand from src.utils import utils +# limit symbols for API inclusion +__all__ = ("CmdBatchCommands", "CmdBatchCode") + HEADER_WIDTH = 70 UTF8_ERROR = \ """ diff --git a/src/commands/default/building.py b/src/commands/default/building.py index 679a2b218e..bb254dbf6a 100644 --- a/src/commands/default/building.py +++ b/src/commands/default/building.py @@ -11,6 +11,16 @@ from src.utils import create, utils, debug from src.commands.default.muxcommand import MuxCommand from src.commands.cmdhandler import get_and_merge_cmdsets +# limit symbol import for API +__all__ = ("ObjManipCommand", "CmdSetObjAlias", "CmdCopy", + "CmdCpAttr", "CmdMvAttr", "CmdCreate", "CmdDebug", + "CmdDesc", "CmdDestroy", "CmdDig", "CmdTunnel", "CmdLink", + "CmdUnLink", "CmdHome", "CmdListCmdSets", "CmdName", + "CmdOpen", "CmdSetAttribute", "CmdTypeclass", "CmdWipe", + "CmdLock", "CmdExamine", "CmdFind", "CmdTeleport", + "CmdScript") + + # used by @find CHAR_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS diff --git a/src/commands/default/cmdset_unloggedin.py b/src/commands/default/cmdset_unloggedin.py index 1e189ed460..f62946d0d7 100644 --- a/src/commands/default/cmdset_unloggedin.py +++ b/src/commands/default/cmdset_unloggedin.py @@ -15,8 +15,8 @@ class UnloggedinCmdSet(CmdSet): def at_cmdset_creation(self): "Populate the cmdset" - self.add(unloggedin.CmdConnect()) - self.add(unloggedin.CmdCreate()) - self.add(unloggedin.CmdQuit()) + self.add(unloggedin.CmdUnconnectedConnect()) + self.add(unloggedin.CmdUnconnectedCreate()) + self.add(unloggedin.CmdUnconnectedQuit()) self.add(unloggedin.CmdUnconnectedLook()) self.add(unloggedin.CmdUnconnectedHelp()) diff --git a/src/commands/default/comms.py b/src/commands/default/comms.py index 32e6bb437e..adc20a406a 100644 --- a/src/commands/default/comms.py +++ b/src/commands/default/comms.py @@ -14,6 +14,13 @@ from src.comms.channelhandler import CHANNELHANDLER from src.utils import create, utils from src.commands.default.muxcommand import MuxCommand +# limit symbol import for API +__all__ = ("CommCommand", "CmdAddCom", "CmdDelCom", "CmdAllCom", + "CmdChannels", "CmdCdestroy", "CmdCBoot", "CmdCemit", + "CmdCWho", "CmdChannelCreate", "CmdCset", "CmdCdesc", + "CmdPage", "CmdIRC2Chan", "CmdIMC2Chan", "CmdIMCInfo", + "CmdIMCTell", "CmdRSS2Chan") + def find_channel(caller, channelname, silent=False, noaliases=False): """ Helper function for searching for a single channel with diff --git a/src/commands/default/general.py b/src/commands/default/general.py index 0483aa1802..01d9877b1e 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -9,6 +9,12 @@ from src.utils import utils from src.objects.models import ObjectNick as Nick from src.commands.default.muxcommand import MuxCommand +# limit symbol import for API +__all__ = ("CmdHome", "CmdLook", "CmdPassword", "CmdNick", + "CmdInventory", "CmdGet", "CmdDrop", "CmdQuit", "CmdWho", + "CmdSay", "CmdPose", "CmdEncoding", "CmdAccess", + "CmdOOCLook", "CmdIC", "CmdOOC") + AT_SEARCH_RESULT = utils.mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) BASE_PLAYER_TYPECLASS = settings.BASE_PLAYER_TYPECLASS diff --git a/src/commands/default/help.py b/src/commands/default/help.py index 91ce86f163..6fabddae7e 100644 --- a/src/commands/default/help.py +++ b/src/commands/default/help.py @@ -12,6 +12,10 @@ from src.help.models import HelpEntry from src.utils import create from src.commands.default.muxcommand import MuxCommand +# limit symbol import for API +__all__ = ("CmdHelp", "CmdSetHelp") + + LIST_ARGS = ("list", "all") SEP = "{C" + "-"*78 + "{n" diff --git a/src/commands/default/muxcommand.py b/src/commands/default/muxcommand.py index d1787eb1f9..5753b4bf3c 100644 --- a/src/commands/default/muxcommand.py +++ b/src/commands/default/muxcommand.py @@ -5,6 +5,9 @@ The command template for the default MUX-style command set from src.utils import utils from src.commands.command import Command +# limit symbol import for API +__all__ = ("MuxCommand",) + class MuxCommand(Command): """ This sets up the basis for a MUX command. The idea diff --git a/src/commands/default/system.py b/src/commands/default/system.py index 396950c6c6..4fa43b4282 100644 --- a/src/commands/default/system.py +++ b/src/commands/default/system.py @@ -18,6 +18,10 @@ from src.server.models import ServerConfig from src.utils import create, logger, utils, gametime from src.commands.default.muxcommand import MuxCommand +# limit symbol import for API +__all__ = ("CmdReload", "CmdReset", "CmdShutdown", "CmdPy", + "CmdScripts", "CmdObjects", "CmdService", "CmdVersion", + "CmdTime", "CmdServerLoad", "CmdPs") class CmdReload(MuxCommand): """ diff --git a/src/commands/default/unloggedin.py b/src/commands/default/unloggedin.py index 32444f5f3f..694d09f578 100644 --- a/src/commands/default/unloggedin.py +++ b/src/commands/default/unloggedin.py @@ -15,9 +15,12 @@ from src.utils import create, logger, utils, ansi from src.commands.default.muxcommand import MuxCommand from src.commands.cmdhandler import CMD_LOGINSTART +# limit symbol import for API +__all__ = ("CmdUnconnectedConnect", "CmdUnconnectedCreate", "CmdUnconnectedQuit", "CmdUnconnectedLook", "CmdUnconnectedHelp") + CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE -class CmdConnect(MuxCommand): +class CmdUnconnectedConnect(MuxCommand): """ Connect to the game. @@ -86,7 +89,7 @@ class CmdConnect(MuxCommand): player.execute_cmd("look") -class CmdCreate(MuxCommand): +class CmdUnconnectedCreate(MuxCommand): """ Create a new account. @@ -215,7 +218,7 @@ its and @/./+/-/_ only.") # this echoes the restrictions made by django's auth m session.msg(string % (traceback.format_exc())) logger.log_errmsg(traceback.format_exc()) -class CmdQuit(MuxCommand): +class CmdUnconnectedQuit(MuxCommand): """ We maintain a different version of the quit command here for unconnected players for the sake of simplicity. The logged in diff --git a/src/comms/__init__.py b/src/comms/__init__.py index e69de29bb2..6338f63c97 100644 --- a/src/comms/__init__.py +++ b/src/comms/__init__.py @@ -0,0 +1,12 @@ +""" +Makes it easier to import by grouping all relevant things already at this level. + +You can henceforth import most things directly from src.comms +Also, the initiated object manager is available as src.comms.msgmanager and src.comms.channelmanager. + +""" + +from src.comms.models import * + +msgmanager = Msg.objects +channelmanager = Channel.objects diff --git a/src/help/__init__.py b/src/help/__init__.py index e69de29bb2..95dd700232 100644 --- a/src/help/__init__.py +++ b/src/help/__init__.py @@ -0,0 +1,11 @@ +""" +Makes it easier to import by grouping all relevant things already at this level. + +You can henceforth import most things directly from src.help +Also, the initiated object manager is available as src.help.manager. + +""" + +from src.help.models import * + +manager = HelpEntry.objects diff --git a/src/objects/__init__.py b/src/objects/__init__.py index e69de29bb2..87a96402ab 100644 --- a/src/objects/__init__.py +++ b/src/objects/__init__.py @@ -0,0 +1,12 @@ +""" +Makes it easier to import by grouping all relevant things already at this level. + +You can henceforth import most things directly from src.objects +Also, the initiated object manager is available as src.objects.manager. + +""" + +from src.objects.objects import * +from src.objects.models import ObjectDB + +manager = ObjectDB.objects diff --git a/src/objects/objects.py b/src/objects/objects.py index 9bea5cc4ee..c9658d4da9 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -29,35 +29,104 @@ class Object(TypeClass): objects in the game. """ - ## available properties + def __init__(self, dbobj): + """ + This is the root typeclass object, implementing an in-game Evennia + game object, such as having a location, being able to be + manipulated or looked at, etc. If you create a new typeclass, it + must always inherit from this object (or any of the other objects + in this file, since they all actually inherit from BaseObject, as + seen in src.object.objects). + + + Object Typeclass API: + + * Available properties (only available on initiated typeclass objects) + + key (string) - name of object + name (string)- same as key + aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. + dbref (int, read-only) - unique #id-number. Also "id" can be used. + dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class + typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. + date_created (string) - time stamp of object creation + permissions (list of strings) - list of permission strings + + player (Player) - controlling player (will also return offline player) + location (Object) - current location. Is None if this is a room + home (Object) - safety start-location + sessions (list of Sessions, read-only) - returns all sessions connected to this object + has_player (bool, read-only)- will only return *connected* players + contents (list of Objects, read-only) - returns all objects inside this object (including exits) + exits (list of Objects, read-only) - returns all exits from this object, if any + destination (Object) - only set if this object is an exit. + is_superuser (bool, read-only) - True/False if this user is a superuser + + * Handlers available + + locks - lock-handler: use locks.add() to add new lock strings + db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr + ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data + scripts - script-handler. Add new scripts to object with scripts.add() + cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object + nicks - nick-handler. New nicks with nicks.add(). + + * Helper methods (see src.objects.objects.py for full headers) + + search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False) + execute_cmd(raw_string) + msg(message, from_obj=None, data=None) + msg_contents(message, exclude=None, from_obj=None, data=None) + move_to(destination, quiet=False, emit_to_obj=None, use_destination=True) + copy(new_key=None) + delete() + is_typeclass(typeclass, exact=False) + swap_typeclass(new_typeclass, clean_attributes=False, no_default=True) + access(accessing_obj, access_type='read', default=False) + check_permstring(permstring) + + * Hook methods + + basetype_setup() - only called once, used for behind-the-scenes setup. Normally not modified. + basetype_posthook_setup() - customization in basetype, after the object has been created; Normally not modified. + + at_object_creation() - only called once, when object is first created. Object customizations go here. + at_object_delete() - called just before deleting an object. If returning False, deletion is aborted. Note that all objects + inside a deleted object are automatically moved to their , they don't need to be removed here. + + at_init() - called whenever typeclass is cached from memory, at least once every server restart/reload + at_cmdset_get() - this is called just before the command handler requests a cmdset from this object + at_first_login() - (player-controlled objects only) called once, the very first time user logs in. + at_pre_login() - (player-controlled objects only) called every time the user connects, after they have identified, before other setup + at_post_login() - (player-controlled objects only) called at the end of login, just before setting the player loose in the world. + at_disconnect() - (player-controlled objects only) called just before the user disconnects (or goes linkless) + at_server_reload() - called before server is reloaded + at_server_shutdown() - called just before server is fully shut down + + at_before_move(destination) - called just before moving object to the destination. If returns False, move is cancelled. + announce_move_from(destination) - called in old location, just before move, if obj.move_to() has quiet=False + announce_move_to(source_location) - called in new location, just after move, if obj.move_to() has quiet=False + at_after_move(source_location) - always called after a move has been successfully performed. + at_object_leave(obj, target_location) - called when an object leaves this object in any fashion + at_object_receive(obj, source_location) - called when this object receives another object + + at_before_traverse(traversing_object) - (exit-objects only) called just before an object traverses this object + at_after_traverse(traversing_object, source_location) - (exit-objects only) called just after a traversal has happened. + at_failed_traverse(traversing_object) - (exit-objects only) called if traversal fails and property err_traverse is not defined. + + at_msg_receive(self, msg, from_obj=None, data=None) - called when a message (via self.msg()) is sent to this obj. + If returns false, aborts send. + at_msg_send(self, msg, to_obj=None, data=None) - called when this objects sends a message to someone via self.msg(). + + return_appearance(looker) - describes this object. Used by "look" command by default + at_desc(looker=None) - called by 'look' whenever the appearance is requested. + at_get(getter) - called after object has been picked up. Does not stop pickup. + at_drop(dropper) - called when this object has been dropped. + at_say(speaker, message) - by default, called if an object inside this object speaks + + """ + super(Object, self).__init__(dbobj) - # key (string) - name of object - # name (string)- same as key - # aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. - # dbref (int, read-only) - unique #id-number. Also "id" can be used. - # dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class - # typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. - # date_created (string) - time stamp of object creation - # permissions (list of strings) - list of permission strings - - # player (Player) - controlling player (will also return offline player) - # location (Object) - current location. Is None if this is a room - # home (Object) - safety start-location - # sessions (list of Sessions, read-only) - returns all sessions connected to this object - # has_player (bool, read-only)- will only return *connected* players - # contents (list of Objects, read-only) - returns all objects inside this object (including exits) - # exits (list of Objects, read-only) - returns all exits from this object, if any - # destination (Object) - only set if this object is an exit. - # is_superuser (bool, read-only) - True/False if this user is a superuser - - # Handlers - # locks - lock-handler: use locks.add() to add new lock strings - # db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr - # ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data - # scripts - script-handler. Add new scripts to object with scripts.add() - # cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object - # nicks - nick-handler. New nicks with nicks.add(). - ## methods inherited from the database object (overload them here) def search(self, ostring, diff --git a/src/players/__init__.py b/src/players/__init__.py index e69de29bb2..fb882aa549 100644 --- a/src/players/__init__.py +++ b/src/players/__init__.py @@ -0,0 +1,12 @@ +""" +Makes it easier to import by grouping all relevant things already at this level. + +You can henceforth import most things directly from src.player +Also, the initiated object manager is available as src.players.manager. + +""" + +from src.players.player import * +from src.players.models import PlayerDB + +manager = PlayerDB.objects diff --git a/src/players/player.py b/src/players/player.py index 7d0a17937b..3a5c0e0aa4 100644 --- a/src/players/player.py +++ b/src/players/player.py @@ -18,33 +18,73 @@ class Player(TypeClass): """ Base typeclass for all Players. """ + def __init__(self, dbobj): + """ + This is the base Typeclass for all Players. Players represent + the person playing the game and tracks account info, password + etc. They are OOC entities without presence in-game. A Player + can connect to a Character Object in order to "enter" the + game. - ## available properties + Player Typeclass API: - # key (string) - name of player - # name (string)- wrapper for user.username - # aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. - # dbref (int, read-only) - unique #id-number. Also "id" can be used. - # dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class - # typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. - # date_created (string) - time stamp of object creation - # permissions (list of strings) - list of permission strings + * Available properties (only available on initiated typeclass objects) - # user (User, read-only) - django User authorization object - # obj (Object) - game object controlled by player. 'character' can also be used. - # sessions (list of Sessions) - sessions connected to this player - # is_superuser (bool, read-only) - if the connected user is a superuser + key (string) - name of player + name (string)- wrapper for user.username + aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. + dbref (int, read-only) - unique #id-number. Also "id" can be used. + dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class + typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. + date_created (string) - time stamp of object creation + permissions (list of strings) - list of permission strings + + user (User, read-only) - django User authorization object + obj (Object) - game object controlled by player. 'character' can also be used. + sessions (list of Sessions) - sessions connected to this player + is_superuser (bool, read-only) - if the connected user is a superuser + + * Handlers + + locks - lock-handler: use locks.add() to add new lock strings + db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr + ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data + scripts - script-handler. Add new scripts to object with scripts.add() + cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object + nicks - nick-handler. New nicks with nicks.add(). - ## Handlers + * Helper methods + + msg(outgoing_string, from_obj=None, data=None) + swap_character(new_character, delete_old_character=False) + execute_cmd(raw_string) + search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False) + is_typeclass(typeclass, exact=False) + swap_typeclass(new_typeclass, clean_attributes=False, no_default=True) + access(accessing_obj, access_type='read', default=False) + check_permstring(permstring) + + * Hook methods + + basetype_setup() + at_player_creation() + + - note that the following hooks are also found on Objects and are + usually handled on the character level: + + at_init() + at_cmdset_get() + at_first_login() + at_post_login() + at_disconnect() + at_message_receive() + at_message_send() + at_server_reload() + at_server_shutdown() + + """ + super(Player, self).__init__(dbobj) - # locks - lock-handler: use locks.add() to add new lock strings - # db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr - # ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data - # scripts - script-handler. Add new scripts to object with scripts.add() - # cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object - # nicks - nick-handler. New nicks with nicks.add(). - - ## methods inherited from database model def msg(self, outgoing_string, from_obj=None, data=None): diff --git a/src/scripts/__init__.py b/src/scripts/__init__.py index e69de29bb2..5f15860a10 100644 --- a/src/scripts/__init__.py +++ b/src/scripts/__init__.py @@ -0,0 +1,12 @@ +""" +Makes it easier to import by grouping all relevant things already at this level. + +You can henceforth import most things directly from src.scripts +Also, the initiated object manager is available as src.scripts.manager. + +""" + +from src.scripts.scripts import * +from src.scripts.models import ScriptDB + +manager = ScriptDB.objects diff --git a/src/scripts/scripts.py b/src/scripts/scripts.py index b3c8d4db46..bcb137c588 100644 --- a/src/scripts/scripts.py +++ b/src/scripts/scripts.py @@ -20,9 +20,8 @@ from src.utils import logger # class ScriptClass(TypeClass): """ - Base class for scripts + Base class for scripts. Don't inherit from this, inherit from Script instead. """ - # private methods def __eq__(self, other): @@ -253,31 +252,73 @@ class Script(ScriptClass): the hooks called by the script machinery. """ - ## available properties + def __init__(self, dbobj): + """ + This is the base TypeClass for all Scripts. Scripts describe events, timers and states in game, + they can have a time component or describe a state that changes under certain conditions. - # key (string) - name of object - # name (string)- same as key - # aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. - # dbref (int, read-only) - unique #id-number. Also "id" can be used. - # dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class - # typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. - # date_created (string) - time stamp of object creation - # permissions (list of strings) - list of permission strings + Script API: - # desc (string) - optional description of script, shown in listings - # obj (Object) - optional object that this script is connected to and acts on (set automatically by obj.scripts.add()) - # interval (int) - how often script should run, in seconds. <0 turns off ticker - # start_delay (bool) - if the script should start repeating right away or wait self.interval seconds - # repeats (int) - how many times the script should repeat before stopping. 0 means infinite repeats - # persistent (bool) - if script should survive a server shutdown or not - # is_active (bool) - if script is currently running + * Available properties (only available on initiated Typeclass objects) - ## Handlers + key (string) - name of object + name (string)- same as key + aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. + dbref (int, read-only) - unique #id-number. Also "id" can be used. + dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class + typeclass (Object, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. + date_created (string) - time stamp of object creation + permissions (list of strings) - list of permission strings - # locks - lock-handler: use locks.add() to add new lock strings - # db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr - # ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data + desc (string) - optional description of script, shown in listings + obj (Object) - optional object that this script is connected to and acts on (set automatically by obj.scripts.add()) + interval (int) - how often script should run, in seconds. <0 turns off ticker + start_delay (bool) - if the script should start repeating right away or wait self.interval seconds + repeats (int) - how many times the script should repeat before stopping. 0 means infinite repeats + persistent (bool) - if script should survive a server shutdown or not + is_active (bool) - if script is currently running + * Handlers + + locks - lock-handler: use locks.add() to add new lock strings + db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr + ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data + + * Helper methods + + start() - start script (this usually happens automatically at creation and obj.script.add() etc) + stop() - stop script, and delete it + pause() - put the script on hold, until unpause() is called. If script is persistent, the pause state will survive a shutdown. + unpause() - restart a previously paused script. The script will continue as if it was never paused. + time_until_next_repeat() - if a timed script (interval>0), returns time until next tick + + * Hook methods + + at_script_creation() - called only once, when an object of this + class is first created. + is_valid() - is called to check if the script is valid to be running + at the current time. If is_valid() returns False, the running + script is stopped and removed from the game. You can use this + to check state changes (i.e. an script tracking some combat + stats at regular intervals is only valid to run while there is + actual combat going on). + at_start() - Called every time the script is started, which for persistent + scripts is at least once every server start. Note that this is + unaffected by self.delay_start, which only delays the first call + to at_repeat(). + at_repeat() - Called every self.interval seconds. It will be called immediately + upon launch unless self.delay_start is True, which will delay + the first call of this method by self.interval seconds. If + self.interval==0, this method will never be called. + at_stop() - Called as the script object is stopped and is about to be removed from + the game, e.g. because is_valid() returned False. + at_server_reload() - Called when server reloads. Can be used to save temporary + variables you want should survive a reload. + at_server_shutdown() - called at a full server shutdown. + + + """ + super(Script, self).__init__(dbobj) def at_script_creation(self): """ diff --git a/src/server/__init__.py b/src/server/__init__.py index e69de29bb2..1e2c610945 100644 --- a/src/server/__init__.py +++ b/src/server/__init__.py @@ -0,0 +1,11 @@ +""" +Makes it easier to import by grouping all relevant things already at this level. + +You can henceforth import most things directly from src.server +Also, the initiated object manager is available as src.server.manager. + +""" + +from src.server.models import * + +manager = ServerConfig.objects diff --git a/src/typeclasses/typeclass.py b/src/typeclasses/typeclass.py index 67acd8c6f2..edd0a94301 100644 --- a/src/typeclasses/typeclass.py +++ b/src/typeclasses/typeclass.py @@ -44,6 +44,9 @@ class MetaTypeClass(type): super(MetaTypeClass, mcs).__init__(*args, **kwargs) mcs.typename = mcs.__name__ mcs.path = "%s.%s" % (mcs.__module__, mcs.__name__) + + + def __str__(cls): return "%s" % cls.__name__