diff --git a/locale/sv/LC_MESSAGES/django.po b/locale/sv/LC_MESSAGES/django.po index c3eb93fd34..ab1016686f 100644 --- a/locale/sv/LC_MESSAGES/django.po +++ b/locale/sv/LC_MESSAGES/django.po @@ -37,7 +37,7 @@ msgid " Type \"help\" for help." msgstr "Skriv \"help\" för hjälp." #: src/commands/cmdhandler.py:212 -msgid "There where multiple matches." +msgid "There were multiple matches." msgstr "Det fanns många träffar." #: src/commands/cmdparser.py:144 diff --git a/src/commands/cmdparser.py b/src/commands/cmdparser.py index 386ed8f0c6..1b4650eaa2 100644 --- a/src/commands/cmdparser.py +++ b/src/commands/cmdparser.py @@ -245,7 +245,7 @@ def at_multimatch_cmd(caller, matches): """ Format multiple command matches to a useful error. """ - string = "There where multiple matches:" + string = "There were multiple matches:" for num, match in enumerate(matches): # each match is a tuple (candidate, cmd) cmdname, arg, cmd, dum, dum = match diff --git a/src/commands/default/admin.py b/src/commands/default/admin.py index 4eb8e6ec7e..861f875247 100644 --- a/src/commands/default/admin.py +++ b/src/commands/default/admin.py @@ -298,12 +298,8 @@ class CmdDelPlayer(MuxCommand): string = "No Player nor User found matching '%s'." % args self.msg(string) return - try: - player = user.get_profile() - except Exception: - player = None - if player and not player.access(caller, 'delete'): + if user and not user.access(caller, 'delete'): string = "You don't have the permissions to delete this player." self.msg(string) return @@ -311,9 +307,9 @@ class CmdDelPlayer(MuxCommand): string = "" name = user.username user.delete() - if player: - name = player.name - player.delete() + if user: + name = user.name + user.delete() string = "Player %s was deleted." % name else: string += "The User %s was deleted. It had no Player associated with it." % name @@ -322,16 +318,16 @@ class CmdDelPlayer(MuxCommand): elif utils.is_iter(players): string = "There were multiple matches:" - for player in players: - string += "\n %s %s" % (player.id, player.key) + for user in players: + string += "\n %s %s" % (user.id, user.key) return else: # one single match - player = players - user = player.user + user = players + user = user.user - if not player.access(caller, 'delete'): + if not user.access(caller, 'delete'): string = "You don't have the permissions to delete that player." self.msg(string) return @@ -342,12 +338,12 @@ class CmdDelPlayer(MuxCommand): string = "\nYour account '%s' is being *permanently* deleted.\n" % uname if reason: string += " Reason given:\n '%s'" % reason - player.unpuppet_all() - for session in SESSIONS.sessions_from_player(player): - player.msg(string, sessid=session.sessid) - player.disconnect_session_from_player(session.sessid) + user.unpuppet_all() + for session in SESSIONS.sessions_from_player(user): + user.msg(string, sessid=session.sessid) + user.disconnect_session_from_player(session.sessid) + user.delete() user.delete() - player.delete() self.msg("Player %s was successfully deleted." % uname) diff --git a/src/commands/default/syscommands.py b/src/commands/default/syscommands.py index ccd46f9e9d..cab02d66dd 100644 --- a/src/commands/default/syscommands.py +++ b/src/commands/default/syscommands.py @@ -88,7 +88,7 @@ class SystemMultimatch(MuxCommand): src.commands.cmdhandler. """ - string = "There where multiple matches:" + string = "There were multiple matches:" for num, match in enumerate(matches): # each match is a tuple (candidate, cmd) candidate, cmd = match diff --git a/src/comms/managers.py b/src/comms/managers.py index 118fcc5039..d54cba0391 100644 --- a/src/comms/managers.py +++ b/src/comms/managers.py @@ -65,7 +65,6 @@ def identify_object(inp): obj = inp typ = type(obj) if typ == _PlayerDB: return obj, "player" - if typ == _User: return obj.get_profile(), "player" elif typ == _ObjectDB: return obj, "object" elif typ == _Channel: return obj, "channel" elif dbref(obj): return dbref(obj), "dbref" diff --git a/src/players/admin.py b/src/players/admin.py index bac20f2a2f..52db397665 100644 --- a/src/players/admin.py +++ b/src/players/admin.py @@ -33,7 +33,7 @@ class PlayerDBChangeForm(UserChangeForm): username = self.cleaned_data['username'] if username.upper() == self.instance.username.upper(): return username - elif User.objects.filter(username__iexact=username): + elif PlayerDB.objects.filter(username__iexact=username): raise forms.ValidationError('A player with that name already exists.') return self.cleaned_data['username'] @@ -52,7 +52,7 @@ class PlayerDBCreationForm(UserCreationForm): def clean_username(self): username = self.cleaned_data['username'] - if User.objects.filter(username__iexact=username): + if PlayerDB.objects.filter(username__iexact=username): raise forms.ValidationError('A player with that name already exists.') return username @@ -139,7 +139,9 @@ class PlayerDBAdmin(BaseUserAdmin): ('Website dates', {'fields': ('last_login', 'date_joined'), 'description':'Relevant only to the website.'}), ('Website Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions','groups'), - 'description': "These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights."}),) + 'description': "These are permissions/permission groups for accessing the admin site. They are unrelated to in-game access rights."}), + ('Game Options', {'fields': ('db_typeclass_path', 'db_cmdset_storage', 'db_permissions', 'db_lock_storage'), + 'description': 'These are attributes that are more relevant to gameplay.'})) add_fieldsets = ( @@ -152,8 +154,7 @@ class PlayerDBAdmin(BaseUserAdmin): "Run all hooks on the player object" super(PlayerDBAdmin, self).save_formset(request, form, formset, change) userobj = form.instance - playerobj = userobj.get_profile() - playerobj.name = userobj.username + userobj.name = userobj.username if not change: #uname, passwd, email = str(request.POST.get(u"username")), \ # str(request.POST.get(u"password1")), str(request.POST.get(u"email")) @@ -161,6 +162,6 @@ class PlayerDBAdmin(BaseUserAdmin): create.create_player("","","", user=userobj, typeclass=typeclass, - player_dbobj=playerobj) + player_dbobj=userobj) admin.site.register(PlayerDB, PlayerDBAdmin) diff --git a/src/players/models.py b/src/players/models.py index 9f2f1eadfb..1b28ee7885 100644 --- a/src/players/models.py +++ b/src/players/models.py @@ -1,21 +1,14 @@ """ Player -The Player class is a simple extension of the django User model using -the 'profile' system of django. A profile is a model that tack new -fields to the User model without actually editing the User model -(which would mean hacking into django internals which we want to avoid -for future compatability reasons). The profile, which we call -'Player', is accessed with user.get_profile() by the property 'player' -defined on ObjectDB objects. Since we can customize it, we will try to -abstract as many operations as possible to work on Player rather than -on User. +The player class is an extension of the default Django user class, +and is customized for the needs of Evennia. We use the Player to store a more mud-friendly style of permission system as well as to allow the admin more flexibility by storing attributes on the Player. Within the game we should normally use the -Player manager's methods to create users, since that automatically -adds the profile extension. +Player manager's methods to create users so that permissions are set +correctly. To make the Player model more flexible for your own game, it can also persistently store attributes of its own. This is ideal for extra diff --git a/src/server/caches.py b/src/server/caches.py index b4d2707001..54941a88c0 100644 --- a/src/server/caches.py +++ b/src/server/caches.py @@ -172,6 +172,8 @@ def post_attr_update(sender, **kwargs): pass else: # forward relation changed (the Object holding the Attribute m2m field) + if not kwargs["pk_set"]: + return if action == "post_add": # cache all added objects for attr_id in kwargs["pk_set"]: @@ -185,10 +187,7 @@ def post_attr_update(sender, **kwargs): attr_obj.delete() elif action == "post_clear": # obj.db_attributes.clear() was called - for attr_id in kwargs["pk_set"]: - attr_obj = model.objects.get(pk=attr_id) - del_attr_cache(obj, _GA(attr_obj, "db_key")) - attr_obj.delete() + clear_obj_attr_cache(obj) # access methods @@ -215,6 +214,11 @@ def flush_attr_cache(): global _ATTR_CACHE _ATTR_CACHE = {} +def clear_obj_attr_cache(obj): + global _ATTR_CACHE + hid = hashid(obj) + _ATTR_CACHE = {key:value for key, value in _ATTR_CACHE if not key.startswith(hid)} + #------------------------------------------------------------ # Property cache - this is a generic cache for properties stored on models. #------------------------------------------------------------ diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py index c81a97965f..b49de392ca 100644 --- a/src/server/initial_setup.py +++ b/src/server/initial_setup.py @@ -51,10 +51,7 @@ def create_objects(): god_player = get_god_player() # Create a Player 'user profile' object to hold eventual - # mud-specific settings for the bog standard User object. This is - # accessed by user.get_profile() and can also store attributes. - # It also holds mud permissions, but for a superuser these - # have no effect anyhow. + # mud-specific settings for the PlayerDB object. player_typeclass = settings.BASE_PLAYER_TYPECLASS # run all creation hooks on god_player (we must do so manually since the manage.py command does not)