diff --git a/evennia/__init__.py b/evennia/__init__.py index 41244b91ec..0aa5ae7af0 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -136,7 +136,7 @@ __version__ = _create_version() del _create_version -def _init(): +def _init(portal_mode=False): """ This function is called automatically by the launcher only after Evennia has fully initialized all its models. It sets up the API @@ -185,7 +185,6 @@ def _init(): from .scripts.taskhandler import TASK_HANDLER from .scripts.tickerhandler import TICKER_HANDLER from .server import signals - from .server.sessionhandler import SESSION_HANDLER from .typeclasses.attributes import AttributeProperty from .typeclasses.tags import TagProperty from .utils import ansi, gametime, logger @@ -220,6 +219,21 @@ def _init(): search_tag, ) + from .utils.utils import class_from_module + if portal_mode: + # Set up the PortalSessionHandler + from evennia.server.portal import portalsessionhandler + portal_sess_handler_class = class_from_module(settings.PORTAL_SESSION_HANDLER_CLASS) + portalsessionhandler.PORTAL_SESSIONS = portal_sess_handler_class() + else: + # Create the ServerSesssionHandler + from evennia.server import sessionhandler + sess_handler_class = class_from_module(settings.SERVER_SESSION_HANDLER_CLASS) + sessionhandler.SESSIONS = sess_handler_class() + sessionhandler.SESSION_HANDLER = sessionhandler.SESSIONS + SESSION_HANDLER = sessionhandler.SESSIONS + + # API containers class _EvContainer(object): diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 3c1708c72d..baf2c50d93 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -20,6 +20,7 @@ from django.core.exceptions import ImproperlyConfigured, ValidationError from django.utils import timezone from django.utils.module_loading import import_string from django.utils.translation import gettext as _ +import evennia from evennia.accounts.manager import AccountManager from evennia.accounts.models import AccountDB from evennia.commands.cmdsethandler import CmdSetHandler @@ -41,8 +42,6 @@ from evennia.utils.utils import is_iter, lazy_property, make_iter, to_str, varia __all__ = ("DefaultAccount", "DefaultGuest") -_SESSIONS = None - _AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1)) _MULTISESSION_MODE = settings.MULTISESSION_MODE _AUTO_CREATE_CHARACTER_WITH_ACCOUNT = settings.AUTO_CREATE_CHARACTER_WITH_ACCOUNT @@ -95,13 +94,10 @@ class AccountSessionHandler(object): is given, this is a list with one (or zero) elements. """ - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS if sessid: - return make_iter(_SESSIONS.session_from_account(self.account, sessid)) + return make_iter(evennia.SESSION_HANDLER.session_from_account(self.account, sessid)) else: - return _SESSIONS.sessions_from_account(self.account) + return evennia.SESSION_HANDLER.sessions_from_account(self.account) def all(self): """ @@ -284,10 +280,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): reason (str, optional): Eventual reason for the disconnect. """ - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS - _SESSIONS.disconnect(session, reason) + evennia.SESSION_HANDLER.disconnect(session, reason) # puppeting operations diff --git a/evennia/accounts/bots.py b/evennia/accounts/bots.py index 97ef98134d..0f5a2cbddd 100644 --- a/evennia/accounts/bots.py +++ b/evennia/accounts/bots.py @@ -9,6 +9,7 @@ import time from django.conf import settings from django.utils.translation import gettext as _ +import evennia from evennia.accounts.accounts import DefaultAccount from evennia.scripts.scripts import DefaultScript from evennia.utils import logger, search, utils @@ -21,8 +22,6 @@ _RSS_ENABLED = settings.RSS_ENABLED _GRAPEVINE_ENABLED = settings.GRAPEVINE_ENABLED _DISCORD_ENABLED = settings.DISCORD_ENABLED and hasattr(settings, "DISCORD_BOT_TOKEN") -_SESSIONS = None - class BotStarter(DefaultScript): """ @@ -61,10 +60,7 @@ class BotStarter(DefaultScript): instead. This keeps the bot getting hit by IDLE_TIMEOUT. """ - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS - for session in _SESSIONS.sessions_from_account(self.account): + for session in evennia.SESSION_HANDLER.sessions_from_account(self.account): session.update_session_counters(idle=True) @@ -170,10 +166,6 @@ class IRCBot(Bot): self.delete() return - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS - # if keywords are given, store (the BotStarter script # will not give any keywords, so this should normally only # happen at initialization) @@ -208,7 +200,7 @@ class IRCBot(Bot): "port": self.db.irc_port, "ssl": self.db.irc_ssl, } - _SESSIONS.start_bot_session(self.factory_path, configdict) + evennia.SESSION_HANDLER.start_bot_session(self.factory_path, configdict) def at_msg_send(self, **kwargs): "Shortcut here or we can end up in infinite loop" @@ -336,12 +328,9 @@ class IRCBot(Bot): if txt.lower().startswith("who"): # return server WHO list (abbreviated for IRC) - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS whos = [] t0 = time.time() - for sess in _SESSIONS.get_sessions(): + for sess in evennia.SESSION_HANDLER.get_sessions(): delta_cmd = t0 - sess.cmd_last_visible delta_conn = t0 - session.conn_time account = sess.get_account() @@ -407,10 +396,6 @@ class RSSBot(Bot): self.delete() return - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS - if ev_channel: # connect to Evennia channel channel = search.channel_search(ev_channel) @@ -425,7 +410,7 @@ class RSSBot(Bot): # instruct the server and portal to create a new session with # the stored configuration configdict = {"uid": self.dbid, "url": self.db.rss_url, "rate": self.db.rss_rate} - _SESSIONS.start_bot_session("evennia.server.portal.rss.RSSBotFactory", configdict) + evennia.SESSION_HANDLER.start_bot_session("evennia.server.portal.rss.RSSBotFactory", configdict) def execute_cmd(self, txt=None, session=None, **kwargs): """ @@ -468,10 +453,6 @@ class GrapevineBot(Bot): self.delete() return - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS - # connect to Evennia channel if ev_channel: # connect to Evennia channel @@ -488,7 +469,7 @@ class GrapevineBot(Bot): # these will be made available as properties on the protocol factory configdict = {"uid": self.dbid, "grapevine_channel": self.db.grapevine_channel} - _SESSIONS.start_bot_session(self.factory_path, configdict) + evennia.SESSION_HANDLER.start_bot_session(self.factory_path, configdict) def at_msg_send(self, **kwargs): "Shortcut here or we can end up in infinite loop" @@ -619,12 +600,9 @@ class DiscordBot(Bot): channel.connect(self) # connect - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSION_HANDLER as _SESSIONS # these will be made available as properties on the protocol factory configdict = {"uid": self.dbid} - _SESSIONS.start_bot_session(self.factory_path, configdict) + evennia.SESSION_HANDLER.start_bot_session(self.factory_path, configdict) def at_pre_channel_msg(self, message, channel, senders=None, **kwargs): """ diff --git a/evennia/accounts/tests.py b/evennia/accounts/tests.py index 5cf6369412..384f9f882d 100644 --- a/evennia/accounts/tests.py +++ b/evennia/accounts/tests.py @@ -6,6 +6,7 @@ from unittest import TestCase from django.test import override_settings from mock import MagicMock, Mock, patch +import evennia from evennia.accounts.accounts import ( AccountSessionHandler, DefaultAccount, @@ -37,22 +38,20 @@ class TestAccountSessionHandler(TestCase): self.assertEqual(self.handler.get(), []) self.assertEqual(self.handler.get(100), []) - import evennia.server.sessionhandler - s1 = MagicMock() s1.logged_in = True s1.uid = self.account.uid - evennia.server.sessionhandler.SESSIONS[s1.uid] = s1 + evennia.SESSION_HANDLER[s1.uid] = s1 s2 = MagicMock() s2.logged_in = True s2.uid = self.account.uid + 1 - evennia.server.sessionhandler.SESSIONS[s2.uid] = s2 + evennia.SESSION_HANDLER[s2.uid] = s2 s3 = MagicMock() s3.logged_in = False s3.uid = self.account.uid + 2 - evennia.server.sessionhandler.SESSIONS[s3.uid] = s3 + evennia.SESSION_HANDLER[s3.uid] = s3 self.assertEqual([s.uid for s in self.handler.get()], [s1.uid]) self.assertEqual([s.uid for s in [self.handler.get(self.account.uid)]], [s1.uid]) @@ -251,8 +250,6 @@ class TestDefaultAccount(TestCase): def test_puppet_object_already_puppeting(self): "Check puppet_object method called, already puppeting this" - import evennia.server.sessionhandler - account = create.create_account( f"TestAccount{randint(0, 999999)}", email="test@test.com", @@ -260,7 +257,7 @@ class TestDefaultAccount(TestCase): typeclass=DefaultAccount, ) self.s1.uid = account.uid - evennia.server.sessionhandler.SESSIONS[self.s1.uid] = self.s1 + evennia.SESSION_HANDLER[self.s1.uid] = self.s1 self.s1.logged_in = True self.s1.data_out = Mock(return_value=None) @@ -276,8 +273,6 @@ class TestDefaultAccount(TestCase): def test_puppet_object_no_permission(self): "Check puppet_object method called, no permission" - import evennia.server.sessionhandler - account = create.create_account( f"TestAccount{randint(0, 999999)}", email="test@test.com", @@ -285,7 +280,7 @@ class TestDefaultAccount(TestCase): typeclass=DefaultAccount, ) self.s1.uid = account.uid - evennia.server.sessionhandler.SESSIONS[self.s1.uid] = self.s1 + evennia.SESSION_HANDLER[self.s1.uid] = self.s1 self.s1.data_out = MagicMock() obj = Mock() @@ -302,8 +297,6 @@ class TestDefaultAccount(TestCase): def test_puppet_object_joining_other_session(self): "Check puppet_object method called, joining other session" - import evennia.server.sessionhandler - account = create.create_account( f"TestAccount{randint(0, 999999)}", email="test@test.com", @@ -311,7 +304,7 @@ class TestDefaultAccount(TestCase): typeclass=DefaultAccount, ) self.s1.uid = account.uid - evennia.server.sessionhandler.SESSIONS[self.s1.uid] = self.s1 + evennia.SESSION_HANDLER[self.s1.uid] = self.s1 self.s1.puppet = None self.s1.logged_in = True @@ -332,8 +325,6 @@ class TestDefaultAccount(TestCase): def test_puppet_object_already_puppeted(self): "Check puppet_object method called, already puppeted" - import evennia.server.sessionhandler - account = create.create_account( f"TestAccount{randint(0, 999999)}", email="test@test.com", @@ -342,7 +333,7 @@ class TestDefaultAccount(TestCase): ) self.account = account self.s1.uid = account.uid - evennia.server.sessionhandler.SESSIONS[self.s1.uid] = self.s1 + evennia.SESSION_HANDLER[self.s1.uid] = self.s1 self.s1.puppet = None self.s1.logged_in = True @@ -410,7 +401,7 @@ class TestDefaultAccountEv(BaseEvenniaTest): # test no sessions with patch( - "evennia.accounts.accounts._SESSIONS.sessions_from_account", return_value=[] + "evennia.SESSION_HANDLER.sessions_from_account", return_value=[] ) as mock_sessh: idle = self.account.idle_time self.assertEqual(idle, None) @@ -423,7 +414,7 @@ class TestDefaultAccountEv(BaseEvenniaTest): # test no sessions with patch( - "evennia.accounts.accounts._SESSIONS.sessions_from_account", return_value=[] + "evennia.SESSION_HANDLER.sessions_from_account", return_value=[] ) as mock_sessh: idle = self.account.connection_time self.assertEqual(idle, None) diff --git a/evennia/commands/default/account.py b/evennia/commands/default/account.py index 6fb8bbb3f2..eb0b07495e 100644 --- a/evennia/commands/default/account.py +++ b/evennia/commands/default/account.py @@ -22,7 +22,7 @@ import time from codecs import lookup as codecs_lookup from django.conf import settings -from evennia.server.sessionhandler import SESSIONS +import evennia from evennia.utils import create, logger, search, utils COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) @@ -495,9 +495,8 @@ class CmdWho(COMMAND_DEFAULT_CLASS): """ Get all connected accounts by polling session. """ - account = self.account - session_list = SESSIONS.get_sessions() + session_list = evennia.SESSION_HANDLER.get_sessions() session_list = sorted(session_list, key=lambda o: o.account.key) @@ -508,7 +507,7 @@ class CmdWho(COMMAND_DEFAULT_CLASS): "Admins" ) - naccounts = SESSIONS.account_count() + naccounts = evennia.SESSION_HANDLER.account_count() if show_session_data: # privileged info table = self.styled_table( diff --git a/evennia/commands/default/admin.py b/evennia/commands/default/admin.py index 312c672c4f..69f9dee59f 100644 --- a/evennia/commands/default/admin.py +++ b/evennia/commands/default/admin.py @@ -10,7 +10,8 @@ import time from django.conf import settings from evennia.server.models import ServerConfig -from evennia.server.sessionhandler import SESSIONS + +import evennia from evennia.utils import class_from_module, evtable, logger, search COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS) @@ -68,7 +69,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS): if "sid" in self.switches: # Boot a particular session id. - sessions = SESSIONS.get_sessions(True) + sessions = evennia.SESSION_HANDLER.get_sessions(True) for sess in sessions: # Find the session with the matching session id. if sess.sessid == int(args): @@ -85,7 +86,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS): caller.msg(f"You don't have the permission to boot {pobj.key}.") return # we have a bootable object with a connected user - matches = SESSIONS.sessions_from_account(pobj) + matches = evennia.SESSION_HANDLER.sessions_from_account(pobj) for match in matches: boot_list.append(match) @@ -564,7 +565,7 @@ class CmdWall(COMMAND_DEFAULT_CLASS): return message = f'{self.caller.name} shouts "{self.args}"' self.msg("Announcing to all connected sessions ...") - SESSIONS.announce_all(message) + evennia.SESSION_HANDLER.announce_all(message) class CmdForce(COMMAND_DEFAULT_CLASS): diff --git a/evennia/commands/default/system.py b/evennia/commands/default/system.py index b33f50d1ec..58fcc19a51 100644 --- a/evennia/commands/default/system.py +++ b/evennia/commands/default/system.py @@ -16,9 +16,9 @@ import django import twisted from django.conf import settings +import evennia from evennia.accounts.models import AccountDB from evennia.scripts.taskhandler import TaskHandlerTask -from evennia.server.sessionhandler import SESSIONS from evennia.utils import gametime, logger, search, utils from evennia.utils.eveditor import EvEditor from evennia.utils.evmenu import ask_yes_no @@ -74,8 +74,8 @@ class CmdReload(COMMAND_DEFAULT_CLASS): if self.args: reason = "(Reason: %s) " % self.args.rstrip(".") if _BROADCAST_SERVER_RESTART_MESSAGES: - SESSIONS.announce_all(f" Server restart initiated {reason}...") - SESSIONS.portal_restart_server() + evennia.SESSION_HANDLER.announce_all(f" Server restart initiated {reason}...") + evennia.SESSION_HANDLER.portal_restart_server() class CmdReset(COMMAND_DEFAULT_CLASS): @@ -108,8 +108,8 @@ class CmdReset(COMMAND_DEFAULT_CLASS): """ Reload the system. """ - SESSIONS.announce_all(" Server resetting/restarting ...") - SESSIONS.portal_reset_server() + evennia.SESSION_HANDLER.announce_all(" Server resetting/restarting ...") + evennia.SESSION_HANDLER.portal_reset_server() class CmdShutdown(COMMAND_DEFAULT_CLASS): @@ -137,8 +137,8 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS): if self.args: announcement += "%s\n" % self.args logger.log_info(f"Server shutdown by {self.caller.name}.") - SESSIONS.announce_all(announcement) - SESSIONS.portal_shutdown() + evennia.SESSION_HANDLER.announce_all(announcement) + evennia.SESSION_HANDLER.portal_shutdown() def _py_load(caller): @@ -562,7 +562,7 @@ class CmdService(COMMAND_DEFAULT_CLASS): return # get all services - service_collection = SESSIONS.server.services + service_collection = evennia.SESSION_HANDLER.server.services if not switches or switches[0] == "list": # Just display the list of installed services and their diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 8b09cebf38..c499e6ada0 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -17,6 +17,7 @@ from unittest.mock import MagicMock, Mock, patch from anything import Anything from django.conf import settings from django.test import override_settings +import evennia from evennia import ( DefaultCharacter, DefaultExit, @@ -34,7 +35,6 @@ from evennia.commands.default import syscommands, system, unloggedin from evennia.commands.default.cmdset_character import CharacterCmdSet from evennia.commands.default.muxcommand import MuxCommand from evennia.prototypes import prototypes as protlib -from evennia.server.sessionhandler import SESSIONS from evennia.utils import create, gametime, utils from evennia.utils.test_resources import BaseEvenniaCommandTest # noqa from evennia.utils.test_resources import BaseEvenniaTest, EvenniaCommandTest @@ -2113,7 +2113,7 @@ class TestUnconnectedCommand(BaseEvenniaCommandTest): % ( settings.SERVERNAME, datetime.datetime.fromtimestamp(gametime.SERVER_START_TIME).ctime(), - SESSIONS.account_count(), + evennia.SESSION_HANDLER.account_count(), utils.get_evennia_version(), ) ) diff --git a/evennia/commands/default/unloggedin.py b/evennia/commands/default/unloggedin.py index 6d72c9d805..97bc953568 100644 --- a/evennia/commands/default/unloggedin.py +++ b/evennia/commands/default/unloggedin.py @@ -8,9 +8,9 @@ from codecs import lookup as codecs_lookup from django.conf import settings +import evennia from evennia.commands.cmdhandler import CMD_LOGINSTART from evennia.comms.models import ChannelDB -from evennia.server.sessionhandler import SESSIONS from evennia.utils import class_from_module, create, gametime, logger, utils COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS) @@ -462,7 +462,7 @@ class CmdUnconnectedInfo(COMMAND_DEFAULT_CLASS): % ( settings.SERVERNAME, datetime.datetime.fromtimestamp(gametime.SERVER_START_TIME).ctime(), - SESSIONS.account_count(), + evennia.SESSION_HANDLER.account_count(), utils.get_evennia_version(), ) ) diff --git a/evennia/contrib/base_systems/godotwebsocket/webclient.py b/evennia/contrib/base_systems/godotwebsocket/webclient.py index 9154d1c653..0c8001825f 100644 --- a/evennia/contrib/base_systems/godotwebsocket/webclient.py +++ b/evennia/contrib/base_systems/godotwebsocket/webclient.py @@ -12,7 +12,6 @@ from twisted.application import internet from evennia import settings from evennia.contrib.base_systems.godotwebsocket.text2bbcode import parse_to_bbcode from evennia.server.portal import webclient -from evennia.server.portal.portalsessionhandler import PORTAL_SESSIONS from evennia.settings_default import LOCKDOWN_MODE @@ -70,6 +69,7 @@ def start_plugin_services(portal): factory = GodotWebsocket() factory.noisy = False factory.protocol = GodotWebSocketClient + from evennia.server.portal.portalsessionhandler import PORTAL_SESSIONS factory.sessionhandler = PORTAL_SESSIONS interface = "127.0.0.1" if LOCKDOWN_MODE else settings.GODOT_CLIENT_WEBSOCKET_CLIENT_INTERFACE diff --git a/evennia/contrib/utils/auditing/tests.py b/evennia/contrib/utils/auditing/tests.py index 930cc1993e..d46b0cfc15 100644 --- a/evennia/contrib/utils/auditing/tests.py +++ b/evennia/contrib/utils/auditing/tests.py @@ -9,7 +9,7 @@ from anything import Anything from django.test import override_settings from mock import patch -from evennia.server.sessionhandler import SESSIONS +import evennia from evennia.utils.test_resources import BaseEvenniaTest from .server import AuditedServerSession @@ -21,13 +21,13 @@ class AuditingTest(BaseEvenniaTest): def setup_session(self): """Overrides default one in EvenniaTest""" dummysession = AuditedServerSession() - dummysession.init_session("telnet", ("localhost", "testmode"), SESSIONS) + dummysession.init_session("telnet", ("localhost", "testmode"), evennia.SESSION_HANDLER) dummysession.sessid = 1 - SESSIONS.portal_connect( + evennia.SESSION_HANDLER.portal_connect( dummysession.get_sync_data() ) # note that this creates a new Session! - session = SESSIONS.session_from_sessid(1) # the real session - SESSIONS.login(session, self.account, testmode=True) + session = evennia.SESSION_HANDLER.session_from_sessid(1) # the real session + evennia.SESSION_HANDLER.login(session, self.account, testmode=True) self.session = session @patch( diff --git a/evennia/contrib/utils/fieldfill/fieldfill.py b/evennia/contrib/utils/fieldfill/fieldfill.py index 6da046ed75..625002611d 100644 --- a/evennia/contrib/utils/fieldfill/fieldfill.py +++ b/evennia/contrib/utils/fieldfill/fieldfill.py @@ -138,9 +138,8 @@ Optional: object dbrefs). For boolean fields, return '0' or '1' to set the field to False or True. """ - +import evennia from evennia import Command -from evennia.server.sessionhandler import SESSIONS from evennia.utils import delay, evmenu, evtable, list_to_string, logger @@ -573,7 +572,7 @@ def verify_online_player(caller, value): made. """ # Get a list of sessions - session_list = SESSIONS.get_sessions() + session_list = evennia.SESSION_HANDLER.get_sessions() char_list = [] matched_character = None diff --git a/evennia/contrib/utils/git_integration/git_integration.py b/evennia/contrib/utils/git_integration/git_integration.py index cf50cc9fdd..a1020b8fe7 100644 --- a/evennia/contrib/utils/git_integration/git_integration.py +++ b/evennia/contrib/utils/git_integration/git_integration.py @@ -3,9 +3,9 @@ import datetime import git from django.conf import settings +import evennia from evennia import CmdSet, InterruptCommand from evennia.commands.default.muxcommand import MuxCommand -from evennia.server.sessionhandler import SESSIONS from evennia.utils.utils import list_to_string @@ -147,10 +147,10 @@ class GitCommand(MuxCommand): caller.msg(self.get_branches()) elif self.action == "checkout": if self.checkout(): - SESSIONS.portal_restart_server() + evennia.SESSION_HANDLER.portal_restart_server() elif self.action == "pull": if self.pull(): - SESSIONS.portal_restart_server() + evennia.SESSION_HANDLER.portal_restart_server() else: caller.msg("You can only git status, git branch, git checkout, or git pull.") return diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 77c7ee446b..481854e55c 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -13,6 +13,7 @@ from collections import defaultdict import inflect from django.conf import settings from django.utils.translation import gettext as _ +import evennia from evennia.commands import cmdset from evennia.commands.cmdsethandler import CmdSetHandler from evennia.objects.manager import ObjectManager @@ -36,7 +37,6 @@ _INFLECT = inflect.engine() _MULTISESSION_MODE = settings.MULTISESSION_MODE _ScriptDB = None -_SESSIONS = None _CMDHANDLER = None _AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1)) @@ -67,15 +67,12 @@ class ObjectSessionHandler: self._recache() def _recache(self): - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS self._sessid_cache = list( set(int(val) for val in (self.obj.db_sessid or "").split(",") if val) ) - if any(sessid for sessid in self._sessid_cache if sessid not in _SESSIONS): + if any(sessid for sessid in self._sessid_cache if sessid not in evennia.SESSION_HANDLER): # cache is out of sync with sessionhandler! Only retain the ones in the handler. - self._sessid_cache = [sessid for sessid in self._sessid_cache if sessid in _SESSIONS] + self._sessid_cache = [sessid for sessid in self._sessid_cache if sessid in evennia.SESSION_HANDLER] self.obj.db_sessid = ",".join(str(val) for val in self._sessid_cache) self.obj.save(update_fields=["db_sessid"]) @@ -94,18 +91,16 @@ class ObjectSessionHandler: Aliased to `self.all()`. """ - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS + if sessid: sessions = ( - [_SESSIONS[sessid] if sessid in _SESSIONS else None] + [evennia.SESSION_HANDLER[sessid] if sessid in evennia.SESSION_HANDLER else None] if sessid in self._sessid_cache else [] ) else: sessions = [ - _SESSIONS[ssid] if ssid in _SESSIONS else None for ssid in self._sessid_cache + evennia.SESSION_HANDLER[ssid] if ssid in evennia.SESSION_HANDLER else None for ssid in self._sessid_cache ] if None in sessions: # this happens only if our cache has gone out of sync with the SessionHandler. @@ -135,16 +130,13 @@ class ObjectSessionHandler: in the the core sessionhandler. """ - global _SESSIONS - if not _SESSIONS: - from evennia.server.sessionhandler import SESSIONS as _SESSIONS try: sessid = session.sessid except AttributeError: sessid = session sessid_cache = self._sessid_cache - if sessid in _SESSIONS and sessid not in sessid_cache: + if sessid in evennia.SESSION_HANDLER and sessid not in sessid_cache: if len(sessid_cache) >= _SESSID_MAX: return sessid_cache.append(sessid) diff --git a/evennia/server/game_index_client/client.py b/evennia/server/game_index_client/client.py index f2d354cdda..32f4f41d8d 100644 --- a/evennia/server/game_index_client/client.py +++ b/evennia/server/game_index_client/client.py @@ -16,8 +16,8 @@ from twisted.web.http_headers import Headers from twisted.web.iweb import IBodyProducer from zope.interface import implementer +import evennia from evennia.accounts.models import AccountDB -from evennia.server.sessionhandler import SESSIONS from evennia.utils import get_evennia_version, logger _EGI_HOST = "http://evennia-game-index.appspot.com" @@ -98,7 +98,7 @@ class EvenniaGameIndexClient(object): "telnet_port": egi_config.get("telnet_port", ""), "web_client_url": egi_config.get("web_client_url", ""), # Game stats - "connected_account_count": SESSIONS.account_count(), + "connected_account_count": evennia.SESSION_HANDLER.account_count(), "total_account_count": AccountDB.objects.num_total_accounts() or 0, # System info "evennia_version": get_evennia_version(), diff --git a/evennia/server/initial_setup.py b/evennia/server/initial_setup.py index b77bcbaadf..ffec79ab17 100644 --- a/evennia/server/initial_setup.py +++ b/evennia/server/initial_setup.py @@ -12,6 +12,7 @@ import time from django.conf import settings from django.utils.translation import gettext as _ +import evennia from evennia.accounts.models import AccountDB from evennia.server.models import ServerConfig from evennia.utils import create, logger @@ -180,10 +181,9 @@ def reset_server(): """ ServerConfig.objects.conf("server_epoch", time.time()) - from evennia.server.sessionhandler import SESSIONS logger.log_info("Initial setup complete. Restarting Server once.") - SESSIONS.portal_reset_server() + evennia.SESSION_HANDLER.portal_reset_server() def handle_setup(last_step=None): diff --git a/evennia/server/portal/portal.py b/evennia/server/portal/portal.py index 15a603658a..87077b0ac7 100644 --- a/evennia/server/portal/portal.py +++ b/evennia/server/portal/portal.py @@ -24,9 +24,9 @@ from django.db import connection import evennia -evennia._init() - +evennia._init(portal_mode=True) from evennia.server.portal.portalsessionhandler import PORTAL_SESSIONS + from evennia.server.webserver import EvenniaReverseProxyResource from evennia.utils import logger from evennia.utils.utils import ( diff --git a/evennia/server/portal/portalsessionhandler.py b/evennia/server/portal/portalsessionhandler.py index 47fd22578c..386263cbc1 100644 --- a/evennia/server/portal/portalsessionhandler.py +++ b/evennia/server/portal/portalsessionhandler.py @@ -489,5 +489,5 @@ class PortalSessionHandler(SessionHandler): log_trace() -_PORTAL_SESSION_HANDLER_CLASS = class_from_module(settings.PORTAL_SESSION_HANDLER_CLASS) -PORTAL_SESSIONS = _PORTAL_SESSION_HANDLER_CLASS() +# This will be filled in when the portal boots. +PORTAL_SESSIONS = None diff --git a/evennia/server/server.py b/evennia/server/server.py index f3ef4397e2..b926c46cdd 100644 --- a/evennia/server/server.py +++ b/evennia/server/server.py @@ -27,6 +27,8 @@ import evennia evennia._init() +from evennia.server.sessionhandler import SESSIONS + from django.conf import settings from django.db import connection from django.db.utils import OperationalError @@ -35,10 +37,12 @@ from django.utils.translation import gettext as _ from evennia.accounts.models import AccountDB from evennia.scripts.models import ScriptDB from evennia.server.models import ServerConfig -from evennia.server.sessionhandler import SESSIONS + from evennia.utils import logger from evennia.utils.utils import get_evennia_version, make_iter, mod_import + + _SA = object.__setattr__ # a file with a flag telling the server to restart after shutdown or not. diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 60036ad3e2..0dd7956b48 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -874,9 +874,6 @@ class ServerSessionHandler(SessionHandler): log_trace() -# import class from settings -_SESSION_HANDLER_CLASS = class_from_module(settings.SERVER_SESSION_HANDLER_CLASS) - -# Instantiate class. These globals are used to provide singleton-like behavior. -SESSION_HANDLER = _SESSION_HANDLER_CLASS() -SESSIONS = SESSION_HANDLER # legacy +# These are filled in during server boot. +SESSION_HANDLER = None +SESSIONS = None # legacy diff --git a/evennia/utils/dbserialize.py b/evennia/utils/dbserialize.py index 3ae239d263..e6ff52ded4 100644 --- a/evennia/utils/dbserialize.py +++ b/evennia/utils/dbserialize.py @@ -30,6 +30,7 @@ except ImportError: from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.utils.safestring import SafeString +import evennia from evennia.utils import logger from evennia.utils.utils import is_iter, to_bytes, uses_database @@ -71,7 +72,6 @@ _SA = object.__setattr__ _FROM_MODEL_MAP = None _TO_MODEL_MAP = None _IGNORE_DATETIME_MODELS = None -_SESSION_HANDLER = None def _IS_PACKED_DBOBJ(o): @@ -114,7 +114,7 @@ def _TO_DATESTRING(obj): def _init_globals(): """Lazy importing to avoid circular import issues""" - global _FROM_MODEL_MAP, _TO_MODEL_MAP, _SESSION_HANDLER, _IGNORE_DATETIME_MODELS + global _FROM_MODEL_MAP, _TO_MODEL_MAP, _IGNORE_DATETIME_MODELS if not _FROM_MODEL_MAP: _FROM_MODEL_MAP = defaultdict(str) _FROM_MODEL_MAP.update(dict((c.model, c.natural_key()) for c in ContentType.objects.all())) @@ -129,9 +129,6 @@ def _init_globals(): for src_key, dst_key in settings.ATTRIBUTE_STORED_MODEL_RENAME: _TO_MODEL_MAP[src_key] = _TO_MODEL_MAP.get(dst_key, None) _IGNORE_DATETIME_MODELS.append(src_key) - if not _SESSION_HANDLER: - from evennia.server.sessionhandler import SESSION_HANDLER as _SESSION_HANDLER - # # SaverList, SaverDict, SaverSet - Attribute-specific helper classes and functions @@ -609,7 +606,7 @@ def pack_session(item): """ _init_globals() - session = _SESSION_HANDLER.get(item.sessid) + session = evennia.SESSION_HANDLER.get(item.sessid) if session and session.conn_time == item.conn_time: # we require connection times to be identical for the Session # to be accepted as actually being a session (sessids gets @@ -636,7 +633,7 @@ def unpack_session(item): exists, None will be returned. """ _init_globals() - session = _SESSION_HANDLER.get(item[1]) + session = evennia.SESSION_HANDLER.get(item[1]) if session and session.conn_time == item[2]: # we require connection times to be identical for the Session # to be accepted as the same as the one stored (sessids gets diff --git a/evennia/utils/gametime.py b/evennia/utils/gametime.py index b390b2a59a..297badde51 100644 --- a/evennia/utils/gametime.py +++ b/evennia/utils/gametime.py @@ -13,6 +13,7 @@ from datetime import datetime, timedelta from django.conf import settings from django.db.utils import OperationalError +import evennia from evennia import DefaultScript from evennia.server.models import ServerConfig from evennia.utils.create import create_script @@ -125,9 +126,8 @@ def portal_uptime(): Returns: time (float): The uptime of the portal. """ - from evennia.server.sessionhandler import SESSIONS - return time.time() - SESSIONS.portal_start_time + return time.time() - evennia.SESSION_HANDLER.portal_start_time def game_epoch(): diff --git a/evennia/utils/test_resources.py b/evennia/utils/test_resources.py index 4e05499eeb..c7e1570617 100644 --- a/evennia/utils/test_resources.py +++ b/evennia/utils/test_resources.py @@ -31,6 +31,7 @@ from django.test import TestCase, override_settings from mock import MagicMock, Mock, patch from twisted.internet.defer import Deferred +import evennia from evennia import settings_default from evennia.accounts.accounts import DefaultAccount from evennia.commands.command import InterruptCommand @@ -43,7 +44,6 @@ from evennia.objects.objects import ( ) from evennia.scripts.scripts import DefaultScript from evennia.server.serversession import ServerSession -from evennia.server.sessionhandler import SESSIONS from evennia.utils import ansi, create from evennia.utils.idmapper.models import flush_cache from evennia.utils.utils import all_from_module, to_str @@ -234,18 +234,18 @@ class EvenniaTestMixin: def setup_session(self): dummysession = ServerSession() - dummysession.init_session("telnet", ("localhost", "testmode"), SESSIONS) + dummysession.init_session("telnet", ("localhost", "testmode"), evennia.SESSION_HANDLER) dummysession.sessid = 1 - SESSIONS.portal_connect( + evennia.SESSION_HANDLER.portal_connect( dummysession.get_sync_data() ) # note that this creates a new Session! - session = SESSIONS.session_from_sessid(1) # the real session - SESSIONS.login(session, self.account, testmode=True) + session = evennia.SESSION_HANDLER.session_from_sessid(1) # the real session + evennia.SESSION_HANDLER.login(session, self.account, testmode=True) self.session = session def teardown_session(self): if hasattr(self, "sessions"): - del SESSIONS[self.session.sessid] + del evennia.SESSION_HANDLER[self.session.sessid] @patch("evennia.scripts.taskhandler.deferLater", _mock_deferlater) def setUp(self): @@ -253,13 +253,13 @@ class EvenniaTestMixin: Sets up testing environment """ self.backups = ( - SESSIONS.data_out, - SESSIONS.disconnect, + evennia.SESSION_HANDLER.data_out, + evennia.SESSION_HANDLER.disconnect, settings.DEFAULT_HOME, settings.PROTOTYPE_MODULES, ) - SESSIONS.data_out = Mock() - SESSIONS.disconnect = Mock() + evennia.SESSION_HANDLER.data_out = Mock() + evennia.SESSION_HANDLER.disconnect = Mock() self.create_accounts() self.create_rooms() @@ -271,8 +271,8 @@ class EvenniaTestMixin: def tearDown(self): flush_cache() try: - SESSIONS.data_out = self.backups[0] - SESSIONS.disconnect = self.backups[1] + evennia.SESSION_HANDLER.data_out = self.backups[0] + evennia.SESSION_HANDLER.disconnect = self.backups[1] settings.DEFAULT_HOME = self.backups[2] settings.PROTOTYPE_MODULES = self.backups[3] except AttributeError as err: @@ -281,7 +281,7 @@ class EvenniaTestMixin: "in your test, make sure you also added `super().setUp()`!" ) - del SESSIONS[self.session.sessid] + del evennia.SESSION_HANDLER[self.session.sessid] self.teardown_accounts() super().tearDown() @@ -422,7 +422,7 @@ class EvenniaCommandTestMixin: cmdobj.cmdstring = cmdobj.cmdname # deprecated cmdobj.args = input_args cmdobj.cmdset = cmdset - cmdobj.session = SESSIONS.session_from_sessid(1) + cmdobj.session = evennia.SESSION_HANDLER.session_from_sessid(1) cmdobj.account = self.account cmdobj.raw_string = raw_string if raw_string is not None else cmdobj.key + " " + input_args cmdobj.obj = obj or (caller if caller else self.char1) diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index 0cdb40eca5..36c7716372 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -34,6 +34,8 @@ from django.core.validators import validate_email as django_validate_email from django.utils import timezone from django.utils.html import strip_tags from django.utils.translation import gettext as _ + +import evennia from evennia.utils import logger from simpleeval import simple_eval from twisted.internet import reactor, threads @@ -1061,14 +1063,13 @@ def server_services(): services (dict): A dict of available services. """ - from evennia.server.sessionhandler import SESSIONS - if hasattr(SESSIONS, "server") and hasattr(SESSIONS.server, "services"): - server = SESSIONS.server.services.namedServices + if hasattr(evennia.SESSION_HANDLER, "server") and hasattr(evennia.SESSION_HANDLER.server, "services"): + server = evennia.SESSION_HANDLER.server.services.namedServices else: # This function must be called from inside the evennia process. server = {} - del SESSIONS + del evennia.SESSION_HANDLER return server diff --git a/evennia/web/website/views/index.py b/evennia/web/website/views/index.py index 0540233d1e..8f8b973884 100644 --- a/evennia/web/website/views/index.py +++ b/evennia/web/website/views/index.py @@ -6,7 +6,7 @@ The main index page, including the game stats from django.conf import settings from django.views.generic import TemplateView -from evennia import SESSION_HANDLER +import evennia from evennia.accounts.models import AccountDB from evennia.objects.models import ObjectDB from evennia.utils import class_from_module @@ -25,7 +25,7 @@ def _gamestats(): nplyrs_conn_recent = len(recent_users) or "none" nplyrs = AccountDB.objects.num_total_accounts() or "none" nplyrs_reg_recent = len(AccountDB.objects.get_recently_created_accounts()) or "none" - nsess = SESSION_HANDLER.account_count() + nsess = evennia.SESSION_HANDLER.account_count() # nsess = len(AccountDB.objects.get_connected_accounts()) or "no one" nobjs = ObjectDB.objects.count()