diff --git a/src/commands/default/unloggedin.py b/src/commands/default/unloggedin.py
index d9c5145f7c..f4f734ca5c 100644
--- a/src/commands/default/unloggedin.py
+++ b/src/commands/default/unloggedin.py
@@ -4,7 +4,6 @@ Commands that are available from the connect screen.
import re
import traceback
from django.conf import settings
-from django.contrib.auth.models import User
from src.players.models import PlayerDB
from src.objects.models import ObjectDB
from src.server.models import ServerConfig
@@ -68,7 +67,7 @@ class CmdUnconnectedConnect(MuxCommand):
player = PlayerDB.objects.get_player_from_name(playername)
pswd = None
if player:
- pswd = player.user.check_password(password)
+ pswd = player.check_password(password)
if not (player and pswd):
# No playername or password match
@@ -142,7 +141,7 @@ class CmdUnconnectedCreate(MuxCommand):
return
# strip excessive spaces in playername
playername = re.sub(r"\s+", " ", playername).strip()
- if PlayerDB.objects.filter(user__username__iexact=playername) or User.objects.filter(username__iexact=playername):
+ if PlayerDB.objects.filter(username__iexact=playername):
# player already exists (we also ignore capitalization here)
session.msg("Sorry, there is already a player with the name '%s'." % playername)
return
diff --git a/src/objects/manager.py b/src/objects/manager.py
index 0e8d0bbc57..d45e4b4d7e 100644
--- a/src/objects/manager.py
+++ b/src/objects/manager.py
@@ -34,7 +34,6 @@ class ObjectManager(TypedObjectManager):
get_dbref_range
object_totals
typeclass_search
- get_object_with_user
get_object_with_player
get_objs_with_key_and_typeclass
get_objs_with_attr
@@ -52,29 +51,8 @@ class ObjectManager(TypedObjectManager):
# ObjectManager Get methods
#
- # user/player related
+ # player related
- @returns_typeclass
- def get_object_with_user(self, user):
- """
- Matches objects with obj.player.user matching the argument.
- A player<->user is a one-to-relationship, so this always
- returns just one result or None.
-
- user - may be a user object or user id.
- """
- dbref = self.dbref(user)
- if dbref:
- try:
- return self.get(db_player__user__id=dbref)
- except self.model.DoesNotExist:
- pass
- try:
- return self.get(db_player__user=user)
- except self.model.DoesNotExist:
- return None
-
- # This returns typeclass since get_object_with_user and get_dbref does.
@returns_typeclass
def get_object_with_player(self, ostring, exact=True, candidates=None):
"""
@@ -92,9 +70,9 @@ class ObjectManager(TypedObjectManager):
# not a dbref. Search by name.
cand_restriction = candidates and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q()
if exact:
- return self.filter(cand_restriction & Q(db_player__user__username__iexact=ostring))
+ return self.filter(cand_restriction & Q(db_player__username__iexact=ostring))
else: # fuzzy matching
- ply_cands = self.filter(cand_restriction & Q(playerdb__user__username__istartswith=ostring)).values_list("db_key", flat=True)
+ ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring)).values_list("db_key", flat=True)
if candidates:
index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
return [obj for ind, obj in enumerate(make_iter(candidates)) if ind in index_matches]
diff --git a/src/players/admin.py b/src/players/admin.py
index 64e8e3d36b..b61b36f60a 100644
--- a/src/players/admin.py
+++ b/src/players/admin.py
@@ -141,6 +141,7 @@ class UserAdmin(BaseUserAdmin):
{'fields': ('username', 'password1', 'password2', 'email'),
'description':"These account details are shared by the admin system and the game."},),)
+ # TODO! Remove User reference!
def save_formset(self, request, form, formset, change):
"Run all hooks on the player object"
super(UserAdmin, self).save_formset(request, form, formset, change)
diff --git a/src/players/manager.py b/src/players/manager.py
index b95c96284b..4bfc9605b0 100644
--- a/src/players/manager.py
+++ b/src/players/manager.py
@@ -3,8 +3,8 @@ The managers for the custom Player object and permissions.
"""
import datetime
-from functools import update_wrapper
from django.contrib.auth.models import UserManager
+from functools import update_wrapper
from src.typeclasses.managers import returns_typeclass_list, returns_typeclass, TypedObjectManager
from src.utils import logger
__all__ = ("PlayerManager",)
@@ -13,53 +13,6 @@ __all__ = ("PlayerManager",)
# Player Manager
#
-def returns_player_list(method):
- """
- decorator that makes sure that a method
- returns a Player object instead of a User
- one (if you really want the User object, not
- the player, use the player's 'user' property)
- """
- def func(self, *args, **kwargs):
- "This *always* returns a list."
- match = method(self, *args, **kwargs)
- if not match:
- return []
- try:
- match = list(match)
- except TypeError:
- match = [match]
- players = []
- for user in match:
- try:
- players.append(user.get_profile())
- except Exception:
- # there is something wrong with get_profile. But
- # there is a 1-1 relation between Users-Players, so we
- # try to go the other way instead.
- from src.players.models import PlayerDB
- match = PlayerDB.objects.filter(user__id=user.id)
- if match:
- players.append(match[0])
- else:
- logger.log_trace("No connection User<->Player, maybe database was partially reset?")
- return players
- return update_wrapper(func, method)
-
-def returns_player(method):
- """
- Decorator: Always returns a single result or None.
- """
- def func(self, *args, **kwargs):
- "decorator"
- rfunc = returns_player_list(method)
- match = rfunc(self, *args, **kwargs)
- if match:
- return match[0]
- else:
- return None
- return update_wrapper(func, method)
-
class PlayerManager(TypedObjectManager, UserManager):
"""
This PlayerManager implements methods for searching
@@ -87,7 +40,7 @@ class PlayerManager(TypedObjectManager, UserManager):
"""
def num_total_players(self):
"""
- Returns the total number of registered users/players.
+ Returns the total number of registered players.
"""
return self.count()
@@ -99,7 +52,6 @@ class PlayerManager(TypedObjectManager, UserManager):
return self.filter(db_is_connected=True)
@returns_typeclass_list
- @returns_player_list
def get_recently_created_players(self, days=7):
"""
Returns a QuerySet containing the player User accounts that have been
@@ -108,13 +60,12 @@ class PlayerManager(TypedObjectManager, UserManager):
end_date = datetime.datetime.now()
tdelta = datetime.timedelta(days)
start_date = end_date - tdelta
- return User.objects.filter(date_joined__range=(start_date, end_date))
+ return self.filter(date_joined__range=(start_date, end_date))
@returns_typeclass_list
- @returns_player_list
def get_recently_connected_players(self, days=7):
"""
- Returns a QuerySet containing the player User accounts that have been
+ Returns a QuerySet containing the player accounts that have been
connected within the last days.
days - number of days backwards to check
@@ -122,33 +73,31 @@ class PlayerManager(TypedObjectManager, UserManager):
end_date = datetime.datetime.now()
tdelta = datetime.timedelta(days)
start_date = end_date - tdelta
- return User.objects.filter(last_login__range=(
+ return self.filter(last_login__range=(
start_date, end_date)).order_by('-last_login')
@returns_typeclass
- @returns_player
def get_player_from_email(self, uemail):
"""
Returns a player object when given an email address.
"""
- return User.objects.filter(email__iexact=uemail)
+ return self.filter(email__iexact=uemail)
@returns_typeclass
- @returns_player
def get_player_from_uid(self, uid):
"""
Returns a player object based on User id.
"""
try:
- return User.objects.get(id=uid)
- except User.model.DoesNotExist:
+ return self.get(id=uid)
+ except self.model.DoesNotExist:
return None
@returns_typeclass
def get_player_from_name(self, uname):
"Get player object based on name"
try:
- return self.get(user__username__iexact=uname)
+ return self.get(username__iexact=uname)
except self.model.DoesNotExist:
return None
@@ -165,7 +114,7 @@ class PlayerManager(TypedObjectManager, UserManager):
matches = self.filter(id=dbref)
if matches:
return matches
- return self.filter(user__username__iexact=ostring)
+ return self.filter(username__iexact=ostring)
def swap_character(self, player, new_character, delete_old_character=False):
"""
diff --git a/src/server/initial_setup.py b/src/server/initial_setup.py
index f93da77d5b..feaca4ec33 100644
--- a/src/server/initial_setup.py
+++ b/src/server/initial_setup.py
@@ -25,20 +25,20 @@ def create_config_values():
ServerConfig.objects.conf("site_name", settings.SERVERNAME)
ServerConfig.objects.conf("idle_timeout", settings.IDLE_TIMEOUT)
-def get_god_user():
+def get_god_player():
"""
Creates the god user.
"""
PlayerDB = get_user_model()
try:
- god_user = PlayerDB.objects.get(id=1)
+ god_player = PlayerDB.objects.get(id=1)
except PlayerDB.DoesNotExist:
txt = "\n\nNo superuser exists yet. The superuser is the 'owner' account on the"
- txt += "\nEvennia server; a good safety fallback. Create a new superuser using the command"
+ txt += "\nEvennia server. Create a new superuser using the command"
txt += "\n\n python manage.py createsuperuser"
txt += "\n\nFollow the prompts, then restart the server."
raise Exception(txt)
- return god_user
+ return god_player
def create_objects():
"""
@@ -49,22 +49,26 @@ def create_objects():
# Set the initial User's account object's username on the #1 object.
# This object is pure django and only holds name, email and password.
- god_user = get_god_user()
+ 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.
- character_typeclass = settings.BASE_CHARACTER_TYPECLASS
+ player_typeclass = settings.BASE_PLAYER_TYPECLASS
- # Create the Player object as well as the in-game god-character
- # for user #1. We can't set location and home yet since nothing
+ # run all creation hooks on god_player (we must do so manually since the manage.py command does not)
+ god_player.typeclass_path = player_typeclass
+ god_player.basetype_setup()
+ god_player.at_player_creation()
+ god_player.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all()")
+
+ # Create the in-game god-character for player #1. We can't set location and home yet since nothing
# exists. Also, all properties (name, email, password, is_superuser)
# is inherited from the user so we don't specify it again here.
-
- god_player = create.create_player(god_user.username, None, None, user=god_user)
- god_character = create.create_object(character_typeclass, key=god_user.username)
+ character_typeclass = settings.BASE_CHARACTER_TYPECLASS
+ god_character = create.create_object(character_typeclass, key=god_player.username)
god_character.id = 1
god_character.db.desc = _('This is User #1.')
@@ -132,7 +136,7 @@ def create_channels():
return
# connect the god user to all these channels by default.
- goduser = get_god_user()
+ goduser = get_god_player()
from src.comms.models import PlayerChannelConnection
PlayerChannelConnection.objects.create_connection(goduser, pchan)
PlayerChannelConnection.objects.create_connection(goduser, ichan)
diff --git a/src/server/serversession.py b/src/server/serversession.py
index 49493311f8..24ba73cae1 100644
--- a/src/server/serversession.py
+++ b/src/server/serversession.py
@@ -77,17 +77,16 @@ class ServerSession(Session):
player - the player associated with the session
"""
self.player = player
- self.user = player.user
- self.uid = self.user.id
- self.uname = self.user.username
+ self.uid = self.player.id
+ self.uname = self.player.username
self.logged_in = True
self.conn_time = time.time()
self.puid = None
self.puppet = None
# Update account's last login time.
- self.user.last_login = datetime.now()
- self.user.save()
+ self.player.last_login = datetime.now()
+ self.player.save()
def at_disconnect(self):
"""
@@ -97,7 +96,7 @@ class ServerSession(Session):
sessid = self.sessid
player = self.player
_GA(player.dbobj, "unpuppet_object")(sessid)
- uaccount = _GA(player.dbobj, "user")
+ uaccount = player.dbobj
uaccount.last_login = datetime.now()
uaccount.save()
# calling player hook
diff --git a/src/utils/create.py b/src/utils/create.py
index 0eae842304..32e07dfa7c 100644
--- a/src/utils/create.py
+++ b/src/utils/create.py
@@ -22,7 +22,6 @@ Models covered:
Players
"""
from django.conf import settings
-from django.contrib.auth.models import User
from django.db import IntegrityError
from src.utils.idmapper.models import SharedMemoryModel
from src.utils import utils, logger
@@ -387,49 +386,32 @@ channel = create_channel
# Player creation methods
#
-def create_player(name, email, password,
- user=None,
+def create_player(key, email, password,
typeclass=None,
is_superuser=False,
locks=None, permissions=None,
- player_dbobj=None, report_to=None):
+ report_to=None):
"""
- This creates a new player, handling the creation of the User
- object and its associated Player object.
+ This creates a new player.
- If player_dbobj is given, this player object is used instead of
- creating a new one. This is called by the admin interface since it
- needs to create the player object in order to relate it automatically
- to the user.
+ key - the player's name. This should be unique.
+ email - email on valid addr@addr.domain form.
+ password - password in cleartext
+ is_superuser - wether or not this player is to be a superuser
+ locks - lockstring
+ permission - list of permissions
+ report_to - an object with a msg() method to report errors to. If
+ not given, errors will be logged.
- If create_character is
- True, a game player object with the same name as the User/Player will
- also be created. Its typeclass and base properties can also be given.
-
- Returns the new game character, or the Player obj if no
- character is created. For more info about the typeclass argument,
- see create_objects() above.
-
- Note: if user is supplied, it will NOT be modified (args name, email,
- passw and is_superuser will be ignored). Change those properties
- directly on the User instead.
-
- If no permissions are given (None), the default permission group
- as defined in settings.PERMISSION_PLAYER_DEFAULT will be
- assigned. If permissions are given, no automatic assignment will
- occur.
+ Will return the Player-typeclass or None/raise Exception if the
+ Typeclass given failed to load.
Concerning is_superuser:
- A superuser should have access to everything
- in the game and on the server/web interface. The very first user
- created in the database is always a superuser (that's using
- django's own creation, not this one).
Usually only the server admin should need to be superuser, all
other access levels can be handled with more fine-grained
- permissions or groups.
- Since superuser overrules all permissions, we don't
- set any in this case.
+ permissions or groups. A superuser bypasses all lock checking
+ operations and is thus not suitable for play-testing the game.
"""
global _PlayerDB, _Player
@@ -440,48 +422,28 @@ def create_player(name, email, password,
if not email:
email = "dummy@dummy.com"
- if user:
- new_user = user
- email = user.email
-
- if user:
- conflict_check = User.objects.filter(username__iexact=user.username)
- conflict_check = len(conflict_check) > 1
- else:
- conflict_check = User.objects.filter(username__iexact=name)
-
- if conflict_check:
- raise ValueError("A user with this name already exists.")
-
- if not user:
- if is_superuser:
- new_user = User.objects.create_superuser(name, email, password)
- else:
- new_user = User.objects.create_user(name, email, password)
+ if _PlayerDB.objects.filter(username__iexact=key):
+ raise ValueError("A Player with this name already exists.")
try:
+
+ # create the correct Player object
+ if is_superuser:
+ new_db_player = _PlayerDB.objects.create_superuser(key, email, password)
+ else:
+ new_db_player = _PlayerDB.objects.create_user(key, email, password)
+
if not typeclass:
typeclass = settings.BASE_PLAYER_TYPECLASS
elif isinstance(typeclass, _PlayerDB):
- # this is already an objectdb instance, extract its typeclass
+ # this is an PlayerDB instance, extract its typeclass path
typeclass = typeclass.typeclass.path
elif isinstance(typeclass, _Player) or utils.inherits_from(typeclass, _Player):
- # this is already an object typeclass, extract its path
+ # this is Player object typeclass, extract its path
typeclass = typeclass.path
- if player_dbobj:
- try:
- _GA(player_dbobj, "dbobj")
- new_db_player = player_dbobj.dbobj
- except AttributeError:
- new_db_player = player_dbobj
- # use the typeclass from this object
- typeclass = new_db_player.typeclass_path
- else:
- new_user = User.objects.get(username=new_user.username)
- new_db_player = _PlayerDB(db_key=name, user=new_user)
- new_db_player.save()
- # assign the typeclass
- typeclass = utils.to_unicode(typeclass)
- new_db_player.typeclass_path = typeclass
+
+ # assign the typeclass
+ typeclass = utils.to_unicode(typeclass)
+ new_db_player.typeclass_path = typeclass
# this will either load the typeclass or the default one
new_player = new_db_player.typeclass
@@ -500,34 +462,27 @@ def create_player(name, email, password,
# call hook method (may override default permissions)
new_player.at_player_creation()
- print
# custom given arguments potentially overrides the hook
if permissions:
new_player.permissions = permissions
elif not new_player.permissions:
new_player.permissions = settings.PERMISSION_PLAYER_DEFAULT
-
if locks:
new_player.locks.add(locks)
-
return new_player
+
except Exception:
- # a failure in creating the character
- if not user:
- # in there was a failure we clean up everything we can
- logger.log_trace()
- try:
- new_user.delete()
- except Exception:
- pass
- try:
- new_player.delete()
- except Exception:
- pass
- try:
- del new_player
- except Exception:
- pass
+ # a failure in creating the player; we try to clean
+ # up as much as we can
+ logger.log_trace()
+ try:
+ new_player.delete()
+ except Exception:
+ pass
+ try:
+ del new_player
+ except Exception:
+ pass
raise
# alias
diff --git a/src/utils/search.py b/src/utils/search.py
index a7abbc2354..032c6241d1 100644
--- a/src/utils/search.py
+++ b/src/utils/search.py
@@ -16,11 +16,11 @@ the database model and call its 'objects' property.
Also remember that all commands in this file return lists (also if
there is only one match) unless noted otherwise.
-Example: To reach the search method 'get_object_with_user'
+Example: To reach the search method 'get_object_with_player'
in src/objects/managers.py:
> from src.objects.models import ObjectDB
-> match = Object.objects.get_object_with_user(...)
+> match = Object.objects.get_object_with_player(...)
"""