From 79f5a4a93ade2487f8bdc47fddf9e2d6ad7f7063 Mon Sep 17 00:00:00 2001 From: Griatch Date: Fri, 15 Apr 2016 00:34:41 +0200 Subject: [PATCH] Added the ability to save protocol options on the player level. Implements #957. --- evennia/commands/default/player.py | 63 ++++++++++++++++++++++++------ evennia/players/players.py | 6 +++ evennia/server/serversession.py | 18 +++++++++ evennia/server/session.py | 2 +- 4 files changed, 77 insertions(+), 12 deletions(-) diff --git a/evennia/commands/default/player.py b/evennia/commands/default/player.py index 1faa2c2565..ff5023c66d 100644 --- a/evennia/commands/default/player.py +++ b/evennia/commands/default/player.py @@ -25,7 +25,7 @@ import time from django.conf import settings from evennia.server.sessionhandler import SESSIONS from evennia.commands.default.muxcommand import MuxPlayerCommand -from evennia.utils import utils, create, search, prettytable +from evennia.utils import utils, create, search, prettytable, evtable _MAX_NR_CHARACTERS = settings.MAX_NR_CHARACTERS _MULTISESSION_MODE = settings.MULTISESSION_MODE @@ -381,10 +381,15 @@ class CmdOption(MuxPlayerCommand): Set an account option Usage: - @option [name = value] + @option[/save] [name = value] + + Switch: + save - Save the current option settings for future logins. + clear - Clear the saved options. This command allows for viewing and setting client interface - settings. + settings. Note that saved options may not be able to be used if + later connecting with a client with different capabilities. """ @@ -404,7 +409,19 @@ class CmdOption(MuxPlayerCommand): # Display current options if not self.args: # list the option settings - options = dict(flags) + + if "save" in self.switches: + # save all options + self.player.db._saved_protocol_flags = flags + self.msg("{gSaved all options. Use @option/clear to remove.{n") + if "clear" in self.switches: + # clear all saves + self.player.db._saved_protocol_flags = {} + self.msg("{gCleared all saved options.") + + options = dict(flags) # make a copy of the flag dict + saved_options = dict(self.player.attributes.get("_saved_protocol_flags", default={})) + if "SCREENWIDTH" in options: if len(options["SCREENWIDTH"]) == 1: options["SCREENWIDTH"] = options["SCREENWIDTH"][0] @@ -419,8 +436,18 @@ class CmdOption(MuxPlayerCommand): for screenid, size in options["SCREENHEIGHT"].iteritems()) options.pop("TTYPE", None) - options = "\n".join(" {w%s{n: %s" % (key, options[key]) for key in sorted(options)) - self.msg("{wClient settings (%s):{n\n%s{n" % (self.session.protocol_key, options)) + header = ("Name", "Value", "Saved") if saved_options else ("Name", "Value") + table = evtable.EvTable(*header) + for key in sorted(options): + row = [key, options[key]] + if saved_options: + saved = " |YYes|n" if key in saved_options else "" + changed = "|y*|n" if key in saved_options and flags[key] != saved_options[key] else "" + row.append("%s%s" % (saved, changed)) + table.add_row(*row) + + self.msg("|wClient settings (%s):|n\n%s|n" % (self.session.protocol_key, table)) + return if not self.rhs: @@ -450,7 +477,7 @@ class CmdOption(MuxPlayerCommand): new_val = validator(val) flags[name] = new_val self.msg("Option |w%s|n was changed from '|w%s|n' to '|w%s|n'." % (name, old_val, new_val)) - return True + return {name: new_val} except Exception, err: self.msg("|rCould not set option |w%s|r:|n %s" % (name, err)) return False @@ -471,15 +498,29 @@ class CmdOption(MuxPlayerCommand): name = self.lhs.upper() val = self.rhs.strip() - do_sync = False + optiondict = False if val and name in validators: - do_sync = update(name, val, validators[name]) + optiondict = update(name, val, validators[name]) else: self.session.msg("|rNo option named '|w%s|r'." % name) - if do_sync: - self.session.sessionhandler.session_portal_sync(self.session) + if optiondict: + # a valid setting + if "save" in self.switches: + # save this option only + saved_options = self.player.attributes.get("_saved_protocol_flags", default={}) + saved_options.update(optiondict) + self.player.attributes.add("_saved_protocol_flags", saved_options) + for key in optiondict: + self.msg("{gSaved option %s.{n" % key) + if "clear" in self.switches: + # clear this save + for key in optiondict: + self.player.attributes.get("_saved_protocol_flags", {}).pop(key, None) + self.msg("{gCleared saved %s." % key) + self.session.update_flags(**optiondict) + class CmdPassword(MuxPlayerCommand): """ change your password diff --git a/evennia/players/players.py b/evennia/players/players.py index 6ed8d1063b..55a161d54a 100644 --- a/evennia/players/players.py +++ b/evennia/players/players.py @@ -567,6 +567,7 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): lockstring = "attrread:perm(Admins);attredit:perm(Admins);" \ "attrcreate:perm(Admins)" self.attributes.add("_playable_characters", [], lockstring=lockstring) + self.attributes.add("_saved_protocol_flags", {}, lockstring=lockstring) def at_init(self): """ @@ -705,6 +706,11 @@ class DefaultPlayer(with_metaclass(TypeclassBase, PlayerDB)): auto-puppeting based on `MULTISESSION_MODE`. """ + # if we have saved protocol flags on ourselves, load them here. + protocol_flags = self.attributes.get("_saved_protocol_flags", None) + if session and protocol_flags: + session.update_flags(**protocol_flags) + self._send_to_connect_channel("{G%s connected{n" % self.key) if _MULTISESSION_MODE == 0: # in this mode we should have only one character available. We diff --git a/evennia/server/serversession.py b/evennia/server/serversession.py index 4e2f2aeab6..88c19b942e 100644 --- a/evennia/server/serversession.py +++ b/evennia/server/serversession.py @@ -329,6 +329,24 @@ class ServerSession(Session): # Player-visible idle time, not used in idle timeout calcs. self.cmd_last_visible = self.cmd_last + def update_flags(self, **kwargs): + """ + Update the protocol_flags and sync them with Portal. + + Kwargs: + key, value - A key:value pair to set in the + protocol_flags dictionary. + + Notes: + Since protocols can vary, no checking is done + as to the existene of the flag or not. The input + data should have been validated before this call. + + """ + if kwargs: + self.protocol_flags.update(kwargs) + self.sessionhandler.session_portal_sync(self) + def data_out(self, **kwargs): """ diff --git a/evennia/server/session.py b/evennia/server/session.py index b1ab9f9038..bfd8625905 100644 --- a/evennia/server/session.py +++ b/evennia/server/session.py @@ -123,7 +123,7 @@ class Session(object): on uid etc). """ - pass + self.protocol_flags.update(self.player.attributs.get("_saved_protocol_flags"), {}) # access hooks