From e2bd2b4c5a778d8abb84acdca0423d21f0e1b9be Mon Sep 17 00:00:00 2001 From: Griatch Date: Mon, 24 Jun 2019 23:16:53 +0200 Subject: [PATCH] Move game index client into server/ --- evennia/contrib/egi_client/__init__.py | 1 - evennia/server/deprecations.py | 10 ++- evennia/server/evennia_launcher.py | 4 +- .../game_index_client}/README.md | 0 evennia/server/game_index_client/__init__.py | 1 + .../game_index_client}/client.py | 74 ++++++++++--------- .../game_index_client}/service.py | 15 ++-- evennia/server/server.py | 6 ++ evennia/settings_default.py | 16 ++++ 9 files changed, 83 insertions(+), 44 deletions(-) delete mode 100644 evennia/contrib/egi_client/__init__.py rename evennia/{contrib/egi_client => server/game_index_client}/README.md (100%) create mode 100644 evennia/server/game_index_client/__init__.py rename evennia/{contrib/egi_client => server/game_index_client}/client.py (73%) rename evennia/{contrib/egi_client => server/game_index_client}/service.py (82%) diff --git a/evennia/contrib/egi_client/__init__.py b/evennia/contrib/egi_client/__init__.py deleted file mode 100644 index ae61c611a2..0000000000 --- a/evennia/contrib/egi_client/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from evennia.contrib.egi_client.service import EvenniaGameIndexService diff --git a/evennia/server/deprecations.py b/evennia/server/deprecations.py index 6cb260f260..e25c6636a0 100644 --- a/evennia/server/deprecations.py +++ b/evennia/server/deprecations.py @@ -50,8 +50,6 @@ def check_errors(settings): if hasattr(settings, "ACCOUNT_TYPECLASS_PATHS"): raise DeprecationWarning(deprstring % "ACCOUNT_TYPECLASS_PATHS") if hasattr(settings, "CHANNEL_TYPECLASS_PATHS"): - raise DeprecationWarning(deprstring % "CHANNEL_TYPECLASS_PATHS") - if hasattr(settings, "SEARCH_MULTIMATCH_SEPARATOR"): raise DeprecationWarning( "settings.SEARCH_MULTIMATCH_SEPARATOR was replaced by " "SEARCH_MULTIMATCH_REGEX and SEARCH_MULTIMATCH_TEMPLATE. " @@ -66,10 +64,16 @@ def check_errors(settings): "and manipulate these time units, the tools from utils.gametime " "are now found in contrib/convert_gametime.py instead.") if any(hasattr(settings, value) for value in ("TIME_SEC_PER_MIN", "TIME_MIN_PER_HOUR", - "TIME_HOUR_PER_DAY", "TIME_DAY_PER_WEEK", "TIME_WEEK_PER_MONTH", + "TIME_HOUR_PER_DAY", "TIME_DAY_PER_WEEK", + "TIME_WEEK_PER_MONTH", "TIME_MONTH_PER_YEAR")): raise DeprecationWarning(gametime_deprecation) + game_directory_deprecation = ("The setting GAME_DIRECTORY_LISTING was removed. It must be " + "renamed to GAME_INDEX_LISTING instead.") + if hasattr(settings, "GAME_DIRECTORY_LISTING"): + raise DeprecationWarning(game_directory_deprecation) + def check_warnings(settings): """ diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 7384ab60b7..b7e02eded2 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -1675,7 +1675,8 @@ def init_game_directory(path, check_db=True, need_gamedir=True): Args: path (str): Path to new game directory, including its name. check_db (bool, optional): Check if the databae exists. - need_gamedir (bool, optional): set to False if Evennia doesn't require to be run in a valid game directory. + need_gamedir (bool, optional): set to False if Evennia doesn't require to + be run in a valid game directory. """ # set the GAMEDIR path @@ -2090,6 +2091,7 @@ def main(): elif option == "info": query_info() elif option == "start": + error_check_python_modules() start_evennia(args.profiler, args.profiler) elif option == "istart": start_server_interactive() diff --git a/evennia/contrib/egi_client/README.md b/evennia/server/game_index_client/README.md similarity index 100% rename from evennia/contrib/egi_client/README.md rename to evennia/server/game_index_client/README.md diff --git a/evennia/server/game_index_client/__init__.py b/evennia/server/game_index_client/__init__.py new file mode 100644 index 0000000000..7e58b476ae --- /dev/null +++ b/evennia/server/game_index_client/__init__.py @@ -0,0 +1 @@ +from .service import EvenniaGameIndexService diff --git a/evennia/contrib/egi_client/client.py b/evennia/server/game_index_client/client.py similarity index 73% rename from evennia/contrib/egi_client/client.py rename to evennia/server/game_index_client/client.py index 8c422fbd2a..aea3e27f36 100644 --- a/evennia/contrib/egi_client/client.py +++ b/evennia/server/game_index_client/client.py @@ -1,3 +1,7 @@ +""" +The client for sending data to the Evennia Game Index + +""" import urllib.request, urllib.parse, urllib.error import platform import warnings @@ -17,12 +21,15 @@ 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' +_EGI_REPORT_PATH = '/api/v1/game/check_in' + class EvenniaGameIndexClient(object): """ This client class is used for gathering and sending game details to the Evennia Game Index. Since EGI is in the early goings, this isn't - incredibly configurable as far as what is being sent. + incredibly configurable as far as to what is being sent. """ def __init__(self, on_bad_request=None): @@ -30,8 +37,8 @@ class EvenniaGameIndexClient(object): :param on_bad_request: Optional callable to trigger when a bad request was sent. This is almost always going to be due to bad config. """ - self.report_host = 'http://evennia-game-index.appspot.com' - self.report_path = '/api/v1/game/check_in' + self.report_host = _EGI_HOST + self.report_path = _EGI_REPORT_PATH self.report_url = self.report_host + self.report_path self.logged_first_connect = False @@ -65,48 +72,47 @@ class EvenniaGameIndexClient(object): # to EGD, though. self._on_bad_request() - def _get_config_dict(self): - egi_config = getattr(settings, 'GAME_DIRECTORY_LISTING', None) - if egi_config: - warnings.warn( - "settings.GAME_DIRECTORY_LISTING is deprecated. Rename this to " - "GAME_INDEX_LISTING in your settings file.", DeprecationWarning) - return egi_config - return settings.GAME_INDEX_LISTING - def _form_and_send_request(self): + """ + Build the request to send to the index. + + """ agent = Agent(reactor, pool=self._conn_pool) headers = { b'User-Agent': [b'Evennia Game Index Client'], b'Content-Type': [b'application/x-www-form-urlencoded'], } - egi_config = self._get_config_dict() + egi_config = settings.GAME_INDEX_LISTING # We are using `or` statements below with dict.get() to avoid sending # stringified 'None' values to the server. - values = { - # Game listing stuff - 'game_name': settings.SERVERNAME, - 'game_status': egi_config['game_status'], - 'game_website': egi_config.get('game_website') or '', - 'short_description': egi_config['short_description'], - 'long_description': egi_config.get('long_description') or '', - 'listing_contact': egi_config['listing_contact'], + try: + values = { + # Game listing stuff + 'game_name': settings.SERVERNAME, + 'game_status': egi_config['game_status'], + 'game_website': egi_config.get('game_website', ''), + 'short_description': egi_config['short_description'], + 'long_description': egi_config.get('long_description', ''), + 'listing_contact': egi_config['listing_contact'], - # How to play - 'telnet_hostname': egi_config.get('telnet_hostname') or '', - 'telnet_port': egi_config.get('telnet_port') or '', - 'web_client_url': egi_config.get('web_client_url') or '', + # How to play + 'telnet_hostname': egi_config.get('telnet_hostname', ''), + 'telnet_port': egi_config.get('telnet_port', ''), + 'web_client_url': egi_config.get('web_client_url', ''), - # Game stats - 'connected_account_count': SESSIONS.account_count(), - 'total_account_count': AccountDB.objects.num_total_accounts() or 0, + # Game stats + 'connected_account_count': SESSIONS.account_count(), + 'total_account_count': AccountDB.objects.num_total_accounts() or 0, + + # System info + 'evennia_version': get_evennia_version(), + 'python_version': platform.python_version(), + 'django_version': django.get_version(), + 'server_platform': platform.platform(), + } + except KeyError as err: + raise KeyError(f"Error loading GAME_INDEX_LISTING: {err}") - # System info - 'evennia_version': get_evennia_version(), - 'python_version': platform.python_version(), - 'django_version': django.get_version(), - 'server_platform': platform.platform(), - } data = urllib.parse.urlencode(values) d = agent.request( diff --git a/evennia/contrib/egi_client/service.py b/evennia/server/game_index_client/service.py similarity index 82% rename from evennia/contrib/egi_client/service.py rename to evennia/server/game_index_client/service.py index c18e898776..9e92a4c949 100644 --- a/evennia/contrib/egi_client/service.py +++ b/evennia/server/game_index_client/service.py @@ -1,9 +1,13 @@ +""" +Service for integrating the Evennia Game Index client into Evennia. + +""" from twisted.internet import reactor from twisted.internet.task import LoopingCall from twisted.application.service import Service -from evennia.contrib.egi_client.client import EvenniaGameIndexClient from evennia.utils import logger +from .client import EvenniaGameIndexClient # How many seconds to wait before triggering the first EGI check-in. _FIRST_UPDATE_DELAY = 10 @@ -13,8 +17,9 @@ _CLIENT_UPDATE_RATE = 60 * 30 class EvenniaGameIndexService(Service): """ - Twisted Service that contains a LoopingCall for sending details on a - game to the Evennia Game Index. + Twisted Service that contains a LoopingCall for regularly sending game details + to the Evennia Game Index. + """ # We didn't stick the Evennia prefix on here because it'd get marked as # a core system service. @@ -27,7 +32,7 @@ class EvenniaGameIndexService(Service): def startService(self): super().startService() - # TODO: Check to make sure that the client is configured. + # Check to make sure that the client is configured. # Start the loop, but only after a short delay. This allows the # portal and the server time to sync up as far as total player counts. # Prevents always reporting a count of 0. @@ -36,7 +41,7 @@ class EvenniaGameIndexService(Service): def stopService(self): if self.running == 0: - # @reload errors if we've stopped this service. + # reload errors if we've stopped this service. return super().stopService() if self.loop.running: diff --git a/evennia/server/server.py b/evennia/server/server.py index 0a87ab6b3b..38461891c9 100644 --- a/evennia/server/server.py +++ b/evennia/server/server.py @@ -74,6 +74,7 @@ IRC_ENABLED = settings.IRC_ENABLED RSS_ENABLED = settings.RSS_ENABLED GRAPEVINE_ENABLED = settings.GRAPEVINE_ENABLED WEBCLIENT_ENABLED = settings.WEBCLIENT_ENABLED +GAME_INDEX_ENABLED = settings.GAME_INDEX_ENABLED INFO_DICT = {"servername": SERVERNAME, "version": VERSION, "amp": "", "errors": "", "info": "", "webserver": "", "irc_rss": ""} @@ -588,6 +589,11 @@ if GRAPEVINE_ENABLED: # Grapevine channel connections ENABLED.append('grapevine') +if GAME_INDEX_ENABLED: + from evennia.server.game_index_client.service import EvenniaGameIndexService + egi_service = EvenniaGameIndexService() + EVENNIA.services.addService(egi_service) + if ENABLED: INFO_DICT["irc_rss"] = ", ".join(ENABLED) + " enabled." diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 226f187a7e..47a8cba271 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -682,6 +682,22 @@ DEFAULT_CHANNELS = [ # While the MudInfo channel will also receieve this, this channel is meant for non-staffers. CHANNEL_CONNECTINFO = None +# The Evennia Game Index is a dynamic listing of Evennia games. You can add your game +# to this list also if it is in closed pre-alpha development. +GAME_INDEX_ENABLED = False +# This dict +GAME_INDEX_LISTING = { + 'game_status': 'closed-dev', # closed-dev, pre-alpha, pre-alpha, alpha, beta or launched + 'short_description': '', + 'long_description': '', + 'listing_contact': '', # email + 'telnet_hostname': '', # mygame.com + 'telnet_port': 1234, + 'game_website': '', # http://mygame.com + 'web_client_url': '' # http://mygame.com/webclient +} + + ###################################################################### # External Channel connections ######################################################################