From f95dd3f2aa8ad2cf746073a535fb0cc94e3bef13 Mon Sep 17 00:00:00 2001 From: trhr Date: Sun, 5 Apr 2020 23:54:10 -0500 Subject: [PATCH 1/3] #1445 #1709 - Latinify character names in .create() --- evennia/objects/objects.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 25731923e..42952a874 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -2065,6 +2065,7 @@ class DefaultCharacter(DefaultObject): # Set the supplied key as the name of the intended object kwargs["key"] = key + key = cls._validate(key) # Get home for character kwargs["home"] = ObjectDB.objects.get_id(kwargs.get("home", settings.DEFAULT_HOME)) @@ -2115,6 +2116,22 @@ class DefaultCharacter(DefaultObject): return obj, errors + def _validate(self, key): + """ + Validate that character name is acceptable prior to creating. Note that this should be refactored + to support i18n for non-latin scripts, but as we (currently) have no bug reports requesting better + support of non-latin character sets, requiring character names to be latinified is an acceptable option. + + Args: + key (str) : The name of the character + + Returns: + key (str) : A valid name. + """ + from evennia.utils.utils import latinify + key = latinify(key, default="X") + return key + def basetype_setup(self): """ Setup character-specific security. From d61dc07796b56a955f446450e49dbf442b14f299 Mon Sep 17 00:00:00 2001 From: trhr Date: Mon, 6 Apr 2020 00:03:33 -0500 Subject: [PATCH 2/3] Code that doesn't compile is an antipattern --- evennia/objects/objects.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 42952a874..9d9d2eb41 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -2116,7 +2116,8 @@ class DefaultCharacter(DefaultObject): return obj, errors - def _validate(self, key): + @classmethod + def _validate(cls, key): """ Validate that character name is acceptable prior to creating. Note that this should be refactored to support i18n for non-latin scripts, but as we (currently) have no bug reports requesting better From e9fc3463cb5b5ee4bb3c4053d4544c7093916777 Mon Sep 17 00:00:00 2001 From: trhr Date: Thu, 9 Apr 2020 18:30:54 -0500 Subject: [PATCH 3/3] With recommended changes --- evennia/objects/objects.py | 34 +++++++++++++++++++++++++++------- evennia/objects/tests.py | 6 ++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 9d9d2eb41..9a04ba696 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -2063,9 +2063,15 @@ class DefaultCharacter(DefaultObject): # If no typeclass supplied, use this class kwargs["typeclass"] = kwargs.pop("typeclass", cls) + # Normalize to latin characters and validate, if necessary, the supplied key + key = cls.normalize_name(key) + + if not cls.validate_name(key): + errors.append("Invalid character name.") + return obj, errors + # Set the supplied key as the name of the intended object kwargs["key"] = key - key = cls._validate(key) # Get home for character kwargs["home"] = ObjectDB.objects.get_id(kwargs.get("home", settings.DEFAULT_HOME)) @@ -2117,21 +2123,35 @@ class DefaultCharacter(DefaultObject): return obj, errors @classmethod - def _validate(cls, key): + def normalize_name(cls, name): """ - Validate that character name is acceptable prior to creating. Note that this should be refactored + Normalize the character name prior to creating. Note that this should be refactored to support i18n for non-latin scripts, but as we (currently) have no bug reports requesting better support of non-latin character sets, requiring character names to be latinified is an acceptable option. Args: - key (str) : The name of the character + name (str) : The name of the character Returns: - key (str) : A valid name. + latin_name (str) : A valid name. """ + from evennia.utils.utils import latinify - key = latinify(key, default="X") - return key + latin_name = latinify(name, default="X") + return latin_name + + @classmethod + def validate_name(cls, name): + """ Validate the character name prior to creating. Overload this function to add custom validators + + Args: + name (str) : The name of the character + Returns: + valid (bool) : True if character creation should continue; False if it should fail + + """ + + return True # Default validator does not perform any operations def basetype_setup(self): """ diff --git a/evennia/objects/tests.py b/evennia/objects/tests.py index 75f91cba3..5944ee5aa 100644 --- a/evennia/objects/tests.py +++ b/evennia/objects/tests.py @@ -39,6 +39,12 @@ class DefaultObjectTest(EvenniaTest): self.assertFalse(errors, errors) self.assertEqual(obj.db_home, self.room1) + def test_character_create_weirdname(self): + obj, errors = DefaultCharacter.create("SigurðurÞórarinsson", self.account, home=self.room1.dbref) + self.assertTrue(obj, errors) + self.assertFalse(errors, errors) + self.assertEqual(obj.name, "SigurXurXorarinsson") + def test_room_create(self): description = "A dimly-lit alley behind the local Chinese restaurant." obj, errors = DefaultRoom.create("alley", self.account, description=description, ip=self.ip)