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)