<s> """<STR_LIT>""" <EOL> from builtins import object <EOL> from collections import defaultdict <EOL> from django . conf import settings <EOL> from evennia . server . models import ServerConfig <EOL> from evennia . server . sessionhandler import SESSIONS <EOL> from evennia . scripts . tickerhandler import TickerHandler <EOL> from evennia . utils . dbserialize import dbserialize , dbunserialize , pack_dbobj , unpack_dbobj <EOL> from evennia . utils import logger <EOL> from evennia . utils . utils import make_iter , mod_import <EOL> _SA = object . __setattr__ <EOL> _GA = object . __getattribute__ <EOL> _DA = object . __delattr__ <EOL> _OOB_FUNCS = None <EOL> _OOB_ERROR = None <EOL> class OOBFieldMonitor ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> self . obj = obj <EOL> self . subscribers = defaultdict ( list ) <EOL> def __call__ ( self , fieldname ) : <EOL> """<STR_LIT>""" <EOL> for sessid , oobtuples in self . subscribers . items ( ) : <EOL> sessid = SESSIONS . get ( sessid ) <EOL> if sessid : <EOL> for ( oobfuncname , args , kwargs ) in oobtuples : <EOL> OOB_HANDLER . execute_cmd ( sessid , oobfuncname , fieldname , self . obj , * args , ** kwargs ) <EOL> def add ( self , session , oobfuncname , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> self . subscribers [ session . sessid ] . append ( ( oobfuncname , args , kwargs ) ) <EOL> def remove ( self , session , oobfuncname = None ) : <EOL> """<STR_LIT>""" <EOL> if oobfuncname : <EOL> self . subscribers [ session . sessid ] = [ item for item in self . subscribers [ session . sessid ] <EOL> if item [ <NUM_LIT:0> ] != oobfuncname ] <EOL> else : <EOL> self . subscribers . pop ( session . sessid , None ) <EOL> class OOBAtRepeater ( object ) : <EOL> """<STR_LIT>""" <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> "<STR_LIT>" <EOL> OOB_HANDLER . execute_cmd ( kwargs [ "<STR_LIT>" ] , kwargs [ "<STR_LIT>" ] , * args , ** kwargs ) <EOL> class OOBHandler ( TickerHandler ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> super ( OOBHandler , self ) . __init__ ( * args , ** kwargs ) <EOL> self . save_name = "<STR_LIT>" <EOL> self . oob_save_name = "<STR_LIT>" <EOL> self . oob_monitor_storage = { } <EOL> def _get_repeater_hook_name ( self , oobfuncname , interval , sessid ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" % ( oobfuncname , interval , sessid ) <EOL> def _get_fieldmonitor_name ( self , fieldname ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" % fieldname <EOL> def _add_monitor ( self , obj , sessid , fieldname , oobfuncname , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> fieldmonitorname = self . _get_fieldmonitor_name ( fieldname ) <EOL> if not hasattr ( obj , fieldmonitorname ) : <EOL> _SA ( obj , fieldmonitorname , OOBFieldMonitor ( obj ) ) <EOL> _GA ( obj , fieldmonitorname ) . add ( sessid , oobfuncname , * args , ** kwargs ) <EOL> storekey = ( pack_dbobj ( obj ) , sessid , fieldname , oobfuncname ) <EOL> stored = ( args , kwargs ) <EOL> self . oob_monitor_storage [ storekey ] = stored <EOL> def _remove_monitor ( self , obj , sessid , fieldname , oobfuncname = None ) : <EOL> """<STR_LIT>""" <EOL> fieldmonitorname = self . _get_fieldmonitor_name ( fieldname ) <EOL> try : <EOL> _GA ( obj , fieldmonitorname ) . remove ( sessid , oobfuncname = oobfuncname ) <EOL> if not _GA ( obj , fieldmonitorname ) . subscribers : <EOL> _DA ( obj , fieldmonitorname ) <EOL> except AttributeError : <EOL> pass <EOL> store_key = ( pack_dbobj ( obj ) , sessid , fieldname , oobfuncname ) <EOL> self . oob_monitor_storage . pop ( store_key , None ) <EOL> def save ( self ) : <EOL> """<STR_LIT>""" <EOL> super ( OOBHandler , self ) . save ( ) <EOL> if self . ticker_storage : <EOL> ServerConfig . objects . conf ( key = self . oob_save_name , <EOL> value = dbserialize ( self . oob_monitor_storage ) ) <EOL> else : <EOL> ServerConfig . objects . conf ( key = self . oob_save_name , delete = True ) <EOL> def restore ( self ) : <EOL> """<STR_LIT>""" <EOL> oob_storage = ServerConfig . objects . conf ( key = self . oob_save_name ) <EOL> if oob_storage : <EOL> self . oob_storage = dbunserialize ( oob_storage ) <EOL> for store_key , ( args , kwargs ) in self . oob_storage . items ( ) : <EOL> obj , sessid , fieldname , oobfuncname = store_key <EOL> obj = unpack_dbobj ( obj ) <EOL> self . _add_monitor ( obj , sessid , fieldname , oobfuncname , * args , ** kwargs ) <EOL> ticker_storage = ServerConfig . objects . conf ( key = self . save_name ) <EOL> if ticker_storage : <EOL> self . ticker_storage = dbunserialize ( ticker_storage ) <EOL> for store_key , ( args , kwargs ) in self . ticker_storage . items ( ) : <EOL> obj , interval , idstring = store_key <EOL> obj = unpack_dbobj ( obj ) <EOL> sessid = kwargs [ "<STR_LIT>" ] <EOL> oobfuncname = kwargs [ "<STR_LIT>" ] <EOL> self . add_repeater ( obj , sessid , oobfuncname , interval , * args , ** kwargs ) <EOL> def add_repeater ( self , obj , session , oobfuncname , interval = <NUM_LIT:20> , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> sessid = session <EOL> hook = OOBAtRepeater ( ) <EOL> hookname = self . _get_repeater_hook_name ( oobfuncname , interval , sessid ) <EOL> _SA ( obj , hookname , hook ) <EOL> kwargs . update ( { "<STR_LIT>" : sessid , "<STR_LIT>" : oobfuncname } ) <EOL> super ( OOBHandler , self ) . add ( obj , int ( interval ) , oobfuncname , hookname , * args , ** kwargs ) <EOL> def remove_repeater ( self , obj , session , oobfuncname , interval = <NUM_LIT:20> ) : <EOL> """<STR_LIT>""" <EOL> sessid = session . sessid <EOL> super ( OOBHandler , self ) . remove ( obj , interval , idstring = oobfuncname ) <EOL> hookname = self . _get_repeater_hook_name ( oobfuncname , interval , sessid ) <EOL> try : <EOL> _DA ( obj , hookname ) <EOL> except AttributeError : <EOL> pass <EOL> def add_field_monitor ( self , obj , session , field_name , oobfuncname , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> sessid = session . sessid <EOL> field_name = field_name if field_name . startswith ( "<STR_LIT>" ) else "<STR_LIT>" % field_name <EOL> self . _add_monitor ( obj , sessid , field_name , oobfuncname , * args , ** kwargs ) <EOL> def remove_field_monitor ( self , obj , session , field_name , oobfuncname = None ) : <EOL> """<STR_LIT>""" <EOL> sessid = session . sessid <EOL> field_name = field_name if field_name . startswith ( "<STR_LIT>" ) else "<STR_LIT>" % field_name <EOL> self . _remove_monitor ( obj , sessid , field_name , oobfuncname = oobfuncname ) <EOL> def add_attribute_monitor ( self , obj , session , attr_name , oobfuncname , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> sessid = session . sessid <EOL> attrobj = obj . attributes . get ( attr_name , return_obj = True ) <EOL> if attrobj : <EOL> self . _add_monitor ( attrobj , sessid , "<STR_LIT>" , oobfuncname ) <EOL> def remove_attribute_monitor ( self , obj , session , attr_name , oobfuncname ) : <EOL> """<STR_LIT>""" <EOL> sessid = session . sessid <EOL> attrobj = obj . attributes . get ( attr_name , return_obj = True ) <EOL> if attrobj : <EOL> self . _remove_monitor ( attrobj , sessid , "<STR_LIT>" , oobfuncname ) <EOL> def get_all_monitors ( self , session ) : <EOL> """<STR_LIT>""" <EOL> sessid = session . sessid <EOL> return [ ( unpack_dbobj ( key [ <NUM_LIT:0> ] ) , key [ <NUM_LIT:2> ] , stored [ <NUM_LIT:0> ] , stored [ <NUM_LIT:1> ] ) <EOL> for key , stored in self . oob_monitor_storage . items ( ) if key [ <NUM_LIT:1> ] == sessid ] <EOL> def execute_cmd ( self , session , oobfuncname , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if not session : <EOL> errmsg = "<STR_LIT>" % ( session , oobfuncname , args , kwargs ) <EOL> raise RuntimeError ( errmsg ) <EOL> try : <EOL> oobfunc = _OOB_FUNCS [ oobfuncname ] <EOL> except Exception : <EOL> errmsg = "<STR_LIT>" % ( oobfuncname , "<STR_LIT:U+002CU+0020>" . join ( _OOB_FUNCS ) ) <EOL> if _OOB_ERROR : <EOL> _OOB_ERROR ( session , errmsg , * args , ** kwargs ) <EOL> errmsg = "<STR_LIT>" % errmsg <EOL> logger . log_trace ( errmsg ) <EOL> return <EOL> try : <EOL> oobfunc ( session , * args , ** kwargs ) <EOL> except Exception as err : <EOL> errmsg = "<STR_LIT>" % ( oobfuncname , args , kwargs , err ) <EOL> if _OOB_ERROR : <EOL> _OOB_ERROR ( session , errmsg , * args , ** kwargs ) <EOL> errmsg = "<STR_LIT>" % errmsg <EOL> logger . log_trace ( errmsg ) <EOL> OOB_HANDLER = OOBHandler ( ) <EOL> _OOB_FUNCS = { } <EOL> for modname in make_iter ( settings . OOB_PLUGIN_MODULES ) : <EOL> _OOB_FUNCS . update ( mod_import ( modname ) . CMD_MAP ) <EOL> _OOB_ERROR = _OOB_FUNCS . get ( "<STR_LIT>" , None ) <EOL> if not _OOB_ERROR : <EOL> def oob_error ( session , errmsg , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> session . msg ( oob = ( "<STR_LIT>" , ( "<STR_LIT>" , errmsg ) ) ) <EOL> _OOB_ERROR = oob_error </s>
