Merge branch 'add_signals' of https://github.com/volundmush/evennia into volundmush-add_signals
This commit is contained in:
commit
9e366b757f
5 changed files with 83 additions and 5 deletions
|
|
@ -29,6 +29,8 @@ from evennia.utils import class_from_module, create, logger
|
||||||
from evennia.utils.utils import (lazy_property, to_str,
|
from evennia.utils.utils import (lazy_property, to_str,
|
||||||
make_iter, is_iter,
|
make_iter, is_iter,
|
||||||
variable_from_module)
|
variable_from_module)
|
||||||
|
from evennia.server.signals import (SIGNAL_ACCOUNT_POST_CREATE, SIGNAL_OBJECT_POST_PUPPET,
|
||||||
|
SIGNAL_OBJECT_POST_UNPUPPET)
|
||||||
from evennia.typeclasses.attributes import NickHandler
|
from evennia.typeclasses.attributes import NickHandler
|
||||||
from evennia.scripts.scripthandler import ScriptHandler
|
from evennia.scripts.scripthandler import ScriptHandler
|
||||||
from evennia.commands.cmdsethandler import CmdSetHandler
|
from evennia.commands.cmdsethandler import CmdSetHandler
|
||||||
|
|
@ -52,6 +54,7 @@ _CONNECT_CHANNEL = None
|
||||||
CREATION_THROTTLE = Throttle(limit=2, timeout=10 * 60)
|
CREATION_THROTTLE = Throttle(limit=2, timeout=10 * 60)
|
||||||
LOGIN_THROTTLE = Throttle(limit=5, timeout=5 * 60)
|
LOGIN_THROTTLE = Throttle(limit=5, timeout=5 * 60)
|
||||||
|
|
||||||
|
|
||||||
class AccountSessionHandler(object):
|
class AccountSessionHandler(object):
|
||||||
"""
|
"""
|
||||||
Manages the session(s) attached to an account.
|
Manages the session(s) attached to an account.
|
||||||
|
|
@ -312,6 +315,7 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
||||||
obj.locks.cache_lock_bypass(obj)
|
obj.locks.cache_lock_bypass(obj)
|
||||||
# final hook
|
# final hook
|
||||||
obj.at_post_puppet()
|
obj.at_post_puppet()
|
||||||
|
SIGNAL_OBJECT_POST_PUPPET.send(sender=obj, account=self, session=session)
|
||||||
|
|
||||||
def unpuppet_object(self, session):
|
def unpuppet_object(self, session):
|
||||||
"""
|
"""
|
||||||
|
|
@ -334,6 +338,7 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
||||||
if not obj.sessions.count():
|
if not obj.sessions.count():
|
||||||
del obj.account
|
del obj.account
|
||||||
obj.at_post_unpuppet(self, session=session)
|
obj.at_post_unpuppet(self, session=session)
|
||||||
|
SIGNAL_OBJECT_POST_UNPUPPET.send(sender=obj, session=session, account=self)
|
||||||
# Just to be sure we're always clear.
|
# Just to be sure we're always clear.
|
||||||
session.puppet = None
|
session.puppet = None
|
||||||
session.puid = None
|
session.puid = None
|
||||||
|
|
@ -746,7 +751,9 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
||||||
# Update the throttle to indicate a new account was created from this IP
|
# Update the throttle to indicate a new account was created from this IP
|
||||||
if ip and not guest: CREATION_THROTTLE.update(ip, 'Too many accounts being created.')
|
if ip and not guest:
|
||||||
|
CREATION_THROTTLE.update(ip, 'Too many accounts being created.')
|
||||||
|
SIGNAL_ACCOUNT_POST_CREATE.send(sender=account, ip=ip)
|
||||||
return account, errors
|
return account, errors
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ from django.utils.encoding import smart_str
|
||||||
from evennia.accounts.manager import AccountDBManager
|
from evennia.accounts.manager import AccountDBManager
|
||||||
from evennia.typeclasses.models import TypedObject
|
from evennia.typeclasses.models import TypedObject
|
||||||
from evennia.utils.utils import make_iter
|
from evennia.utils.utils import make_iter
|
||||||
|
from evennia.server.signals import SIGNAL_ACCOUNT_POST_RENAME
|
||||||
|
|
||||||
__all__ = ("AccountDB",)
|
__all__ = ("AccountDB",)
|
||||||
|
|
||||||
|
|
@ -146,8 +147,10 @@ class AccountDB(TypedObject, AbstractUser):
|
||||||
return self.username
|
return self.username
|
||||||
|
|
||||||
def __username_set(self, value):
|
def __username_set(self, value):
|
||||||
|
old_name = self.username
|
||||||
self.username = value
|
self.username = value
|
||||||
self.save(update_fields=["username"])
|
self.save(update_fields=["username"])
|
||||||
|
SIGNAL_ACCOUNT_POST_RENAME.send(self, old_name=old_name, new_name=value)
|
||||||
|
|
||||||
def __username_del(self):
|
def __username_del(self):
|
||||||
del self.username
|
del self.username
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ from django.conf import settings
|
||||||
from evennia.commands.cmdhandler import CMD_LOGINSTART
|
from evennia.commands.cmdhandler import CMD_LOGINSTART
|
||||||
from evennia.utils.logger import log_trace
|
from evennia.utils.logger import log_trace
|
||||||
from evennia.utils.utils import (variable_from_module, is_iter,
|
from evennia.utils.utils import (variable_from_module, is_iter,
|
||||||
to_str, make_iter, delay, callables_from_module)
|
make_iter, delay, callables_from_module)
|
||||||
|
from evennia.server.signals import SIGNAL_ACCOUNT_POST_LOGIN, SIGNAL_ACCOUNT_POST_LOGOUT
|
||||||
|
from evennia.server.signals import SIGNAL_ACCOUNT_POST_CONNECT, SIGNAL_ACCOUNT_POST_DISCONNECT
|
||||||
from evennia.utils.inlinefuncs import parse_inlinefunc
|
from evennia.utils.inlinefuncs import parse_inlinefunc
|
||||||
from codecs import decode as codecs_decode
|
from codecs import decode as codecs_decode
|
||||||
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
_INLINEFUNC_ENABLED = settings.INLINEFUNC_ENABLED
|
_INLINEFUNC_ENABLED = settings.INLINEFUNC_ENABLED
|
||||||
|
|
||||||
# delayed imports
|
# delayed imports
|
||||||
|
|
@ -483,7 +483,6 @@ class ServerSessionHandler(SessionHandler):
|
||||||
faking login without any AMP being actually active.
|
faking login without any AMP being actually active.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if session.logged_in and not force:
|
if session.logged_in and not force:
|
||||||
# don't log in a session that is already logged in.
|
# don't log in a session that is already logged in.
|
||||||
return
|
return
|
||||||
|
|
@ -519,6 +518,9 @@ class ServerSessionHandler(SessionHandler):
|
||||||
sessiondata={"logged_in": True,
|
sessiondata={"logged_in": True,
|
||||||
"uid": session.uid})
|
"uid": session.uid})
|
||||||
account.at_post_login(session=session)
|
account.at_post_login(session=session)
|
||||||
|
if nsess < 2:
|
||||||
|
SIGNAL_ACCOUNT_POST_LOGIN.send(sender=account, session=session)
|
||||||
|
SIGNAL_ACCOUNT_POST_CONNECT.send(sender=account, session=session)
|
||||||
|
|
||||||
def disconnect(self, session, reason="", sync_portal=True):
|
def disconnect(self, session, reason="", sync_portal=True):
|
||||||
"""
|
"""
|
||||||
|
|
@ -545,7 +547,11 @@ class ServerSessionHandler(SessionHandler):
|
||||||
string = string.format(reason=sreason, account=session.account, address=session.address, nsessions=nsess)
|
string = string.format(reason=sreason, account=session.account, address=session.address, nsessions=nsess)
|
||||||
session.log(string)
|
session.log(string)
|
||||||
|
|
||||||
|
if nsess == 0:
|
||||||
|
SIGNAL_ACCOUNT_POST_LOGOUT.send(sender=session.account, session=session)
|
||||||
|
|
||||||
session.at_disconnect(reason)
|
session.at_disconnect(reason)
|
||||||
|
SIGNAL_ACCOUNT_POST_DISCONNECT.send(sender=session.account, session=session)
|
||||||
sessid = session.sessid
|
sessid = session.sessid
|
||||||
if sessid in self and not hasattr(self, "_disconnect_all"):
|
if sessid in self and not hasattr(self, "_disconnect_all"):
|
||||||
del self[sessid]
|
del self[sessid]
|
||||||
|
|
|
||||||
60
evennia/server/signals.py
Normal file
60
evennia/server/signals.py
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
"""
|
||||||
|
This module brings Django Signals into Evennia. These are events that
|
||||||
|
can be subscribed to by importing a given Signal and using the
|
||||||
|
following code.
|
||||||
|
|
||||||
|
THIS_SIGNAL.connect(callback, sender_object)
|
||||||
|
|
||||||
|
When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback
|
||||||
|
will be triggered.
|
||||||
|
|
||||||
|
Callbacks must be in the following format:
|
||||||
|
|
||||||
|
def my_callback(sender, **kwargs):
|
||||||
|
...
|
||||||
|
|
||||||
|
This is used on top of hooks to make certain features easier to
|
||||||
|
add to contribs without necessitating a full takeover of hooks
|
||||||
|
that may be in high demand.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from django.dispatch import Signal
|
||||||
|
|
||||||
|
# The sender is the created Account. This is triggered at the very end of Account.create()
|
||||||
|
# after the Account is created.
|
||||||
|
SIGNAL_ACCOUNT_POST_CREATE = Signal(providing_args=['ip', ])
|
||||||
|
|
||||||
|
# The Sender is the renamed Account. This is triggered by the username setter in AccountDB.
|
||||||
|
SIGNAL_ACCOUNT_POST_RENAME = Signal(providing_args=['old_name', 'new_name'])
|
||||||
|
|
||||||
|
# The Sender is the connecting Account. This is triggered when an Account connects cold;
|
||||||
|
# that is, it had no other sessions connected.
|
||||||
|
SIGNAL_ACCOUNT_POST_LOGIN = Signal(providing_args=['session', ])
|
||||||
|
|
||||||
|
# The Sender is the Account attempting to authenticate. This is triggered whenever a
|
||||||
|
# session tries to login to an Account but fails.
|
||||||
|
SIGNAL_ACCOUNT_POST_LOGIN_FAIL = Signal(providing_args=['session', ])
|
||||||
|
|
||||||
|
# The sender is the connecting Account. This is triggered whenever a session authenticates
|
||||||
|
# to an Account regardless of existing sessions.
|
||||||
|
SIGNAL_ACCOUNT_POST_CONNECT = Signal(providing_args=['session', ])
|
||||||
|
|
||||||
|
# The sender is the Account. This is triggered when an Account's final session disconnects.
|
||||||
|
SIGNAL_ACCOUNT_POST_LOGOUT = Signal(providing_args=['session', ])
|
||||||
|
|
||||||
|
# The sender is the disconnecting Account. This is triggered whenever a session disconnects
|
||||||
|
# from the account, regardless of how many it started with or remain.
|
||||||
|
SIGNAL_ACCOUNT_POST_DISCONNECT = Signal(providing_args=['session', ])
|
||||||
|
|
||||||
|
# The sender is the Object being puppeted. This is triggered after all puppeting hooks have
|
||||||
|
# been called. The Object has already been puppeted by this point.
|
||||||
|
SIGNAL_OBJECT_POST_PUPPET = Signal(providing_args=['session', 'account'])
|
||||||
|
|
||||||
|
# The sender is the Object being released. This is triggered after all hooks are called.
|
||||||
|
# The Object is no longer puppeted by this point.
|
||||||
|
SIGNAL_OBJECT_POST_UNPUPPET = Signal(providing_args=['session', 'account'])
|
||||||
|
|
||||||
|
# The sender is the Typed Object being released. This isn't necessarily an Object;
|
||||||
|
# it could be a script. It fires whenever the value of the Typed object's 'key'
|
||||||
|
# changes. Will need to use isinstance() or other filtering on things that use this.
|
||||||
|
SIGNAL_TYPED_OBJECT_POST_RENAME = Signal(providing_args=['old_key', 'new_key'])
|
||||||
|
|
@ -42,6 +42,7 @@ from evennia.typeclasses.attributes import Attribute, AttributeHandler, NAttribu
|
||||||
from evennia.typeclasses.tags import Tag, TagHandler, AliasHandler, PermissionHandler
|
from evennia.typeclasses.tags import Tag, TagHandler, AliasHandler, PermissionHandler
|
||||||
|
|
||||||
from evennia.utils.idmapper.models import SharedMemoryModel, SharedMemoryModelBase
|
from evennia.utils.idmapper.models import SharedMemoryModel, SharedMemoryModelBase
|
||||||
|
from evennia.server.signals import SIGNAL_TYPED_OBJECT_POST_RENAME
|
||||||
|
|
||||||
from evennia.typeclasses import managers
|
from evennia.typeclasses import managers
|
||||||
from evennia.locks.lockhandler import LockHandler
|
from evennia.locks.lockhandler import LockHandler
|
||||||
|
|
@ -326,6 +327,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
self.db_key = value
|
self.db_key = value
|
||||||
self.save(update_fields=["db_key"])
|
self.save(update_fields=["db_key"])
|
||||||
self.at_rename(oldname, value)
|
self.at_rename(oldname, value)
|
||||||
|
SIGNAL_TYPED_OBJECT_POST_RENAME.send(sender=self, old_key=oldname, new_key=value)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue