From 4a5de0495657e483517b6774e489ce81b59d8349 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 14 Sep 2013 09:10:31 +0200 Subject: [PATCH] Changed msg() to work with **kwargs rather than data dicts. Still not fully updated the portal side (also remember that keywords let through to the portal must not contain dbobjs, since the portal has no connection to the database). --- src/commands/default/player.py | 2 +- src/commands/default/system.py | 2 +- src/objects/models.py | 12 ++++++------ src/objects/objects.py | 8 ++++---- src/players/models.py | 14 ++++++++------ src/players/player.py | 4 ++-- src/server/oobhandler.py | 8 ++++++++ src/server/serversession.py | 8 ++++---- src/server/sessionhandler.py | 20 ++++++++++++++------ src/typeclasses/models.py | 1 - src/utils/dbserialize.py | 14 +++++++++++--- 11 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/commands/default/player.py b/src/commands/default/player.py index 009ea4b98f..51c8f1c479 100644 --- a/src/commands/default/player.py +++ b/src/commands/default/player.py @@ -370,7 +370,7 @@ class CmdWho(MuxPlayerCommand): session.protocol_key, isinstance(session.address, tuple) and session.address[0] or session.address]) else: - table = prettytable.PrettyTable(["{wPlayer name", "{wOn for", "{Idle"]) + table = prettytable.PrettyTable(["{wPlayer name", "{wOn for", "{wIdle"]) for session in session_list: if not session.logged_in: continue delta_cmd = time.time() - session.cmd_last_visible diff --git a/src/commands/default/system.py b/src/commands/default/system.py index fe4b56bfeb..da57382afe 100644 --- a/src/commands/default/system.py +++ b/src/commands/default/system.py @@ -404,7 +404,7 @@ class CmdPlayers(MuxCommand): """ key = "@players" aliases = ["@listplayers"] - locks = "cmd:perm(listplayers) or perm(Admins)" + locks = "cmd:perm(listplayers) or perm(Wizards)" def func(self): "List the players" diff --git a/src/objects/models.py b/src/objects/models.py index 7fcb0d7684..d536ce7165 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -658,7 +658,7 @@ class ObjectDB(TypedObject): break return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, callertype="object", sessid=sessid) - def msg(self, msg=None, from_obj=None, data=None, sessid=0): + def msg(self, text=None, **kwargs):#from_obj=None, data=None, sessid=0): """ Emits something to a session attached to the object. @@ -672,13 +672,13 @@ class ObjectDB(TypedObject): """ if _GA(self, 'player'): # note that we must call the player *typeclass'* msg(), otherwise one couldn't overload it. - if sessid == 0: + if kwargs.get("sessid",0) == 0: sessid = None - if from_obj and hasattr(from_obj, "sessid"): - sessid = from_obj.sessid + if "from_obj" in kwargs and hasattr(kwargs["from_obj"], "sessid"): + kwargs["sessid"] = from_obj.sessid elif hasattr(self, "sessid"): - sessid = self.sessid - _GA(_GA(self, 'player'), "typeclass").msg(msg, from_obj=from_obj, data=data, sessid=sessid) + kwargs["sessid"] = self.sessid + _GA(_GA(self, 'player'), "typeclass").msg(text=text, **kwargs)#from_obj=from_obj, data=data, sessid=sessid) def emit_to(self, message, from_obj=None, data=None): "Deprecated. Alias for msg" diff --git a/src/objects/objects.py b/src/objects/objects.py index a6b74c664c..2eea10dc86 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -222,7 +222,7 @@ class Object(TypeClass): """ return self.dbobj.execute_cmd(raw_string, sessid=sessid) - def msg(self, message, from_obj=None, data=None, sessid=0): + def msg(self, text=None, **kwargs):#message, from_obj=None, data=None, sessid=0): """ Emits something to any sessions attached to the object. @@ -233,7 +233,7 @@ class Object(TypeClass): sessid: optional session target. If sessid=0, the session will default to self.sessid or from_obj.sessid. """ - self.dbobj.msg(message, from_obj=from_obj, data=data, sessid=0) + self.dbobj.msg(text=text, **kwargs)#message, from_obj=from_obj, data=data, sessid=0) def msg_contents(self, message, exclude=None, from_obj=None, data=None): """ @@ -653,7 +653,7 @@ class Object(TypeClass): """ pass - def at_msg_receive(self, msg, from_obj=None, data=None): + def at_msg_receive(self, text=None, **kwargs):#from_obj=None, data=None): """ This hook is called whenever someone sends a message to this object. @@ -674,7 +674,7 @@ class Object(TypeClass): """ return True - def at_msg_send(self, msg, to_obj=None, data=None): + def at_msg_send(self, text=None, **kwargs):#msg, to_obj=None, data=None): """ This is a hook that is called when /this/ object sends a message to another object with obj.msg() diff --git a/src/players/models.py b/src/players/models.py index 79eecd043b..2e38cc4d0b 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -248,7 +248,7 @@ class PlayerDB(TypedObject, AbstractUser): # PlayerDB class access methods # - def msg(self, outgoing_string, from_obj=None, data=None, sessid=None): + def msg(self, text=None, **kwargs):#outgoing_string, from_obj=None, data=None, sessid=None): """ Evennia -> User This is the main route for sending data back to the user from the server. @@ -262,25 +262,27 @@ class PlayerDB(TypedObject, AbstractUser): a command on a Character, the character automatically stores and handles the sessid). """ + from_obj = kwargs.pop("from_obj", None) + sessid = kwargs.pop("sessid", 0) if from_obj: # call hook try: - _GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data) + _GA(from_obj, "at_msg_send")(text=text, to_obj=self, data=data) except Exception: pass - outgoing_string = utils.to_str(outgoing_string, force_string=True) + outgoing_string = utils.to_str(text, force_string=True) session = _MULTISESSION_MODE == 2 and sessid and _GA(self, "get_session")(sessid) or None if session: obj = session.puppet - if obj and not obj.at_msg_receive(outgoing_string, from_obj=from_obj, data=data): + if obj and not obj.at_msg_receive(text, **kwargs): # if hook returns false, cancel send return - session.msg(outgoing_string, data) + session.msg(text=text, **kwargs) else: # if no session was specified, send to them all for sess in _GA(self, 'get_all_sessions')(): - sess.msg(outgoing_string, data) + sess.msg(text=text, **kwargs) def inmsg(self, ingoing_string, session): """ diff --git a/src/players/player.py b/src/players/player.py index 89db5db450..6f1c4c8b58 100644 --- a/src/players/player.py +++ b/src/players/player.py @@ -96,7 +96,7 @@ class Player(TypeClass): ## methods inherited from database model - def msg(self, outgoing_string, from_obj=None, data=None, sessid=None): + def msg(self, text=None, **kwargs):#outgoing_string, from_obj=None, data=None, sessid=None): """ Evennia -> User This is the main route for sending data back to the user from the server. @@ -110,7 +110,7 @@ class Player(TypeClass): a command on a Character, the character automatically stores and handles the sessid). """ - self.dbobj.msg(outgoing_string, from_obj=from_obj, data=data, sessid=sessid) + self.dbobj.msg(text=text, **kwargs)#outgoing_string, from_obj=from_obj, data=data, sessid=sessid) def swap_character(self, new_character, delete_old_character=False): """ diff --git a/src/server/oobhandler.py b/src/server/oobhandler.py index ca91e8632f..e6467fa64f 100644 --- a/src/server/oobhandler.py +++ b/src/server/oobhandler.py @@ -126,6 +126,14 @@ class OOBHandler(object): self.tracked = defaultdict(dict) self.oobstrings = "" + def parse_commanddict(self, dic): + """ + The command dict is on the form + {functionname:((args), {kwargs}), ...} + It is stored in text form as a pickle. + """ + + def _make_hash(self, callback_key, hashkey): """ diff --git a/src/server/serversession.py b/src/server/serversession.py index 2626eb008e..ff0dbbbcd5 100644 --- a/src/server/serversession.py +++ b/src/server/serversession.py @@ -183,11 +183,11 @@ class ServerSession(Session): self.update_session_counters() execute_cmd = data_in # alias - def data_out(self, msg, data=None): + def data_out(self, text=None, **kwargs): """ Send Evennia -> Player """ - self.sessionhandler.data_out(self, msg, data) + self.sessionhandler.data_out(self, text=text, **kwargs) def oob_data_in(self, data): """ @@ -276,9 +276,9 @@ class ServerSession(Session): #def disconnect(self): # "alias for session_disconnect" # self.session_disconnect() - def msg(self, string='', data=None): + def msg(self, text='', **kwargs): "alias for at_data_out" - self.data_out(string, data=data) + self.data_out(text=text, **kwargs) # Dummy API hooks for use during non-loggedin operation diff --git a/src/server/sessionhandler.py b/src/server/sessionhandler.py index eaa76c7d9a..7dc40cb832 100644 --- a/src/server/sessionhandler.py +++ b/src/server/sessionhandler.py @@ -15,7 +15,14 @@ There are two similar but separate stores of sessions: import time from django.conf import settings from src.commands.cmdhandler import CMD_LOGINSTART -from src.utils.utils import variable_from_module +from src.utils.utils import variable_from_module, to_str +try: + import cPickle as pickle +except ImportError: + import pickle + +dumps = lambda data: to_str(pickle.dumps(data, pickle.HIGHEST_PROTOCOL)) +loads = lambda data: pickle.loads(to_str(data)) # delayed imports _PlayerDB = None @@ -350,20 +357,21 @@ class ServerSessionHandler(SessionHandler): for sess in self.sessions.values(): self.data_out(sess, message) - def data_out(self, session, string="", data=""): + def data_out(self, session, text="", **kwargs): """ Sending data Server -> Portal """ self.server.amp_protocol.call_remote_MsgServer2Portal(sessid=session.sessid, - msg=string, - data=data) - def data_in(self, sessid, string="", data=""): + msg=text, + data=kwargs) + def data_in(self, sessid, text="", data=""): """ Data Portal -> Server """ session = self.sessions.get(sessid, None) if session: - session.data_in(string) + kwargs = data if data else {} + session.data_in(text, **kwargs) # ignore 'data' argument for now; this is otherwise the place # to put custom effects on the server due to data input, e.g. diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 6e624e54c4..4c939e5f40 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -82,7 +82,6 @@ class Attribute(SharedMemoryModel): attributes, rather than making different classes for each object type and storing them directly. The added benefit is that we can add/remove attributes on the fly as we like. - The Attribute class defines the following properties: key - primary identifier lock_storage - perm strings diff --git a/src/utils/dbserialize.py b/src/utils/dbserialize.py index 44c1d36a1d..cb0b81f4a6 100644 --- a/src/utils/dbserialize.py +++ b/src/utils/dbserialize.py @@ -251,9 +251,10 @@ def from_pickle(data, db_obj=None): to a form that may contain database objects again. Note that if a database object was removed (or changed in-place) in the database, None will be returned. - db_obj - this is the model instance (normally an Attribute) that Saver*-type - iterables will save to when they update. It must have a 'value' - property that saves assigned data to the database. + db_obj - this is the model instance (normally an Attribute) that _Saver*-type + iterables (_SaverList etc) will save to when they update. It must have a 'value' + property that saves assigned data to the database. Skip if not serializing onto + a given object. If db_obj is given, this function will convert lists, dicts and sets to their _SaverList, _SaverDict and _SaverSet counterparts. @@ -338,3 +339,10 @@ def do_pickle(data): def do_unpickle(data): "Retrieve pickle from pickled string" return loads(to_str(data)) + +def dbserialize(data): + "Serialize to pickled form in one step" + return do_pickle(to_pickle(data)) +def dbunserialize(data, db_obj=None): + "Un-serialize in one step. See from_pickle for help db_obj." + return do_unpickle(from_pickle(data, db_obj=db_obj))