Rename all instances of Player->Account.

This commit is contained in:
Griatch 2017-07-07 23:47:21 +02:00
parent a14e11640b
commit 5590ee2258
94 changed files with 1316 additions and 2327 deletions

View file

@ -25,7 +25,7 @@ from builtins import object
# Typeclasses # Typeclasses
DefaultPlayer = None DefaultAccount = None
DefaultGuest = None DefaultGuest = None
DefaultObject = None DefaultObject = None
DefaultCharacter = None DefaultCharacter = None
@ -36,7 +36,7 @@ DefaultScript = None
# Database models # Database models
ObjectDB = None ObjectDB = None
PlayerDB = None AccountDB = None
ScriptDB = None ScriptDB = None
ChannelDB = None ChannelDB = None
Msg = None Msg = None
@ -51,7 +51,7 @@ InterruptCommand = None
# search functions # search functions
search_object = None search_object = None
search_script = None search_script = None
search_player = None search_account = None
search_channel = None search_channel = None
search_message = None search_message = None
search_help = None search_help = None
@ -60,7 +60,7 @@ search_tag = None
# create functions # create functions
create_object = None create_object = None
create_script = None create_script = None
create_player = None create_account = None
create_channel = None create_channel = None
create_message = None create_message = None
create_help_entry = None create_help_entry = None
@ -117,17 +117,17 @@ def _init():
Evennia has fully initialized all its models. It sets up the API Evennia has fully initialized all its models. It sets up the API
in a safe environment where all models are available already. in a safe environment where all models are available already.
""" """
global DefaultPlayer, DefaultObject, DefaultGuest, DefaultCharacter global DefaultAccount, DefaultObject, DefaultGuest, DefaultCharacter
global DefaultRoom, DefaultExit, DefaultChannel, DefaultScript global DefaultRoom, DefaultExit, DefaultChannel, DefaultScript
global ObjectDB, PlayerDB, ScriptDB, ChannelDB, Msg global ObjectDB, AccountDB, ScriptDB, ChannelDB, Msg
global Command, CmdSet, default_cmds, syscmdkeys, InterruptCommand global Command, CmdSet, default_cmds, syscmdkeys, InterruptCommand
global search_object, search_script, search_player, search_channel, search_help, search_tag global search_object, search_script, search_account, search_channel, search_help, search_tag
global create_object, create_script, create_player, create_channel, create_message, create_help_entry global create_object, create_script, create_account, create_channel, create_message, create_help_entry
global settings,lockfuncs, logger, utils, gametime, ansi, spawn, managers global settings,lockfuncs, logger, utils, gametime, ansi, spawn, managers
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER
from .players.players import DefaultPlayer from .accounts.accounts import DefaultAccount
from .players.players import DefaultGuest from .accounts.accounts import DefaultGuest
from .objects.objects import DefaultObject from .objects.objects import DefaultObject
from .objects.objects import DefaultCharacter from .objects.objects import DefaultCharacter
from .objects.objects import DefaultRoom from .objects.objects import DefaultRoom
@ -137,7 +137,7 @@ def _init():
# Database models # Database models
from .objects.models import ObjectDB from .objects.models import ObjectDB
from .players.models import PlayerDB from .accounts.models import AccountDB
from .scripts.models import ScriptDB from .scripts.models import ScriptDB
from .comms.models import ChannelDB from .comms.models import ChannelDB
from .comms.models import Msg from .comms.models import Msg
@ -149,7 +149,7 @@ def _init():
# search functions # search functions
from .utils.search import search_object from .utils.search import search_object
from .utils.search import search_script from .utils.search import search_script
from .utils.search import search_player from .utils.search import search_account
from .utils.search import search_message from .utils.search import search_message
from .utils.search import search_channel from .utils.search import search_channel
from .utils.search import search_help from .utils.search import search_help
@ -158,7 +158,7 @@ def _init():
# create functions # create functions
from .utils.create import create_object from .utils.create import create_object
from .utils.create import create_script from .utils.create import create_script
from .utils.create import create_player from .utils.create import create_account
from .utils.create import create_channel from .utils.create import create_channel
from .utils.create import create_message from .utils.create import create_message
from .utils.create import create_help_entry from .utils.create import create_help_entry
@ -202,7 +202,7 @@ def _init():
Links to instantiated database managers. Links to instantiated database managers.
helpentry - HelpEntry.objects helpentry - HelpEntry.objects
players - PlayerDB.objects accounts - AccountDB.objects
scripts - ScriptDB.objects scripts - ScriptDB.objects
msgs - Msg.objects msgs - Msg.objects
channels - Channel.objects channels - Channel.objects
@ -213,7 +213,7 @@ def _init():
""" """
from .help.models import HelpEntry from .help.models import HelpEntry
from .players.models import PlayerDB from .accounts.models import AccountDB
from .scripts.models import ScriptDB from .scripts.models import ScriptDB
from .comms.models import Msg, ChannelDB from .comms.models import Msg, ChannelDB
from .objects.models import ObjectDB from .objects.models import ObjectDB
@ -223,7 +223,7 @@ def _init():
# create container's properties # create container's properties
helpentries = HelpEntry.objects helpentries = HelpEntry.objects
players = PlayerDB.objects accounts = AccountDB.objects
scripts = ScriptDB.objects scripts = ScriptDB.objects
msgs = Msg.objects msgs = Msg.objects
channels = ChannelDB.objects channels = ChannelDB.objects
@ -232,7 +232,7 @@ def _init():
attributes = Attribute.objects attributes = Attribute.objects
tags = Tag.objects tags = Tag.objects
# remove these so they are not visible as properties # remove these so they are not visible as properties
del HelpEntry, PlayerDB, ScriptDB, Msg, ChannelDB del HelpEntry, AccountDB, ScriptDB, Msg, ChannelDB
#del ExternalChannelConnection #del ExternalChannelConnection
del ObjectDB, ServerConfig, Tag, Attribute del ObjectDB, ServerConfig, Tag, Attribute
@ -250,10 +250,10 @@ def _init():
""" """
from .commands.default.cmdset_character import CharacterCmdSet from .commands.default.cmdset_character import CharacterCmdSet
from .commands.default.cmdset_player import PlayerCmdSet from .commands.default.cmdset_account import AccountCmdSet
from .commands.default.cmdset_unloggedin import UnloggedinCmdSet from .commands.default.cmdset_unloggedin import UnloggedinCmdSet
from .commands.default.cmdset_session import SessionCmdSet from .commands.default.cmdset_session import SessionCmdSet
from .commands.default.muxcommand import MuxCommand, MuxPlayerCommand from .commands.default.muxcommand import MuxCommand, MuxAccountCommand
def __init__(self): def __init__(self):
"populate the object with commands" "populate the object with commands"
@ -265,14 +265,14 @@ def _init():
from .commands.default import (admin, batchprocess, from .commands.default import (admin, batchprocess,
building, comms, general, building, comms, general,
player, help, system, unloggedin) account, help, system, unloggedin)
add_cmds(admin) add_cmds(admin)
add_cmds(building) add_cmds(building)
add_cmds(batchprocess) add_cmds(batchprocess)
add_cmds(building) add_cmds(building)
add_cmds(comms) add_cmds(comms)
add_cmds(general) add_cmds(general)
add_cmds(player) add_cmds(account)
add_cmds(help) add_cmds(help)
add_cmds(system) add_cmds(system)
add_cmds(unloggedin) add_cmds(unloggedin)
@ -293,7 +293,7 @@ def _init():
CMD_MULTIMATCH - multiple command matches were found CMD_MULTIMATCH - multiple command matches were found
CMD_CHANNEL - the command name is a channel name CMD_CHANNEL - the command name is a channel name
CMD_LOGINSTART - this command will be called as the very CMD_LOGINSTART - this command will be called as the very
first command when a player connects to first command when an account connects to
the server. the server.
To access in code, do 'from evennia import syscmdkeys' then To access in code, do 'from evennia import syscmdkeys' then

View file

@ -107,7 +107,7 @@ class AccountForm(forms.ModelForm):
db_typeclass_path = forms.CharField( db_typeclass_path = forms.CharField(
label="Typeclass", label="Typeclass",
initial=settings.BASE_PLAYER_TYPECLASS, initial=settings.BASE_ACCOUNT_TYPECLASS,
widget=forms.TextInput( widget=forms.TextInput(
attrs={'size': '78'}), attrs={'size': '78'}),
help_text="Required. Defines what 'type' of entity this is. This " help_text="Required. Defines what 'type' of entity this is. This "
@ -117,7 +117,7 @@ class AccountForm(forms.ModelForm):
db_permissions = forms.CharField( db_permissions = forms.CharField(
label="Permissions", label="Permissions",
initial=settings.PERMISSION_PLAYER_DEFAULT, initial=settings.PERMISSION_ACCOUNT_DEFAULT,
required=False, required=False,
widget=forms.TextInput( widget=forms.TextInput(
attrs={'size': '78'}), attrs={'size': '78'}),
@ -137,7 +137,7 @@ class AccountForm(forms.ModelForm):
"<i>type:lockfunction(args);type2:lockfunction2(args);...") "<i>type:lockfunction(args);type2:lockfunction2(args);...")
db_cmdset_storage = forms.CharField( db_cmdset_storage = forms.CharField(
label="cmdset", label="cmdset",
initial=settings.CMDSET_PLAYER, initial=settings.CMDSET_ACCOUNT,
widget=forms.TextInput(attrs={'size': '78'}), widget=forms.TextInput(attrs={'size': '78'}),
required=False, required=False,
help_text="python path to account cmdset class (set in " help_text="python path to account cmdset class (set in "
@ -241,7 +241,7 @@ class AccountDBAdmin(BaseUserAdmin):
obj.save() obj.save()
if not change: if not change:
#calling hooks for new account #calling hooks for new account
obj.set_class_from_typeclass(typeclass_path=settings.BASE_PLAYER_TYPECLASS) obj.set_class_from_typeclass(typeclass_path=settings.BASE_ACCOUNT_TYPECLASS)
obj.basetype_setup() obj.basetype_setup()
obj.at_account_creation() obj.at_account_creation()

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
This sub-package contains Evennia's command system. It handles This sub-package contains Evennia's command system. It handles
everything related to parsing input from the player, building cmdsets everything related to parsing input from the account, building cmdsets
and executing the code associated with a found command class. and executing the code associated with a found command class.
commands.default contains all the default "mux-like" commands of commands.default contains all the default "mux-like" commands of

View file

@ -13,7 +13,7 @@ command line. The processing of a command works as follows:
- object cmdsets: all objects at caller's location are scanned for non-empty - object cmdsets: all objects at caller's location are scanned for non-empty
cmdsets. This includes cmdsets on exits. cmdsets. This includes cmdsets on exits.
- caller: the caller is searched for its own currently active cmdset. - caller: the caller is searched for its own currently active cmdset.
- player: lastly the cmdsets defined on caller.player are added. - account: lastly the cmdsets defined on caller.account are added.
3. The collected cmdsets are merged together to a combined, current cmdset. 3. The collected cmdsets are merged together to a combined, current cmdset.
4. If the input string is empty -> check for CMD_NOINPUT command in 4. If the input string is empty -> check for CMD_NOINPUT command in
current cmdset or fallback to error message. Exit. current cmdset or fallback to error message. Exit.
@ -85,7 +85,7 @@ CMD_LOGINSTART = "__unloggedin_look_command"
_SEARCH_AT_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) _SEARCH_AT_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
# Output strings. The first is the IN_GAME_ERRORS return, the second # Output strings. The first is the IN_GAME_ERRORS return, the second
# is the normal "production message to echo to the player. # is the normal "production message to echo to the account.
_ERROR_UNTRAPPED = ( _ERROR_UNTRAPPED = (
""" """
@ -210,7 +210,7 @@ def _process_input(caller, prompt, result, cmd, generator):
part of yielding from a Command's `func`. part of yielding from a Command's `func`.
Args: Args:
caller (Character, Player or Session): the caller. caller (Character, Account or Session): the caller.
prompt (basestring): The sent prompt. prompt (basestring): The sent prompt.
result (basestring): The unprocessed answer. result (basestring): The unprocessed answer.
cmd (Command): The command itself. cmd (Command): The command itself.
@ -248,20 +248,20 @@ class ErrorReported(Exception):
# Helper function # Helper function
@inlineCallbacks @inlineCallbacks
def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string): def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string):
""" """
Gather all relevant cmdsets and merge them. Gather all relevant cmdsets and merge them.
Args: Args:
caller (Session, Player or Object): The entity executing the command. Which caller (Session, Account or Object): The entity executing the command. Which
type of object this is depends on the current game state; for example type of object this is depends on the current game state; for example
when the user is not logged in, this will be a Session, when being OOC when the user is not logged in, this will be a Session, when being OOC
it will be a Player and when puppeting an object this will (often) be it will be an Account and when puppeting an object this will (often) be
a Character Object. In the end it depends on where the cmdset is stored. a Character Object. In the end it depends on where the cmdset is stored.
session (Session or None): The Session associated with caller, if any. session (Session or None): The Session associated with caller, if any.
player (Player or None): The calling Player associated with caller, if any. account (Account or None): The calling Account associated with caller, if any.
obj (Object or None): The Object associated with caller, if any. obj (Object or None): The Object associated with caller, if any.
callertype (str): This identifies caller as either "player", "object" or "session" callertype (str): This identifies caller as either "account", "object" or "session"
to avoid having to do this check internally. to avoid having to do this check internally.
raw_string (str): The input string. This is only used for error reporting. raw_string (str): The input string. This is only used for error reporting.
@ -272,18 +272,18 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
Notes: Notes:
The cdmsets are merged in order or generality, so that the The cdmsets are merged in order or generality, so that the
Object's cmdset is merged last (and will thus take precedence Object's cmdset is merged last (and will thus take precedence
over same-named and same-prio commands on Player and Session). over same-named and same-prio commands on Account and Session).
""" """
try: try:
@inlineCallbacks @inlineCallbacks
def _get_channel_cmdset(player_or_obj): def _get_channel_cmdset(account_or_obj):
""" """
Helper-method; Get channel-cmdsets Helper-method; Get channel-cmdsets
""" """
# Create cmdset for all player's available channels # Create cmdset for all account's available channels
try: try:
channel_cmdset = yield CHANNELHANDLER.get_cmdset(player_or_obj) channel_cmdset = yield CHANNELHANDLER.get_cmdset(account_or_obj)
returnValue([channel_cmdset]) returnValue([channel_cmdset])
except Exception: except Exception:
_msg_err(caller, _ERROR_CMDSETS) _msg_err(caller, _ERROR_CMDSETS)
@ -313,8 +313,8 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
_GA(lobj, "at_cmdset_get")(caller=caller) _GA(lobj, "at_cmdset_get")(caller=caller)
except Exception: except Exception:
logger.log_trace() logger.log_trace()
# the call-type lock is checked here, it makes sure a player # the call-type lock is checked here, it makes sure an account
# is not seeing e.g. the commands on a fellow player (which is why # is not seeing e.g. the commands on a fellow account (which is why
# the no_superuser_bypass must be True) # the no_superuser_bypass must be True)
local_obj_cmdsets = \ local_obj_cmdsets = \
yield list(chain.from_iterable( yield list(chain.from_iterable(
@ -355,9 +355,9 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
# we are calling the command from the session level # we are calling the command from the session level
report_to = session report_to = session
current, cmdsets = yield _get_cmdsets(session) current, cmdsets = yield _get_cmdsets(session)
if player: # this automatically implies logged-in if account: # this automatically implies logged-in
pcurrent, player_cmdsets = yield _get_cmdsets(player) pcurrent, account_cmdsets = yield _get_cmdsets(account)
cmdsets += player_cmdsets cmdsets += account_cmdsets
current = current + pcurrent current = current + pcurrent
if obj: if obj:
ocurrent, obj_cmdsets = yield _get_cmdsets(obj) ocurrent, obj_cmdsets = yield _get_cmdsets(obj)
@ -374,13 +374,13 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
channel_cmdsets = yield _get_channel_cmdset(obj) channel_cmdsets = yield _get_channel_cmdset(obj)
cmdsets += channel_cmdsets cmdsets += channel_cmdsets
if not current.no_channels: if not current.no_channels:
channel_cmdsets = yield _get_channel_cmdset(player) channel_cmdsets = yield _get_channel_cmdset(account)
cmdsets += channel_cmdsets cmdsets += channel_cmdsets
elif callertype == "player": elif callertype == "account":
# we are calling the command from the player level # we are calling the command from the account level
report_to = player report_to = account
current, cmdsets = yield _get_cmdsets(player) current, cmdsets = yield _get_cmdsets(account)
if obj: if obj:
ocurrent, obj_cmdsets = yield _get_cmdsets(obj) ocurrent, obj_cmdsets = yield _get_cmdsets(obj)
current = current + ocurrent current = current + ocurrent
@ -395,7 +395,7 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
# also objs may have channels # also objs may have channels
cmdsets += yield _get_channel_cmdset(obj) cmdsets += yield _get_channel_cmdset(obj)
if not current.no_channels: if not current.no_channels:
cmdsets += yield _get_channel_cmdset(player) cmdsets += yield _get_channel_cmdset(account)
elif callertype == "object": elif callertype == "object":
# we are calling the command from the object level # we are calling the command from the object level
@ -472,22 +472,22 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
This is the main mechanism that handles any string sent to the engine. This is the main mechanism that handles any string sent to the engine.
Args: Args:
called_by (Session, Player or Object): Object from which this called_by (Session, Account or Object): Object from which this
command was called. which this was called from. What this is command was called. which this was called from. What this is
depends on the game state. depends on the game state.
raw_string (str): The command string as given on the command line. raw_string (str): The command string as given on the command line.
_testing (bool, optional): Used for debug purposes and decides if we _testing (bool, optional): Used for debug purposes and decides if we
should actually execute the command or not. If True, the should actually execute the command or not. If True, the
command instance will be returned. command instance will be returned.
callertype (str, optional): One of "session", "player" or callertype (str, optional): One of "session", "account" or
"object". These are treated in decending order, so when the "object". These are treated in decending order, so when the
Session is the caller, it will merge its own cmdset into Session is the caller, it will merge its own cmdset into
cmdsets from both Player and eventual puppeted Object (and cmdsets from both Account and eventual puppeted Object (and
cmdsets in its room etc). A Player will only include its own cmdsets in its room etc). An Account will only include its own
cmdset and the Objects and so on. Merge order is the same cmdset and the Objects and so on. Merge order is the same
order, so that Object cmdsets are merged in last, giving them order, so that Object cmdsets are merged in last, giving them
precendence for same-name and same-prio commands. precendence for same-name and same-prio commands.
session (Session, optional): Relevant if callertype is "player" - the session will help session (Session, optional): Relevant if callertype is "account" - the session will help
retrieve the correct cmdsets from puppeted objects. retrieve the correct cmdsets from puppeted objects.
cmdobj (Command, optional): If given a command instance, this will be executed using cmdobj (Command, optional): If given a command instance, this will be executed using
`called_by` as the caller, `raw_string` representing its arguments and (optionally) `called_by` as the caller, `raw_string` representing its arguments and (optionally)
@ -513,7 +513,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
""" """
@inlineCallbacks @inlineCallbacks
def _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, player): def _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account):
""" """
Helper function: This initializes and runs the Command Helper function: This initializes and runs the Command
instance once the parser has identified it as either a normal instance once the parser has identified it as either a normal
@ -528,7 +528,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
as cmdname). as cmdname).
cmdset (CmdSet): Command sert the command belongs to (if any).. cmdset (CmdSet): Command sert the command belongs to (if any)..
session (Session): Session of caller (if any). session (Session): Session of caller (if any).
player (Player): Player of caller (if any). account (Account): Account of caller (if any).
Returns: Returns:
deferred (Deferred): this will fire with the return of the deferred (Deferred): this will fire with the return of the
@ -548,7 +548,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
cmd.args = args cmd.args = args
cmd.cmdset = cmdset cmd.cmdset = cmdset
cmd.session = session cmd.session = session
cmd.player = player cmd.account = account
cmd.raw_string = unformatted_raw_string cmd.raw_string = unformatted_raw_string
#cmd.obj # set via on-object cmdset handler for each command, #cmd.obj # set via on-object cmdset handler for each command,
# since this may be different for every command when # since this may be different for every command when
@ -618,13 +618,13 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
raw_string = to_unicode(raw_string, force_string=True) raw_string = to_unicode(raw_string, force_string=True)
session, player, obj = session, None, None session, account, obj = session, None, None
if callertype == "session": if callertype == "session":
session = called_by session = called_by
player = session.player account = session.account
obj = session.puppet obj = session.puppet
elif callertype == "player": elif callertype == "account":
player = called_by account = called_by
if session: if session:
obj = yield session.puppet obj = yield session.puppet
elif callertype == "object": elif callertype == "object":
@ -633,10 +633,10 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
raise RuntimeError("cmdhandler: callertype %s is not valid." % callertype) raise RuntimeError("cmdhandler: callertype %s is not valid." % callertype)
# the caller will be the one to receive messages and excert its permissions. # the caller will be the one to receive messages and excert its permissions.
# we assign the caller with preference 'bottom up' # we assign the caller with preference 'bottom up'
caller = obj or player or session caller = obj or account or session
# The error_to is the default recipient for errors. Tries to make sure a player # The error_to is the default recipient for errors. Tries to make sure an account
# does not get spammed for errors while preserving character mirroring. # does not get spammed for errors while preserving character mirroring.
error_to = obj or session or player error_to = obj or session or account
try: # catch bugs in cmdhandler itself try: # catch bugs in cmdhandler itself
try: # catch special-type commands try: # catch special-type commands
@ -648,11 +648,11 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
unformatted_raw_string = "%s%s" % (cmdname, args) unformatted_raw_string = "%s%s" % (cmdname, args)
cmdset = None cmdset = None
session = session session = session
player = player account = account
else: else:
# no explicit cmdobject given, figure it out # no explicit cmdobject given, figure it out
cmdset = yield get_and_merge_cmdsets(caller, session, player, obj, cmdset = yield get_and_merge_cmdsets(caller, session, account, obj,
callertype, raw_string) callertype, raw_string)
if not cmdset: if not cmdset:
# this is bad and shouldn't happen. # this is bad and shouldn't happen.
@ -722,7 +722,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
raise ExecSystemCommand(cmd, sysarg) raise ExecSystemCommand(cmd, sysarg)
# A normal command. # A normal command.
ret = yield _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, player) ret = yield _run_command(cmd, cmdname, args, raw_cmdname, cmdset, session, account)
returnValue(ret) returnValue(ret)
except ErrorReported as exc: except ErrorReported as exc:
@ -738,7 +738,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
if syscmd: if syscmd:
ret = yield _run_command(syscmd, syscmd.key, sysarg, ret = yield _run_command(syscmd, syscmd.key, sysarg,
unformatted_raw_string, cmdset, session, player) unformatted_raw_string, cmdset, session, account)
returnValue(ret) returnValue(ret)
elif sysarg: elif sysarg:
# return system arg # return system arg

View file

@ -22,7 +22,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
Args: Args:
raw_string (str): The unparsed text entered by the caller. raw_string (str): The unparsed text entered by the caller.
cmdset (CmdSet): The merged, currently valid cmdset cmdset (CmdSet): The merged, currently valid cmdset
caller (Session, Player or Object): The caller triggering this parsing. caller (Session, Account or Object): The caller triggering this parsing.
match_index (int, optional): Index to pick a given match in a match_index (int, optional): Index to pick a given match in a
list of same-named command matches. If this is given, it suggests list of same-named command matches. If this is given, it suggests
this is not the first time this function was called: normally this is not the first time this function was called: normally

View file

@ -4,7 +4,7 @@ A Command Set (CmdSet) holds a set of commands. The Cmdsets can be
merged and combined to create new sets of commands in a merged and combined to create new sets of commands in a
non-destructive way. This makes them very powerful for implementing non-destructive way. This makes them very powerful for implementing
custom game states where different commands (or different variations custom game states where different commands (or different variations
of commands) are available to the players depending on circumstance. of commands) are available to the accounts depending on circumstance.
The available merge operations are partly borrowed from mathematical The available merge operations are partly borrowed from mathematical
Set theory. Set theory.
@ -110,9 +110,9 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
merger (i.e. A above) automatically taking merger (i.e. A above) automatically taking
precedence. But if allow_duplicates is true, the precedence. But if allow_duplicates is true, the
result will be a merger with more than one of each result will be a merger with more than one of each
name match. This will usually lead to the player name match. This will usually lead to the account
receiving a multiple-match error higher up the road, receiving a multiple-match error higher up the road,
but can be good for things like cmdsets on non-player but can be good for things like cmdsets on non-account
objects in a room, to allow the system to warn that objects in a room, to allow the system to warn that
more than one 'ball' in the room has the same 'kick' more than one 'ball' in the room has the same 'kick'
command defined on it, so it may offer a chance to command defined on it, so it may offer a chance to
@ -134,7 +134,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
commands commands
no_channels - ignore the name of channels when matching against no_channels - ignore the name of channels when matching against
commands (WARNING- this is dangerous since the commands (WARNING- this is dangerous since the
player can then not even ask staff for help if account can then not even ask staff for help if
something goes wrong) something goes wrong)
@ -167,9 +167,9 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
Creates a new CmdSet instance. Creates a new CmdSet instance.
Args: Args:
cmdsetobj (Session, Player, Object, optional): This is the database object cmdsetobj (Session, Account, Object, optional): This is the database object
to which this particular instance of cmdset is related. It to which this particular instance of cmdset is related. It
is often a character but may also be a regular object, Player is often a character but may also be a regular object, Account
or Session. or Session.
key (str, optional): The idenfier for this cmdset. This key (str, optional): The idenfier for this cmdset. This
helps if wanting to selectively remov cmdsets. helps if wanting to selectively remov cmdsets.

View file

@ -9,8 +9,8 @@ intelligent container that, when added to other CmdSet make sure that
same-name commands are treated correctly (usually so there are no same-name commands are treated correctly (usually so there are no
doublets). This temporary but up-to-date merger of CmdSet is jointly doublets). This temporary but up-to-date merger of CmdSet is jointly
called the Current Cmset. It is this Current CmdSet that the called the Current Cmset. It is this Current CmdSet that the
commandhandler looks through whenever a player enters a command (it commandhandler looks through whenever an account enters a command (it
also adds CmdSets from objects in the room in real-time). All player also adds CmdSets from objects in the room in real-time). All account
objects have a 'default cmdset' containing all the normal in-game mud objects have a 'default cmdset' containing all the normal in-game mud
commands (look etc). commands (look etc).
@ -19,12 +19,12 @@ So what is all this cmdset complexity good for?
In its simplest form, a CmdSet has no commands, only a key name. In In its simplest form, a CmdSet has no commands, only a key name. In
this case the cmdset's use is up to each individual game - it can be this case the cmdset's use is up to each individual game - it can be
used by an AI module for example (mobs in cmdset 'roam' move from room used by an AI module for example (mobs in cmdset 'roam' move from room
to room, in cmdset 'attack' they enter combat with players). to room, in cmdset 'attack' they enter combat with accounts).
Defining commands in cmdsets offer some further powerful game-design Defining commands in cmdsets offer some further powerful game-design
consequences however. Here are some examples: consequences however. Here are some examples:
As mentioned above, all players always have at least the Default As mentioned above, all accounts always have at least the Default
CmdSet. This contains the set of all normal-use commands in-game, CmdSet. This contains the set of all normal-use commands in-game,
stuff like look and @desc etc. Now assume our players end up in a dark stuff like look and @desc etc. Now assume our players end up in a dark
room. You don't want the player to be able to do much in that dark room. You don't want the player to be able to do much in that dark
@ -37,7 +37,7 @@ and have this completely replace the default cmdset.
Another example: Say you want your players to be able to go Another example: Say you want your players to be able to go
fishing. You could implement this as a 'fish' command that fails fishing. You could implement this as a 'fish' command that fails
whenever the player has no fishing rod. Easy enough. But what if you whenever the account has no fishing rod. Easy enough. But what if you
want to make fishing more complex - maybe you want four-five different want to make fishing more complex - maybe you want four-five different
commands for throwing your line, reeling in, etc? Most players won't commands for throwing your line, reeling in, etc? Most players won't
(we assume) have fishing gear, and having all those detailed commands (we assume) have fishing gear, and having all those detailed commands
@ -48,7 +48,7 @@ for a minor thing like fishing?
So instead you put all those detailed fishing commands into their own So instead you put all those detailed fishing commands into their own
CommandSet called 'Fishing'. Whenever the player gives the command CommandSet called 'Fishing'. Whenever the player gives the command
'fish' (presumably the code checks there is also water nearby), only 'fish' (presumably the code checks there is also water nearby), only
THEN this CommandSet is added to the Cmdhandler of the player. The THEN this CommandSet is added to the Cmdhandler of the account. The
'throw' command (which normally throws rocks) is replaced by the 'throw' command (which normally throws rocks) is replaced by the
custom 'fishing variant' of throw. What has happened is that the custom 'fishing variant' of throw. What has happened is that the
Fishing CommandSet was merged on top of the Default ones, and due to Fishing CommandSet was merged on top of the Default ones, and due to
@ -128,7 +128,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
Args: Args:
path (str): The path to the command set to load. path (str): The path to the command set to load.
cmdsetobj (CmdSet): The database object/typeclass on which this cmdset is to be cmdsetobj (CmdSet): The database object/typeclass on which this cmdset is to be
assigned (this can be also channels and exits, as well as players assigned (this can be also channels and exits, as well as accounts
but there will always be such an object) but there will always be such an object)
emit_to_obj (Object, optional): If given, error is emitted to emit_to_obj (Object, optional): If given, error is emitted to
this object (in addition to logging) this object (in addition to logging)

View file

@ -152,14 +152,14 @@ class Command(with_metaclass(CommandMeta, object)):
is_exit = False is_exit = False
# define the command not only by key but by the regex form of its arguments # define the command not only by key but by the regex form of its arguments
arg_regex = settings.COMMAND_DEFAULT_ARG_REGEX arg_regex = settings.COMMAND_DEFAULT_ARG_REGEX
# whether self.msg sends to all sessions of a related player/object (default # whether self.msg sends to all sessions of a related account/object (default
# is to only send to the session sending the command). # is to only send to the session sending the command).
msg_all_sessions = settings.COMMAND_DEFAULT_MSG_ALL_SESSIONS msg_all_sessions = settings.COMMAND_DEFAULT_MSG_ALL_SESSIONS
# auto-set (by Evennia on command instantiation) are: # auto-set (by Evennia on command instantiation) are:
# obj - which object this command is defined on # obj - which object this command is defined on
# session - which session is responsible for triggering this command. Only set # session - which session is responsible for triggering this command. Only set
# if triggered by a player. # if triggered by an account.
def __init__(self, **kwargs): def __init__(self, **kwargs):
""" """
@ -307,7 +307,7 @@ class Command(with_metaclass(CommandMeta, object)):
session=None, **kwargs): session=None, **kwargs):
""" """
This is a shortcut instead of calling msg() directly on an This is a shortcut instead of calling msg() directly on an
object - it will detect if caller is an Object or a Player and object - it will detect if caller is an Object or an Account and
also appends self.session automatically if self.msg_all_sessions is False. also appends self.session automatically if self.msg_all_sessions is False.
Args: Args:
@ -340,7 +340,7 @@ class Command(with_metaclass(CommandMeta, object)):
Args: Args:
raw_string (str): Execute this string as a command input. raw_string (str): Execute this string as a command input.
session (Session, optional): If not given, the current command's Session will be used. session (Session, optional): If not given, the current command's Session will be used.
obj (Object or Player, optional): Object or Player on which to call the execute_cmd. obj (Object or Account, optional): Object or Account on which to call the execute_cmd.
If not given, self.caller will be used. If not given, self.caller will be used.
Kwargs: Kwargs:
@ -443,7 +443,7 @@ class Command(with_metaclass(CommandMeta, object)):
commands the caller can use. commands the caller can use.
Args: Args:
caller (Object or Player): the caller asking for help on the command. caller (Object or Account): the caller asking for help on the command.
cmdset (CmdSet): the command set (if you need additional commands). cmdset (CmdSet): the command set (if you need additional commands).
Returns: Returns:

View file

@ -16,22 +16,22 @@ COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
# limit members for API inclusion # limit members for API inclusion
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer", __all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelAccount",
"CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall") "CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall")
class CmdBoot(COMMAND_DEFAULT_CLASS): class CmdBoot(COMMAND_DEFAULT_CLASS):
""" """
kick a player from the server. kick an account from the server.
Usage Usage
@boot[/switches] <player obj> [: reason] @boot[/switches] <account obj> [: reason]
Switches: Switches:
quiet - Silently boot without informing player quiet - Silently boot without informing account
sid - boot by session id instead of name or dbref sid - boot by session id instead of name or dbref
Boot a player object from the server. If a reason is Boot an account object from the server. If a reason is
supplied it will be echoed to the user unless /quiet is set. supplied it will be echoed to the user unless /quiet is set.
""" """
@ -45,7 +45,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
args = self.args args = self.args
if not args: if not args:
caller.msg("Usage: @boot[/switches] <player> [:reason]") caller.msg("Usage: @boot[/switches] <account> [:reason]")
return return
if ':' in args: if ':' in args:
@ -64,10 +64,10 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
boot_list.append(sess) boot_list.append(sess)
break break
else: else:
# Boot by player object # Boot by account object
pobj = search.player_search(args) pobj = search.account_search(args)
if not pobj: if not pobj:
caller.msg("Player %s was not found." % args) caller.msg("Account %s was not found." % args)
return return
pobj = pobj[0] pobj = pobj[0]
if not pobj.access(caller, 'boot'): if not pobj.access(caller, 'boot'):
@ -75,12 +75,12 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
caller.msg(string) caller.msg(string)
return return
# we have a bootable object with a connected user # we have a bootable object with a connected user
matches = SESSIONS.sessions_from_player(pobj) matches = SESSIONS.sessions_from_account(pobj)
for match in matches: for match in matches:
boot_list.append(match) boot_list.append(match)
if not boot_list: if not boot_list:
caller.msg("No matching sessions found. The Player does not seem to be online.") caller.msg("No matching sessions found. The Account does not seem to be online.")
return return
# Carry out the booting of the sessions in the boot list. # Carry out the booting of the sessions in the boot list.
@ -93,7 +93,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
for session in boot_list: for session in boot_list:
session.msg(feedback) session.msg(feedback)
session.player.disconnect_session_from_player(session) session.account.disconnect_session_from_account(session)
# regex matching IP addresses with wildcards, eg. 233.122.4.* # regex matching IP addresses with wildcards, eg. 233.122.4.*
@ -118,7 +118,7 @@ def list_bans(banlist):
class CmdBan(COMMAND_DEFAULT_CLASS): class CmdBan(COMMAND_DEFAULT_CLASS):
""" """
ban a player from the server ban an account from the server
Usage: Usage:
@ban [<name or ip> [: reason]] @ban [<name or ip> [: reason]]
@ -128,8 +128,8 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
This command bans a user from accessing the game. Supply an optional This command bans a user from accessing the game. Supply an optional
reason to be able to later remember why the ban was put in place. reason to be able to later remember why the ban was put in place.
It is often preferable to ban a player from the server than to It is often preferable to ban an account from the server than to
delete a player with @delplayer. If banned by name, that player delete an account with @delaccount. If banned by name, that account
account can no longer be logged into. account can no longer be logged into.
IP (Internet Protocol) address banning allows blocking all access IP (Internet Protocol) address banning allows blocking all access
@ -206,12 +206,12 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
class CmdUnban(COMMAND_DEFAULT_CLASS): class CmdUnban(COMMAND_DEFAULT_CLASS):
""" """
remove a ban from a player remove a ban from an account
Usage: Usage:
@unban <banid> @unban <banid>
This will clear a player name/ip ban previously set with the @ban This will clear an account name/ip ban previously set with the @ban
command. Use this command without an argument to view a numbered command. Use this command without an argument to view a numbered
list of bans. Use the numbers in this list to select which one to list of bans. Use the numbers in this list to select which one to
unban. unban.
@ -249,23 +249,23 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
(num, " ".join([s for s in ban[:2]]))) (num, " ".join([s for s in ban[:2]])))
class CmdDelPlayer(COMMAND_DEFAULT_CLASS): class CmdDelAccount(COMMAND_DEFAULT_CLASS):
""" """
delete a player from the server delete an account from the server
Usage: Usage:
@delplayer[/switch] <name> [: reason] @delaccount[/switch] <name> [: reason]
Switch: Switch:
delobj - also delete the player's currently delobj - also delete the account's currently
assigned in-game object. assigned in-game object.
Completely deletes a user from the server database, Completely deletes a user from the server database,
making their nick and e-mail again available. making their nick and e-mail again available.
""" """
key = "@delplayer" key = "@delaccount"
locks = "cmd:perm(delplayer) or perm(Developer)" locks = "cmd:perm(delaccount) or perm(Developer)"
help_category = "Admin" help_category = "Admin"
def func(self): def func(self):
@ -274,49 +274,49 @@ class CmdDelPlayer(COMMAND_DEFAULT_CLASS):
caller = self.caller caller = self.caller
args = self.args args = self.args
if hasattr(caller, 'player'): if hasattr(caller, 'account'):
caller = caller.player caller = caller.account
if not args: if not args:
self.msg("Usage: @delplayer <player/user name or #id> [: reason]") self.msg("Usage: @delaccount <account/user name or #id> [: reason]")
return return
reason = "" reason = ""
if ':' in args: if ':' in args:
args, reason = [arg.strip() for arg in args.split(':', 1)] args, reason = [arg.strip() for arg in args.split(':', 1)]
# We use player_search since we want to be sure to find also players # We use account_search since we want to be sure to find also accounts
# that lack characters. # that lack characters.
players = search.player_search(args) accounts = search.account_search(args)
if not players: if not accounts:
self.msg('Could not find a player by that name.') self.msg('Could not find an account by that name.')
return return
if len(players) > 1: if len(accounts) > 1:
string = "There were multiple matches:\n" string = "There were multiple matches:\n"
string += "\n".join(" %s %s" % (player.id, player.key) for player in players) string += "\n".join(" %s %s" % (account.id, account.key) for account in accounts)
self.msg(string) self.msg(string)
return return
# one single match # one single match
player = players.pop() account = accounts.pop()
if not player.access(caller, 'delete'): if not account.access(caller, 'delete'):
string = "You don't have the permissions to delete that player." string = "You don't have the permissions to delete that account."
self.msg(string) self.msg(string)
return return
uname = player.username uname = account.username
# boot the player then delete # boot the account then delete
self.msg("Informing and disconnecting player ...") self.msg("Informing and disconnecting account ...")
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
if reason: if reason:
string += " Reason given:\n '%s'" % reason string += " Reason given:\n '%s'" % reason
player.msg(string) account.msg(string)
player.delete() account.delete()
self.msg("Player %s was successfully deleted." % uname) self.msg("Account %s was successfully deleted." % uname)
class CmdEmit(COMMAND_DEFAULT_CLASS): class CmdEmit(COMMAND_DEFAULT_CLASS):
@ -330,14 +330,14 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
Switches: Switches:
room : limit emits to rooms only (default) room : limit emits to rooms only (default)
players : limit emits to players only accounts : limit emits to accounts only
contents : send to the contents of matched objects too contents : send to the contents of matched objects too
Emits a message to the selected objects or to Emits a message to the selected objects or to
your immediate surroundings. If the object is a room, your immediate surroundings. If the object is a room,
send to its contents. @remit and @pemit are just send to its contents. @remit and @pemit are just
limited forms of @emit, for sending to rooms and limited forms of @emit, for sending to rooms and
to players respectively. to accounts respectively.
""" """
key = "@emit" key = "@emit"
aliases = ["@pemit", "@remit"] aliases = ["@pemit", "@remit"]
@ -359,7 +359,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
return return
rooms_only = 'rooms' in self.switches rooms_only = 'rooms' in self.switches
players_only = 'players' in self.switches accounts_only = 'accounts' in self.switches
send_to_contents = 'contents' in self.switches send_to_contents = 'contents' in self.switches
# we check which command was used to force the switches # we check which command was used to force the switches
@ -367,7 +367,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
rooms_only = True rooms_only = True
send_to_contents = True send_to_contents = True
elif self.cmdstring == '@pemit': elif self.cmdstring == '@pemit':
players_only = True accounts_only = True
if not self.rhs: if not self.rhs:
message = self.args message = self.args
@ -384,8 +384,8 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
if rooms_only and obj.location is not None: if rooms_only and obj.location is not None:
caller.msg("%s is not a room. Ignored." % objname) caller.msg("%s is not a room. Ignored." % objname)
continue continue
if players_only and not obj.has_player: if accounts_only and not obj.has_account:
caller.msg("%s has no active player. Ignored." % objname) caller.msg("%s has no active account. Ignored." % objname)
continue continue
if obj.access(caller, 'tell'): if obj.access(caller, 'tell'):
obj.msg(message) obj.msg(message)
@ -400,12 +400,12 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
class CmdNewPassword(COMMAND_DEFAULT_CLASS): class CmdNewPassword(COMMAND_DEFAULT_CLASS):
""" """
change the password of a player change the password of an account
Usage: Usage:
@userpassword <user obj> = <new password> @userpassword <user obj> = <new password>
Set a player's password. Set an account's password.
""" """
key = "@userpassword" key = "@userpassword"
@ -421,32 +421,32 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
self.msg("Usage: @userpassword <user obj> = <new password>") self.msg("Usage: @userpassword <user obj> = <new password>")
return return
# the player search also matches 'me' etc. # the account search also matches 'me' etc.
player = caller.search_player(self.lhs) account = caller.search_account(self.lhs)
if not player: if not account:
return return
player.set_password(self.rhs) account.set_password(self.rhs)
player.save() account.save()
self.msg("%s - new password set to '%s'." % (player.name, self.rhs)) self.msg("%s - new password set to '%s'." % (account.name, self.rhs))
if player.character != caller: if account.character != caller:
player.msg("%s has changed your password to '%s'." % (caller.name, account.msg("%s has changed your password to '%s'." % (caller.name,
self.rhs)) self.rhs))
class CmdPerm(COMMAND_DEFAULT_CLASS): class CmdPerm(COMMAND_DEFAULT_CLASS):
""" """
set the permissions of a player/object set the permissions of an account/object
Usage: Usage:
@perm[/switch] <object> [= <permission>[,<permission>,...]] @perm[/switch] <object> [= <permission>[,<permission>,...]]
@perm[/switch] *<player> [= <permission>[,<permission>,...]] @perm[/switch] *<account> [= <permission>[,<permission>,...]]
Switches: Switches:
del : delete the given permission from <object> or <player>. del : delete the given permission from <object> or <account>.
player : set permission on a player (same as adding * to name) account : set permission on an account (same as adding * to name)
This command sets/clears individual permission strings on an object This command sets/clears individual permission strings on an object
or player. If no permission is given, list all permissions on <object>. or account. If no permission is given, list all permissions on <object>.
""" """
key = "@perm" key = "@perm"
aliases = "@setperm" aliases = "@setperm"
@ -465,11 +465,11 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
caller.msg(string) caller.msg(string)
return return
playermode = 'player' in self.switches or lhs.startswith('*') accountmode = 'account' in self.switches or lhs.startswith('*')
lhs = lhs.lstrip("*") lhs = lhs.lstrip("*")
if playermode: if accountmode:
obj = caller.search_player(lhs) obj = caller.search_account(lhs)
else: else:
obj = caller.search(lhs, global_search=True) obj = caller.search(lhs, global_search=True)
if not obj: if not obj:
@ -485,19 +485,19 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
string += "<None>" string += "<None>"
else: else:
string += ", ".join(obj.permissions.all()) string += ", ".join(obj.permissions.all())
if (hasattr(obj, 'player') and if (hasattr(obj, 'account') and
hasattr(obj.player, 'is_superuser') and hasattr(obj.account, 'is_superuser') and
obj.player.is_superuser): obj.account.is_superuser):
string += "\n(... but this object is currently controlled by a SUPERUSER! " string += "\n(... but this object is currently controlled by a SUPERUSER! "
string += "All access checks are passed automatically.)" string += "All access checks are passed automatically.)"
caller.msg(string) caller.msg(string)
return return
# we supplied an argument on the form obj = perm # we supplied an argument on the form obj = perm
locktype = "edit" if playermode else "control" locktype = "edit" if accountmode else "control"
if not obj.access(caller, locktype): if not obj.access(caller, locktype):
caller.msg("You are not allowed to edit this %s's permissions." caller.msg("You are not allowed to edit this %s's permissions."
% ("player" if playermode else "object")) % ("account" if accountmode else "object"))
return return
caller_result = [] caller_result = []
@ -528,7 +528,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
caller_result.append("\nPermission '%s' is already defined on %s." % (rhs, obj.name)) caller_result.append("\nPermission '%s' is already defined on %s." % (rhs, obj.name))
else: else:
obj.permissions.add(perm) obj.permissions.add(perm)
plystring = "the Player" if playermode else "the Object/Character" plystring = "the Account" if accountmode else "the Object/Character"
caller_result.append("\nPermission '%s' given to %s (%s)." % (rhs, obj.name, plystring)) caller_result.append("\nPermission '%s' given to %s (%s)." % (rhs, obj.name, plystring))
target_result.append("\n%s gives you (%s, %s) the permission '%s'." target_result.append("\n%s gives you (%s, %s) the permission '%s'."
% (caller.name, obj.name, plystring, rhs)) % (caller.name, obj.name, plystring, rhs))
@ -544,7 +544,7 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
Usage: Usage:
@wall <message> @wall <message>
Announces a message to all connected players. Announces a message to all connected accounts.
""" """
key = "@wall" key = "@wall"
locks = "cmd:perm(wall) or perm(Admin)" locks = "cmd:perm(wall) or perm(Admin)"
@ -556,5 +556,5 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
self.caller.msg("Usage: @wall <message>") self.caller.msg("Usage: @wall <message>")
return return
message = "%s shouts \"%s\"" % (self.caller.name, self.args) message = "%s shouts \"%s\"" % (self.caller.name, self.args)
self.msg("Announcing to all connected players ...") self.msg("Announcing to all connected accounts ...")
SESSIONS.announce_all(message) SESSIONS.announce_all(message)

View file

@ -607,7 +607,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
switches: switches:
override - The @destroy command will usually avoid accidentally override - The @destroy command will usually avoid accidentally
destroying player objects. This switch overrides this safety. destroying account objects. This switch overrides this safety.
examples: examples:
@destroy house, roof, door, 44-78 @destroy house, roof, door, 44-78
@destroy 5-10, flower, 45 @destroy 5-10, flower, 45
@ -640,8 +640,8 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
objname = obj.name objname = obj.name
if not (obj.access(caller, "control") or obj.access(caller, 'delete')): if not (obj.access(caller, "control") or obj.access(caller, 'delete')):
return "\nYou don't have permission to delete %s." % objname return "\nYou don't have permission to delete %s." % objname
if obj.player and not 'override' in self.switches: if obj.account and not 'override' in self.switches:
return "\nObject %s is controlled by an active player. Use /override to delete anyway." % objname return "\nObject %s is controlled by an active account. Use /override to delete anyway." % objname
if obj.dbid == int(settings.DEFAULT_HOME.lstrip("#")): if obj.dbid == int(settings.DEFAULT_HOME.lstrip("#")):
return "\nYou are trying to delete |c%s|n, which is set as DEFAULT_HOME. " \ return "\nYou are trying to delete |c%s|n, which is set as DEFAULT_HOME. " \
"Re-point settings.DEFAULT_HOME to another " \ "Re-point settings.DEFAULT_HOME to another " \
@ -1108,7 +1108,7 @@ class CmdName(ObjManipCommand):
@name obj = name;alias1;alias2 @name obj = name;alias1;alias2
Rename an object to something new. Use *obj to Rename an object to something new. Use *obj to
rename a player. rename an account.
""" """
@ -1129,22 +1129,22 @@ class CmdName(ObjManipCommand):
if self.lhs_objs: if self.lhs_objs:
objname = self.lhs_objs[0]['name'] objname = self.lhs_objs[0]['name']
if objname.startswith("*"): if objname.startswith("*"):
# player mode # account mode
obj = caller.player.search(objname.lstrip("*")) obj = caller.account.search(objname.lstrip("*"))
if obj: if obj:
if self.rhs_objs[0]['aliases']: if self.rhs_objs[0]['aliases']:
caller.msg("Players can't have aliases.") caller.msg("Accounts can't have aliases.")
return return
newname = self.rhs newname = self.rhs
if not newname: if not newname:
caller.msg("No name defined!") caller.msg("No name defined!")
return return
if not (obj.access(caller, "control") or obj.access(caller, "edit")): if not (obj.access(caller, "control") or obj.access(caller, "edit")):
caller.msg("You don't have right to edit this player %s." % obj) caller.msg("You don't have right to edit this account %s." % obj)
return return
obj.username = newname obj.username = newname
obj.save() obj.save()
caller.msg("Player's name changed to '%s'." % newname) caller.msg("Account's name changed to '%s'." % newname)
return return
# object search, also with * # object search, also with *
obj = caller.search(objname) obj = caller.search(objname)
@ -1326,7 +1326,7 @@ def _convert_from_string(cmd, strobj):
be converted to a string and a warning will be given. be converted to a string and a warning will be given.
We need to convert like this since all data being sent over the We need to convert like this since all data being sent over the
telnet connection by the Player is text - but we will want to telnet connection by the Account is text - but we will want to
store it as the "real" python type so we can do convenient store it as the "real" python type so we can do convenient
comparisons later (e.g. obj.db.value = 2, if value is stored as a comparisons later (e.g. obj.db.value = 2, if value is stored as a
string this will always fail). string this will always fail).
@ -1381,13 +1381,13 @@ def _convert_from_string(cmd, strobj):
class CmdSetAttribute(ObjManipCommand): class CmdSetAttribute(ObjManipCommand):
""" """
set attribute on an object or player set attribute on an object or account
Usage: Usage:
@set <obj>/<attr> = <value> @set <obj>/<attr> = <value>
@set <obj>/<attr> = @set <obj>/<attr> =
@set <obj>/<attr> @set <obj>/<attr>
@set *<player>/attr = <value> @set *<account>/attr = <value>
Switch: Switch:
edit: Open the line editor (string values only) edit: Open the line editor (string values only)
@ -1419,7 +1419,7 @@ class CmdSetAttribute(ObjManipCommand):
""" """
This may be overridden by subclasses in case restrictions need to be This may be overridden by subclasses in case restrictions need to be
placed on whether certain objects can have attributes set by certain placed on whether certain objects can have attributes set by certain
players. accounts.
This function is expected to display its own error message. This function is expected to display its own error message.
@ -1505,7 +1505,7 @@ class CmdSetAttribute(ObjManipCommand):
attrs = self.lhs_objattr[0]['attrs'] attrs = self.lhs_objattr[0]['attrs']
if objname.startswith('*'): if objname.startswith('*'):
obj = caller.search_player(objname.lstrip('*')) obj = caller.search_account(objname.lstrip('*'))
else: else:
obj = caller.search(objname) obj = caller.search(objname)
if not obj: if not obj:
@ -1831,17 +1831,17 @@ class CmdExamine(ObjManipCommand):
Usage: Usage:
examine [<object>[/attrname]] examine [<object>[/attrname]]
examine [*<player>[/attrname]] examine [*<account>[/attrname]]
Switch: Switch:
player - examine a Player (same as adding *) account - examine an Account (same as adding *)
object - examine an Object (useful when OOC) object - examine an Object (useful when OOC)
The examine command shows detailed game info about an The examine command shows detailed game info about an
object and optionally a specific attribute on it. object and optionally a specific attribute on it.
If object is not specified, the current location is examined. If object is not specified, the current location is examined.
Append a * before the search string to examine a player. Append a * before the search string to examine an account.
""" """
key = "@examine" key = "@examine"
@ -1850,7 +1850,7 @@ class CmdExamine(ObjManipCommand):
help_category = "Building" help_category = "Building"
arg_regex = r"(/\w+?(\s|$))|\s|$" arg_regex = r"(/\w+?(\s|$))|\s|$"
player_mode = False account_mode = False
def list_attribute(self, crop, attr, value): def list_attribute(self, crop, attr, value):
""" """
@ -1910,15 +1910,15 @@ class CmdExamine(ObjManipCommand):
for sess in obj.sessions.all())) for sess in obj.sessions.all()))
if hasattr(obj, "email") and obj.email: if hasattr(obj, "email") and obj.email:
string += "\n|wEmail|n: |c%s|n" % obj.email string += "\n|wEmail|n: |c%s|n" % obj.email
if hasattr(obj, "has_player") and obj.has_player: if hasattr(obj, "has_account") and obj.has_account:
string += "\n|wPlayer|n: |c%s|n" % obj.player.name string += "\n|wAccount|n: |c%s|n" % obj.account.name
perms = obj.player.permissions.all() perms = obj.account.permissions.all()
if obj.player.is_superuser: if obj.account.is_superuser:
perms = ["<Superuser>"] perms = ["<Superuser>"]
elif not perms: elif not perms:
perms = ["<None>"] perms = ["<None>"]
string += "\n|wPlayer Perms|n: %s" % (", ".join(perms)) string += "\n|wAccount Perms|n: %s" % (", ".join(perms))
if obj.player.attributes.has("_quell"): if obj.account.attributes.has("_quell"):
string += " |r(quelled)|n" string += " |r(quelled)|n"
string += "\n|wTypeclass|n: %s (%s)" % (obj.typename, string += "\n|wTypeclass|n: %s (%s)" % (obj.typename,
obj.typeclass_path) obj.typeclass_path)
@ -1961,16 +1961,16 @@ class CmdExamine(ObjManipCommand):
# this gets all components of the currently merged set # this gets all components of the currently merged set
all_cmdsets = [(cmdset.key, cmdset) for cmdset in avail_cmdset.merged_from] all_cmdsets = [(cmdset.key, cmdset) for cmdset in avail_cmdset.merged_from]
# we always at least try to add player- and session sets since these are ignored # we always at least try to add account- and session sets since these are ignored
# if we merge on the object level. # if we merge on the object level.
if hasattr(obj, "player") and obj.player: if hasattr(obj, "account") and obj.account:
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.player.cmdset.all()]) all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()])
if obj.sessions.count(): if obj.sessions.count():
# if there are more sessions than one on objects it's because of multisession mode 3. # if there are more sessions than one on objects it's because of multisession mode 3.
# we only show the first session's cmdset here (it is -in principle- possible that # we only show the first session's cmdset here (it is -in principle- possible that
# different sessions have different cmdsets but for admins who want such madness # different sessions have different cmdsets but for admins who want such madness
# it is better that they overload with their own CmdExamine to handle it). # it is better that they overload with their own CmdExamine to handle it).
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.player.sessions.all()[0].cmdset.all()]) all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.sessions.all()[0].cmdset.all()])
else: else:
try: try:
# we have to protect this since many objects don't have sessions. # we have to protect this since many objects don't have sessions.
@ -2011,7 +2011,7 @@ class CmdExamine(ObjManipCommand):
for content in obj.contents: for content in obj.contents:
if content.destination: if content.destination:
exits.append(content) exits.append(content)
elif content.player: elif content.account:
pobjs.append(content) pobjs.append(content)
else: else:
things.append(content) things.append(content)
@ -2051,7 +2051,7 @@ class CmdExamine(ObjManipCommand):
self.msg(caller.at_look(obj)) self.msg(caller.at_look(obj))
return return
# using callback for printing result whenever function returns. # using callback for printing result whenever function returns.
get_and_merge_cmdsets(obj, self.session, self.player, obj, "object", self.raw_string).addCallback(get_cmdset_callback) get_and_merge_cmdsets(obj, self.session, self.account, obj, "object", self.raw_string).addCallback(get_cmdset_callback)
else: else:
self.msg("You need to supply a target to examine.") self.msg("You need to supply a target to examine.")
return return
@ -2063,13 +2063,13 @@ class CmdExamine(ObjManipCommand):
obj_name = objdef['name'] obj_name = objdef['name']
obj_attrs = objdef['attrs'] obj_attrs = objdef['attrs']
self.player_mode = utils.inherits_from(caller, "evennia.players.players.DefaultPlayer") or \ self.account_mode = utils.inherits_from(caller, "evennia.accounts.accounts.DefaultAccount") or \
"player" in self.switches or obj_name.startswith('*') "account" in self.switches or obj_name.startswith('*')
if self.player_mode: if self.account_mode:
try: try:
obj = caller.search_player(obj_name.lstrip('*')) obj = caller.search_account(obj_name.lstrip('*'))
except AttributeError: except AttributeError:
# this means we are calling examine from a player object # this means we are calling examine from an account object
obj = caller.search(obj_name.lstrip('*'), search_object = 'object' in self.switches) obj = caller.search(obj_name.lstrip('*'), search_object = 'object' in self.switches)
else: else:
obj = caller.search(obj_name) obj = caller.search(obj_name)
@ -2089,12 +2089,12 @@ class CmdExamine(ObjManipCommand):
else: else:
if obj.sessions.count(): if obj.sessions.count():
mergemode = "session" mergemode = "session"
elif self.player_mode: elif self.account_mode:
mergemode = "player" mergemode = "account"
else: else:
mergemode = "object" mergemode = "object"
# using callback to print results whenever function returns. # using callback to print results whenever function returns.
get_and_merge_cmdsets(obj, self.session, self.player, obj, mergemode, self.raw_string).addCallback(get_cmdset_callback) get_and_merge_cmdsets(obj, self.session, self.account, obj, mergemode, self.raw_string).addCallback(get_cmdset_callback)
class CmdFind(COMMAND_DEFAULT_CLASS): class CmdFind(COMMAND_DEFAULT_CLASS):
@ -2102,7 +2102,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
search the database for objects search the database for objects
Usage: Usage:
@find[/switches] <name or dbref or *player> [= dbrefmin[-dbrefmax]] @find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]
Switches: Switches:
room - only look for rooms (location=None) room - only look for rooms (location=None)
@ -2111,7 +2111,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
exact- only exact matches are returned. exact- only exact matches are returned.
Searches the database for an object of a particular name or exact #dbref. Searches the database for an object of a particular name or exact #dbref.
Use *playername to search for a player. The switches allows for Use *accountname to search for an account. The switches allows for
limiting object matches to certain game entities. Dbrefmin and dbrefmax limiting object matches to certain game entities. Dbrefmin and dbrefmax
limits matches to within the given dbrefs range, or above/below if only limits matches to within the given dbrefs range, or above/below if only
one is given. one is given.
@ -2148,22 +2148,22 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
high = max(low, high) high = max(low, high)
is_dbref = utils.dbref(searchstring) is_dbref = utils.dbref(searchstring)
is_player = searchstring.startswith("*") is_account = searchstring.startswith("*")
restrictions = "" restrictions = ""
if self.switches: if self.switches:
restrictions = ", %s" % (",".join(self.switches)) restrictions = ", %s" % (",".join(self.switches))
if is_dbref or is_player: if is_dbref or is_account:
if is_dbref: if is_dbref:
# a dbref search # a dbref search
result = caller.search(searchstring, global_search=True, quiet=True) result = caller.search(searchstring, global_search=True, quiet=True)
string = "|wExact dbref match|n(#%i-#%i%s):" % (low, high, restrictions) string = "|wExact dbref match|n(#%i-#%i%s):" % (low, high, restrictions)
else: else:
# a player search # an account search
searchstring = searchstring.lstrip("*") searchstring = searchstring.lstrip("*")
result = caller.search_player(searchstring, quiet=True) result = caller.search_account(searchstring, quiet=True)
string = "|wMatch|n(#%i-#%i%s):" % (low, high, restrictions) string = "|wMatch|n(#%i-#%i%s):" % (low, high, restrictions)
if "room" in switches: if "room" in switches:
@ -2181,7 +2181,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
result=result[0] result=result[0]
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path) string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
else: else:
# Not a player/dbref search but a wider search; build a queryset. # Not an account/dbref search but a wider search; build a queryset.
# Searchs for key and aliases # Searchs for key and aliases
if "exact" in switches: if "exact" in switches:
keyquery = Q(db_key__iexact=searchstring, id__gte=low, id__lte=high) keyquery = Q(db_key__iexact=searchstring, id__gte=low, id__lte=high)
@ -2274,10 +2274,10 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
if not obj_to_teleport: if not obj_to_teleport:
caller.msg("Did not find object to teleport.") caller.msg("Did not find object to teleport.")
return return
if obj_to_teleport.has_player: if obj_to_teleport.has_account:
caller.msg("Cannot teleport a puppeted object " caller.msg("Cannot teleport a puppeted object "
"(%s, puppeted by %s) to a None-location." % ( "(%s, puppeted by %s) to a None-location." % (
obj_to_teleport.key, obj_to_teleport.player)) obj_to_teleport.key, obj_to_teleport.account))
return return
caller.msg("Teleported %s -> None-location." % obj_to_teleport) caller.msg("Teleported %s -> None-location." % obj_to_teleport)
if obj_to_teleport.location and not tel_quietly: if obj_to_teleport.location and not tel_quietly:

View file

@ -1,8 +1,8 @@
""" """
This module ties together all the commands default Character objects have This module ties together all the commands default Character objects have
available (i.e. IC commands). Note that some commands, such as available (i.e. IC commands). Note that some commands, such as
communication-commands are instead put on the player level, in the communication-commands are instead put on the account level, in the
Player cmdset. Player commands remain available also to Characters. Account cmdset. Account commands remain available also to Characters.
""" """
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.commands.default import general, help, admin, system from evennia.commands.default import general, help, admin, system
@ -41,7 +41,7 @@ class CharacterCmdSet(CmdSet):
self.add(system.CmdPy()) self.add(system.CmdPy())
self.add(system.CmdScripts()) self.add(system.CmdScripts())
self.add(system.CmdObjects()) self.add(system.CmdObjects())
self.add(system.CmdPlayers()) self.add(system.CmdAccounts())
self.add(system.CmdService()) self.add(system.CmdService())
self.add(system.CmdAbout()) self.add(system.CmdAbout())
self.add(system.CmdTime()) self.add(system.CmdTime())

View file

@ -1,73 +0,0 @@
"""
This is the cmdset for Player (OOC) commands. These are
stored on the Player object and should thus be able to handle getting
a Player object as caller rather than a Character.
Note - in order for session-rerouting (in MULTISESSION_MODE=2) to
function, all commands in this cmdset should use the self.msg()
command method rather than caller.msg().
"""
from evennia.commands.cmdset import CmdSet
from evennia.commands.default import help, comms, admin, system
from evennia.commands.default import building, player
class PlayerCmdSet(CmdSet):
"""
Implements the player command set.
"""
key = "DefaultPlayer"
priority = -10
def at_cmdset_creation(self):
"Populates the cmdset"
# Player-specific commands
self.add(player.CmdOOCLook())
self.add(player.CmdIC())
self.add(player.CmdOOC())
self.add(player.CmdCharCreate())
self.add(player.CmdCharDelete())
#self.add(player.CmdSessions())
self.add(player.CmdWho())
self.add(player.CmdOption())
self.add(player.CmdQuit())
self.add(player.CmdPassword())
self.add(player.CmdColorTest())
self.add(player.CmdQuell())
# testing
self.add(building.CmdExamine())
# Help command
self.add(help.CmdHelp())
# system commands
self.add(system.CmdReload())
self.add(system.CmdReset())
self.add(system.CmdShutdown())
self.add(system.CmdPy())
# Admin commands
self.add(admin.CmdDelPlayer())
self.add(admin.CmdNewPassword())
# Comm commands
self.add(comms.CmdAddCom())
self.add(comms.CmdDelCom())
self.add(comms.CmdAllCom())
self.add(comms.CmdChannels())
self.add(comms.CmdCdestroy())
self.add(comms.CmdChannelCreate())
self.add(comms.CmdClock())
self.add(comms.CmdCBoot())
self.add(comms.CmdCemit())
self.add(comms.CmdCWho())
self.add(comms.CmdCdesc())
self.add(comms.CmdPage())
self.add(comms.CmdIRC2Chan())
self.add(comms.CmdIRCStatus())
self.add(comms.CmdRSS2Chan())

View file

@ -2,7 +2,7 @@
This module stores session-level commands. This module stores session-level commands.
""" """
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
from evennia.commands.default import player from evennia.commands.default import account
class SessionCmdSet(CmdSet): class SessionCmdSet(CmdSet):
""" """
@ -13,4 +13,4 @@ class SessionCmdSet(CmdSet):
def at_cmdset_creation(self): def at_cmdset_creation(self):
"Populate the cmdset" "Populate the cmdset"
self.add(player.CmdSessions()) self.add(account.CmdSessions())

View file

@ -2,16 +2,16 @@
Comsystem command module. Comsystem command module.
Comm commands are OOC commands and intended to be made available to Comm commands are OOC commands and intended to be made available to
the Player at all times (they go into the PlayerCmdSet). So we the Account at all times (they go into the AccountCmdSet). So we
make sure to homogenize self.caller to always be the player object make sure to homogenize self.caller to always be the account object
for easy handling. for easy handling.
""" """
from past.builtins import cmp from past.builtins import cmp
from django.conf import settings from django.conf import settings
from evennia.comms.models import ChannelDB, Msg from evennia.comms.models import ChannelDB, Msg
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.players import bots from evennia.accounts import bots
from evennia.comms.channelhandler import CHANNELHANDLER from evennia.comms.channelhandler import CHANNELHANDLER
from evennia.locks.lockhandler import LockException from evennia.locks.lockhandler import LockException
from evennia.utils import create, utils, evtable from evennia.utils import create, utils, evtable
@ -69,14 +69,14 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
locks = "cmd:not pperm(channel_banned)" locks = "cmd:not pperm(channel_banned)"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implement the command""" """Implement the command"""
caller = self.caller caller = self.caller
args = self.args args = self.args
player = caller account = caller
if not args: if not args:
self.msg("Usage: addcom [alias =] channelname.") self.msg("Usage: addcom [alias =] channelname.")
@ -96,21 +96,21 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
return return
# check permissions # check permissions
if not channel.access(player, 'listen'): if not channel.access(account, 'listen'):
self.msg("%s: You are not allowed to listen to this channel." % channel.key) self.msg("%s: You are not allowed to listen to this channel." % channel.key)
return return
string = "" string = ""
if not channel.has_connection(player): if not channel.has_connection(account):
# we want to connect as well. # we want to connect as well.
if not channel.connect(player): if not channel.connect(account):
# if this would have returned True, the player is connected # if this would have returned True, the account is connected
self.msg("%s: You are not allowed to join this channel." % channel.key) self.msg("%s: You are not allowed to join this channel." % channel.key)
return return
else: else:
string += "You now listen to the channel %s. " % channel.key string += "You now listen to the channel %s. " % channel.key
else: else:
if channel.unmute(player): if channel.unmute(account):
string += "You unmute channel %s." % channel.key string += "You unmute channel %s." % channel.key
else: else:
string += "You are already connected to channel %s." % channel.key string += "You are already connected to channel %s." % channel.key
@ -145,13 +145,13 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
locks = "cmd:not perm(channel_banned)" locks = "cmd:not perm(channel_banned)"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implementing the command. """ """Implementing the command. """
caller = self.caller caller = self.caller
player = caller account = caller
if not self.args: if not self.args:
self.msg("Usage: delcom <alias or channel>") self.msg("Usage: delcom <alias or channel>")
@ -161,7 +161,7 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
channel = find_channel(caller, ostring, silent=True, noaliases=True) channel = find_channel(caller, ostring, silent=True, noaliases=True)
if channel: if channel:
# we have given a channel name - unsubscribe # we have given a channel name - unsubscribe
if not channel.has_connection(player): if not channel.has_connection(account):
self.msg("You are not listening to that channel.") self.msg("You are not listening to that channel.")
return return
chkey = channel.key.lower() chkey = channel.key.lower()
@ -171,7 +171,7 @@ class CmdDelCom(COMMAND_DEFAULT_CLASS):
for nick in [nick for nick in make_iter(caller.nicks.get(category="channel", return_obj=True)) for nick in [nick for nick in make_iter(caller.nicks.get(category="channel", return_obj=True))
if nick and nick.pk and nick.value[3].lower() == chkey]: if nick and nick.pk and nick.value[3].lower() == chkey]:
nick.delete() nick.delete()
disconnect = channel.disconnect(player) disconnect = channel.disconnect(account)
if disconnect: if disconnect:
wipednicks = " Eventual aliases were removed." if delnicks else "" wipednicks = " Eventual aliases were removed." if delnicks else ""
self.msg("You stop listening to channel '%s'.%s" % (channel.key, wipednicks)) self.msg("You stop listening to channel '%s'.%s" % (channel.key, wipednicks))
@ -209,7 +209,7 @@ class CmdAllCom(COMMAND_DEFAULT_CLASS):
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Runs the function""" """Runs the function"""
@ -273,7 +273,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
locks = "cmd: not pperm(channel_banned)" locks = "cmd: not pperm(channel_banned)"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implement function""" """Implement function"""
@ -345,7 +345,7 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
locks = "cmd: not pperm(channel_banned)" locks = "cmd: not pperm(channel_banned)"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Destroy objects cleanly.""" """Destroy objects cleanly."""
@ -372,15 +372,15 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
class CmdCBoot(COMMAND_DEFAULT_CLASS): class CmdCBoot(COMMAND_DEFAULT_CLASS):
""" """
kick a player from a channel you control kick an account from a channel you control
Usage: Usage:
@cboot[/quiet] <channel> = <player> [:reason] @cboot[/quiet] <channel> = <account> [:reason]
Switches: Switches:
quiet - don't notify the channel quiet - don't notify the channel
Kicks a player or object from a channel you control. Kicks an account or object from a channel you control.
""" """
@ -389,13 +389,13 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""implement the function""" """implement the function"""
if not self.args or not self.rhs: if not self.args or not self.rhs:
string = "Usage: @cboot[/quiet] <channel> = <player> [:reason]" string = "Usage: @cboot[/quiet] <channel> = <account> [:reason]"
self.msg(string) self.msg(string)
return return
@ -404,12 +404,12 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
return return
reason = "" reason = ""
if ":" in self.rhs: if ":" in self.rhs:
playername, reason = self.rhs.rsplit(":", 1) accountname, reason = self.rhs.rsplit(":", 1)
searchstring = playername.lstrip('*') searchstring = accountname.lstrip('*')
else: else:
searchstring = self.rhs.lstrip('*') searchstring = self.rhs.lstrip('*')
player = self.caller.search(searchstring, player=True) account = self.caller.search(searchstring, account=True)
if not player: if not account:
return return
if reason: if reason:
reason = " (reason: %s)" % reason reason = " (reason: %s)" % reason
@ -417,20 +417,20 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
string = "You don't control this channel." string = "You don't control this channel."
self.msg(string) self.msg(string)
return return
if player not in channel.db_subscriptions.all(): if account not in channel.db_subscriptions.all():
string = "Player %s is not connected to channel %s." % (player.key, channel.key) string = "Account %s is not connected to channel %s." % (account.key, channel.key)
self.msg(string) self.msg(string)
return return
if "quiet" not in self.switches: if "quiet" not in self.switches:
string = "%s boots %s from channel.%s" % (self.caller, player.key, reason) string = "%s boots %s from channel.%s" % (self.caller, account.key, reason)
channel.msg(string) channel.msg(string)
# find all player's nicks linked to this channel and delete them # find all account's nicks linked to this channel and delete them
for nick in [nick for nick in for nick in [nick for nick in
player.character.nicks.get(category="channel") or [] account.character.nicks.get(category="channel") or []
if nick.value[3].lower() == channel.key]: if nick.value[3].lower() == channel.key]:
nick.delete() nick.delete()
# disconnect player # disconnect account
channel.disconnect(player) channel.disconnect(account)
CHANNELHANDLER.update() CHANNELHANDLER.update()
@ -453,11 +453,11 @@ class CmdCemit(COMMAND_DEFAULT_CLASS):
key = "@cemit" key = "@cemit"
aliases = ["@cmsg"] aliases = ["@cmsg"]
locks = "cmd: not pperm(channel_banned) and pperm(Player)" locks = "cmd: not pperm(channel_banned) and pperm(Account)"
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implement function""" """Implement function"""
@ -496,7 +496,7 @@ class CmdCWho(COMMAND_DEFAULT_CLASS):
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""implement function""" """implement function"""
@ -530,11 +530,11 @@ class CmdChannelCreate(COMMAND_DEFAULT_CLASS):
key = "@ccreate" key = "@ccreate"
aliases = "channelcreate" aliases = "channelcreate"
locks = "cmd:not pperm(channel_banned) and pperm(Player)" locks = "cmd:not pperm(channel_banned) and pperm(Account)"
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implement the command""" """Implement the command"""
@ -587,7 +587,7 @@ class CmdClock(COMMAND_DEFAULT_CLASS):
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""run the function""" """run the function"""
@ -639,7 +639,7 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implement command""" """Implement command"""
@ -666,10 +666,10 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
class CmdPage(COMMAND_DEFAULT_CLASS): class CmdPage(COMMAND_DEFAULT_CLASS):
""" """
send a private message to another player send a private message to another account
Usage: Usage:
page[/switches] [<player>,<player>,... = <message>] page[/switches] [<account>,<account>,... = <message>]
tell '' tell ''
page <number> page <number>
@ -687,12 +687,12 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
help_category = "Comms" help_category = "Comms"
# this is used by the COMMAND_DEFAULT_CLASS parent # this is used by the COMMAND_DEFAULT_CLASS parent
player_caller = True account_caller = True
def func(self): def func(self):
"""Implement function using the Msg methods""" """Implement function using the Msg methods"""
# Since player_caller is set above, this will be a Player. # Since account_caller is set above, this will be an Account.
caller = self.caller caller = self.caller
# get the messages we've sent (not to channels) # get the messages we've sent (not to channels)
@ -718,7 +718,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
try: try:
number = int(self.args) number = int(self.args)
except ValueError: except ValueError:
self.msg("Usage: tell [<player> = msg]") self.msg("Usage: tell [<account> = msg]")
return return
if len(pages) > number: if len(pages) > number:
@ -767,7 +767,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
self.msg("Noone found to page.") self.msg("Noone found to page.")
return return
header = "|wPlayer|n |c%s|n |wpages:|n" % caller.key header = "|wAccount|n |c%s|n |wpages:|n" % caller.key
message = self.rhs message = self.rhs
# if message begins with a :, we assume it is a 'page-pose' # if message begins with a :, we assume it is a 'page-pose'
@ -778,7 +778,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
create.create_message(caller, message, create.create_message(caller, message,
receivers=recobjs) receivers=recobjs)
# tell the players they got a message. # tell the accounts they got a message.
received = [] received = []
rstrings = [] rstrings = []
for pobj in recobjs: for pobj in recobjs:
@ -805,7 +805,7 @@ def _list_bots():
bots (str): A table of bots or an error message. bots (str): A table of bots or an error message.
""" """
ircbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")] ircbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
if ircbots: if ircbots:
from evennia.utils.evtable import EvTable from evennia.utils.evtable import EvTable
table = EvTable("|w#dbref|n", "|wbotname|n", "|wev-channel|n", table = EvTable("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
@ -836,7 +836,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
Example: Example:
@irc2chan myircchan = irc.dalnet.net 6667 #mychannel evennia-bot @irc2chan myircchan = irc.dalnet.net 6667 #mychannel evennia-bot
@irc2chan public = irc.freenode.net 6667 #evgaming #evbot:players.mybot.MyBot @irc2chan public = irc.freenode.net 6667 #evgaming #evbot:accounts.mybot.MyBot
This creates an IRC bot that connects to a given IRC network and This creates an IRC bot that connects to a given IRC network and
channel. If a custom typeclass path is given, this will be used channel. If a custom typeclass path is given, this will be used
@ -868,11 +868,11 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches: if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
botname = "ircbot-%s" % self.lhs botname = "ircbot-%s" % self.lhs
matches = PlayerDB.objects.filter(db_is_bot=True, username=botname) matches = AccountDB.objects.filter(db_is_bot=True, username=botname)
dbref = utils.dbref(self.lhs) dbref = utils.dbref(self.lhs)
if not matches and dbref: if not matches and dbref:
# try dbref match # try dbref match
matches = PlayerDB.objects.filter(db_is_bot=True, id=dbref) matches = AccountDB.objects.filter(db_is_bot=True, id=dbref)
if matches: if matches:
matches[0].delete() matches[0].delete()
self.msg("IRC connection destroyed.") self.msg("IRC connection destroyed.")
@ -906,16 +906,16 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
irc_ssl = "ssl" in self.switches irc_ssl = "ssl" in self.switches
# create a new bot # create a new bot
bot = PlayerDB.objects.filter(username__iexact=botname) bot = AccountDB.objects.filter(username__iexact=botname)
if bot: if bot:
# re-use an existing bot # re-use an existing bot
bot = bot[0] bot = bot[0]
if not bot.is_bot: if not bot.is_bot:
self.msg("Player '%s' already exists and is not a bot." % botname) self.msg("Account '%s' already exists and is not a bot." % botname)
return return
else: else:
try: try:
bot = create.create_player(botname, None, None, typeclass=botclass) bot = create.create_account(botname, None, None, typeclass=botclass)
except Exception as err: except Exception as err:
self.msg("|rError, could not create the bot:|n '%s'." % err) self.msg("|rError, could not create the bot:|n '%s'." % err)
return return
@ -963,7 +963,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
return return
matches = None matches = None
if utils.dbref(botname): if utils.dbref(botname):
matches = PlayerDB.objects.filter(db_is_bot=True, id=utils.dbref(botname)) matches = AccountDB.objects.filter(db_is_bot=True, id=utils.dbref(botname))
if not matches: if not matches:
self.msg("No matching IRC-bot found. Use @ircstatus without arguments to list active bots.") self.msg("No matching IRC-bot found. Use @ircstatus without arguments to list active bots.")
return return
@ -1038,7 +1038,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
if 'list' in self.switches: if 'list' in self.switches:
# show all connections # show all connections
rssbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")] rssbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")]
if rssbots: if rssbots:
from evennia.utils.evtable import EvTable from evennia.utils.evtable import EvTable
table = EvTable("|wdbid|n", "|wupdate rate|n", "|wev-channel", table = EvTable("|wdbid|n", "|wupdate rate|n", "|wev-channel",
@ -1052,10 +1052,10 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches: if 'disconnect' in self.switches or 'remove' in self.switches or 'delete' in self.switches:
botname = "rssbot-%s" % self.lhs botname = "rssbot-%s" % self.lhs
matches = PlayerDB.objects.filter(db_is_bot=True, db_key=botname) matches = AccountDB.objects.filter(db_is_bot=True, db_key=botname)
if not matches: if not matches:
# try dbref match # try dbref match
matches = PlayerDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#")) matches = AccountDB.objects.filter(db_is_bot=True, id=self.args.lstrip("#"))
if matches: if matches:
matches[0].delete() matches[0].delete()
self.msg("RSS connection destroyed.") self.msg("RSS connection destroyed.")
@ -1072,14 +1072,14 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
botname = "rssbot-%s" % url botname = "rssbot-%s" % url
# create a new bot # create a new bot
bot = PlayerDB.objects.filter(username__iexact=botname) bot = AccountDB.objects.filter(username__iexact=botname)
if bot: if bot:
# re-use existing bot # re-use existing bot
bot = bot[0] bot = bot[0]
if not bot.is_bot: if not bot.is_bot:
self.msg("Player '%s' already exists and is not a bot." % botname) self.msg("Account '%s' already exists and is not a bot." % botname)
return return
else: else:
bot = create.create_player(botname, None, None, typeclass=bots.RSSBot) bot = create.create_account(botname, None, None, typeclass=bots.RSSBot)
bot.start(ev_channel=channel, rss_url=url, rss_rate=10) bot.start(ev_channel=channel, rss_url=url, rss_rate=10)
self.msg("RSS reporter created. Fetching RSS.") self.msg("RSS reporter created. Fetching RSS.")

View file

@ -47,7 +47,7 @@ class CmdLook(COMMAND_DEFAULT_CLASS):
Usage: Usage:
look look
look <obj> look <obj>
look *<player> look *<account>
Observes your location or objects in your vicinity. Observes your location or objects in your vicinity.
""" """
@ -86,7 +86,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
Switches: Switches:
inputline - replace on the inputline (default) inputline - replace on the inputline (default)
object - replace on object-lookup object - replace on object-lookup
player - replace on player-lookup account - replace on account-lookup
delete - remove nick by name or by index given by /list delete - remove nick by name or by index given by /list
clearall - clear all nicks clearall - clear all nicks
list - show all defined aliases (also "nicks" works) list - show all defined aliases (also "nicks" works)
@ -121,7 +121,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
caller = self.caller caller = self.caller
switches = self.switches switches = self.switches
nicktypes = [switch for switch in switches if switch in ("object", "player", "inputline")] or ["inputline"] nicktypes = [switch for switch in switches if switch in ("object", "account", "inputline")] or ["inputline"]
nicklist = utils.make_iter(caller.nicks.get(return_obj=True) or []) nicklist = utils.make_iter(caller.nicks.get(return_obj=True) or [])
@ -441,7 +441,7 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
caller = self.caller caller = self.caller
if not self.lhs or not self.rhs: if not self.lhs or not self.rhs:
caller.msg("Usage: whisper <player> = <message>") caller.msg("Usage: whisper <account> = <message>")
return return
receiver = caller.search(self.lhs) receiver = caller.search(self.lhs)
@ -529,15 +529,15 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
hierarchy_full = settings.PERMISSION_HIERARCHY hierarchy_full = settings.PERMISSION_HIERARCHY
string = "\n|wPermission Hierarchy|n (climbing):\n %s" % ", ".join(hierarchy_full) string = "\n|wPermission Hierarchy|n (climbing):\n %s" % ", ".join(hierarchy_full)
if self.caller.player.is_superuser: if self.caller.account.is_superuser:
cperms = "<Superuser>" cperms = "<Superuser>"
pperms = "<Superuser>" pperms = "<Superuser>"
else: else:
cperms = ", ".join(caller.permissions.all()) cperms = ", ".join(caller.permissions.all())
pperms = ", ".join(caller.player.permissions.all()) pperms = ", ".join(caller.account.permissions.all())
string += "\n|wYour access|n:" string += "\n|wYour access|n:"
string += "\nCharacter |c%s|n: %s" % (caller.key, cperms) string += "\nCharacter |c%s|n: %s" % (caller.key, cperms)
if hasattr(caller, 'player'): if hasattr(caller, 'account'):
string += "\nPlayer |c%s|n: %s" % (caller.player.key, pperms) string += "\nAccount |c%s|n: %s" % (caller.account.key, pperms)
caller.msg(string) caller.msg(string)

View file

@ -60,7 +60,7 @@ class CmdHelp(Command):
if self.session.protocol_key in ("websocket", "ajax/comet"): if self.session.protocol_key in ("websocket", "ajax/comet"):
try: try:
options = self.player.db._saved_webclient_options options = self.account.db._saved_webclient_options
if options and options["helppopup"]: if options and options["helppopup"]:
usemore = False usemore = False
except KeyError: except KeyError:
@ -128,12 +128,12 @@ class CmdHelp(Command):
Helper method. If this return True, the given cmd Helper method. If this return True, the given cmd
auto-help will be viewable in the help listing. auto-help will be viewable in the help listing.
Override this to easily select what is shown to Override this to easily select what is shown to
the player. Note that only commands available the account. Note that only commands available
in the caller's merged cmdset are available. in the caller's merged cmdset are available.
Args: Args:
cmd (Command): Command class from the merged cmdset cmd (Command): Command class from the merged cmdset
caller (Character, Player or Session): The current caller caller (Character, Account or Session): The current caller
executing the help command. executing the help command.
""" """

View file

@ -1,13 +1,13 @@
""" """
The command template for the default MUX-style command set. There The command template for the default MUX-style command set. There
is also an Player/OOC version that makes sure caller is a Player object. is also an Account/OOC version that makes sure caller is an Account object.
""" """
from evennia.utils import utils from evennia.utils import utils
from evennia.commands.command import Command from evennia.commands.command import Command
# limit symbol import for API # limit symbol import for API
__all__ = ("MuxCommand", "MuxPlayerCommand") __all__ = ("MuxCommand", "MuxAccountCommand")
class MuxCommand(Command): class MuxCommand(Command):
@ -128,17 +128,17 @@ class MuxCommand(Command):
self.rhs = rhs self.rhs = rhs
self.rhslist = rhslist self.rhslist = rhslist
# if the class has the player_caller property set on itself, we make # if the class has the account_caller property set on itself, we make
# sure that self.caller is always the player if possible. We also create # sure that self.caller is always the account if possible. We also create
# a special property "character" for the puppeted object, if any. This # a special property "character" for the puppeted object, if any. This
# is convenient for commands defined on the Player only. # is convenient for commands defined on the Account only.
if hasattr(self, "player_caller") and self.player_caller: if hasattr(self, "account_caller") and self.account_caller:
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"): if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
# caller is an Object/Character # caller is an Object/Character
self.character = self.caller self.character = self.caller
self.caller = self.caller.player self.caller = self.caller.account
elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"): elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
# caller was already a Player # caller was already an Account
self.character = self.caller.get_puppet(self.session) self.character = self.caller.get_puppet(self.session)
else: else:
self.character = None self.character = None
@ -177,32 +177,32 @@ class MuxCommand(Command):
self.caller.msg(string) self.caller.msg(string)
class MuxPlayerCommand(MuxCommand): class MuxAccountCommand(MuxCommand):
""" """
This is an on-Player version of the MuxCommand. Since these commands sit This is an on-Account version of the MuxCommand. Since these commands sit
on Players rather than on Characters/Objects, we need to check on Accounts rather than on Characters/Objects, we need to check
this in the parser. this in the parser.
Player commands are available also when puppeting a Character, it's Account commands are available also when puppeting a Character, it's
just that they are applied with a lower priority and are always just that they are applied with a lower priority and are always
available, also when disconnected from a character (i.e. "ooc"). available, also when disconnected from a character (i.e. "ooc").
This class makes sure that caller is always a Player object, while This class makes sure that caller is always an Account object, while
creating a new property "character" that is set only if a creating a new property "character" that is set only if a
character is actually attached to this Player and Session. character is actually attached to this Account and Session.
""" """
def parse(self): def parse(self):
""" """
We run the parent parser as usual, then fix the result We run the parent parser as usual, then fix the result
""" """
super(MuxPlayerCommand, self).parse() super(MuxAccountCommand, self).parse()
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"): if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
# caller is an Object/Character # caller is an Object/Character
self.character = self.caller self.character = self.caller
self.caller = self.caller.player self.caller = self.caller.account
elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"): elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
# caller was already a Player # caller was already an Account
self.character = self.caller.get_puppet(self.session) self.character = self.caller.get_puppet(self.session)
else: else:
self.character = None self.character = None

View file

@ -1,836 +0,0 @@
"""
Player (OOC) commands. These are stored on the Player object
and self.caller is thus always a Player, not an Object/Character.
These commands go in the PlayerCmdset and are accessible also
when puppeting a Character (although with lower priority)
These commands use the player_caller property which tells the command
parent (MuxCommand, usually) to setup caller correctly. They use
self.player to make sure to always use the player object rather than
self.caller (which change depending on the level you are calling from)
The property self.character can be used to access the character when
these commands are triggered with a connected character (such as the
case of the @ooc command), it is None if we are OOC.
Note that under MULTISESSION_MODE > 2, Player commands should use
self.msg() and similar methods to reroute returns to the correct
method. Otherwise all text will be returned to all connected sessions.
"""
from builtins import range
import time
from django.conf import settings
from evennia.server.sessionhandler import SESSIONS
from evennia.utils import utils, create, search, evtable
COMMAND_DEFAULT_CLASS = utils.class_from_module(settings.COMMAND_DEFAULT_CLASS)
_MAX_NR_CHARACTERS = settings.MAX_NR_CHARACTERS
_MULTISESSION_MODE = settings.MULTISESSION_MODE
# limit symbol import for API
__all__ = ("CmdOOCLook", "CmdIC", "CmdOOC", "CmdPassword", "CmdQuit",
"CmdCharCreate", "CmdOption", "CmdSessions", "CmdWho",
"CmdColorTest", "CmdQuell")
class MuxPlayerLookCommand(COMMAND_DEFAULT_CLASS):
"""
Custom parent (only) parsing for OOC looking, sets a "playable"
property on the command based on the parsing.
"""
def parse(self):
"""Custom parsing"""
super(MuxPlayerLookCommand, self).parse()
if _MULTISESSION_MODE < 2:
# only one character allowed - not used in this mode
self.playable = None
return
playable = self.player.db._playable_characters
if playable is not None:
# clean up list if character object was deleted in between
if None in playable:
playable = [character for character in playable if character]
self.player.db._playable_characters = playable
# store playable property
if self.args:
self.playable = dict((utils.to_str(char.key.lower()), char)
for char in playable).get(self.args.lower(), None)
else:
self.playable = playable
# Obs - these are all intended to be stored on the Player, and as such,
# use self.player instead of self.caller, just to be sure. Also self.msg()
# is used to make sure returns go to the right session
# note that this is inheriting from MuxPlayerLookCommand,
# and has the .playable property.
class CmdOOCLook(MuxPlayerLookCommand):
"""
look while out-of-character
Usage:
look
Look in the ooc state.
"""
# This is an OOC version of the look command. Since a
# Player doesn't have an in-game existence, there is no
# concept of location or "self". If we are controlling
# a character, pass control over to normal look.
key = "look"
aliases = ["l", "ls"]
locks = "cmd:all()"
help_category = "General"
# this is used by the parent
player_caller = True
def func(self):
"""implement the ooc look command"""
if _MULTISESSION_MODE < 2:
# only one character allowed
self.msg("You are out-of-character (OOC).\nUse |w@ic|n to get back into the game.")
return
# call on-player look helper method
self.msg(self.player.at_look(target=self.playable, session=self.session))
class CmdCharCreate(COMMAND_DEFAULT_CLASS):
"""
create a new character
Usage:
@charcreate <charname> [= desc]
Create a new character, optionally giving it a description. You
may use upper-case letters in the name - you will nevertheless
always be able to access your character using lower-case letters
if you want.
"""
key = "@charcreate"
locks = "cmd:pperm(Player)"
help_category = "General"
# this is used by the parent
player_caller = True
def func(self):
"""create the new character"""
player = self.player
if not self.args:
self.msg("Usage: @charcreate <charname> [= description]")
return
key = self.lhs
desc = self.rhs
charmax = _MAX_NR_CHARACTERS if _MULTISESSION_MODE > 1 else 1
if not player.is_superuser and \
(player.db._playable_characters and
len(player.db._playable_characters) >= charmax):
self.msg("You may only create a maximum of %i characters." % charmax)
return
from evennia.objects.models import ObjectDB
typeclass = settings.BASE_CHARACTER_TYPECLASS
if ObjectDB.objects.filter(db_typeclass_path=typeclass, db_key__iexact=key):
# check if this Character already exists. Note that we are only
# searching the base character typeclass here, not any child
# classes.
self.msg("|rA character named '|w%s|r' already exists.|n" % key)
return
# create the character
start_location = ObjectDB.objects.get_id(settings.START_LOCATION)
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
permissions = settings.PERMISSION_PLAYER_DEFAULT
new_character = create.create_object(typeclass, key=key,
location=start_location,
home=default_home,
permissions=permissions)
# only allow creator (and developers) to puppet this char
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
(new_character.id, player.id))
player.db._playable_characters.append(new_character)
if desc:
new_character.db.desc = desc
elif not new_character.db.desc:
new_character.db.desc = "This is a Player."
self.msg("Created new character %s. Use |w@ic %s|n to enter the game as this character."
% (new_character.key, new_character.key))
class CmdCharDelete(COMMAND_DEFAULT_CLASS):
"""
delete a character - this cannot be undone!
Usage:
@chardelete <charname>
Permanently deletes one of your characters.
"""
key = "@chardelete"
locks = "cmd:pperm(Player)"
help_category = "General"
def func(self):
"""delete the character"""
player = self.player
if not self.args:
self.msg("Usage: @chardelete <charactername>")
return
# use the playable_characters list to search
match = [char for char in utils.make_iter(player.db._playable_characters)
if char.key.lower() == self.args.lower()]
if not match:
self.msg("You have no such character to delete.")
return
elif len(match) > 1:
self.msg("Aborting - there are two characters with the same name. Ask an admin to delete the right one.")
return
else: # one match
from evennia.utils.evmenu import get_input
def _callback(caller, callback_prompt, result):
if result.lower() == "yes":
# only take action
delobj = caller.ndb._char_to_delete
key = delobj.key
caller.db._playable_characters = [pc for pc in caller.db._playable_characters if pc != delobj]
delobj.delete()
self.msg("Character '%s' was permanently deleted." % key)
else:
self.msg("Deletion was aborted.")
del caller.ndb._char_to_delete
match = match[0]
player.ndb._char_to_delete = match
prompt = "|rThis will permanently destroy '%s'. This cannot be undone.|n Continue yes/[no]?"
get_input(player, prompt % match.key, _callback)
class CmdIC(COMMAND_DEFAULT_CLASS):
"""
control an object you have permission to puppet
Usage:
@ic <character>
Go in-character (IC) as a given Character.
This will attempt to "become" a different object assuming you have
the right to do so. Note that it's the PLAYER character that puppets
characters/objects and which needs to have the correct permission!
You cannot become an object that is already controlled by another
player. In principle <character> can be any in-game object as long
as you the player have access right to puppet it.
"""
key = "@ic"
# lock must be all() for different puppeted objects to access it.
locks = "cmd:all()"
aliases = "@puppet"
help_category = "General"
# this is used by the parent
player_caller = True
def func(self):
"""
Main puppet method
"""
player = self.player
session = self.session
new_character = None
if not self.args:
new_character = player.db._last_puppet
if not new_character:
self.msg("Usage: @ic <character>")
return
if not new_character:
# search for a matching character
new_character = [char for char in search.object_search(self.args) if char.access(player, "puppet")]
if not new_character:
self.msg("That is not a valid character choice.")
return
if len(new_character) > 1:
self.msg("Multiple targets with the same name:\n %s"
% ", ".join("%s(#%s)" % (obj.key, obj.id) for obj in new_character))
return
else:
new_character = new_character[0]
try:
player.puppet_object(session, new_character)
player.db._last_puppet = new_character
except RuntimeError as exc:
self.msg("|rYou cannot become |C%s|n: %s" % (new_character.name, exc))
# note that this is inheriting from MuxPlayerLookCommand,
# and as such has the .playable property.
class CmdOOC(MuxPlayerLookCommand):
"""
stop puppeting and go ooc
Usage:
@ooc
Go out-of-character (OOC).
This will leave your current character and put you in a incorporeal OOC state.
"""
key = "@ooc"
locks = "cmd:pperm(Player)"
aliases = "@unpuppet"
help_category = "General"
# this is used by the parent
player_caller = True
def func(self):
"""Implement function"""
player = self.player
session = self.session
old_char = player.get_puppet(session)
if not old_char:
string = "You are already OOC."
self.msg(string)
return
player.db._last_puppet = old_char
# disconnect
try:
player.unpuppet_object(session)
self.msg("\n|GYou go OOC.|n\n")
if _MULTISESSION_MODE < 2:
# only one character allowed
self.msg("You are out-of-character (OOC).\nUse |w@ic|n to get back into the game.")
return
self.msg(player.at_look(target=self.playable, session=session))
except RuntimeError as exc:
self.msg("|rCould not unpuppet from |c%s|n: %s" % (old_char, exc))
class CmdSessions(COMMAND_DEFAULT_CLASS):
"""
check your connected session(s)
Usage:
@sessions
Lists the sessions currently connected to your account.
"""
key = "@sessions"
locks = "cmd:all()"
help_category = "General"
# this is used by the parent
player_caller = True
def func(self):
"""Implement function"""
player = self.player
sessions = player.sessions.all()
table = evtable.EvTable("|wsessid",
"|wprotocol",
"|whost",
"|wpuppet/character",
"|wlocation")
for sess in sorted(sessions, key=lambda x: x.sessid):
char = player.get_puppet(sess)
table.add_row(str(sess.sessid), str(sess.protocol_key),
type(sess.address) == tuple and sess.address[0] or sess.address,
char and str(char) or "None",
char and str(char.location) or "N/A")
self.msg("|wYour current session(s):|n\n%s" % table)
class CmdWho(COMMAND_DEFAULT_CLASS):
"""
list who is currently online
Usage:
who
doing
Shows who is currently online. Doing is an alias that limits info
also for those with all permissions.
"""
key = "who"
aliases = "doing"
locks = "cmd:all()"
# this is used by the parent
player_caller = True
def func(self):
"""
Get all connected players by polling session.
"""
player = self.player
session_list = SESSIONS.get_sessions()
session_list = sorted(session_list, key=lambda o: o.player.key)
if self.cmdstring == "doing":
show_session_data = False
else:
show_session_data = player.check_permstring("Developer") or player.check_permstring("Admins")
nplayers = (SESSIONS.player_count())
if show_session_data:
# privileged info
table = evtable.EvTable("|wPlayer Name",
"|wOn for",
"|wIdle",
"|wPuppeting",
"|wRoom",
"|wCmds",
"|wProtocol",
"|wHost")
for session in session_list:
if not session.logged_in:
continue
delta_cmd = time.time() - session.cmd_last_visible
delta_conn = time.time() - session.conn_time
player = session.get_player()
puppet = session.get_puppet()
location = puppet.location.key if puppet and puppet.location else "None"
table.add_row(utils.crop(player.name, width=25),
utils.time_format(delta_conn, 0),
utils.time_format(delta_cmd, 1),
utils.crop(puppet.key if puppet else "None", width=25),
utils.crop(location, width=25),
session.cmd_total,
session.protocol_key,
isinstance(session.address, tuple) and session.address[0] or session.address)
else:
# unprivileged
table = evtable.EvTable("|wPlayer name", "|wOn for", "|wIdle")
for session in session_list:
if not session.logged_in:
continue
delta_cmd = time.time() - session.cmd_last_visible
delta_conn = time.time() - session.conn_time
player = session.get_player()
table.add_row(utils.crop(player.key, width=25),
utils.time_format(delta_conn, 0),
utils.time_format(delta_cmd, 1))
is_one = nplayers == 1
self.msg("|wPlayers:|n\n%s\n%s unique account%s logged in."
% (table, "One" if is_one else nplayers, "" if is_one else "s"))
class CmdOption(COMMAND_DEFAULT_CLASS):
"""
Set an account option
Usage:
@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. Note that saved options may not be able to be used if
later connecting with a client with different capabilities.
"""
key = "@option"
aliases = "@options"
locks = "cmd:all()"
# this is used by the parent
player_caller = True
def func(self):
"""
Implements the command
"""
if self.session is None:
return
flags = self.session.protocol_flags
# Display current options
if not self.args:
# list the option settings
if "save" in self.switches:
# save all options
self.caller.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.caller.db._saved_protocol_flags = {}
self.msg("|gCleared all saved options.")
options = dict(flags) # make a copy of the flag dict
saved_options = dict(self.caller.attributes.get("_saved_protocol_flags", default={}))
if "SCREENWIDTH" in options:
if len(options["SCREENWIDTH"]) == 1:
options["SCREENWIDTH"] = options["SCREENWIDTH"][0]
else:
options["SCREENWIDTH"] = " \n".join("%s : %s" % (screenid, size)
for screenid, size in options["SCREENWIDTH"].iteritems())
if "SCREENHEIGHT" in options:
if len(options["SCREENHEIGHT"]) == 1:
options["SCREENHEIGHT"] = options["SCREENHEIGHT"][0]
else:
options["SCREENHEIGHT"] = " \n".join("%s : %s" % (screenid, size)
for screenid, size in options["SCREENHEIGHT"].iteritems())
options.pop("TTYPE", None)
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:
self.msg("Usage: @option [name = [value]]")
return
# Try to assign new values
def validate_encoding(new_encoding):
# helper: change encoding
try:
utils.to_str(utils.to_unicode("test-string"), encoding=new_encoding)
except LookupError:
raise RuntimeError("The encoding '|w%s|n' is invalid. " % new_encoding)
return val
def validate_size(new_size):
return {0: int(new_size)}
def validate_bool(new_bool):
return True if new_bool.lower() in ("true", "on", "1") else False
def update(new_name, new_val, validator):
# helper: update property and report errors
try:
old_val = flags.get(new_name, False)
new_val = validator(new_val)
flags[new_name] = new_val
self.msg("Option |w%s|n was changed from '|w%s|n' to '|w%s|n'." % (new_name, old_val, new_val))
return {new_name: new_val}
except Exception, err:
self.msg("|rCould not set option |w%s|r:|n %s" % (new_name, err))
return False
validators = {"ANSI": validate_bool,
"CLIENTNAME": utils.to_str,
"ENCODING": validate_encoding,
"MCCP": validate_bool,
"NOGOAHEAD": validate_bool,
"MXP": validate_bool,
"NOCOLOR": validate_bool,
"NOPKEEPALIVE": validate_bool,
"OOB": validate_bool,
"RAW": validate_bool,
"SCREENHEIGHT": validate_size,
"SCREENWIDTH": validate_size,
"SCREENREADER": validate_bool,
"TERM": utils.to_str,
"UTF-8": validate_bool,
"XTERM256": validate_bool,
"INPUTDEBUG": validate_bool}
name = self.lhs.upper()
val = self.rhs.strip()
optiondict = False
if val and name in validators:
optiondict = update(name, val, validators[name])
else:
self.msg("|rNo option named '|w%s|r'." % name)
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(COMMAND_DEFAULT_CLASS):
"""
change your password
Usage:
@password <old password> = <new password>
Changes your password. Make sure to pick a safe one.
"""
key = "@password"
locks = "cmd:pperm(Player)"
# this is used by the parent
player_caller = True
def func(self):
"""hook function."""
player = self.player
if not self.rhs:
self.msg("Usage: @password <oldpass> = <newpass>")
return
oldpass = self.lhslist[0] # Both of these are
newpass = self.rhslist[0] # already stripped by parse()
if not player.check_password(oldpass):
self.msg("The specified old password isn't correct.")
elif len(newpass) < 3:
self.msg("Passwords must be at least three characters long.")
else:
player.set_password(newpass)
player.save()
self.msg("Password changed.")
class CmdQuit(COMMAND_DEFAULT_CLASS):
"""
quit the game
Usage:
@quit
Switch:
all - disconnect all connected sessions
Gracefully disconnect your current session from the
game. Use the /all switch to disconnect from all sessions.
"""
key = "@quit"
locks = "cmd:all()"
# this is used by the parent
player_caller = True
def func(self):
"""hook function"""
player = self.player
if 'all' in self.switches:
player.msg("|RQuitting|n all sessions. Hope to see you soon again.", session=self.session)
for session in player.sessions.all():
player.disconnect_session_from_player(session)
else:
nsess = len(player.sessions.all())
if nsess == 2:
player.msg("|RQuitting|n. One session is still connected.", session=self.session)
elif nsess > 2:
player.msg("|RQuitting|n. %i sessions are still connected." % (nsess-1), session=self.session)
else:
# we are quitting the last available session
player.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
player.disconnect_session_from_player(self.session)
class CmdColorTest(COMMAND_DEFAULT_CLASS):
"""
testing which colors your client support
Usage:
@color ansi||xterm256
Prints a color map along with in-mud color codes to use to produce
them. It also tests what is supported in your client. Choices are
16-color ansi (supported in most muds) or the 256-color xterm256
standard. No checking is done to determine your client supports
color - if not you will see rubbish appear.
"""
key = "@color"
locks = "cmd:all()"
help_category = "General"
# this is used by the parent
player_caller = True
def table_format(self, table):
"""
Helper method to format the ansi/xterm256 tables.
Takes a table of columns [[val,val,...],[val,val,...],...]
"""
if not table:
return [[]]
extra_space = 1
max_widths = [max([len(str(val)) for val in col]) for col in table]
ftable = []
for irow in range(len(table[0])):
ftable.append([str(col[irow]).ljust(max_widths[icol]) + " " *
extra_space for icol, col in enumerate(table)])
return ftable
def func(self):
"""Show color tables"""
if self.args.startswith("a"):
# show ansi 16-color table
from evennia.utils import ansi
ap = ansi.ANSI_PARSER
# ansi colors
# show all ansi color-related codes
col1 = ["%s%s|n" % (code, code.replace("|", "||")) for code, _ in ap.ext_ansi_map[48:56]]
col2 = ["%s%s|n" % (code, code.replace("|", "||")) for code, _ in ap.ext_ansi_map[56:64]]
col3 = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
for code, _ in ap.ext_ansi_map[-8:]]
col4 = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
for code, _ in ap.ansi_bright_bgs[-8:]]
col2.extend(["" for _ in range(len(col1)-len(col2))])
table = utils.format_table([col1, col2, col4, col3])
string = "ANSI colors:"
for row in table:
string += "\n " + " ".join(row)
self.msg(string)
self.msg("||X : black. ||/ : return, ||- : tab, ||_ : space, ||* : invert, ||u : underline\n"
"To combine background and foreground, add background marker last, e.g. ||r||[B.\n"
"Note: bright backgrounds like ||[r requires your client handling Xterm256 colors.")
elif self.args.startswith("x"):
# show xterm256 table
table = [[], [], [], [], [], [], [], [], [], [], [], []]
for ir in range(6):
for ig in range(6):
for ib in range(6):
# foreground table
table[ir].append("|%i%i%i%s|n" % (ir, ig, ib, "||%i%i%i" % (ir, ig, ib)))
# background table
table[6+ir].append("|%i%i%i|[%i%i%i%s|n"
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib)))
table = self.table_format(table)
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
string += "\n" + "\n".join("".join(row) for row in table)
table = [[], [], [], [], [], [], [], [], [], [], [], []]
for ibatch in range(4):
for igray in range(6):
letter = chr(97 + (ibatch*6 + igray))
inverse = chr(122 - (ibatch*6 + igray))
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % letter))
table[6 + igray].append("|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter))
for igray in range(6):
# the last row (y, z) has empty columns
if igray < 2:
letter = chr(121 + igray)
inverse = chr(98 - igray)
fg = "|=%s%s |n" % (letter, "||=%s" % letter)
bg = "|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter)
else:
fg, bg = " ", " "
table[0 + igray].append(fg)
table[6 + igray].append(bg)
table = self.table_format(table)
string += "\n" + "\n".join("".join(row) for row in table)
self.msg(string)
else:
# malformed input
self.msg("Usage: @color ansi||xterm256")
class CmdQuell(COMMAND_DEFAULT_CLASS):
"""
use character's permissions instead of player's
Usage:
quell
unquell
Normally the permission level of the Player is used when puppeting a
Character/Object to determine access. This command will switch the lock
system to make use of the puppeted Object's permissions instead. This is
useful mainly for testing.
Hierarchical permission quelling only work downwards, thus a Player cannot
use a higher-permission Character to escalate their permission level.
Use the unquell command to revert back to normal operation.
"""
key = "@quell"
aliases = ["@unquell"]
locks = "cmd:pperm(Player)"
help_category = "General"
# this is used by the parent
player_caller = True
def _recache_locks(self, player):
"""Helper method to reset the lockhandler on an already puppeted object"""
if self.session:
char = self.session.puppet
if char:
# we are already puppeting an object. We need to reset
# the lock caches (otherwise the superuser status change
# won't be visible until repuppet)
char.locks.reset()
player.locks.reset()
def func(self):
"""Perform the command"""
player = self.player
permstr = player.is_superuser and " (superuser)" or "(%s)" % (", ".join(player.permissions.all()))
if self.cmdstring == '@unquell':
if not player.attributes.get('_quell'):
self.msg("Already using normal Player permissions %s." % permstr)
else:
player.attributes.remove('_quell')
self.msg("Player permissions %s restored." % permstr)
else:
if player.attributes.get('_quell'):
self.msg("Already quelling Player %s permissions." % permstr)
return
player.attributes.add('_quell', True)
puppet = self.session.puppet
if puppet:
cpermstr = "(%s)" % ", ".join(puppet.permissions.all())
cpermstr = "Quelling to current puppet's permissions %s." % cpermstr
cpermstr += "\n(Note: If this is higher than Player permissions %s," \
" the lowest of the two will be used.)" % permstr
cpermstr += "\nUse @unquell to return to normal permission usage."
self.msg(cpermstr)
else:
self.msg("Quelling Player permissions%s. Use @unquell to get them back." % permstr)
self._recache_locks(player)

View file

@ -17,7 +17,7 @@ from django.conf import settings
from evennia.server.sessionhandler import SESSIONS from evennia.server.sessionhandler import SESSIONS
from evennia.scripts.models import ScriptDB from evennia.scripts.models import ScriptDB
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.utils import logger, utils, gametime, create from evennia.utils import logger, utils, gametime, create
from evennia.utils.eveditor import EvEditor from evennia.utils.eveditor import EvEditor
from evennia.utils.evtable import EvTable from evennia.utils.evtable import EvTable
@ -455,24 +455,24 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
caller.msg(string) caller.msg(string)
class CmdPlayers(COMMAND_DEFAULT_CLASS): class CmdAccounts(COMMAND_DEFAULT_CLASS):
""" """
list all registered players list all registered accounts
Usage: Usage:
@players [nr] @accounts [nr]
Lists statistics about the Players registered with the game. Lists statistics about the Accounts registered with the game.
It will list the <nr> amount of latest registered players It will list the <nr> amount of latest registered accounts
If not given, <nr> defaults to 10. If not given, <nr> defaults to 10.
""" """
key = "@players" key = "@accounts"
aliases = ["@listplayers"] aliases = ["@listaccounts"]
locks = "cmd:perm(listplayers) or perm(Admin)" locks = "cmd:perm(listaccounts) or perm(Admin)"
help_category = "System" help_category = "System"
def func(self): def func(self):
"""List the players""" """List the accounts"""
caller = self.caller caller = self.caller
if self.args and self.args.isdigit(): if self.args and self.args.isdigit():
@ -480,21 +480,21 @@ class CmdPlayers(COMMAND_DEFAULT_CLASS):
else: else:
nlim = 10 nlim = 10
nplayers = PlayerDB.objects.count() naccounts = AccountDB.objects.count()
# typeclass table # typeclass table
dbtotals = PlayerDB.objects.object_totals() dbtotals = AccountDB.objects.object_totals()
typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l") typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
for path, count in dbtotals.items(): for path, count in dbtotals.items():
typetable.add_row(path, count, "%.2f" % ((float(count) / nplayers) * 100)) typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
# last N table # last N table
plyrs = PlayerDB.objects.all().order_by("db_date_created")[max(0, nplayers - nlim):] plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):]
latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l") latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
for ply in plyrs: for ply in plyrs:
latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path) latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path)
string = "\n|wPlayer typeclass distribution:|n\n%s" % typetable string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
string += "\n|wLast %s Players created:|n\n%s" % (min(nplayers, nlim), latesttable) string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
caller.msg(string) caller.msg(string)
@ -644,7 +644,7 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
""" """
key = "@time" key = "@time"
aliases = "@uptime" aliases = "@uptime"
locks = "cmd:perm(time) or perm(Player)" locks = "cmd:perm(time) or perm(Account)"
help_category = "System" help_category = "System"
def func(self): def func(self):

View file

@ -19,7 +19,7 @@ from mock import Mock
from evennia.commands.default.cmdset_character import CharacterCmdSet from evennia.commands.default.cmdset_character import CharacterCmdSet
from evennia.utils.test_resources import EvenniaTest from evennia.utils.test_resources import EvenniaTest
from evennia.commands.default import help, general, system, admin, player, building, batchprocess, comms from evennia.commands.default import help, general, system, admin, account, building, batchprocess, comms
from evennia.commands.command import Command, InterruptCommand from evennia.commands.command import Command, InterruptCommand
from evennia.utils import ansi, utils from evennia.utils import ansi, utils
from evennia.server.sessionhandler import SESSIONS from evennia.server.sessionhandler import SESSIONS
@ -63,7 +63,7 @@ class CommandTest(EvenniaTest):
cmdobj.args = args cmdobj.args = args
cmdobj.cmdset = cmdset cmdobj.cmdset = cmdset
cmdobj.session = SESSIONS.session_from_sessid(1) cmdobj.session = SESSIONS.session_from_sessid(1)
cmdobj.player = self.player cmdobj.account = self.account
cmdobj.raw_string = cmdobj.key + " " + args cmdobj.raw_string = cmdobj.key + " " + args
cmdobj.obj = obj or (caller if caller else self.char1) cmdobj.obj = obj or (caller if caller else self.char1)
# test # test
@ -119,10 +119,10 @@ class TestGeneral(CommandTest):
def test_nick(self): def test_nick(self):
self.call(general.CmdNick(), "testalias = testaliasedstring1", "Nick 'testalias' mapped to 'testaliasedstring1'.") self.call(general.CmdNick(), "testalias = testaliasedstring1", "Nick 'testalias' mapped to 'testaliasedstring1'.")
self.call(general.CmdNick(), "/player testalias = testaliasedstring2", "Nick 'testalias' mapped to 'testaliasedstring2'.") self.call(general.CmdNick(), "/account testalias = testaliasedstring2", "Nick 'testalias' mapped to 'testaliasedstring2'.")
self.call(general.CmdNick(), "/object testalias = testaliasedstring3", "Nick 'testalias' mapped to 'testaliasedstring3'.") self.call(general.CmdNick(), "/object testalias = testaliasedstring3", "Nick 'testalias' mapped to 'testaliasedstring3'.")
self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias")) self.assertEqual(u"testaliasedstring1", self.char1.nicks.get("testalias"))
self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="player")) self.assertEqual(u"testaliasedstring2", self.char1.nicks.get("testalias", category="account"))
self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", category="object")) self.assertEqual(u"testaliasedstring3", self.char1.nicks.get("testalias", category="object"))
def test_get_and_drop(self): def test_get_and_drop(self):
@ -176,50 +176,50 @@ class TestAdmin(CommandTest):
self.call(admin.CmdPerm(), "Char2 = Builder", "Permission 'Builder' given to Char2 (the Object/Character).") self.call(admin.CmdPerm(), "Char2 = Builder", "Permission 'Builder' given to Char2 (the Object/Character).")
def test_wall(self): def test_wall(self):
self.call(admin.CmdWall(), "Test", "Announcing to all connected players ...") self.call(admin.CmdWall(), "Test", "Announcing to all connected accounts ...")
def test_ban(self): def test_ban(self):
self.call(admin.CmdBan(), "Char", "NameBan char was added.") self.call(admin.CmdBan(), "Char", "NameBan char was added.")
class TestPlayer(CommandTest): class TestAccount(CommandTest):
def test_ooc_look(self): def test_ooc_look(self):
if settings.MULTISESSION_MODE < 2: if settings.MULTISESSION_MODE < 2:
self.call(player.CmdOOCLook(), "", "You are outofcharacter (OOC).", caller=self.player) self.call(account.CmdOOCLook(), "", "You are outofcharacter (OOC).", caller=self.account)
if settings.MULTISESSION_MODE == 2: if settings.MULTISESSION_MODE == 2:
self.call(player.CmdOOCLook(), "", "Account TestPlayer (you are OutofCharacter)", caller=self.player) self.call(account.CmdOOCLook(), "", "Account TestAccount (you are OutofCharacter)", caller=self.account)
def test_ooc(self): def test_ooc(self):
self.call(player.CmdOOC(), "", "You go OOC.", caller=self.player) self.call(account.CmdOOC(), "", "You go OOC.", caller=self.account)
def test_ic(self): def test_ic(self):
self.player.unpuppet_object(self.session) self.account.unpuppet_object(self.session)
self.call(player.CmdIC(), "Char", "You become Char.", caller=self.player, receiver=self.char1) self.call(account.CmdIC(), "Char", "You become Char.", caller=self.account, receiver=self.char1)
def test_password(self): def test_password(self):
self.call(player.CmdPassword(), "testpassword = testpassword", "Password changed.", caller=self.player) self.call(account.CmdPassword(), "testpassword = testpassword", "Password changed.", caller=self.account)
def test_option(self): def test_option(self):
self.call(player.CmdOption(), "", "Client settings", caller=self.player) self.call(account.CmdOption(), "", "Client settings", caller=self.account)
def test_who(self): def test_who(self):
self.call(player.CmdWho(), "", "Players:", caller=self.player) self.call(account.CmdWho(), "", "Accounts:", caller=self.account)
def test_quit(self): def test_quit(self):
self.call(player.CmdQuit(), "", "Quitting. Hope to see you again, soon.", caller=self.player) self.call(account.CmdQuit(), "", "Quitting. Hope to see you again, soon.", caller=self.account)
def test_sessions(self): def test_sessions(self):
self.call(player.CmdSessions(), "", "Your current session(s):", caller=self.player) self.call(account.CmdSessions(), "", "Your current session(s):", caller=self.account)
def test_color_test(self): def test_color_test(self):
self.call(player.CmdColorTest(), "ansi", "ANSI colors:", caller=self.player) self.call(account.CmdColorTest(), "ansi", "ANSI colors:", caller=self.account)
def test_char_create(self): def test_char_create(self):
self.call(player.CmdCharCreate(), "Test1=Test char", "Created new character Test1. Use @ic Test1 to enter the game", caller=self.player) self.call(account.CmdCharCreate(), "Test1=Test char", "Created new character Test1. Use @ic Test1 to enter the game", caller=self.account)
def test_quell(self): def test_quell(self):
self.call(player.CmdQuell(), "", "Quelling to current puppet's permissions (developer).", caller=self.player) self.call(account.CmdQuell(), "", "Quelling to current puppet's permissions (developer).", caller=self.account)
class TestBuilding(CommandTest): class TestBuilding(CommandTest):
@ -290,39 +290,39 @@ class TestComms(CommandTest):
def setUp(self): def setUp(self):
super(CommandTest, self).setUp() super(CommandTest, self).setUp()
self.call(comms.CmdChannelCreate(), "testchan;test=Test Channel", "Created channel testchan and connected to it.", receiver=self.player) self.call(comms.CmdChannelCreate(), "testchan;test=Test Channel", "Created channel testchan and connected to it.", receiver=self.account)
def test_toggle_com(self): def test_toggle_com(self):
self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.player) self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.account)
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.player) self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.account)
def test_channels(self): def test_channels(self):
self.call(comms.CmdChannels(), "" ,"Available channels (use comlist,addcom and delcom to manage", receiver=self.player) self.call(comms.CmdChannels(), "" ,"Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
def test_all_com(self): def test_all_com(self):
self.call(comms.CmdAllCom(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.player) self.call(comms.CmdAllCom(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
def test_clock(self): def test_clock(self):
self.call(comms.CmdClock(), "testchan=send:all()", "Lock(s) applied. Current locks on testchan:", receiver=self.player) self.call(comms.CmdClock(), "testchan=send:all()", "Lock(s) applied. Current locks on testchan:", receiver=self.account)
def test_cdesc(self): def test_cdesc(self):
self.call(comms.CmdCdesc(), "testchan = Test Channel", "Description of channel 'testchan' set to 'Test Channel'.", receiver=self.player) self.call(comms.CmdCdesc(), "testchan = Test Channel", "Description of channel 'testchan' set to 'Test Channel'.", receiver=self.account)
def test_cemit(self): def test_cemit(self):
self.call(comms.CmdCemit(), "testchan = Test Message", "[testchan] Test Message|Sent to channel testchan: Test Message", receiver=self.player) self.call(comms.CmdCemit(), "testchan = Test Message", "[testchan] Test Message|Sent to channel testchan: Test Message", receiver=self.account)
def test_cwho(self): def test_cwho(self):
self.call(comms.CmdCWho(), "testchan", "Channel subscriptions\ntestchan:\n TestPlayer", receiver=self.player) self.call(comms.CmdCWho(), "testchan", "Channel subscriptions\ntestchan:\n TestAccount", receiver=self.account)
def test_page(self): def test_page(self):
self.call(comms.CmdPage(), "TestPlayer2 = Test", "TestPlayer2 is offline. They will see your message if they list their pages later.|You paged TestPlayer2 with: 'Test'.", receiver=self.player) self.call(comms.CmdPage(), "TestAccount2 = Test", "TestAccount2 is offline. They will see your message if they list their pages later.|You paged TestAccount2 with: 'Test'.", receiver=self.account)
def test_cboot(self): def test_cboot(self):
# No one else connected to boot # No one else connected to boot
self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <player> [:reason]", receiver=self.player) self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <account> [:reason]", receiver=self.account)
def test_cdestroy(self): def test_cdestroy(self):
self.call(comms.CmdCdestroy(), "testchan" ,"[testchan] TestPlayer: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.player) self.call(comms.CmdCdestroy(), "testchan" ,"[testchan] TestAccount: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.account)
class TestBatchProcess(CommandTest): class TestBatchProcess(CommandTest):

View file

@ -7,7 +7,7 @@ from collections import defaultdict
from random import getrandbits from random import getrandbits
from django.conf import settings from django.conf import settings
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.server.models import ServerConfig from evennia.server.models import ServerConfig
from evennia.comms.models import ChannelDB from evennia.comms.models import ChannelDB
@ -25,7 +25,7 @@ MULTISESSION_MODE = settings.MULTISESSION_MODE
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
# Helper function to throttle failed connection attempts. # Helper function to throttle failed connection attempts.
# This can easily be used to limit player creation too, # This can easily be used to limit account creation too,
# (just supply a different storage dictionary), but this # (just supply a different storage dictionary), but this
# would also block dummyrunner, so it's not added as default. # would also block dummyrunner, so it's not added as default.
@ -77,17 +77,17 @@ def _throttle(session, maxlim=None, timeout=None, storage=_LATEST_FAILED_LOGINS)
return False return False
def create_guest_player(session): def create_guest_account(session):
""" """
Creates a guest player/character for this session, if one is available. Creates a guest account/character for this session, if one is available.
Args: Args:
session (Session): the session which will use the guest player/character. session (Session): the session which will use the guest account/character.
Returns: Returns:
GUEST_ENABLED (boolean), player (Player): GUEST_ENABLED (boolean), account (Account):
the boolean is whether guest accounts are enabled at all. the boolean is whether guest accounts are enabled at all.
the Player which was created from an available guest name. the Account which was created from an available guest name.
""" """
# check if guests are enabled. # check if guests are enabled.
if not settings.GUEST_ENABLED: if not settings.GUEST_ENABLED:
@ -105,25 +105,25 @@ def create_guest_player(session):
try: try:
# Find an available guest name. # Find an available guest name.
playername = None accountname = None
for name in settings.GUEST_LIST: for name in settings.GUEST_LIST:
if not PlayerDB.objects.filter(username__iexact=playername).count(): if not AccountDB.objects.filter(username__iexact=accountname).count():
playername = name accountname = name
break break
if not playername: if not accountname:
session.msg("All guest accounts are in use. Please try again later.") session.msg("All guest accounts are in use. Please try again later.")
return True, None return True, None
else: else:
# build a new player with the found guest playername # build a new account with the found guest accountname
password = "%016x" % getrandbits(64) password = "%016x" % getrandbits(64)
home = ObjectDB.objects.get_id(settings.GUEST_HOME) home = ObjectDB.objects.get_id(settings.GUEST_HOME)
permissions = settings.PERMISSION_GUEST_DEFAULT permissions = settings.PERMISSION_GUEST_DEFAULT
typeclass = settings.BASE_CHARACTER_TYPECLASS typeclass = settings.BASE_CHARACTER_TYPECLASS
ptypeclass = settings.BASE_GUEST_TYPECLASS ptypeclass = settings.BASE_GUEST_TYPECLASS
new_player = _create_player(session, playername, password, permissions, ptypeclass) new_account = _create_account(session, accountname, password, permissions, ptypeclass)
if new_player: if new_account:
_create_character(session, new_player, typeclass, home, permissions) _create_character(session, new_account, typeclass, home, permissions)
return True, new_player return True, new_account
except Exception: except Exception:
# We are in the middle between logged in and -not, so we have # We are in the middle between logged in and -not, so we have
@ -134,17 +134,17 @@ def create_guest_player(session):
raise raise
def create_normal_player(session, name, password): def create_normal_account(session, name, password):
""" """
Creates a player with the given name and password. Creates an account with the given name and password.
Args: Args:
session (Session): the session which is requesting to create a player. session (Session): the session which is requesting to create an account.
name (str): the name that the player wants to use for login. name (str): the name that the account wants to use for login.
password (str): the password desired by this player, for login. password (str): the password desired by this account, for login.
Returns: Returns:
player (Player): the player which was created from the name and password. account (Account): the account which was created from the name and password.
""" """
# check for too many login errors too quick. # check for too many login errors too quick.
if _throttle(session, maxlim=5, timeout=5*60): if _throttle(session, maxlim=5, timeout=5*60):
@ -153,22 +153,22 @@ def create_normal_player(session, name, password):
return None return None
# Match account name and check password # Match account name and check password
player = authenticate(username=name, password=password) account = authenticate(username=name, password=password)
if not player: if not account:
# No playername or password match # No accountname or password match
session.msg("Incorrect login information given.") session.msg("Incorrect login information given.")
# this just updates the throttle # this just updates the throttle
_throttle(session) _throttle(session)
# calls player hook for a failed login if possible. # calls account hook for a failed login if possible.
player = PlayerDB.objects.get_player_from_name(name) account = AccountDB.objects.get_account_from_name(name)
if player: if account:
player.at_failed_login(session) account.at_failed_login(session)
return None return None
# Check IP and/or name bans # Check IP and/or name bans
bans = ServerConfig.objects.conf("server_bans") bans = ServerConfig.objects.conf("server_bans")
if bans and (any(tup[0] == player.name.lower() for tup in bans) if bans and (any(tup[0] == account.name.lower() for tup in bans)
or or
any(tup[2].match(session.address) for tup in bans if tup[2])): any(tup[2].match(session.address) for tup in bans if tup[2])):
# this is a banned IP or name! # this is a banned IP or name!
@ -178,7 +178,7 @@ def create_normal_player(session, name, password):
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.") session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
return None return None
return player return account
class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS): class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
@ -186,8 +186,8 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
connect to the game connect to the game
Usage (at login screen): Usage (at login screen):
connect playername password connect accountname password
connect "player name" "pass word" connect "account name" "pass word"
Use the create command to first create an account before logging in. Use the create command to first create an account before logging in.
@ -204,7 +204,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
have a unique position in that their func() receives have a unique position in that their func() receives
a session object instead of a source_object like all a session object instead of a source_object like all
other types of logged-in commands (this is because other types of logged-in commands (this is because
there is no object yet before the player has logged in) there is no object yet before the account has logged in)
""" """
session = self.caller session = self.caller
@ -222,9 +222,9 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
parts = parts[0].split(None, 1) parts = parts[0].split(None, 1)
# Guest login # Guest login
if len(parts) == 1 and parts[0].lower() == "guest": if len(parts) == 1 and parts[0].lower() == "guest":
enabled, new_player = create_guest_player(session) enabled, new_account = create_guest_account(session)
if new_player: if new_account:
session.sessionhandler.login(session, new_player) session.sessionhandler.login(session, new_account)
if enabled: if enabled:
return return
@ -233,20 +233,20 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
return return
name, password = parts name, password = parts
player = create_normal_player(session, name, password) account = create_normal_account(session, name, password)
if player: if account:
session.sessionhandler.login(session, player) session.sessionhandler.login(session, account)
class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS): class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
""" """
create a new player account create a new account account
Usage (at login screen): Usage (at login screen):
create <playername> <password> create <accountname> <password>
create "player name" "pass word" create "account name" "pass word"
This creates a new player account. This creates a new account account.
If you have spaces in your name, enclose it in double quotes. If you have spaces in your name, enclose it in double quotes.
""" """
@ -271,25 +271,25 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
"\nIf <name> or <password> contains spaces, enclose it in double quotes." "\nIf <name> or <password> contains spaces, enclose it in double quotes."
session.msg(string) session.msg(string)
return return
playername, password = parts accountname, password = parts
# sanity checks # sanity checks
if not re.findall(r"^[\w. @+\-']+$", playername) or not (0 < len(playername) <= 30): if not re.findall(r"^[\w. @+\-']+$", accountname) or not (0 < len(accountname) <= 30):
# this echoes the restrictions made by django's auth # this echoes the restrictions made by django's auth
# module (except not allowing spaces, for convenience of # module (except not allowing spaces, for convenience of
# logging in). # logging in).
string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only." string = "\n\r Accountname can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only."
session.msg(string) session.msg(string)
return return
# strip excessive spaces in playername # strip excessive spaces in accountname
playername = re.sub(r"\s+", " ", playername).strip() accountname = re.sub(r"\s+", " ", accountname).strip()
if PlayerDB.objects.filter(username__iexact=playername): if AccountDB.objects.filter(username__iexact=accountname):
# player already exists (we also ignore capitalization here) # account already exists (we also ignore capitalization here)
session.msg("Sorry, there is already a player with the name '%s'." % playername) session.msg("Sorry, there is already an account with the name '%s'." % accountname)
return return
# Reserve playernames found in GUEST_LIST # Reserve accountnames found in GUEST_LIST
if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST): if settings.GUEST_LIST and accountname.lower() in (guest.lower() for guest in settings.GUEST_LIST):
string = "\n\r That name is reserved. Please choose another Playername." string = "\n\r That name is reserved. Please choose another Accountname."
session.msg(string) session.msg(string)
return return
if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)): if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)):
@ -301,7 +301,7 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
# Check IP and/or name bans # Check IP and/or name bans
bans = ServerConfig.objects.conf("server_bans") bans = ServerConfig.objects.conf("server_bans")
if bans and (any(tup[0] == playername.lower() for tup in bans) if bans and (any(tup[0] == accountname.lower() for tup in bans)
or or
any(tup[2].match(session.address) for tup in bans if tup[2])): any(tup[2].match(session.address) for tup in bans if tup[2])):
# this is a banned IP or name! # this is a banned IP or name!
@ -311,22 +311,22 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.") session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
return return
# everything's ok. Create the new player account. # everything's ok. Create the new account account.
try: try:
permissions = settings.PERMISSION_PLAYER_DEFAULT permissions = settings.PERMISSION_ACCOUNT_DEFAULT
typeclass = settings.BASE_CHARACTER_TYPECLASS typeclass = settings.BASE_CHARACTER_TYPECLASS
new_player = _create_player(session, playername, password, permissions) new_account = _create_account(session, accountname, password, permissions)
if new_player: if new_account:
if MULTISESSION_MODE < 2: if MULTISESSION_MODE < 2:
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
_create_character(session, new_player, typeclass, default_home, permissions) _create_character(session, new_account, typeclass, default_home, permissions)
# tell the caller everything went well. # tell the caller everything went well.
string = "A new account '%s' was created. Welcome!" string = "A new account '%s' was created. Welcome!"
if " " in playername: if " " in accountname:
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'." string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
else: else:
string += "\n\nYou can now log with the command 'connect %s <your password>'." string += "\n\nYou can now log with the command 'connect %s <your password>'."
session.msg(string % (playername, playername)) session.msg(string % (accountname, accountname))
except Exception: except Exception:
# We are in the middle between logged in and -not, so we have # We are in the middle between logged in and -not, so we have
@ -344,7 +344,7 @@ class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS):
quit quit
We maintain a different version of the quit command We maintain a different version of the quit command
here for unconnected players for the sake of simplicity. The logged in here for unconnected accounts for the sake of simplicity. The logged in
version is a bit more complicated. version is a bit more complicated.
""" """
key = "quit" key = "quit"
@ -516,50 +516,50 @@ class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
self.session.sessionhandler.session_portal_sync(self.session) self.session.sessionhandler.session_portal_sync(self.session)
def _create_player(session, playername, password, permissions, typeclass=None, email=None): def _create_account(session, accountname, password, permissions, typeclass=None, email=None):
""" """
Helper function, creates a player of the specified typeclass. Helper function, creates an account of the specified typeclass.
""" """
try: try:
new_player = create.create_player(playername, email, password, permissions=permissions, typeclass=typeclass) new_account = create.create_account(accountname, email, password, permissions=permissions, typeclass=typeclass)
except Exception as e: except Exception as e:
session.msg("There was an error creating the Player:\n%s\n If this problem persists, contact an admin." % e) session.msg("There was an error creating the Account:\n%s\n If this problem persists, contact an admin." % e)
logger.log_trace() logger.log_trace()
return False return False
# This needs to be set so the engine knows this player is # This needs to be set so the engine knows this account is
# logging in for the first time. (so it knows to call the right # logging in for the first time. (so it knows to call the right
# hooks during login later) # hooks during login later)
new_player.db.FIRST_LOGIN = True new_account.db.FIRST_LOGIN = True
# join the new player to the public channel # join the new account to the public channel
pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"]) pchannel = ChannelDB.objects.get_channel(settings.DEFAULT_CHANNELS[0]["key"])
if not pchannel or not pchannel.connect(new_player): if not pchannel or not pchannel.connect(new_account):
string = "New player '%s' could not connect to public channel!" % new_player.key string = "New account '%s' could not connect to public channel!" % new_account.key
logger.log_err(string) logger.log_err(string)
return new_player return new_account
def _create_character(session, new_player, typeclass, home, permissions): def _create_character(session, new_account, typeclass, home, permissions):
""" """
Helper function, creates a character based on a player's name. Helper function, creates a character based on an account's name.
This is meant for Guest and MULTISESSION_MODE < 2 situations. This is meant for Guest and MULTISESSION_MODE < 2 situations.
""" """
try: try:
new_character = create.create_object(typeclass, key=new_player.key, home=home, permissions=permissions) new_character = create.create_object(typeclass, key=new_account.key, home=home, permissions=permissions)
# set playable character list # set playable character list
new_player.db._playable_characters.append(new_character) new_account.db._playable_characters.append(new_character)
# allow only the character itself and the player to puppet this character (and Developers). # allow only the character itself and the account to puppet this character (and Developers).
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" % new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
(new_character.id, new_player.id)) (new_character.id, new_account.id))
# If no description is set, set a default description # If no description is set, set a default description
if not new_character.db.desc: if not new_character.db.desc:
new_character.db.desc = "This is a Player." new_character.db.desc = "This is an Account."
# We need to set this to have @ic auto-connect to this character # We need to set this to have @ic auto-connect to this character
new_player.db._last_puppet = new_character new_account.db._last_puppet = new_character
except Exception as e: except Exception as e:
session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e) session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e)
logger.log_trace() logger.log_trace()

View file

@ -266,15 +266,15 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
deferred.addCallback(_callback) deferred.addCallback(_callback)
return deferred return deferred
def test_from_player(self): def test_from_account(self):
from evennia.commands.default.cmdset_player import PlayerCmdSet from evennia.commands.default.cmdset_account import AccountCmdSet
a = self.cmdset_a a = self.cmdset_a
a.no_channels = True a.no_channels = True
self.set_cmdsets(self.player, a) self.set_cmdsets(self.account, a)
deferred = cmdhandler.get_and_merge_cmdsets(self.player, None, self.player, None, "player", "") deferred = cmdhandler.get_and_merge_cmdsets(self.account, None, self.account, None, "account", "")
# get_and_merge_cmdsets converts to lower-case internally. # get_and_merge_cmdsets converts to lower-case internally.
def _callback(cmdset): def _callback(cmdset):
pcmdset = PlayerCmdSet() pcmdset = AccountCmdSet()
pcmdset.at_cmdset_creation() pcmdset.at_cmdset_creation()
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"] pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"]
self.assertTrue(all(cmd.key in pcmds for cmd in cmdset.commands)) self.assertTrue(all(cmd.key in pcmds for cmd in cmdset.commands))
@ -305,18 +305,18 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
def test_autocmdsets(self): def test_autocmdsets(self):
import evennia import evennia
from evennia.commands.default.cmdset_player import PlayerCmdSet from evennia.commands.default.cmdset_account import AccountCmdSet
from evennia.comms.channelhandler import CHANNEL_HANDLER from evennia.comms.channelhandler import CHANNEL_HANDLER
testchannel = evennia.create_channel("channeltest", locks="listen:all();send:all()") testchannel = evennia.create_channel("channeltest", locks="listen:all();send:all()")
CHANNEL_HANDLER.add(testchannel) CHANNEL_HANDLER.add(testchannel)
CHANNEL_HANDLER.update() CHANNEL_HANDLER.update()
self.assertTrue(testchannel.connect(self.player)) self.assertTrue(testchannel.connect(self.account))
self.assertTrue(testchannel.has_connection(self.player)) self.assertTrue(testchannel.has_connection(self.account))
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
self.set_cmdsets(self.player, a, b, c, d) self.set_cmdsets(self.account, a, b, c, d)
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.player, self.char1, "session", "") deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.account, self.char1, "session", "")
def _callback(cmdset): def _callback(cmdset):
pcmdset = PlayerCmdSet() pcmdset = AccountCmdSet()
pcmdset.at_cmdset_creation() pcmdset.at_cmdset_creation()
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"] + ["out"] pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"] + ["out"]
self.assertTrue(all(cmd.key or hasattr(cmd, "is_channel") in pcmds for cmd in cmdset.commands)) self.assertTrue(all(cmd.key or hasattr(cmd, "is_channel") in pcmds for cmd in cmdset.commands))

View file

@ -111,7 +111,7 @@ class ChannelCommand(command.Command):
self.msg(string % channelkey) self.msg(string % channelkey)
return return
if msg == "on": if msg == "on":
caller = caller if not hasattr(caller, 'player') else caller.player caller = caller if not hasattr(caller, 'account') else caller.account
unmuted = channel.unmute(caller) unmuted = channel.unmute(caller)
if unmuted: if unmuted:
self.msg("You start listening to %s." % channel) self.msg("You start listening to %s." % channel)
@ -119,7 +119,7 @@ class ChannelCommand(command.Command):
self.msg("You were already listening to %s." % channel) self.msg("You were already listening to %s." % channel)
return return
if msg == "off": if msg == "off":
caller = caller if not hasattr(caller, 'player') else caller.player caller = caller if not hasattr(caller, 'account') else caller.account
muted = channel.mute(caller) muted = channel.mute(caller)
if muted: if muted:
self.msg("You stop listening to %s." % channel) self.msg("You stop listening to %s." % channel)
@ -133,7 +133,7 @@ class ChannelCommand(command.Command):
if "[-]" in line else line for line in lines)) if "[-]" in line else line for line in lines))
tail_log_file(log_file, self.history_start, 20, callback=send_msg) tail_log_file(log_file, self.history_start, 20, callback=send_msg)
else: else:
caller = caller if not hasattr(caller, 'player') else caller.player caller = caller if not hasattr(caller, 'account') else caller.account
if caller in channel.mutelist: if caller in channel.mutelist:
self.msg("You currently have %s muted." % channel) self.msg("You currently have %s muted." % channel)
return return
@ -144,7 +144,7 @@ class ChannelCommand(command.Command):
Let users know that this command is for communicating on a channel. Let users know that this command is for communicating on a channel.
Args: Args:
caller (TypedObject): A Character or Player who has entered an ambiguous command. caller (TypedObject): A Character or Account who has entered an ambiguous command.
Returns: Returns:
A string with identifying information to disambiguate the object, conventionally with a preceding space. A string with identifying information to disambiguate the object, conventionally with a preceding space.

View file

@ -62,26 +62,26 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
def has_connection(self, subscriber): def has_connection(self, subscriber):
""" """
Checks so this player is actually listening Checks so this account is actually listening
to this channel. to this channel.
Args: Args:
subscriber (Player or Object): Entity to check. subscriber (Account or Object): Entity to check.
Returns: Returns:
has_sub (bool): Whether the subscriber is subscribing to has_sub (bool): Whether the subscriber is subscribing to
this channel or not. this channel or not.
Notes: Notes:
This will first try Player subscribers and only try Object This will first try Account subscribers and only try Object
if the Player fails. if the Account fails.
""" """
has_sub = self.subscriptions.has(subscriber) has_sub = self.subscriptions.has(subscriber)
if not has_sub and hasattr(subscriber, "player"): if not has_sub and hasattr(subscriber, "account"):
# it's common to send an Object when we # it's common to send an Object when we
# by default only allow Players to subscribe. # by default only allow Accounts to subscribe.
has_sub = self.subscriptions.has(subscriber.player) has_sub = self.subscriptions.has(subscriber.account)
return has_sub return has_sub
@property @property
@ -94,7 +94,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
listening = [ob for ob in subs if ob.is_connected and ob not in self.mutelist] listening = [ob for ob in subs if ob.is_connected and ob not in self.mutelist]
if subs: if subs:
# display listening subscribers in bold # display listening subscribers in bold
string = ", ".join([player.key if player not in listening else "|w%s|n" % player.key for player in subs]) string = ", ".join([account.key if account not in listening else "|w%s|n" % account.key for account in subs])
else: else:
string = "<None>" string = "<None>"
return string return string
@ -106,7 +106,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
but may use channel commands. but may use channel commands.
Args: Args:
subscriber (Object or Player): Subscriber to mute. subscriber (Object or Account): Subscriber to mute.
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
@ -124,7 +124,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
but may use channel commands. but may use channel commands.
Args: Args:
subscriber (Object or Player): The subscriber to unmute. subscriber (Object or Account): The subscriber to unmute.
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
@ -141,7 +141,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
Connect the user to this channel. This checks access. Connect the user to this channel. This checks access.
Args: Args:
subscriber (Player or Object): the entity to subscribe subscriber (Account or Object): the entity to subscribe
to this channel. to this channel.
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
@ -171,7 +171,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
Disconnect entity from this channel. Disconnect entity from this channel.
Args: Args:
subscriber (Player of Object): the subscriber (Account of Object): the
entity to disconnect. entity to disconnect.
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
@ -265,7 +265,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
This is also where logging happens, if enabled. This is also where logging happens, if enabled.
""" """
# get all players or objects connected to this channel and send to them # get all accounts or objects connected to this channel and send to them
if online: if online:
subs = self.subscriptions.online() subs = self.subscriptions.online()
else: else:
@ -276,7 +276,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
continue continue
try: try:
# note our addition of the from_channel keyword here. This could be checked # note our addition of the from_channel keyword here. This could be checked
# by a custom player.msg() to treat channel-receives differently. # by a custom account.msg() to treat channel-receives differently.
entity.msg(msgobj.message, from_obj=msgobj.senders, options={"from_channel": self.id}) entity.msg(msgobj.message, from_obj=msgobj.senders, options={"from_channel": self.id})
except AttributeError as e: except AttributeError as e:
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity)) logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
@ -288,7 +288,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
def msg(self, msgobj, header=None, senders=None, sender_strings=None, def msg(self, msgobj, header=None, senders=None, sender_strings=None,
keep_log=None, online=False, emit=False, external=False): keep_log=None, online=False, emit=False, external=False):
""" """
Send the given message to all players connected to channel. Note that Send the given message to all accounts connected to channel. Note that
no permission-checking is done here; it is assumed to have been no permission-checking is done here; it is assumed to have been
done before calling this method. The optional keywords are not used if done before calling this method. The optional keywords are not used if
persistent is False. persistent is False.
@ -300,10 +300,10 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
(if persistent=False) or it will be used together with `header` (if persistent=False) or it will be used together with `header`
and `senders` keywords to create a Msg instance on the fly. and `senders` keywords to create a Msg instance on the fly.
header (str, optional): A header for building the message. header (str, optional): A header for building the message.
senders (Object, Player or list, optional): Optional if persistent=False, used senders (Object, Account or list, optional): Optional if persistent=False, used
to build senders for the message. to build senders for the message.
sender_strings (list, optional): Name strings of senders. Used for external sender_strings (list, optional): Name strings of senders. Used for external
connections where the sender is not a player or object. connections where the sender is not an account or object.
When this is defined, external will be assumed. When this is defined, external will be assumed.
keep_log (bool or None, optional): This allows to temporarily change the logging status of keep_log (bool or None, optional): This allows to temporarily change the logging status of
this channel message. If `None`, the Channel's `keep_log` Attribute will this channel message. If `None`, the Channel's `keep_log` Attribute will
@ -311,8 +311,8 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
message only (note that for unlogged channels, a `True` value here will message only (note that for unlogged channels, a `True` value here will
create a new log file only for this message). create a new log file only for this message).
online (bool, optional) - If this is set true, only messages people who are online (bool, optional) - If this is set true, only messages people who are
online. Otherwise, messages all players connected. This can online. Otherwise, messages all accounts connected. This can
make things faster, but may not trigger listeners on players make things faster, but may not trigger listeners on accounts
that are offline. that are offline.
emit (bool, optional) - Signals to the message formatter that this message is emit (bool, optional) - Signals to the message formatter that this message is
not to be directly associated with a name. not to be directly associated with a name.
@ -389,7 +389,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
Notes: Notes:
This function exists separately so that external sources This function exists separately so that external sources
can use it to format source names in the same manner as can use it to format source names in the same manner as
normal object/player names. normal object/account names.
""" """
if not senders: if not senders:
@ -432,7 +432,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
""" """
Hook method. Used for formatting external messages. This is Hook method. Used for formatting external messages. This is
needed as a separate operation because the senders of external needed as a separate operation because the senders of external
messages may not be in-game objects/players, and so cannot messages may not be in-game objects/accounts, and so cannot
have things like custom user preferences. have things like custom user preferences.
Args: Args:
@ -495,7 +495,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
def post_join_channel(self, joiner, **kwargs): def post_join_channel(self, joiner, **kwargs):
""" """
Hook method. Runs right after an object or player joins a channel. Hook method. Runs right after an object or account joins a channel.
Args: Args:
joiner (object): The joining object. joiner (object): The joining object.
@ -523,7 +523,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
def post_leave_channel(self, leaver, **kwargs): def post_leave_channel(self, leaver, **kwargs):
""" """
Hook method. Runs right after an object or player leaves a channel. Hook method. Runs right after an object or account leaves a channel.
Args: Args:
leaver (object): The leaving object. leaver (object): The leaving object.

View file

@ -10,7 +10,7 @@ from evennia.typeclasses.managers import (TypedObjectManager, TypeclassManager)
from evennia.utils import logger from evennia.utils import logger
_GA = object.__getattribute__ _GA = object.__getattribute__
_PlayerDB = None _AccountDB = None
_ObjectDB = None _ObjectDB = None
_ChannelDB = None _ChannelDB = None
_SESSIONS = None _SESSIONS = None
@ -57,7 +57,7 @@ def dbref(inp, reqhash=True):
def identify_object(inp): def identify_object(inp):
""" """
Helper function. Identifies if an object is a player or an object; Helper function. Identifies if an object is an account or an object;
return its database model return its database model
Args: Args:
@ -65,14 +65,14 @@ def identify_object(inp):
Returns: Returns:
identified (tuple): This is a tuple with (`inp`, identifier) identified (tuple): This is a tuple with (`inp`, identifier)
where `identifier` is one of "player", "object", "channel", where `identifier` is one of "account", "object", "channel",
"string", "dbref" or None. "string", "dbref" or None.
""" """
if hasattr(inp, "__dbclass__"): if hasattr(inp, "__dbclass__"):
clsname = inp.__dbclass__.__name__ clsname = inp.__dbclass__.__name__
if clsname == "PlayerDB": if clsname == "AccountDB":
return inp, "player" return inp, "account"
elif clsname == "ObjectDB": elif clsname == "ObjectDB":
return inp ,"object" return inp ,"object"
elif clsname == "ChannelDB": elif clsname == "ChannelDB":
@ -85,14 +85,14 @@ def identify_object(inp):
return inp, None return inp, None
def to_object(inp, objtype='player'): def to_object(inp, objtype='account'):
""" """
Locates the object related to the given playername or channel key. Locates the object related to the given accountname or channel key.
If input was already the correct object, return it. If input was already the correct object, return it.
Args: Args:
inp (any): The input object/string inp (any): The input object/string
objtype (str): Either 'player' or 'channel'. objtype (str): Either 'account' or 'channel'.
Returns: Returns:
obj (object): The correct object related to `inp`. obj (object): The correct object related to `inp`.
@ -101,17 +101,17 @@ def to_object(inp, objtype='player'):
obj, typ = identify_object(inp) obj, typ = identify_object(inp)
if typ == objtype: if typ == objtype:
return obj return obj
if objtype == 'player': if objtype == 'account':
if typ == 'object': if typ == 'object':
return obj.player return obj.account
if typ == 'string': if typ == 'string':
return _PlayerDB.objects.get(user_username__iexact=obj) return _AccountDB.objects.get(user_username__iexact=obj)
if typ == 'dbref': if typ == 'dbref':
return _PlayerDB.objects.get(id=obj) return _AccountDB.objects.get(id=obj)
logger.log_err("%s %s %s %s %s", objtype, inp, obj, typ, type(inp)) logger.log_err("%s %s %s %s %s", objtype, inp, obj, typ, type(inp))
raise CommError() raise CommError()
elif objtype == 'object': elif objtype == 'object':
if typ == 'player': if typ == 'account':
return obj.obj return obj.obj
if typ == 'string': if typ == 'string':
return _ObjectDB.objects.get(db_key__iexact=obj) return _ObjectDB.objects.get(db_key__iexact=obj)
@ -158,7 +158,7 @@ class MsgManager(TypedObjectManager):
Returns: Returns:
identified (tuple): This is a tuple with (`inp`, identifier) identified (tuple): This is a tuple with (`inp`, identifier)
where `identifier` is one of "player", "object", "channel", where `identifier` is one of "account", "object", "channel",
"string", "dbref" or None. "string", "dbref" or None.
""" """
@ -183,10 +183,10 @@ class MsgManager(TypedObjectManager):
def get_messages_by_sender(self, sender, exclude_channel_messages=False): def get_messages_by_sender(self, sender, exclude_channel_messages=False):
""" """
Get all messages sent by one entity - this could be either a Get all messages sent by one entity - this could be either a
player or an object account or an object
Args: Args:
sender (Player or Object): The sender of the message. sender (Account or Object): The sender of the message.
exclude_channel_messages (bool, optional): Only return messages exclude_channel_messages (bool, optional): Only return messages
not aimed at a channel (that is, private tells for example) not aimed at a channel (that is, private tells for example)
@ -200,9 +200,9 @@ class MsgManager(TypedObjectManager):
obj, typ = identify_object(sender) obj, typ = identify_object(sender)
if exclude_channel_messages: if exclude_channel_messages:
# explicitly exclude channel recipients # explicitly exclude channel recipients
if typ == 'player': if typ == 'account':
return list(self.filter(db_sender_players=obj, return list(self.filter(db_sender_accounts=obj,
db_receivers_channels__isnull=True).exclude(db_hide_from_players=obj)) db_receivers_channels__isnull=True).exclude(db_hide_from_accounts=obj))
elif typ == 'object': elif typ == 'object':
return list(self.filter(db_sender_objects=obj, return list(self.filter(db_sender_objects=obj,
db_receivers_channels__isnull=True).exclude(db_hide_from_objects=obj)) db_receivers_channels__isnull=True).exclude(db_hide_from_objects=obj))
@ -210,8 +210,8 @@ class MsgManager(TypedObjectManager):
raise CommError raise CommError
else: else:
# get everything, channel or not # get everything, channel or not
if typ == 'player': if typ == 'account':
return list(self.filter(db_sender_players=obj).exclude(db_hide_from_players=obj)) return list(self.filter(db_sender_accounts=obj).exclude(db_hide_from_accounts=obj))
elif typ == 'object': elif typ == 'object':
return list(self.filter(db_sender_objects=obj).exclude(db_hide_from_objects=obj)) return list(self.filter(db_sender_objects=obj).exclude(db_hide_from_objects=obj))
else: else:
@ -222,7 +222,7 @@ class MsgManager(TypedObjectManager):
Get all messages sent to one given recipient. Get all messages sent to one given recipient.
Args: Args:
recipient (Object, Player or Channel): The recipient of the messages to search for. recipient (Object, Account or Channel): The recipient of the messages to search for.
Returns: Returns:
messages (list): Matching messages. messages (list): Matching messages.
@ -232,8 +232,8 @@ class MsgManager(TypedObjectManager):
""" """
obj, typ = identify_object(recipient) obj, typ = identify_object(recipient)
if typ == 'player': if typ == 'account':
return list(self.filter(db_receivers_players=obj).exclude(db_hide_from_players=obj)) return list(self.filter(db_receivers_accounts=obj).exclude(db_hide_from_accounts=obj))
elif typ == 'object': elif typ == 'object':
return list(self.filter(db_receivers_objects=obj).exclude(db_hide_from_objects=obj)) return list(self.filter(db_receivers_objects=obj).exclude(db_hide_from_objects=obj))
elif typ == 'channel': elif typ == 'channel':
@ -260,9 +260,9 @@ class MsgManager(TypedObjectManager):
one of the arguments must be given to do a search. one of the arguments must be given to do a search.
Args: Args:
sender (Object or Player, optional): Get messages sent by a particular player or object sender (Object or Account, optional): Get messages sent by a particular account or object
receiver (Object, Player or Channel, optional): Get messages receiver (Object, Account or Channel, optional): Get messages
received by a certain player,object or channel received by a certain account,object or channel
freetext (str): Search for a text string in a message. NOTE: freetext (str): Search for a text string in a message. NOTE:
This can potentially be slow, so make sure to supply one of This can potentially be slow, so make sure to supply one of
the other arguments to limit the search. the other arguments to limit the search.
@ -287,16 +287,16 @@ class MsgManager(TypedObjectManager):
# filter by sender # filter by sender
sender, styp = identify_object(sender) sender, styp = identify_object(sender)
if styp == 'player': if styp == 'account':
sender_restrict = Q(db_sender_players=sender) & ~Q(db_hide_from_players=sender) sender_restrict = Q(db_sender_accounts=sender) & ~Q(db_hide_from_accounts=sender)
elif styp == 'object': elif styp == 'object':
sender_restrict = Q(db_sender_objects=sender) & ~Q(db_hide_from_objects=sender) sender_restrict = Q(db_sender_objects=sender) & ~Q(db_hide_from_objects=sender)
else: else:
sender_restrict = Q() sender_restrict = Q()
# filter by receiver # filter by receiver
receiver, rtyp = identify_object(receiver) receiver, rtyp = identify_object(receiver)
if rtyp == 'player': if rtyp == 'account':
receiver_restrict = Q(db_receivers_players=receiver) & ~Q(db_hide_from_players=receiver) receiver_restrict = Q(db_receivers_accounts=receiver) & ~Q(db_hide_from_accounts=receiver)
elif rtyp == 'object': elif rtyp == 'object':
receiver_restrict = Q(db_receivers_objects=receiver) & ~Q(db_hide_from_objects=receiver) receiver_restrict = Q(db_receivers_objects=receiver) & ~Q(db_hide_from_objects=receiver)
elif rtyp == 'channel': elif rtyp == 'channel':
@ -369,14 +369,14 @@ class ChannelDBManager(TypedObjectManager):
Return all channels a given entity is subscribed to. Return all channels a given entity is subscribed to.
Args: Args:
subscriber (Object or Player): The one subscribing. subscriber (Object or Account): The one subscribing.
Returns: Returns:
subscriptions (list): Channel subscribed to. subscriptions (list): Channel subscribed to.
""" """
clsname = subscriber.__dbclass__.__name__ clsname = subscriber.__dbclass__.__name__
if clsname == "PlayerDB": if clsname == "AccountDB":
return subscriber.subscription_set.all() return subscriber.subscription_set.all()
if clsname == "ObjectDB": if clsname == "ObjectDB":
return subscriber.object_subscription_set.all() return subscriber.object_subscription_set.all()

View file

@ -13,7 +13,7 @@ For non-persistent (and slightly faster) use one can also use the
TempMsg, which mimics the Msg API but without actually saving to the TempMsg, which mimics the Msg API but without actually saving to the
database. database.
Channels are central objects that act as targets for Msgs. Players can Channels are central objects that act as targets for Msgs. Accounts can
connect to channels by use of a ChannelConnect object (this object is connect to channels by use of a ChannelConnect object (this object is
necessary to easily be able to delete connections on the fly). necessary to easily be able to delete connections on the fly).
""" """
@ -48,16 +48,16 @@ _CHANNELHANDLER = None
class Msg(SharedMemoryModel): class Msg(SharedMemoryModel):
""" """
A single message. This model describes all ooc messages A single message. This model describes all ooc messages
sent in-game, both to channels and between players. sent in-game, both to channels and between accounts.
The Msg class defines the following database fields (all The Msg class defines the following database fields (all
accessed via specific handler methods): accessed via specific handler methods):
- db_sender_players: Player senders - db_sender_accounts: Account senders
- db_sender_objects: Object senders - db_sender_objects: Object senders
- db_sender_scripts: Script senders - db_sender_scripts: Script senders
- db_sender_external: External senders (defined as string names) - db_sender_external: External senders (defined as string names)
- db_receivers_players: Receiving players - db_receivers_accounts: Receiving accounts
- db_receivers_objects: Receiving objects - db_receivers_objects: Receiving objects
- db_receivers_scripts: Receiveing scripts - db_receivers_scripts: Receiveing scripts
- db_receivers_channels: Receiving channels - db_receivers_channels: Receiving channels
@ -77,7 +77,7 @@ class Msg(SharedMemoryModel):
# These databse fields are all set using their corresponding properties, # These databse fields are all set using their corresponding properties,
# named same as the field, but withtout the db_* prefix. # named same as the field, but withtout the db_* prefix.
# Sender is either a player, an object or an external sender, like # Sender is either an account, an object or an external sender, like
# an IRC channel; normally there is only one, but if co-modification of # an IRC channel; normally there is only one, but if co-modification of
# a message is allowed, there may be more than one "author" # a message is allowed, there may be more than one "author"
db_sender_accounts = models.ManyToManyField("accounts.AccountDB", related_name='sender_account_set', db_sender_accounts = models.ManyToManyField("accounts.AccountDB", related_name='sender_account_set',
@ -114,8 +114,8 @@ class Msg(SharedMemoryModel):
db_lock_storage = models.TextField('locks', blank=True, db_lock_storage = models.TextField('locks', blank=True,
help_text='access locks on this message.') help_text='access locks on this message.')
# these can be used to filter/hide a given message from supplied objects/players/channels # these can be used to filter/hide a given message from supplied objects/accounts/channels
db_hide_from_players = models.ManyToManyField("players.PlayerDB", related_name='hide_from_players_set', blank=True) db_hide_from_accounts = models.ManyToManyField("accounts.AccountDB", related_name='hide_from_accounts_set', blank=True)
db_hide_from_accounts = models.ManyToManyField("accounts.AccountDB", related_name='hide_from_accounts_set', blank=True) db_hide_from_accounts = models.ManyToManyField("accounts.AccountDB", related_name='hide_from_accounts_set', blank=True)
db_hide_from_objects = models.ManyToManyField("objects.ObjectDB", related_name='hide_from_objects_set', blank=True) db_hide_from_objects = models.ManyToManyField("objects.ObjectDB", related_name='hide_from_objects_set', blank=True)
@ -156,7 +156,7 @@ class Msg(SharedMemoryModel):
#@property #@property
def __senders_get(self): def __senders_get(self):
"Getter. Allows for value = self.sender" "Getter. Allows for value = self.sender"
return list(self.db_sender_players.all()) + \ return list(self.db_sender_accounts.all()) + \
list(self.db_sender_objects.all()) + \ list(self.db_sender_objects.all()) + \
list(self.db_sender_scripts.all()) + \ list(self.db_sender_scripts.all()) + \
self.extra_senders self.extra_senders
@ -177,15 +177,15 @@ class Msg(SharedMemoryModel):
clsname = sender.__dbclass__.__name__ clsname = sender.__dbclass__.__name__
if clsname == "ObjectDB": if clsname == "ObjectDB":
self.db_sender_objects.add(sender) self.db_sender_objects.add(sender)
elif clsname == "PlayerDB": elif clsname == "AccountDB":
self.db_sender_players.add(sender) self.db_sender_accounts.add(sender)
elif clsname == "ScriptDB": elif clsname == "ScriptDB":
self.db_sender_scripts.add(sender) self.db_sender_scripts.add(sender)
#@sender.deleter #@sender.deleter
def __senders_del(self): def __senders_del(self):
"Deleter. Clears all senders" "Deleter. Clears all senders"
self.db_sender_players.clear() self.db_sender_accounts.clear()
self.db_sender_objects.clear() self.db_sender_objects.clear()
self.db_sender_scripts.clear() self.db_sender_scripts.clear()
self.db_sender_external = "" self.db_sender_external = ""
@ -198,7 +198,7 @@ class Msg(SharedMemoryModel):
Remove a single sender or a list of senders. Remove a single sender or a list of senders.
Args: Args:
senders (Player, Object, str or list): Senders to remove. senders (Account, Object, str or list): Senders to remove.
""" """
for sender in make_iter(senders): for sender in make_iter(senders):
@ -212,19 +212,19 @@ class Msg(SharedMemoryModel):
clsname = sender.__dbclass__.__name__ clsname = sender.__dbclass__.__name__
if clsname == "ObjectDB": if clsname == "ObjectDB":
self.db_sender_objects.remove(sender) self.db_sender_objects.remove(sender)
elif clsname == "PlayerDB": elif clsname == "AccountDB":
self.db_sender_players.remove(sender) self.db_sender_accounts.remove(sender)
elif clsname == "ScriptDB": elif clsname == "ScriptDB":
self.db_sender_players.remove(sender) self.db_sender_accounts.remove(sender)
# receivers property # receivers property
#@property #@property
def __receivers_get(self): def __receivers_get(self):
""" """
Getter. Allows for value = self.receivers. Getter. Allows for value = self.receivers.
Returns four lists of receivers: players, objects, scripts and channels. Returns four lists of receivers: accounts, objects, scripts and channels.
""" """
return list(self.db_receivers_players.all()) + \ return list(self.db_receivers_accounts.all()) + \
list(self.db_receivers_objects.all()) + \ list(self.db_receivers_objects.all()) + \
list(self.db_receivers_scripts.all()) + \ list(self.db_receivers_scripts.all()) + \
list(self.db_receivers_channels.all()) list(self.db_receivers_channels.all())
@ -243,8 +243,8 @@ class Msg(SharedMemoryModel):
clsname = receiver.__dbclass__.__name__ clsname = receiver.__dbclass__.__name__
if clsname == "ObjectDB": if clsname == "ObjectDB":
self.db_receivers_objects.add(receiver) self.db_receivers_objects.add(receiver)
elif clsname == "PlayerDB": elif clsname == "AccountDB":
self.db_receivers_players.add(receiver) self.db_receivers_accounts.add(receiver)
elif clsname == "ScriptDB": elif clsname == "ScriptDB":
self.db_receivers_scripts.add(receiver) self.db_receivers_scripts.add(receiver)
elif clsname == "ChannelDB": elif clsname == "ChannelDB":
@ -254,7 +254,7 @@ class Msg(SharedMemoryModel):
#@receivers.deleter #@receivers.deleter
def __receivers_del(self): def __receivers_del(self):
"Deleter. Clears all receivers" "Deleter. Clears all receivers"
self.db_receivers_players.clear() self.db_receivers_accounts.clear()
self.db_receivers_objects.clear() self.db_receivers_objects.clear()
self.db_receivers_scripts.clear() self.db_receivers_scripts.clear()
self.db_receivers_channels.clear() self.db_receivers_channels.clear()
@ -266,7 +266,7 @@ class Msg(SharedMemoryModel):
Remove a single receiver or a list of receivers. Remove a single receiver or a list of receivers.
Args: Args:
receivers (Player, Object, Script, Channel or list): Receiver to remove. receivers (Account, Object, Script, Channel or list): Receiver to remove.
""" """
for receiver in make_iter(receivers): for receiver in make_iter(receivers):
@ -277,8 +277,8 @@ class Msg(SharedMemoryModel):
clsname = receiver.__dbclass__.__name__ clsname = receiver.__dbclass__.__name__
if clsname == "ObjectDB": if clsname == "ObjectDB":
self.db_receivers_objects.remove(receiver) self.db_receivers_objects.remove(receiver)
elif clsname == "PlayerDB": elif clsname == "AccountDB":
self.db_receivers_players.remove(receiver) self.db_receivers_accounts.remove(receiver)
elif clsname == "ScriptDB": elif clsname == "ScriptDB":
self.db_receivers_scripts.remove(receiver) self.db_receivers_scripts.remove(receiver)
elif clsname == "ChannelDB": elif clsname == "ChannelDB":
@ -309,9 +309,9 @@ class Msg(SharedMemoryModel):
def __hide_from_get(self): def __hide_from_get(self):
""" """
Getter. Allows for value = self.hide_from. Getter. Allows for value = self.hide_from.
Returns 3 lists of players, objects and channels Returns 3 lists of accounts, objects and channels
""" """
return self.db_hide_from_players.all(), self.db_hide_from_objects.all(), self.db_hide_from_channels.all() return self.db_hide_from_accounts.all(), self.db_hide_from_objects.all(), self.db_hide_from_channels.all()
#@hide_from_sender.setter #@hide_from_sender.setter
def __hide_from_set(self, hiders): def __hide_from_set(self, hiders):
@ -322,8 +322,8 @@ class Msg(SharedMemoryModel):
if not hasattr(hider, "__dbclass__"): if not hasattr(hider, "__dbclass__"):
raise ValueError("This is a not a typeclassed object!") raise ValueError("This is a not a typeclassed object!")
clsname = hider.__dbclass__.__name__ clsname = hider.__dbclass__.__name__
if clsname == "PlayerDB": if clsname == "AccountDB":
self.db_hide_from_players.add(hider.__dbclass__) self.db_hide_from_accounts.add(hider.__dbclass__)
elif clsname == "ObjectDB": elif clsname == "ObjectDB":
self.db_hide_from_objects.add(hider.__dbclass__) self.db_hide_from_objects.add(hider.__dbclass__)
elif clsname == "ChannelDB": elif clsname == "ChannelDB":
@ -332,7 +332,7 @@ class Msg(SharedMemoryModel):
#@hide_from_sender.deleter #@hide_from_sender.deleter
def __hide_from_del(self): def __hide_from_del(self):
"Deleter. Allows for del self.hide_from_senders" "Deleter. Allows for del self.hide_from_senders"
self.db_hide_from_players.clear() self.db_hide_from_accounts.clear()
self.db_hide_from_objects.clear() self.db_hide_from_objects.clear()
self.db_hide_from_channels.clear() self.db_hide_from_channels.clear()
self.save() self.save()
@ -353,7 +353,7 @@ class Msg(SharedMemoryModel):
Checks lock access. Checks lock access.
Args: Args:
accessing_obj (Object or Player): The object trying to gain access. accessing_obj (Object or Account): The object trying to gain access.
access_type (str, optional): The type of lock access to check. access_type (str, optional): The type of lock access to check.
default (bool): Fallback to use if `access_type` lock is not defined. default (bool): Fallback to use if `access_type` lock is not defined.
@ -383,13 +383,13 @@ class TempMsg(object):
Args: Args:
senders (any or list, optional): Senders of the message. senders (any or list, optional): Senders of the message.
receivers (Player, Object, Channel or list, optional): Receivers of this message. receivers (Account, Object, Channel or list, optional): Receivers of this message.
channels (Channel or list, optional): Channels to send to. channels (Channel or list, optional): Channels to send to.
message (str, optional): Message to send. message (str, optional): Message to send.
header (str, optional): Header of message. header (str, optional): Header of message.
type (str, optional): Message class, if any. type (str, optional): Message class, if any.
lockstring (str, optional): Lock for the message. lockstring (str, optional): Lock for the message.
hide_from (Player, Object, Channel or list, optional): Entities to hide this message from. hide_from (Account, Object, Channel or list, optional): Entities to hide this message from.
""" """
self.senders = senders and make_iter(senders) or [] self.senders = senders and make_iter(senders) or []
@ -419,7 +419,7 @@ class TempMsg(object):
Remove a sender or a list of senders. Remove a sender or a list of senders.
Args: Args:
sender (Object, Player, str or list): Senders to remove. sender (Object, Account, str or list): Senders to remove.
""" """
for o in make_iter(sender): for o in make_iter(sender):
@ -433,7 +433,7 @@ class TempMsg(object):
Remove a receiver or a list of receivers Remove a receiver or a list of receivers
Args: Args:
receiver (Object, Player, Channel, str or list): Receivers to remove. receiver (Object, Account, Channel, str or list): Receivers to remove.
""" """
for o in make_iter(receiver): for o in make_iter(receiver):
@ -447,7 +447,7 @@ class TempMsg(object):
Checks lock access. Checks lock access.
Args: Args:
accessing_obj (Object or Player): The object trying to gain access. accessing_obj (Object or Account): The object trying to gain access.
access_type (str, optional): The type of lock access to check. access_type (str, optional): The type of lock access to check.
default (bool): Fallback to use if `access_type` lock is not defined. default (bool): Fallback to use if `access_type` lock is not defined.
@ -469,7 +469,7 @@ class SubscriptionHandler(object):
""" """
This handler manages subscriptions to the This handler manages subscriptions to the
channel and hides away which type of entity is channel and hides away which type of entity is
subscribing (Player or Object) subscribing (Account or Object)
""" """
def __init__(self, obj): def __init__(self, obj):
""" """
@ -483,7 +483,7 @@ class SubscriptionHandler(object):
self._cache = None self._cache = None
def _recache(self): def _recache(self):
self._cache = {player : True for player in self.obj.db_subscriptions.all()} self._cache = {account : True for account in self.obj.db_subscriptions.all()}
self._cache.update({obj : True for obj in self.obj.db_object_subscriptions.all()}) self._cache.update({obj : True for obj in self.obj.db_object_subscriptions.all()})
def has(self, entity): def has(self, entity):
@ -491,12 +491,12 @@ class SubscriptionHandler(object):
Check if the given entity subscribe to this channel Check if the given entity subscribe to this channel
Args: Args:
entity (str, Player or Object): The entity to return. If entity (str, Account or Object): The entity to return. If
a string, it assumed to be the key or the #dbref a string, it assumed to be the key or the #dbref
of the entity. of the entity.
Returns: Returns:
subscriber (Player, Object or None): The given subscriber (Account, Object or None): The given
subscriber. subscriber.
""" """
@ -509,7 +509,7 @@ class SubscriptionHandler(object):
Subscribe an entity to this channel. Subscribe an entity to this channel.
Args: Args:
entity (Player, Object or list): The entity or entity (Account, Object or list): The entity or
list of entities to subscribe to this channel. list of entities to subscribe to this channel.
Note: Note:
@ -527,7 +527,7 @@ class SubscriptionHandler(object):
# chooses the right type # chooses the right type
if clsname == "ObjectDB": if clsname == "ObjectDB":
self.obj.db_object_subscriptions.add(subscriber) self.obj.db_object_subscriptions.add(subscriber)
elif clsname == "PlayerDB": elif clsname == "AccountDB":
self.obj.db_subscriptions.add(subscriber) self.obj.db_subscriptions.add(subscriber)
_CHANNELHANDLER.cached_cmdsets.pop(subscriber, None) _CHANNELHANDLER.cached_cmdsets.pop(subscriber, None)
self._recache() self._recache()
@ -537,7 +537,7 @@ class SubscriptionHandler(object):
Remove a subscriber from the channel. Remove a subscriber from the channel.
Args: Args:
entity (Player, Object or list): The entity or entity (Account, Object or list): The entity or
entities to un-subscribe from the channel. entities to un-subscribe from the channel.
""" """
@ -548,7 +548,7 @@ class SubscriptionHandler(object):
if subscriber: if subscriber:
clsname = subscriber.__dbclass__.__name__ clsname = subscriber.__dbclass__.__name__
# chooses the right type # chooses the right type
if clsname == "PlayerDB": if clsname == "AccountDB":
self.obj.db_subscriptions.remove(entity) self.obj.db_subscriptions.remove(entity)
elif clsname == "ObjectDB": elif clsname == "ObjectDB":
self.obj.db_object_subscriptions.remove(entity) self.obj.db_object_subscriptions.remove(entity)
@ -561,7 +561,7 @@ class SubscriptionHandler(object):
Returns: Returns:
subscribers (list): The subscribers. This subscribers (list): The subscribers. This
may be a mix of Players and Objects! may be a mix of Accounts and Objects!
""" """
if self._cache is None: if self._cache is None:
@ -570,17 +570,17 @@ class SubscriptionHandler(object):
def online(self): def online(self):
""" """
Get all online players from our cache Get all online accounts from our cache
Returns: Returns:
subscribers (list): Subscribers who are online or subscribers (list): Subscribers who are online or
are puppeted by an online player. are puppeted by an online account.
""" """
subs = [] subs = []
for obj in self.all(): for obj in self.all():
if hasattr(obj, 'player'): if hasattr(obj, 'account'):
if not obj.player: if not obj.account:
continue continue
obj = obj.player obj = obj.account
if not obj.is_connected: if not obj.is_connected:
continue continue
subs.append(obj) subs.append(obj)
@ -604,7 +604,7 @@ class ChannelDB(TypedObject):
The Channel class defines the following database fields The Channel class defines the following database fields
beyond the ones inherited from TypedObject: beyond the ones inherited from TypedObject:
- db_subscriptions: The Player subscriptions (this is the most - db_subscriptions: The Account subscriptions (this is the most
usual case, named this way for legacy. usual case, named this way for legacy.
- db_object_subscriptions: The Object subscriptions. - db_object_subscriptions: The Object subscriptions.

View file

@ -411,7 +411,7 @@ class CmdTradeBase(Command):
if ':' in self.args: if ':' in self.args:
self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)] self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)]
self.str_caller = 'You say, "' + self.emote + '"\n [%s]' self.str_caller = 'You say, "' + self.emote + '"\n [%s]'
if self.caller.has_player: if self.caller.has_account:
self.str_other = '|c%s|n says, "' % self.caller.key + self.emote + '"\n [%s]' self.str_other = '|c%s|n says, "' % self.caller.key + self.emote + '"\n [%s]'
else: else:
self.str_other = '%s says, "' % self.caller.key + self.emote + '"\n [%s]' self.str_other = '%s says, "' % self.caller.key + self.emote + '"\n [%s]'
@ -766,7 +766,7 @@ class CmdTrade(Command):
if ':' in self.args: if ':' in self.args:
self.args, emote = [part.strip() for part in self.args.rsplit(":", 1)] self.args, emote = [part.strip() for part in self.args.rsplit(":", 1)]
selfemote = 'You say, "%s"\n ' % emote selfemote = 'You say, "%s"\n ' % emote
if self.caller.has_player: if self.caller.has_account:
theiremote = '|c%s|n says, "%s"\n ' % (self.caller.key, emote) theiremote = '|c%s|n says, "%s"\n ' % (self.caller.key, emote)
else: else:
theiremote = '%s says, "%s"\n ' % (self.caller.key, emote) theiremote = '%s says, "%s"\n ' % (self.caller.key, emote)

View file

@ -7,8 +7,8 @@ necessary anymore - the ooclook and @charcreate commands in that mode
replaces this module with better functionality. This remains here for replaces this module with better functionality. This remains here for
inspiration. inspiration.
This is a simple character creation commandset for the Player level. This is a simple character creation commandset for the Account level.
It shows some more info and gives the Player the option to create a It shows some more info and gives the Account the option to create a
character without any more customizations than their name (further character without any more customizations than their name (further
options are unique for each game anyway). options are unique for each game anyway).
@ -19,7 +19,7 @@ cmdset.
Installation: Installation:
Import this module to `mygame/commands/default_cmdsets.py` and Import this module to `mygame/commands/default_cmdsets.py` and
add `chargen.OOCCMdSetCharGen` to the `PlayerCmdSet` class add `chargen.OOCCMdSetCharGen` to the `AccountCmdSet` class
(it says where to add it). Reload. (it says where to add it). Reload.
""" """
@ -39,7 +39,7 @@ class CmdOOCLook(default_cmds.CmdLook):
look look
look <character> look <character>
This is an OOC version of the look command. Since a Player doesn't This is an OOC version of the look command. Since an Account doesn't
have an in-game existence, there is no concept of location or have an in-game existence, there is no concept of location or
"self". "self".
@ -56,24 +56,24 @@ class CmdOOCLook(default_cmds.CmdLook):
""" """
Implements the ooc look command Implements the ooc look command
We use an attribute _character_dbrefs on the player in order We use an attribute _character_dbrefs on the account in order
to figure out which characters are "theirs". A drawback of this to figure out which characters are "theirs". A drawback of this
is that only the CmdCharacterCreate command adds this attribute, is that only the CmdCharacterCreate command adds this attribute,
and thus e.g. player #1 will not be listed (although it will work). and thus e.g. account #1 will not be listed (although it will work).
Existence in this list does not depend on puppeting rights though, Existence in this list does not depend on puppeting rights though,
that is checked by the @ic command directly. that is checked by the @ic command directly.
""" """
# making sure caller is really a player # making sure caller is really an account
self.character = None self.character = None
if utils.inherits_from(self.caller, "evennia.objects.objects.Object"): if utils.inherits_from(self.caller, "evennia.objects.objects.Object"):
# An object of some type is calling. Convert to player. # An object of some type is calling. Convert to account.
self.character = self.caller self.character = self.caller
if hasattr(self.caller, "player"): if hasattr(self.caller, "account"):
self.caller = self.caller.player self.caller = self.caller.account
if not self.character: if not self.character:
# ooc mode, we are players # ooc mode, we are accounts
avail_chars = self.caller.db._character_dbrefs avail_chars = self.caller.db._character_dbrefs
if self.args: if self.args:
@ -139,13 +139,13 @@ class CmdOOCCharacterCreate(Command):
attribute on ourselves to remember it. attribute on ourselves to remember it.
""" """
# making sure caller is really a player # making sure caller is really an account
self.character = None self.character = None
if utils.inherits_from(self.caller, "evennia.objects.objects.Object"): if utils.inherits_from(self.caller, "evennia.objects.objects.Object"):
# An object of some type is calling. Convert to player. # An object of some type is calling. Convert to account.
self.character = self.caller self.character = self.caller
if hasattr(self.caller, "player"): if hasattr(self.caller, "account"):
self.caller = self.caller.player self.caller = self.caller.account
if not self.args: if not self.args:
self.caller.msg("Usage: create <character name>") self.caller.msg("Usage: create <character name>")
@ -161,7 +161,7 @@ class CmdOOCCharacterCreate(Command):
if not new_character: if not new_character:
self.caller.msg("|rThe Character couldn't be created. This is a bug. Please contact an admin.") self.caller.msg("|rThe Character couldn't be created. This is a bug. Please contact an admin.")
return return
# make sure to lock the character to only be puppeted by this player # make sure to lock the character to only be puppeted by this account
new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" % new_character.locks.add("puppet:id(%i) or pid(%i) or perm(Developer) or pperm(Developer)" %
(new_character.id, self.caller.id)) (new_character.id, self.caller.id))
@ -175,7 +175,7 @@ class CmdOOCCharacterCreate(Command):
self.caller.msg("|gThe character |c%s|g was successfully created!" % charname) self.caller.msg("|gThe character |c%s|g was successfully created!" % charname)
class OOCCmdSetCharGen(default_cmds.PlayerCmdSet): class OOCCmdSetCharGen(default_cmds.AccountCmdSet):
""" """
Extends the default OOC cmdset. Extends the default OOC cmdset.
""" """

View file

@ -13,7 +13,7 @@ from twisted.web.http_headers import Headers
from twisted.web.iweb import IBodyProducer from twisted.web.iweb import IBodyProducer
from zope.interface import implements from zope.interface import implements
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.server.sessionhandler import SESSIONS from evennia.server.sessionhandler import SESSIONS
from evennia.utils import get_evennia_version, logger from evennia.utils import get_evennia_version, logger
@ -97,8 +97,8 @@ class EvenniaGameIndexClient(object):
'web_client_url': egi_config.get('web_client_url') or '', 'web_client_url': egi_config.get('web_client_url') or '',
# Game stats # Game stats
'connected_player_count': SESSIONS.player_count(), 'connected_account_count': SESSIONS.account_count(),
'total_player_count': PlayerDB.objects.num_total_players() or 0, 'total_account_count': AccountDB.objects.num_total_accounts() or 0,
# System info # System info
'evennia_version': get_evennia_version(), 'evennia_version': get_evennia_version(),

View file

@ -31,7 +31,7 @@ the module given by settings.CONNECTION_SCREEN_MODULE.
""" """
import re import re
from django.conf import settings from django.conf import settings
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.server.models import ServerConfig from evennia.server.models import ServerConfig
@ -77,7 +77,7 @@ class CmdUnconnectedConnect(MuxCommand):
have a unique position in that their `func()` receives have a unique position in that their `func()` receives
a session object instead of a `source_object` like all a session object instead of a `source_object` like all
other types of logged-in commands (this is because other types of logged-in commands (this is because
there is no object yet before the player has logged in) there is no object yet before the account has logged in)
""" """
session = self.caller session = self.caller
@ -90,22 +90,22 @@ class CmdUnconnectedConnect(MuxCommand):
password = arglist[1] password = arglist[1]
# Match an email address to an account. # Match an email address to an account.
player = PlayerDB.objects.get_player_from_email(email) account = AccountDB.objects.get_account_from_email(email)
# No playername match # No accountname match
if not player: if not account:
string = "The email '%s' does not match any accounts." % email string = "The email '%s' does not match any accounts." % email
string += "\n\r\n\rIf you are new you should first create a new account " string += "\n\r\n\rIf you are new you should first create a new account "
string += "using the 'create' command." string += "using the 'create' command."
session.msg(string) session.msg(string)
return return
# We have at least one result, so we can check the password. # We have at least one result, so we can check the password.
if not player[0].check_password(password): if not account[0].check_password(password):
session.msg("Incorrect password.") session.msg("Incorrect password.")
return return
# Check IP and/or name bans # Check IP and/or name bans
bans = ServerConfig.objects.conf("server_bans") bans = ServerConfig.objects.conf("server_bans")
if bans and (any(tup[0] == player.name for tup in bans) or if bans and (any(tup[0] == account.name for tup in bans) or
any(tup[2].match(session.address[0]) for tup in bans if tup[2])): any(tup[2].match(session.address[0]) for tup in bans if tup[2])):
# this is a banned IP or name! # this is a banned IP or name!
string = "|rYou have been banned and cannot continue from here." string = "|rYou have been banned and cannot continue from here."
@ -115,7 +115,7 @@ class CmdUnconnectedConnect(MuxCommand):
return return
# actually do the login. This will call all hooks. # actually do the login. This will call all hooks.
session.sessionhandler.login(session, player) session.sessionhandler.login(session, account)
class CmdUnconnectedCreate(MuxCommand): class CmdUnconnectedCreate(MuxCommand):
@ -123,9 +123,9 @@ class CmdUnconnectedCreate(MuxCommand):
Create a new account. Create a new account.
Usage (at login screen): Usage (at login screen):
create \"playername\" <email> <password> create \"accountname\" <email> <password>
This creates a new player account. This creates a new account account.
""" """
key = "create" key = "create"
@ -134,36 +134,36 @@ class CmdUnconnectedCreate(MuxCommand):
def parse(self): def parse(self):
""" """
The parser must handle the multiple-word player The parser must handle the multiple-word account
name enclosed in quotes: name enclosed in quotes:
connect "Long name with many words" my@myserv.com mypassw connect "Long name with many words" my@myserv.com mypassw
""" """
super(CmdUnconnectedCreate, self).parse() super(CmdUnconnectedCreate, self).parse()
self.playerinfo = [] self.accountinfo = []
if len(self.arglist) < 3: if len(self.arglist) < 3:
return return
if len(self.arglist) > 3: if len(self.arglist) > 3:
# this means we have a multi_word playername. pop from the back. # this means we have a multi_word accountname. pop from the back.
password = self.arglist.pop() password = self.arglist.pop()
email = self.arglist.pop() email = self.arglist.pop()
# what remains is the playername. # what remains is the accountname.
playername = " ".join(self.arglist) accountname = " ".join(self.arglist)
else: else:
playername, email, password = self.arglist accountname, email, password = self.arglist
playername = playername.replace('"', '') # remove " accountname = accountname.replace('"', '') # remove "
playername = playername.replace("'", "") accountname = accountname.replace("'", "")
self.playerinfo = (playername, email, password) self.accountinfo = (accountname, email, password)
def func(self): def func(self):
"""Do checks and create account""" """Do checks and create account"""
session = self.caller session = self.caller
try: try:
playername, email, password = self.playerinfo accountname, email, password = self.accountinfo
except ValueError: except ValueError:
string = "\n\r Usage (without <>): create \"<playername>\" <email> <password>" string = "\n\r Usage (without <>): create \"<accountname>\" <email> <password>"
session.msg(string) session.msg(string)
return return
if not email or not password: if not email or not password:
@ -174,26 +174,26 @@ class CmdUnconnectedCreate(MuxCommand):
session.msg("'%s' is not a valid e-mail address." % email) session.msg("'%s' is not a valid e-mail address." % email)
return return
# sanity checks # sanity checks
if not re.findall(r"^[\w. @+\-']+$", playername) or not (0 < len(playername) <= 30): if not re.findall(r"^[\w. @+\-']+$", accountname) or not (0 < len(accountname) <= 30):
# this echoes the restrictions made by django's auth # this echoes the restrictions made by django's auth
# module (except not allowing spaces, for convenience of # module (except not allowing spaces, for convenience of
# logging in). # logging in).
string = "\n\r Playername can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only." string = "\n\r Accountname can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/' only."
session.msg(string) session.msg(string)
return return
# strip excessive spaces in playername # strip excessive spaces in accountname
playername = re.sub(r"\s+", " ", playername).strip() accountname = re.sub(r"\s+", " ", accountname).strip()
if PlayerDB.objects.filter(username__iexact=playername): if AccountDB.objects.filter(username__iexact=accountname):
# player already exists (we also ignore capitalization here) # account already exists (we also ignore capitalization here)
session.msg("Sorry, there is already a player with the name '%s'." % playername) session.msg("Sorry, there is already an account with the name '%s'." % accountname)
return return
if PlayerDB.objects.get_player_from_email(email): if AccountDB.objects.get_account_from_email(email):
# email already set on a player # email already set on an account
session.msg("Sorry, there is already a player with that email address.") session.msg("Sorry, there is already an account with that email address.")
return return
# Reserve playernames found in GUEST_LIST # Reserve accountnames found in GUEST_LIST
if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST): if settings.GUEST_LIST and accountname.lower() in (guest.lower() for guest in settings.GUEST_LIST):
string = "\n\r That name is reserved. Please choose another Playername." string = "\n\r That name is reserved. Please choose another Accountname."
session.msg(string) session.msg(string)
return return
if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)): if not re.findall(r"^[\w. @+\-']+$", password) or not (3 < len(password)):
@ -205,7 +205,7 @@ class CmdUnconnectedCreate(MuxCommand):
# Check IP and/or name bans # Check IP and/or name bans
bans = ServerConfig.objects.conf("server_bans") bans = ServerConfig.objects.conf("server_bans")
if bans and (any(tup[0] == playername.lower() for tup in bans) or if bans and (any(tup[0] == accountname.lower() for tup in bans) or
any(tup[2].match(session.address) for tup in bans if tup[2])): any(tup[2].match(session.address) for tup in bans if tup[2])):
# this is a banned IP or name! # this is a banned IP or name!
string = "|rYou have been banned and cannot continue from here." \ string = "|rYou have been banned and cannot continue from here." \
@ -216,20 +216,20 @@ class CmdUnconnectedCreate(MuxCommand):
# everything's ok. Create the new player account. # everything's ok. Create the new player account.
try: try:
permissions = settings.PERMISSION_PLAYER_DEFAULT permissions = settings.PERMISSION_ACCOUNT_DEFAULT
typeclass = settings.BASE_CHARACTER_TYPECLASS typeclass = settings.BASE_CHARACTER_TYPECLASS
new_player = default_unloggedin._create_player(session, playername, password, permissions, email=email) new_account = default_unloggedin._create_account(session, accountname, password, permissions, email=email)
if new_player: if new_account:
if MULTISESSION_MODE < 2: if MULTISESSION_MODE < 2:
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
default_unloggedin._create_character(session, new_player, typeclass, default_home, permissions) default_unloggedin._create_character(session, new_account, typeclass, default_home, permissions)
# tell the caller everything went well. # tell the caller everything went well.
string = "A new account '%s' was created. Welcome!" string = "A new account '%s' was created. Welcome!"
if " " in playername: if " " in accountname:
string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'." string += "\n\nYou can now log in with the command 'connect \"%s\" <your password>'."
else: else:
string += "\n\nYou can now log with the command 'connect %s <your password>'." string += "\n\nYou can now log with the command 'connect %s <your password>'."
session.msg(string % (playername, email)) session.msg(string % (accountname, email))
except Exception: except Exception:
# We are in the middle between logged in and -not, so we have # We are in the middle between logged in and -not, so we have
@ -243,7 +243,7 @@ class CmdUnconnectedCreate(MuxCommand):
class CmdUnconnectedQuit(MuxCommand): class CmdUnconnectedQuit(MuxCommand):
""" """
We maintain a different version of the `quit` command We maintain a different version of the `quit` command
here for unconnected players for the sake of simplicity. The logged in here for unconnected accounts for the sake of simplicity. The logged in
version is a bit more complicated. version is a bit more complicated.
""" """
key = "quit" key = "quit"

View file

@ -88,7 +88,7 @@ class CallbackHandler(object):
Args: Args:
callback_name (str): the name of the callback to add. callback_name (str): the name of the callback to add.
code (str): the Python code associated with this callback. code (str): the Python code associated with this callback.
author (Character or Player, optional): the author of the callback. author (Character or Account, optional): the author of the callback.
valid (bool, optional): should the callback be connected? valid (bool, optional): should the callback be connected?
parameters (str, optional): optional parameters. parameters (str, optional): optional parameters.
@ -109,7 +109,7 @@ class CallbackHandler(object):
callback_name (str): the name of the callback to edit. callback_name (str): the name of the callback to edit.
number (int): the callback number to be changed. number (int): the callback number to be changed.
code (str): the Python code associated with this callback. code (str): the Python code associated with this callback.
author (Character or Player, optional): the author of the callback. author (Character or Account, optional): the author of the callback.
valid (bool, optional): should the callback be connected? valid (bool, optional): should the callback be connected?
Returns: Returns:

View file

@ -94,7 +94,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
on user permission. on user permission.
Args: Args:
caller (Object or Player): the caller asking for help on the command. caller (Object or Account): the caller asking for help on the command.
cmdset (CmdSet): the command set (if you need additional commands). cmdset (CmdSet): the command set (if you need additional commands).
Returns: Returns:

View file

@ -200,7 +200,7 @@ class EventHandler(DefaultScript):
obj (Object): the Evennia typeclassed object to be extended. obj (Object): the Evennia typeclassed object to be extended.
callback_name (str): the name of the callback to add. callback_name (str): the name of the callback to add.
code (str): the Python code associated with this callback. code (str): the Python code associated with this callback.
author (Character or Player, optional): the author of the callback. author (Character or Account, optional): the author of the callback.
valid (bool, optional): should the callback be connected? valid (bool, optional): should the callback be connected?
parameters (str, optional): optional parameters. parameters (str, optional): optional parameters.
@ -254,7 +254,7 @@ class EventHandler(DefaultScript):
callback_name (str): the name of the callback to edit. callback_name (str): the name of the callback to edit.
number (int): the callback number to be changed. number (int): the callback number to be changed.
code (str): the Python code associated with this callback. code (str): the Python code associated with this callback.
author (Character or Player, optional): the author of the callback. author (Character or Account, optional): the author of the callback.
valid (bool, optional): should the callback be connected? valid (bool, optional): should the callback be connected?
Raises: Raises:

View file

@ -81,7 +81,7 @@ This event is called when another character arrives in the location
where the current character is. For instance, a puppeted character where the current character is. For instance, a puppeted character
arrives in the shop of a shopkeeper (assuming the shopkeeper is arrives in the shop of a shopkeeper (assuming the shopkeeper is
a character). As its name suggests, this event can be very useful a character). As its name suggests, this event can be very useful
to have NPC greeting one another, or players, who come to visit. to have NPC greeting one another, or accounts, who come to visit.
Variables you can use in this event: Variables you can use in this event:
character: the character connected to this event. character: the character connected to this event.
@ -100,9 +100,9 @@ Variables you can use in this event:
""" """
CHARACTER_PUPPETED = """ CHARACTER_PUPPETED = """
When the character has been puppeted by a player. When the character has been puppeted by an account.
This event is called when a player has just puppeted this character. This event is called when an account has just puppeted this character.
This can commonly happen when a player connects onto this character, This can commonly happen when an account connects onto this character,
or when puppeting to a NPC or free character. or when puppeting to a NPC or free character.
Variables you can use in this event: Variables you can use in this event:
@ -151,8 +151,8 @@ Variables you can use in this event:
CHARACTER_UNPUPPETED = """ CHARACTER_UNPUPPETED = """
When the character is about to be un-puppeted. When the character is about to be un-puppeted.
This event is called when a player is about to un-puppet the This event is called when an account is about to un-puppet the
character, which can happen if the player is disconnecting or character, which can happen if the account is disconnecting or
changing puppets. changing puppets.
Variables you can use in this event: Variables you can use in this event:
@ -244,8 +244,8 @@ class EventCharacter(DefaultCharacter):
""" """
if not source_location and self.location.has_player: if not source_location and self.location.has_account:
# This was created from nowhere and added to a player's # This was created from nowhere and added to an account's
# inventory; it's probably the result of a create command. # inventory; it's probably the result of a create command.
string = "You now have %s in your possession." % self.get_display_name(self.location) string = "You now have %s in your possession." % self.get_display_name(self.location)
self.location.msg(string) self.location.msg(string)
@ -357,11 +357,11 @@ class EventCharacter(DefaultCharacter):
def at_post_puppet(self): def at_post_puppet(self):
""" """
Called just after puppeting has been completed and all Called just after puppeting has been completed and all
Player<->Object links have been established. Account<->Object links have been established.
Note: Note:
You can use `self.player` and `self.sessions.get()` to get You can use `self.account` and `self.sessions.get()` to get
player and sessions at this point; the last entry in the account and sessions at this point; the last entry in the
list from `self.sessions.get()` is the latest Session list from `self.sessions.get()` is the latest Session
puppeting this Object. puppeting this Object.
@ -378,11 +378,11 @@ class EventCharacter(DefaultCharacter):
def at_pre_unpuppet(self): def at_pre_unpuppet(self):
""" """
Called just before beginning to un-connect a puppeting from Called just before beginning to un-connect a puppeting from
this Player. this Account.
Note: Note:
You can use `self.player` and `self.sessions.get()` to get You can use `self.account` and `self.sessions.get()` to get
player and sessions at this point; the last entry in the account and sessions at this point; the last entry in the
list from `self.sessions.get()` is the latest Session list from `self.sessions.get()` is the latest Session
puppeting this Object. puppeting this Object.
@ -683,7 +683,7 @@ Variables you can use in this event:
ROOM_PUPPETED_IN = """ ROOM_PUPPETED_IN = """
After the character has been puppeted in this room. After the character has been puppeted in this room.
This event is called after a character has been puppeted in this This event is called after a character has been puppeted in this
room. This can happen when a player, having connected, begins room. This can happen when an account, having connected, begins
to puppet a character. The character's location at this point, to puppet a character. The character's location at this point,
if it's a room, will see this event fire. if it's a room, will see this event fire.
@ -733,7 +733,7 @@ Variables you can use in this event:
ROOM_UNPUPPETED_IN = """ ROOM_UNPUPPETED_IN = """
Before the character is un-puppeted in this room. Before the character is un-puppeted in this room.
This event is called before a character is un-puppeted in this This event is called before a character is un-puppeted in this
room. This can happen when a player, puppeting a character, is room. This can happen when an account, puppeting a character, is
disconnecting. The character's location at this point, if it's a disconnecting. The character's location at this point, if it's a
room, will see this event fire. room, will see this event fire.

View file

@ -277,7 +277,7 @@ class CmdExtendedLook(default_cmds.CmdLook):
look look
look <obj> look <obj>
look <room detail> look <room detail>
look *<player> look *<account>
Observes your location, details at your location or objects in your vicinity. Observes your location, details at your location or objects in your vicinity.
""" """
@ -315,7 +315,7 @@ class CmdExtendedLook(default_cmds.CmdLook):
return return
if not hasattr(looking_at_obj, 'return_appearance'): if not hasattr(looking_at_obj, 'return_appearance'):
# this is likely due to us having a player instead # this is likely due to us having an account instead
looking_at_obj = looking_at_obj.character looking_at_obj = looking_at_obj.character
if not looking_at_obj.access(caller, "view"): if not looking_at_obj.access(caller, "view"):
caller.msg("Could not find '%s'." % args) caller.msg("Could not find '%s'." % args)

View file

@ -7,12 +7,12 @@ A simple Brandymail style @mail system that uses the Msg class from Evennia Core
Installation: Installation:
import CmdMail from this module (from evennia.contrib.mail import CmdMail), import CmdMail from this module (from evennia.contrib.mail import CmdMail),
and add into the default Player or Character command set (self.add(CmdMail)). and add into the default Account or Character command set (self.add(CmdMail)).
""" """
import re import re
from evennia import ObjectDB, PlayerDB from evennia import ObjectDB, AccountDB
from evennia import default_cmds from evennia import default_cmds
from evennia.utils import create, evtable, make_iter from evennia.utils import create, evtable, make_iter
from evennia.comms.models import Msg from evennia.comms.models import Msg
@ -27,17 +27,17 @@ class CmdMail(default_cmds.MuxCommand):
Commands that allow either IC or OOC communications Commands that allow either IC or OOC communications
Usage: Usage:
@mail - Displays all the mail a player has in their mailbox @mail - Displays all the mail an account has in their mailbox
@mail <#> - Displays a specific message @mail <#> - Displays a specific message
@mail <players>=<subject>/<message> @mail <accounts>=<subject>/<message>
- Sends a message to the comma separated list of players. - Sends a message to the comma separated list of accounts.
@mail/delete <#> - Deletes a specific message @mail/delete <#> - Deletes a specific message
@mail/forward <player list>=<#>[/<Message>] @mail/forward <account list>=<#>[/<Message>]
- Forwards an existing message to the specified list of players, - Forwards an existing message to the specified list of accounts,
original message is delivered with optional Message prepended. original message is delivered with optional Message prepended.
@mail/reply <#>=<message> @mail/reply <#>=<message>
@ -65,7 +65,7 @@ class CmdMail(default_cmds.MuxCommand):
Search a list of targets of the same type as caller. Search a list of targets of the same type as caller.
Args: Args:
caller (Object or Player): The type of object to search. caller (Object or Account): The type of object to search.
namelist (list): List of strings for objects to search for. namelist (list): List of strings for objects to search for.
Returns: Returns:
@ -73,10 +73,10 @@ class CmdMail(default_cmds.MuxCommand):
""" """
nameregex = r"|".join(r"^%s$" % re.escape(name) for name in make_iter(namelist)) nameregex = r"|".join(r"^%s$" % re.escape(name) for name in make_iter(namelist))
if hasattr(self.caller, "player") and self.caller.player: if hasattr(self.caller, "account") and self.caller.account:
matches = list(ObjectDB.objects.filter(db_key__iregex=nameregex)) matches = list(ObjectDB.objects.filter(db_key__iregex=nameregex))
else: else:
matches = list(PlayerDB.objects.filter(username__iregex=nameregex)) matches = list(AccountDB.objects.filter(username__iregex=nameregex))
return matches return matches
def get_all_mail(self): def get_all_mail(self):
@ -89,10 +89,10 @@ class CmdMail(default_cmds.MuxCommand):
# mail_messages = Msg.objects.get_by_tag(category="mail") # mail_messages = Msg.objects.get_by_tag(category="mail")
# messages = [] # messages = []
try: try:
player = self.caller.player account = self.caller.account
except AttributeError: except AttributeError:
player = self.caller account = self.caller
messages = Msg.objects.get_by_tag(category="mail").filter(db_receivers_players=player) messages = Msg.objects.get_by_tag(category="mail").filter(db_receivers_accounts=account)
return messages return messages
def send_mail(self, recipients, subject, message, caller): def send_mail(self, recipients, subject, message, caller):
@ -100,10 +100,10 @@ class CmdMail(default_cmds.MuxCommand):
Function for sending new mail. Also useful for sending notifications from objects or systems. Function for sending new mail. Also useful for sending notifications from objects or systems.
Args: Args:
recipients (list): list of Player or character objects to receive the newly created mails. recipients (list): list of Account or character objects to receive the newly created mails.
subject (str): The header or subject of the message to be delivered. subject (str): The header or subject of the message to be delivered.
message (str): The body of the message being sent. message (str): The body of the message being sent.
caller (obj): The object (or Player or Character) that is sending the message. caller (obj): The object (or Account or Character) that is sending the message.
""" """
for recipient in recipients: for recipient in recipients:
recipient.msg("You have received a new @mail from %s" % caller) recipient.msg("You have received a new @mail from %s" % caller)
@ -114,7 +114,7 @@ class CmdMail(default_cmds.MuxCommand):
caller.msg("You sent your message.") caller.msg("You sent your message.")
return return
else: else:
caller.msg("No valid players found. Cannot send message.") caller.msg("No valid accounts found. Cannot send message.")
return return
def func(self): def func(self):
@ -142,7 +142,7 @@ class CmdMail(default_cmds.MuxCommand):
elif "forward" in self.switches: elif "forward" in self.switches:
try: try:
if not self.rhs: if not self.rhs:
self.caller.msg("Cannot forward a message without a player list. Please try again.") self.caller.msg("Cannot forward a message without an account list. Please try again.")
return return
elif not self.lhs: elif not self.lhs:
self.caller.msg("You must define a message to forward.") self.caller.msg("You must define a message to forward.")
@ -176,7 +176,7 @@ class CmdMail(default_cmds.MuxCommand):
except IndexError: except IndexError:
self.caller.msg("Message does not exixt.") self.caller.msg("Message does not exixt.")
except ValueError: except ValueError:
self.caller.msg("Usage: @mail/forward <player list>=<#>[/<Message>]") self.caller.msg("Usage: @mail/forward <account list>=<#>[/<Message>]")
elif "reply" in self.switches: elif "reply" in self.switches:
try: try:
if not self.rhs: if not self.rhs:

View file

@ -32,7 +32,7 @@ called and so on until the map is completed. Building instructions are passed
the following arguments: the following arguments:
x - The rooms position on the maps x axis x - The rooms position on the maps x axis
y - The rooms position on the maps y axis y - The rooms position on the maps y axis
caller - The player calling the command caller - The account calling the command
iteration - The current iterations number (0, 1 or 2) iteration - The current iterations number (0, 1 or 2)
room_dict - A dictionary containing room references returned by build room_dict - A dictionary containing room references returned by build
functions where tuple coordinates are the keys (x, y). functions where tuple coordinates are the keys (x, y).
@ -119,7 +119,7 @@ def example1_build_forest(x, y, **kwargs):
room = create_object(rooms.Room, key="forest" + str(x) + str(y)) room = create_object(rooms.Room, key="forest" + str(x) + str(y))
room.db.desc = "Basic forest room." room.db.desc = "Basic forest room."
# Send a message to the player # Send a message to the account
kwargs["caller"].msg(room.key + " " + room.dbref) kwargs["caller"].msg(room.key + " " + room.dbref)
# This is generally mandatory. # This is generally mandatory.
@ -143,7 +143,7 @@ def example1_build_mountains(x, y, **kwargs):
rock = create_object(key="Rock", location=room) rock = create_object(key="Rock", location=room)
rock.db.desc = "An ordinary rock." rock.db.desc = "An ordinary rock."
# Send a message to the player # Send a message to the account
kwargs["caller"].msg(room.key + " " + room.dbref) kwargs["caller"].msg(room.key + " " + room.dbref)
# This is generally mandatory. # This is generally mandatory.
@ -167,7 +167,7 @@ def example1_build_temple(x, y, **kwargs):
"keeping the sound level only just below thunderous. " "keeping the sound level only just below thunderous. "
"This is a rare spot of mirth on this dread moor.") "This is a rare spot of mirth on this dread moor.")
# Send a message to the player # Send a message to the account
kwargs["caller"].msg(room.key + " " + room.dbref) kwargs["caller"].msg(room.key + " " + room.dbref)
# This is generally mandatory. # This is generally mandatory.

View file

@ -18,8 +18,8 @@ CMDSET_UNLOGGEDIN = "contrib.menu_login.UnloggedinCmdSet"
When you'll reload the server, new sessions will connect to the new When you'll reload the server, new sessions will connect to the new
login system, where they will be able to: login system, where they will be able to:
* Enter their username, assuming they have an existing player. * Enter their username, assuming they have an existing account.
* Enter 'NEW' to create a new player. * Enter 'NEW' to create a new account.
The top-level functions in this file are menu nodes (as described in The top-level functions in this file are menu nodes (as described in
evennia.utils.evmenu.py). Each one of these functions is responsible evennia.utils.evmenu.py). Each one of these functions is responsible
@ -61,7 +61,7 @@ def start(caller):
a session has been created OR if an error occurs further a session has been created OR if an error occurs further
down the menu tree. From there, users can either enter a down the menu tree. From there, users can either enter a
username (if this username exists) or type NEW (capitalized username (if this username exists) or type NEW (capitalized
or not) to create a new player. or not) to create a new account.
""" """
text = random_string_from_module(CONNECTION_SCREEN_MODULE) text = random_string_from_module(CONNECTION_SCREEN_MODULE)
@ -79,7 +79,7 @@ def start(caller):
def username(caller, string_input): def username(caller, string_input):
"""Check that the username leads to an existing player. """Check that the username leads to an existing account.
Check that the specified username exists. If the username doesn't Check that the specified username exists. If the username doesn't
exist, display an error message and ask the user to try again. If exist, display an error message and ask the user to try again. If
@ -88,8 +88,8 @@ def username(caller, string_input):
""" """
string_input = string_input.strip() string_input = string_input.strip()
player = managers.players.get_player_from_name(string_input) account = managers.accounts.get_account_from_name(string_input)
if player is None: if account is None:
text = dedent(""" text = dedent("""
|rThe username '{}' doesn't exist. Have you created it?|n |rThe username '{}' doesn't exist. Have you created it?|n
Try another name or leave empty to go back. Try another name or leave empty to go back.
@ -100,8 +100,8 @@ def username(caller, string_input):
{"key": "_default", {"key": "_default",
"goto": "username"}) "goto": "username"})
else: else:
caller.ndb._menutree.player = player caller.ndb._menutree.account = account
text = "Enter the password for the {} account.".format(player.name) text = "Enter the password for the {} account.".format(account.name)
# Disables echo for the password # Disables echo for the password
caller.msg("", options={"echo": False}) caller.msg("", options={"echo": False})
options = ( options = (
@ -115,7 +115,7 @@ def username(caller, string_input):
def ask_password(caller, string_input): def ask_password(caller, string_input):
"""Ask the user to enter the password to this player. """Ask the user to enter the password to this account.
This is assuming the user exists (see 'create_username' and This is assuming the user exists (see 'create_username' and
'create_password'). This node "loops" if needed: if the 'create_password'). This node "loops" if needed: if the
@ -129,14 +129,14 @@ def ask_password(caller, string_input):
# Check the password and login is correct; also check for bans # Check the password and login is correct; also check for bans
player = menutree.player account = menutree.account
password_attempts = menutree.password_attempts \ password_attempts = menutree.password_attempts \
if hasattr(menutree, "password_attempts") else 0 if hasattr(menutree, "password_attempts") else 0
bans = ServerConfig.objects.conf("server_bans") bans = ServerConfig.objects.conf("server_bans")
banned = bans and (any(tup[0] == player.name.lower() for tup in bans) or banned = bans and (any(tup[0] == account.name.lower() for tup in bans) or
any(tup[2].match(caller.address) for tup in bans if tup[2])) any(tup[2].match(caller.address) for tup in bans if tup[2]))
if not player.check_password(string_input): if not account.check_password(string_input):
# Didn't enter a correct password # Didn't enter a correct password
password_attempts += 1 password_attempts += 1
if password_attempts > 2: if password_attempts > 2:
@ -173,7 +173,7 @@ def ask_password(caller, string_input):
text = "" text = ""
options = {} options = {}
caller.msg("", options={"echo": True}) caller.msg("", options={"echo": True})
caller.sessionhandler.login(caller, player) caller.sessionhandler.login(caller, account)
return text, options return text, options
@ -201,10 +201,10 @@ def create_username(caller, string_input):
""" """
menutree = caller.ndb._menutree menutree = caller.ndb._menutree
string_input = string_input.strip() string_input = string_input.strip()
player = managers.players.get_player_from_name(string_input) account = managers.accounts.get_account_from_name(string_input)
# If a player with that name exists, a new one will not be created # If an account with that name exists, a new one will not be created
if player: if account:
text = dedent(""" text = dedent("""
|rThe account {} already exists.|n |rThe account {} already exists.|n
Enter another username or leave blank to go back. Enter another username or leave blank to go back.
@ -229,7 +229,7 @@ def create_username(caller, string_input):
"goto": "create_username"}) "goto": "create_username"})
else: else:
# a valid username - continue getting the password # a valid username - continue getting the password
menutree.playername = string_input menutree.accountname = string_input
# Disables echo for entering password # Disables echo for entering password
caller.msg("", options={"echo": False}) caller.msg("", options={"echo": False})
# Redirects to the creation of a password # Redirects to the creation of a password
@ -259,7 +259,7 @@ def create_password(caller, string_input):
"goto": "create_password"}) "goto": "create_password"})
password = string_input.strip() password = string_input.strip()
playername = menutree.playername accountname = menutree.accountname
if len(password) < LEN_PASSWD: if len(password) < LEN_PASSWD:
# The password is too short # The password is too short
@ -273,15 +273,15 @@ def create_password(caller, string_input):
from evennia.commands.default import unloggedin from evennia.commands.default import unloggedin
# We make use of the helper functions from the default set here. # We make use of the helper functions from the default set here.
try: try:
permissions = settings.PERMISSION_PLAYER_DEFAULT permissions = settings.PERMISSION_ACCOUNT_DEFAULT
typeclass = settings.BASE_CHARACTER_TYPECLASS typeclass = settings.BASE_CHARACTER_TYPECLASS
new_player = unloggedin._create_player(caller, playername, new_account = unloggedin._create_account(caller, accountname,
password, permissions) password, permissions)
if new_player: if new_account:
if settings.MULTISESSION_MODE < 2: if settings.MULTISESSION_MODE < 2:
default_home = ObjectDB.objects.get_id( default_home = ObjectDB.objects.get_id(
settings.DEFAULT_HOME) settings.DEFAULT_HOME)
unloggedin._create_character(caller, new_player, unloggedin._create_character(caller, new_account,
typeclass, default_home, permissions) typeclass, default_home, permissions)
except Exception: except Exception:
# We are in the middle between logged in and -not, so we have # We are in the middle between logged in and -not, so we have
@ -297,7 +297,7 @@ def create_password(caller, string_input):
text = "" text = ""
caller.msg("|gWelcome, your new account has been created!|n") caller.msg("|gWelcome, your new account has been created!|n")
caller.msg("", options={"echo": True}) caller.msg("", options={"echo": True})
caller.sessionhandler.login(caller, new_player) caller.sessionhandler.login(caller, new_account)
return text, options return text, options
@ -335,7 +335,7 @@ class UnloggedinCmdSet(CmdSet):
class CmdUnloggedinLook(Command): class CmdUnloggedinLook(Command):
""" """
An unloggedin version of the look command. This is called by the server An unloggedin version of the look command. This is called by the server
when the player first connects. It sets up the menu before handing off when the account first connects. It sets up the menu before handing off
to the menu's own look command. to the menu's own look command.
""" """
key = syscmdkeys.CMD_LOGINSTART key = syscmdkeys.CMD_LOGINSTART

View file

@ -1210,7 +1210,7 @@ class ContribRPObject(DefaultObject):
otherwise it will return a list of 0, 1 or more matches. otherwise it will return a list of 0, 1 or more matches.
Notes: Notes:
To find Players, use eg. `evennia.player_search`. If To find Accounts, use eg. `evennia.account_search`. If
`quiet=False`, error messages will be handled by `quiet=False`, error messages will be handled by
`settings.SEARCH_AT_RESULT` and echoed automatically (on `settings.SEARCH_AT_RESULT` and echoed automatically (on
error, return will be `None`). If `quiet=True`, the error error, return will be `None`). If `quiet=True`, the error
@ -1228,7 +1228,7 @@ class ContribRPObject(DefaultObject):
if use_nicks: if use_nicks:
# do nick-replacement on search # do nick-replacement on search
searchdata = self.nicks.nickreplace(searchdata, categories=("object", "player"), include_player=True) searchdata = self.nicks.nickreplace(searchdata, categories=("object", "account"), include_account=True)
if(global_search or (is_string and searchdata.startswith("#") and if(global_search or (is_string and searchdata.startswith("#") and
len(searchdata) > 1 and searchdata[1:].isdigit())): len(searchdata) > 1 and searchdata[1:].isdigit())):
@ -1296,7 +1296,7 @@ class ContribRPObject(DefaultObject):
Displays the name of the object in a viewer-aware manner. Displays the name of the object in a viewer-aware manner.
Args: Args:
looker (TypedObject): The object or player that is looking looker (TypedObject): The object or account that is looking
at/getting inforamtion for this object. at/getting inforamtion for this object.
Kwargs: Kwargs:
@ -1342,7 +1342,7 @@ class ContribRPObject(DefaultObject):
key = con.get_display_name(looker, pose=True) key = con.get_display_name(looker, pose=True)
if con.destination: if con.destination:
exits.append(key) exits.append(key)
elif con.has_player: elif con.has_account:
users.append(key) users.append(key)
else: else:
things.append(key) things.append(key)
@ -1383,7 +1383,7 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
Displays the name of the object in a viewer-aware manner. Displays the name of the object in a viewer-aware manner.
Args: Args:
looker (TypedObject): The object or player that is looking looker (TypedObject): The object or account that is looking
at/getting inforamtion for this object. at/getting inforamtion for this object.
Kwargs: Kwargs:

View file

@ -395,13 +395,13 @@ class TestWilderness(EvenniaTest):
# Pretend that both char1 and char2 are connected... # Pretend that both char1 and char2 are connected...
self.char1.sessions.add(1) self.char1.sessions.add(1)
self.char2.sessions.add(1) self.char2.sessions.add(1)
self.assertTrue(self.char1.has_player) self.assertTrue(self.char1.has_account)
self.assertTrue(self.char2.has_player) self.assertTrue(self.char2.has_account)
wilderness.create_wilderness() wilderness.create_wilderness()
w = self.get_wilderness_script() w = self.get_wilderness_script()
# We should have no unused room after moving the first player in. # We should have no unused room after moving the first account in.
self.assertEquals(len(w.db.unused_rooms), 0) self.assertEquals(len(w.db.unused_rooms), 0)
w.move_obj(self.char1, (0, 0)) w.move_obj(self.char1, (0, 0))
self.assertEquals(len(w.db.unused_rooms), 0) self.assertEquals(len(w.db.unused_rooms), 0)
@ -442,15 +442,15 @@ from evennia.contrib import chargen
class TestChargen(CommandTest): class TestChargen(CommandTest):
def test_ooclook(self): def test_ooclook(self):
self.call(chargen.CmdOOCLook(), "foo", "You have no characters to look at", caller=self.player) self.call(chargen.CmdOOCLook(), "foo", "You have no characters to look at", caller=self.account)
self.call(chargen.CmdOOCLook(), "", "You, TestPlayer, are an OOC ghost without form.", caller=self.player) self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.", caller=self.account)
def test_charcreate(self): def test_charcreate(self):
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "The character testchar was successfully created!", caller=self.player) self.call(chargen.CmdOOCCharacterCreate(), "testchar", "The character testchar was successfully created!", caller=self.account)
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "Character testchar already exists.", caller=self.player) self.call(chargen.CmdOOCCharacterCreate(), "testchar", "Character testchar already exists.", caller=self.account)
self.assertTrue(self.player.db._character_dbrefs) self.assertTrue(self.account.db._character_dbrefs)
self.call(chargen.CmdOOCLook(), "", "You, TestPlayer, are an OOC ghost without form.",caller=self.player) self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.",caller=self.account)
self.call(chargen.CmdOOCLook(), "testchar", "testchar(", caller=self.player) self.call(chargen.CmdOOCLook(), "testchar", "testchar(", caller=self.account)
# Testing clothing contrib # Testing clothing contrib
from evennia.contrib import clothing from evennia.contrib import clothing
@ -600,9 +600,9 @@ class TestEmailLogin(CommandTest):
def test_connect(self): def test_connect(self):
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test", "The email 'mytest@test.com' does not match any accounts.") self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test", "The email 'mytest@test.com' does not match any accounts.")
self.call(email_login.CmdUnconnectedCreate(), '"mytest" mytest@test.com test11111', "A new account 'mytest' was created. Welcome!") self.call(email_login.CmdUnconnectedCreate(), '"mytest" mytest@test.com test11111', "A new account 'mytest' was created. Welcome!")
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test11111", "", caller=self.player.sessions.get()[0]) self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test11111", "", caller=self.account.sessions.get()[0])
def test_quit(self): def test_quit(self):
self.call(email_login.CmdUnconnectedQuit(), "", "", caller=self.player.sessions.get()[0]) self.call(email_login.CmdUnconnectedQuit(), "", "", caller=self.account.sessions.get()[0])
def test_unconnectedlook(self): def test_unconnectedlook(self):
self.call(email_login.CmdUnconnectedLook(), "", "==========") self.call(email_login.CmdUnconnectedLook(), "", "==========")
def test_unconnectedhelp(self): def test_unconnectedhelp(self):
@ -628,19 +628,19 @@ from evennia.contrib import mail
class TestMail(CommandTest): class TestMail(CommandTest):
def test_mail(self): def test_mail(self):
self.call(mail.CmdMail(), "2", "'2' is not a valid mail id.", caller=self.player) self.call(mail.CmdMail(), "2", "'2' is not a valid mail id.", caller=self.account)
self.call(mail.CmdMail(), "", "There are no messages in your inbox.", caller=self.player) self.call(mail.CmdMail(), "", "There are no messages in your inbox.", caller=self.account)
self.call(mail.CmdMail(), "Char=Message 1", "You have received a new @mail from Char|You sent your message.", caller=self.char1) self.call(mail.CmdMail(), "Char=Message 1", "You have received a new @mail from Char|You sent your message.", caller=self.char1)
self.call(mail.CmdMail(), "Char=Message 2", "You sent your message.", caller=self.char2) self.call(mail.CmdMail(), "Char=Message 2", "You sent your message.", caller=self.char2)
self.call(mail.CmdMail(), "TestPlayer2=Message 2", self.call(mail.CmdMail(), "TestAccount2=Message 2",
"You have received a new @mail from TestPlayer2(player 2)|You sent your message.", caller=self.player2) "You have received a new @mail from TestAccount2(account 2)|You sent your message.", caller=self.account2)
self.call(mail.CmdMail(), "TestPlayer=Message 1", "You sent your message.", caller=self.player2) self.call(mail.CmdMail(), "TestAccount=Message 1", "You sent your message.", caller=self.account2)
self.call(mail.CmdMail(), "TestPlayer=Message 2", "You sent your message.", caller=self.player2) self.call(mail.CmdMail(), "TestAccount=Message 2", "You sent your message.", caller=self.account2)
self.call(mail.CmdMail(), "", "| ID: From: Subject:", caller=self.player) self.call(mail.CmdMail(), "", "| ID: From: Subject:", caller=self.account)
self.call(mail.CmdMail(), "2", "From: TestPlayer2", caller=self.player) self.call(mail.CmdMail(), "2", "From: TestAccount2", caller=self.account)
self.call(mail.CmdMail(), "/forward TestPlayer2 = 1/Forward message", "You sent your message.|Message forwarded.", caller=self.player) self.call(mail.CmdMail(), "/forward TestAccount2 = 1/Forward message", "You sent your message.|Message forwarded.", caller=self.account)
self.call(mail.CmdMail(), "/reply 2=Reply Message2", "You sent your message.", caller=self.player) self.call(mail.CmdMail(), "/reply 2=Reply Message2", "You sent your message.", caller=self.account)
self.call(mail.CmdMail(), "/delete 2", "Message 2 deleted", caller=self.player) self.call(mail.CmdMail(), "/delete 2", "Message 2 deleted", caller=self.account)
# test map builder contrib # test map builder contrib

View file

@ -297,17 +297,17 @@ class LidOpenCmdSet(CmdSet):
class BlindCmdSet(CmdSet): class BlindCmdSet(CmdSet):
""" """
This is the cmdset added to the *player* when This is the cmdset added to the *account* when
the button is pushed. the button is pushed.
""" """
key = "BlindCmdSet" key = "BlindCmdSet"
# we want it to completely replace all normal commands # we want it to completely replace all normal commands
# until the timed script removes it again. # until the timed script removes it again.
mergetype = "Replace" mergetype = "Replace"
# we want to stop the player from walking around # we want to stop the account from walking around
# in this blinded state, so we hide all exits too. # in this blinded state, so we hide all exits too.
# (channel commands will still work). # (channel commands will still work).
no_exits = True # keep player in the same room no_exits = True # keep account in the same room
no_objs = True # don't allow object commands no_objs = True # don't allow object commands
def at_cmdset_creation(self): def at_cmdset_creation(self):

View file

@ -100,17 +100,17 @@ class BlindedState(DefaultScript):
""" """
This is a timed state. This is a timed state.
This adds a (very limited) cmdset TO THE PLAYER, during a certain time, This adds a (very limited) cmdset TO THE ACCOUNT, during a certain time,
after which the script will close and all functions are after which the script will close and all functions are
restored. It's up to the function starting the script to actually restored. It's up to the function starting the script to actually
set it on the right player object. set it on the right account object.
""" """
def at_script_creation(self): def at_script_creation(self):
""" """
We set up the script here. We set up the script here.
""" """
self.key = "temporary_blinder" self.key = "temporary_blinder"
self.desc = "Temporarily blinds the player for a little while." self.desc = "Temporarily blinds the account for a little while."
self.interval = 20 # seconds self.interval = 20 # seconds
self.start_delay = True # we don't want it to stop until after 20s. self.start_delay = True # we don't want it to stop until after 20s.
self.repeats = 1 # this will go away after interval seconds. self.repeats = 1 # this will go away after interval seconds.
@ -123,7 +123,7 @@ class BlindedState(DefaultScript):
Note that the RedButtonBlind cmdset is defined to completly Note that the RedButtonBlind cmdset is defined to completly
replace the other cmdsets on the stack while it is active replace the other cmdsets on the stack while it is active
(this means that while blinded, only operations in this cmdset (this means that while blinded, only operations in this cmdset
will be possible for the player to perform). It is however will be possible for the account to perform). It is however
not persistent, so should there be a bug in it, we just need not persistent, so should there be a bug in it, we just need
to restart the server to clear out of it during development. to restart the server to clear out of it during development.
""" """
@ -228,7 +228,7 @@ class DeactivateButtonEvent(DefaultScript):
This deactivates the button for a short while (it won't blink, won't This deactivates the button for a short while (it won't blink, won't
close its lid etc). It is meant to be called when the button is pushed close its lid etc). It is meant to be called when the button is pushed
and run as long as the blinded effect lasts. We cannot put these methods and run as long as the blinded effect lasts. We cannot put these methods
in the AddBlindedCmdSet script since that script is defined on the *player* in the AddBlindedCmdSet script since that script is defined on the *account*
whereas this one must be defined on the *button*. whereas this one must be defined on the *button*.
""" """
def at_script_creation(self): def at_script_creation(self):
@ -250,7 +250,7 @@ class DeactivateButtonEvent(DefaultScript):
""" """
# closing the lid will also add the ClosedState script # closing the lid will also add the ClosedState script
self.obj.close_lid() self.obj.close_lid()
# lock the lid so other players can't access it until the # lock the lid so other accounts can't access it until the
# first one's effect has worn off. # first one's effect has worn off.
self.obj.db.lid_locked = True self.obj.db.lid_locked = True
# breaking the lamp also sets a correct desc # breaking the lamp also sets a correct desc

View file

@ -206,7 +206,7 @@ class Mob(tut_objects.TutorialObject):
""" """
targets = [obj for obj in location.contents_get(exclude=self) targets = [obj for obj in location.contents_get(exclude=self)
if obj.has_player and not obj.is_superuser] if obj.has_account and not obj.is_superuser]
return targets[0] if targets else None return targets[0] if targets else None
def set_alive(self, *args, **kwargs): def set_alive(self, *args, **kwargs):
@ -290,9 +290,9 @@ class Mob(tut_objects.TutorialObject):
""" """
Called repeatedly during patrolling mode. In this mode, the Called repeatedly during patrolling mode. In this mode, the
mob scans its surroundings and randomly chooses a viable exit. mob scans its surroundings and randomly chooses a viable exit.
One should lock exits with the traverse:has_player() lock in One should lock exits with the traverse:has_account() lock in
order to block the mob from moving outside its area while order to block the mob from moving outside its area while
allowing player-controlled characters to move normally. allowing account-controlled characters to move normally.
""" """
if random.random() < 0.01 and self.db.irregular_msgs: if random.random() < 0.01 and self.db.irregular_msgs:
self.location.msg_contents(random.choice(self.db.irregular_msgs)) self.location.msg_contents(random.choice(self.db.irregular_msgs))

View file

@ -582,7 +582,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
The CrumblingWall can be examined in various ways, but only if a The CrumblingWall can be examined in various ways, but only if a
lit light source is in the room. The traversal itself is blocked lit light source is in the room. The traversal itself is blocked
by a traverse: lock on the exit that only allows passage if a by a traverse: lock on the exit that only allows passage if a
certain attribute is set on the trying player. certain attribute is set on the trying account.
Important attribute Important attribute
destination - this property must be set to make this a valid exit destination - this property must be set to make this a valid exit
@ -701,7 +701,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
self.reset() self.reset()
def at_failed_traverse(self, traverser): def at_failed_traverse(self, traverser):
"""This is called if the player fails to pass the Exit.""" """This is called if the account fails to pass the Exit."""
traverser.msg("No matter how you try, you cannot force yourself through %s." % self.key) traverser.msg("No matter how you try, you cannot force yourself through %s." % self.key)
def reset(self): def reset(self):
@ -868,7 +868,7 @@ class Weapon(TutorialObject):
When reset, the weapon is simply deleted, unless it has a place When reset, the weapon is simply deleted, unless it has a place
to return to. to return to.
""" """
if self.location.has_player and self.home == self.location: if self.location.has_account and self.home == self.location:
self.location.msg_contents("%s suddenly and magically fades into nothingness, as if it was never there ..." self.location.msg_contents("%s suddenly and magically fades into nothingness, as if it was never there ..."
% self.key) % self.key)
self.delete() self.delete()
@ -1032,7 +1032,7 @@ class WeaponRack(TutorialObject):
Attributes to set on this object: Attributes to set on this object:
available_weapons: list of prototype-keys from available_weapons: list of prototype-keys from
WEAPON_PROTOTYPES, the weapons available in this rack. WEAPON_PROTOTYPES, the weapons available in this rack.
no_more_weapons_msg - error message to return to players no_more_weapons_msg - error message to return to accounts
who already got one weapon from the rack and tries to who already got one weapon from the rack and tries to
grab another one. grab another one.

View file

@ -126,7 +126,7 @@ class CmdTutorialLook(default_cmds.CmdLook):
Usage: Usage:
look <obj> look <obj>
look <room detail> look <room detail>
look *<player> look *<account>
Observes your location, details at your location or objects Observes your location, details at your location or objects
in your vicinity. in your vicinity.
@ -182,7 +182,7 @@ class CmdTutorialLook(default_cmds.CmdLook):
return return
if not hasattr(looking_at_obj, 'return_appearance'): if not hasattr(looking_at_obj, 'return_appearance'):
# this is likely due to us having a player instead # this is likely due to us having an account instead
looking_at_obj = looking_at_obj.character looking_at_obj = looking_at_obj.character
if not looking_at_obj.access(caller, "view"): if not looking_at_obj.access(caller, "view"):
caller.msg("Could not find '%s'." % args) caller.msg("Could not find '%s'." % args)
@ -232,7 +232,7 @@ class TutorialRoom(DefaultRoom):
source_location (Object): the previous location of new_arrival. source_location (Object): the previous location of new_arrival.
""" """
if new_arrival.has_player and not new_arrival.is_superuser: if new_arrival.has_account and not new_arrival.is_superuser:
# this is a character # this is a character
for obj in self.contents_get(exclude=new_arrival): for obj in self.contents_get(exclude=new_arrival):
if hasattr(obj, "at_new_arrival"): if hasattr(obj, "at_new_arrival"):
@ -362,7 +362,7 @@ class IntroRoom(TutorialRoom):
super(IntroRoom, self).at_object_creation() super(IntroRoom, self).at_object_creation()
self.db.tutorial_info = "The first room of the tutorial. " \ self.db.tutorial_info = "The first room of the tutorial. " \
"This assigns the health Attribute to "\ "This assigns the health Attribute to "\
"the player." "the account."
def at_object_receive(self, character, source_location): def at_object_receive(self, character, source_location):
""" """
@ -372,7 +372,7 @@ class IntroRoom(TutorialRoom):
# setup character for the tutorial # setup character for the tutorial
health = self.db.char_health or 20 health = self.db.char_health or 20
if character.has_player: if character.has_account:
character.db.health = health character.db.health = health
character.db.health_max = health character.db.health_max = health
@ -388,7 +388,7 @@ class IntroRoom(TutorialRoom):
# Defines a special west-eastward "bridge"-room, a large room that takes # Defines a special west-eastward "bridge"-room, a large room that takes
# several steps to cross. It is complete with custom commands and a # several steps to cross. It is complete with custom commands and a
# chance of falling off the bridge. This room has no regular exits, # chance of falling off the bridge. This room has no regular exits,
# instead the exitings are handled by custom commands set on the player # instead the exitings are handled by custom commands set on the account
# upon first entering the room. # upon first entering the room.
# #
# Since one can enter the bridge room from both ends, it is # Since one can enter the bridge room from both ends, it is
@ -537,7 +537,7 @@ class CmdLookBridge(Command):
BRIDGE_POS_MESSAGES[bridge_position], BRIDGE_POS_MESSAGES[bridge_position],
random.choice(BRIDGE_MOODS)) random.choice(BRIDGE_MOODS))
chars = [obj for obj in self.obj.contents_get(exclude=caller) if obj.has_player] chars = [obj for obj in self.obj.contents_get(exclude=caller) if obj.has_account]
if chars: if chars:
# we create the You see: message manually here # we create the You see: message manually here
message += "\n You see: %s" % ", ".join("|c%s|n" % char.key for char in chars) message += "\n You see: %s" % ", ".join("|c%s|n" % char.key for char in chars)
@ -606,7 +606,7 @@ class BridgeRoom(WeatherRoom):
The bridge room implements an unsafe bridge. It also enters the player into The bridge room implements an unsafe bridge. It also enters the player into
a state where they get new commands so as to try to cross the bridge. a state where they get new commands so as to try to cross the bridge.
We want this to result in the player getting a special set of We want this to result in the account getting a special set of
commands related to crossing the bridge. The result is that it commands related to crossing the bridge. The result is that it
will take several steps to cross it, despite it being represented will take several steps to cross it, despite it being represented
by only a single room. by only a single room.
@ -659,7 +659,7 @@ class BridgeRoom(WeatherRoom):
This hook is called by the engine whenever the player is moved This hook is called by the engine whenever the player is moved
into this room. into this room.
""" """
if character.has_player: if character.has_account:
# we only run this if the entered object is indeed a player object. # we only run this if the entered object is indeed a player object.
# check so our east/west exits are correctly defined. # check so our east/west exits are correctly defined.
wexit = search_object(self.db.west_exit) wexit = search_object(self.db.west_exit)
@ -682,7 +682,7 @@ class BridgeRoom(WeatherRoom):
""" """
This is triggered when the player leaves the bridge room. This is triggered when the player leaves the bridge room.
""" """
if character.has_player: if character.has_account:
# clean up the position attribute # clean up the position attribute
del character.db.tutorial_bridge_position del character.db.tutorial_bridge_position
@ -876,7 +876,7 @@ class DarkRoom(TutorialRoom):
self.locks.add("view:all()") self.locks.add("view:all()")
self.cmdset.remove(DarkCmdSet) self.cmdset.remove(DarkCmdSet)
self.db.is_lit = True self.db.is_lit = True
for char in (obj for obj in self.contents if obj.has_player): for char in (obj for obj in self.contents if obj.has_account):
# this won't do anything if it is already removed # this won't do anything if it is already removed
char.msg("The room is lit up.") char.msg("The room is lit up.")
else: else:
@ -884,7 +884,7 @@ class DarkRoom(TutorialRoom):
self.db.is_lit = False self.db.is_lit = False
self.locks.add("view:false()") self.locks.add("view:false()")
self.cmdset.add(DarkCmdSet, permanent=True) self.cmdset.add(DarkCmdSet, permanent=True)
for char in (obj for obj in self.contents if obj.has_player): for char in (obj for obj in self.contents if obj.has_account):
if char.is_superuser: if char.is_superuser:
char.msg("You are Superuser, so you are not affected by the dark state.") char.msg("You are Superuser, so you are not affected by the dark state.")
else: else:
@ -895,7 +895,7 @@ class DarkRoom(TutorialRoom):
""" """
Called when an object enters the room. Called when an object enters the room.
""" """
if obj.has_player: if obj.has_account:
# a puppeted object, that is, a Character # a puppeted object, that is, a Character
self._heal(obj) self._heal(obj)
# in case the new guy carries light with them # in case the new guy carries light with them
@ -960,7 +960,7 @@ class TeleportRoom(TutorialRoom):
This hook is called by the engine whenever the player is moved into This hook is called by the engine whenever the player is moved into
this room. this room.
""" """
if not character.has_player: if not character.has_account:
# only act on player characters. # only act on player characters.
return return
# determine if the puzzle is a success or not # determine if the puzzle is a success or not
@ -1020,7 +1020,7 @@ class OutroRoom(TutorialRoom):
""" """
Do cleanup. Do cleanup.
""" """
if character.has_player: if character.has_account:
del character.db.health_max del character.db.health_max
del character.db.health del character.db.health
del character.db.last_climbed del character.db.last_climbed

View file

@ -341,7 +341,7 @@ class WildernessScript(DefaultScript):
old_room.wilderness.at_after_object_leave(obj) old_room.wilderness.at_after_object_leave(obj)
else: else:
for item in old_room.contents: for item in old_room.contents:
if item.has_player: if item.has_account:
# There is still a player in the old room. # There is still a player in the old room.
# Let's create a new room and not touch that old # Let's create a new room and not touch that old
# room. # room.
@ -419,7 +419,7 @@ class WildernessScript(DefaultScript):
return return
for item in room.contents: for item in room.contents:
if item.has_player: if item.has_account:
# There is still a character in that room. We can't get rid of # There is still a character in that room. We can't get rid of
# it just yet # it just yet
break break
@ -457,7 +457,7 @@ class WildernessScript(DefaultScript):
class WildernessRoom(DefaultRoom): class WildernessRoom(DefaultRoom):
""" """
This is a single room inside the wilderness. This room provides a "view" This is a single room inside the wilderness. This room provides a "view"
into the wilderness map. When a player moves around, instead of going to into the wilderness map. When an account moves around, instead of going to
another room as with traditional rooms, they stay in the same room but the another room as with traditional rooms, they stay in the same room but the
room itself changes to display another area of the wilderness. room itself changes to display another area of the wilderness.
""" """
@ -588,7 +588,7 @@ class WildernessRoom(DefaultRoom):
Displays the name of the object in a viewer-aware manner. Displays the name of the object in a viewer-aware manner.
Args: Args:
looker (TypedObject): The object or player that is looking looker (TypedObject): The object or account that is looking
at/getting inforamtion for this object. at/getting inforamtion for this object.
Returns: Returns:

View file

@ -1,7 +1,7 @@
""" """
Commands Commands
Commands describe the input the player can do to the game. Commands describe the input the account can do to the game.
""" """
@ -169,17 +169,17 @@ class Command(BaseCommand):
# self.rhs = rhs # self.rhs = rhs
# self.rhslist = rhslist # self.rhslist = rhslist
# #
# # if the class has the player_caller property set on itself, we make # # if the class has the account_caller property set on itself, we make
# # sure that self.caller is always the player if possible. We also create # # sure that self.caller is always the account if possible. We also create
# # a special property "character" for the puppeted object, if any. This # # a special property "character" for the puppeted object, if any. This
# # is convenient for commands defined on the Player only. # # is convenient for commands defined on the Account only.
# if hasattr(self, "player_caller") and self.player_caller: # if hasattr(self, "account_caller") and self.account_caller:
# if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"): # if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
# # caller is an Object/Character # # caller is an Object/Character
# self.character = self.caller # self.character = self.caller
# self.caller = self.caller.player # self.caller = self.caller.account
# elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"): # elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
# # caller was already a Player # # caller was already an Account
# self.character = self.caller.get_puppet(self.session) # self.character = self.caller.get_puppet(self.session)
# else: # else:
# self.character = None # self.character = None

View file

@ -20,7 +20,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
""" """
The `CharacterCmdSet` contains general in-game commands like `look`, The `CharacterCmdSet` contains general in-game commands like `look`,
`get`, etc available on in-game Character objects. It is merged with `get`, etc available on in-game Character objects. It is merged with
the `PlayerCmdSet` when a Player puppets a Character. the `AccountCmdSet` when an Account puppets a Character.
""" """
key = "DefaultCharacter" key = "DefaultCharacter"
@ -34,20 +34,20 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
# #
class PlayerCmdSet(default_cmds.PlayerCmdSet): class AccountCmdSet(default_cmds.AccountCmdSet):
""" """
This is the cmdset available to the Player at all times. It is This is the cmdset available to the Account at all times. It is
combined with the `CharacterCmdSet` when the Player puppets a combined with the `CharacterCmdSet` when the Account puppets a
Character. It holds game-account-specific commands, channel Character. It holds game-account-specific commands, channel
commands, etc. commands, etc.
""" """
key = "DefaultPlayer" key = "DefaultAccount"
def at_cmdset_creation(self): def at_cmdset_creation(self):
""" """
Populates the cmdset Populates the cmdset
""" """
super(PlayerCmdSet, self).at_cmdset_creation() super(AccountCmdSet, self).at_cmdset_creation()
# #
# any commands you add below will overload the default ones. # any commands you add below will overload the default ones.
# #

View file

@ -5,7 +5,7 @@ The serversession is the Server-side in-memory representation of a
user connecting to the game. Evennia manages one Session per user connecting to the game. Evennia manages one Session per
connection to the game. So a user logged into the game with multiple connection to the game. So a user logged into the game with multiple
clients (if Evennia is configured to allow that) will have multiple clients (if Evennia is configured to allow that) will have multiple
sessions tied to one Player object. All communication between Evennia sessions tied to one Account object. All communication between Evennia
and the real-world user goes through the Session(s) associated with that user. and the real-world user goes through the Session(s) associated with that user.
It should be noted that modifying the Session object is not usually It should be noted that modifying the Session object is not usually
@ -28,8 +28,8 @@ class ServerSession(BaseServerSession):
This class represents a player's session and is a template for This class represents a player's session and is a template for
individual protocols to communicate with Evennia. individual protocols to communicate with Evennia.
Each player gets one or more sessions assigned to them whenever they connect Each account gets one or more sessions assigned to them whenever they connect
to the game server. All communication between game and player goes to the game server. All communication between game and account goes
through their session(s). through their session(s).
""" """
pass pass

View file

@ -2,7 +2,7 @@
Channel Channel
The channel class represents the out-of-character chat-room usable by The channel class represents the out-of-character chat-room usable by
Players in-game. It is mostly overloaded to change its appearance, but Accounts in-game. It is mostly overloaded to change its appearance, but
channels can be used to implement many different forms of message channels can be used to implement many different forms of message
distribution systems. distribution systems.
@ -18,9 +18,9 @@ class Channel(DefaultChannel):
""" """
Working methods: Working methods:
at_channel_creation() - called once, when the channel is created at_channel_creation() - called once, when the channel is created
has_connection(player) - check if the given player listens to this channel has_connection(account) - check if the given account listens to this channel
connect(player) - connect player to this channel connect(account) - connect account to this channel
disconnect(player) - disconnect player from channel disconnect(account) - disconnect account from channel
access(access_obj, access_type='listen', default=False) - check the access(access_obj, access_type='listen', default=False) - check the
access on this channel (default access_type is listen) access on this channel (default access_type is listen)
delete() - delete this channel delete() - delete this channel
@ -33,8 +33,8 @@ class Channel(DefaultChannel):
tempmsg(msg, header=None, senders=None) - wrapper for sending non-persistent tempmsg(msg, header=None, senders=None) - wrapper for sending non-persistent
messages. messages.
distribute_message(msg, online=False) - send a message to all distribute_message(msg, online=False) - send a message to all
connected players on channel, optionally sending only connected accounts on channel, optionally sending only
to players that are currently online (optimized for very large sends) to accounts that are currently online (optimized for very large sends)
Useful hooks: Useful hooks:
channel_prefix(msg, emit=False) - how the channel should be channel_prefix(msg, emit=False) - how the channel should be

View file

@ -1,7 +1,7 @@
""" """
Characters Characters
Characters are (by default) Objects setup to be puppeted by Players. Characters are (by default) Objects setup to be puppeted by Accounts.
They are what you "see" in game. The Character class in this module They are what you "see" in game. The Character class in this module
is setup to be the "default" character type created by the default is setup to be the "default" character type created by the default
creation commands. creation commands.
@ -19,14 +19,14 @@ class Character(DefaultCharacter):
and its commands only be called by itself, not anyone else. and its commands only be called by itself, not anyone else.
(to change things, use at_object_creation() instead). (to change things, use at_object_creation() instead).
at_after_move(source_location) - Launches the "look" command after every move. at_after_move(source_location) - Launches the "look" command after every move.
at_post_unpuppet(player) - when Player disconnects from the Character, we at_post_unpuppet(account) - when Account disconnects from the Character, we
store the current location in the pre_logout_location Attribute and store the current location in the pre_logout_location Attribute and
move it to a None-location so the "unpuppeted" character move it to a None-location so the "unpuppeted" character
object does not need to stay on grid. Echoes "Player has disconnected" object does not need to stay on grid. Echoes "Account has disconnected"
to the room. to the room.
at_pre_puppet - Just before Player re-connects, retrieves the character's at_pre_puppet - Just before Account re-connects, retrieves the character's
pre_logout_location Attribute and move it back on the grid. pre_logout_location Attribute and move it back on the grid.
at_post_puppet - Echoes "PlayerName has entered the game" to the room. at_post_puppet - Echoes "AccountName has entered the game" to the room.
""" """
pass pass

View file

@ -40,16 +40,16 @@ class Object(DefaultObject):
date_created (string) - time stamp of object creation date_created (string) - time stamp of object creation
permissions (list of strings) - list of permission strings permissions (list of strings) - list of permission strings
player (Player) - controlling player (if any, only set together with account (Account) - controlling account (if any, only set together with
sessid below) sessid below)
sessid (int, read-only) - session id (if any, only set together with sessid (int, read-only) - session id (if any, only set together with
player above). Use `sessions` handler to get the account above). Use `sessions` handler to get the
Sessions directly. Sessions directly.
location (Object) - current location. Is None if this is a room location (Object) - current location. Is None if this is a room
home (Object) - safety start-location home (Object) - safety start-location
sessions (list of Sessions, read-only) - returns all sessions connected sessions (list of Sessions, read-only) - returns all sessions connected
to this object to this object
has_player (bool, read-only)- will only return *connected* players has_account (bool, read-only)- will only return *connected* accounts
contents (list of Objects, read-only) - returns all objects inside this contents (list of Objects, read-only) - returns all objects inside this
object (including exits) object (including exits)
exits (list of Objects, read-only) - returns all exits from this exits (list of Objects, read-only) - returns all exits from this
@ -73,7 +73,7 @@ class Object(DefaultObject):
* Helper methods (see src.objects.objects.py for full headers) * Helper methods (see src.objects.objects.py for full headers)
search(ostring, global_search=False, attribute_name=None, search(ostring, global_search=False, attribute_name=None,
use_nicks=False, location=None, ignore_errors=False, player=False) use_nicks=False, location=None, ignore_errors=False, account=False)
execute_cmd(raw_string) execute_cmd(raw_string)
msg(text=None, **kwargs) msg(text=None, **kwargs)
msg_contents(message, exclude=None, from_obj=None, **kwargs) msg_contents(message, exclude=None, from_obj=None, **kwargs)
@ -105,14 +105,14 @@ class Object(DefaultObject):
requests a cmdset from this object. The kwargs are requests a cmdset from this object. The kwargs are
not normally used unless the cmdset is created not normally used unless the cmdset is created
dynamically (see e.g. Exits). dynamically (see e.g. Exits).
at_pre_puppet(player)- (player-controlled objects only) called just at_pre_puppet(account)- (account-controlled objects only) called just
before puppeting before puppeting
at_post_puppet() - (player-controlled objects only) called just at_post_puppet() - (account-controlled objects only) called just
after completing connection player<->object after completing connection account<->object
at_pre_unpuppet() - (player-controlled objects only) called just at_pre_unpuppet() - (account-controlled objects only) called just
before un-puppeting before un-puppeting
at_post_unpuppet(player) - (player-controlled objects only) called just at_post_unpuppet(account) - (account-controlled objects only) called just
after disconnecting player<->object link after disconnecting account<->object link
at_server_reload() - called before server is reloaded at_server_reload() - called before server is reloaded
at_server_shutdown() - called just before server is fully shut down at_server_shutdown() - called just before server is fully shut down

View file

@ -1,102 +0,0 @@
"""
Player
The Player represents the game "account" and each login has only one
Player object. A Player is what chats on default channels but has no
other in-game-world existence. Rather the Player puppets Objects (such
as Characters) in order to actually participate in the game world.
Guest
Guest players are simple low-level accounts that are created/deleted
on the fly and allows users to test the game without the commitment
of a full registration. Guest accounts are deactivated by default; to
activate them, add the following line to your settings file:
GUEST_ENABLED = True
You will also need to modify the connection screen to reflect the
possibility to connect with a guest account. The setting file accepts
several more options for customizing the Guest account system.
"""
from evennia import DefaultPlayer, DefaultGuest
class Player(DefaultPlayer):
"""
This class describes the actual OOC player (i.e. the user connecting
to the MUD). It does NOT have visual appearance in the game world (that
is handled by the character which is connected to this). Comm channels
are attended/joined using this object.
It can be useful e.g. for storing configuration options for your game, but
should generally not hold any character-related info (that's best handled
on the character level).
Can be set using BASE_PLAYER_TYPECLASS.
* available properties
key (string) - name of player
name (string)- wrapper for user.username
aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings.
dbref (int, read-only) - unique #id-number. Also "id" can be used.
date_created (string) - time stamp of object creation
permissions (list of strings) - list of permission strings
user (User, read-only) - django User authorization object
obj (Object) - game object controlled by player. 'character' can also be used.
sessions (list of Sessions) - sessions connected to this player
is_superuser (bool, read-only) - if the connected user is a superuser
* Handlers
locks - lock-handler: use locks.add() to add new lock strings
db - attribute-handler: store/retrieve database attributes on this self.db.myattr=val, val=self.db.myattr
ndb - non-persistent attribute handler: same as db but does not create a database entry when storing data
scripts - script-handler. Add new scripts to object with scripts.add()
cmdset - cmdset-handler. Use cmdset.add() to add new cmdsets to object
nicks - nick-handler. New nicks with nicks.add().
* Helper methods
msg(text=None, **kwargs)
swap_character(new_character, delete_old_character=False)
execute_cmd(raw_string, session=None)
search(ostring, global_search=False, attribute_name=None, use_nicks=False, location=None, ignore_errors=False, player=False)
is_typeclass(typeclass, exact=False)
swap_typeclass(new_typeclass, clean_attributes=False, no_default=True)
access(accessing_obj, access_type='read', default=False)
check_permstring(permstring)
* Hook methods (when re-implementation, remember methods need to have self as first arg)
basetype_setup()
at_player_creation()
- note that the following hooks are also found on Objects and are
usually handled on the character level:
at_init()
at_cmdset_get(**kwargs)
at_first_login()
at_post_login(session=None)
at_disconnect()
at_message_receive()
at_message_send()
at_server_reload()
at_server_shutdown()
"""
pass
class Guest(DefaultGuest):
"""
This class is used for guest logins. Unlike Players, Guests and their
characters are deleted after disconnection.
"""
pass

View file

@ -28,38 +28,38 @@ MUX Name: Affects: Effect:
DefaultLock: Exits: controls who may traverse the exit to DefaultLock: Exits: controls who may traverse the exit to
its destination. its destination.
Evennia: "traverse:<lockfunc()>" Evennia: "traverse:<lockfunc()>"
Rooms: controls whether the player sees the Rooms: controls whether the account sees the
SUCC or FAIL message for the room SUCC or FAIL message for the room
following the room description when following the room description when
looking at the room. looking at the room.
Evennia: Custom typeclass Evennia: Custom typeclass
Players/Things: controls who may GET the object. Accounts/Things: controls who may GET the object.
Evennia: "get:<lockfunc()" Evennia: "get:<lockfunc()"
EnterLock: Players/Things: controls who may ENTER the object EnterLock: Accounts/Things: controls who may ENTER the object
Evennia: Evennia:
GetFromLock: All but Exits: controls who may gets things from a GetFromLock: All but Exits: controls who may gets things from a
given location. given location.
Evennia: Evennia:
GiveLock: Players/Things: controls who may give the object. GiveLock: Accounts/Things: controls who may give the object.
Evennia: Evennia:
LeaveLock: Players/Things: controls who may LEAVE the object. LeaveLock: Accounts/Things: controls who may LEAVE the object.
Evennia: Evennia:
LinkLock: All but Exits: controls who may link to the location LinkLock: All but Exits: controls who may link to the location
if the location is LINK_OK (for linking if the location is LINK_OK (for linking
exits or setting drop-tos) or ABODE (for exits or setting drop-tos) or ABODE (for
setting homes) setting homes)
Evennia: Evennia:
MailLock: Players: controls who may @mail the player. MailLock: Accounts: controls who may @mail the account.
Evennia: Evennia:
OpenLock: All but Exits: controls who may open an exit. OpenLock: All but Exits: controls who may open an exit.
Evennia: Evennia:
PageLock: Players: controls who may page the player. PageLock: Accounts: controls who may page the account.
Evennia: "send:<lockfunc()>" Evennia: "send:<lockfunc()>"
ParentLock: All: controls who may make @parent links to ParentLock: All: controls who may make @parent links to
the object. the object.
Evennia: Typeclasses and Evennia: Typeclasses and
"puppet:<lockstring()>" "puppet:<lockstring()>"
ReceiveLock: Players/Things: controls who may give things to the ReceiveLock: Accounts/Things: controls who may give things to the
object. object.
Evennia: Evennia:
SpeechLock: All but Exits: controls who may speak in that location SpeechLock: All but Exits: controls who may speak in that location
@ -95,11 +95,11 @@ from evennia.utils import utils
_PERMISSION_HIERARCHY = [pe.lower() for pe in settings.PERMISSION_HIERARCHY] _PERMISSION_HIERARCHY = [pe.lower() for pe in settings.PERMISSION_HIERARCHY]
def _to_player(accessing_obj): def _to_account(accessing_obj):
"Helper function. Makes sure an accessing object is a player object" "Helper function. Makes sure an accessing object is an account object"
if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject"): if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject"):
# an object. Convert to player. # an object. Convert to account.
accessing_obj = accessing_obj.player accessing_obj = accessing_obj.account
return accessing_obj return accessing_obj
@ -149,11 +149,11 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
If the given permission is part of settings.PERMISSION_HIERARCHY, If the given permission is part of settings.PERMISSION_HIERARCHY,
permission is also granted to all ranks higher up in the hierarchy. permission is also granted to all ranks higher up in the hierarchy.
If accessing_object is an Object controlled by a Player, the If accessing_object is an Object controlled by an Account, the
permissions of the Player is used unless the Attribute _quell permissions of the Account is used unless the Attribute _quell
is set to True on the Object. In this case however, the is set to True on the Object. In this case however, the
LOWEST hieararcy-permission of the Player/Object-pair will be used LOWEST hieararcy-permission of the Account/Object-pair will be used
(this is order to avoid Players potentially escalating their own permissions (this is order to avoid Accounts potentially escalating their own permissions
by use of a higher-level Object) by use of a higher-level Object)
""" """
@ -166,30 +166,30 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
except (AttributeError, IndexError): except (AttributeError, IndexError):
return False return False
if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and accessing_obj.player: if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and accessing_obj.account:
player = accessing_obj.player account = accessing_obj.account
# we strip eventual plural forms, so Builders == Builder # we strip eventual plural forms, so Builders == Builder
perms_player = [p.lower().rstrip("s") for p in player.permissions.all()] perms_account = [p.lower().rstrip("s") for p in account.permissions.all()]
is_quell = player.attributes.get("_quell") is_quell = account.attributes.get("_quell")
if permission in _PERMISSION_HIERARCHY: if permission in _PERMISSION_HIERARCHY:
# check hierarchy without allowing escalation obj->player # check hierarchy without allowing escalation obj->account
hpos_target = _PERMISSION_HIERARCHY.index(permission) hpos_target = _PERMISSION_HIERARCHY.index(permission)
hpos_player = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_player] hpos_account = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_account]
hpos_player = hpos_player and hpos_player[-1] or -1 hpos_account = hpos_account and hpos_account[-1] or -1
if is_quell: if is_quell:
hpos_object = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_object] hpos_object = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_object]
hpos_object = hpos_object and hpos_object[-1] or -1 hpos_object = hpos_object and hpos_object[-1] or -1
if gtmode: if gtmode:
return hpos_target < min(hpos_player, hpos_object) return hpos_target < min(hpos_account, hpos_object)
else: else:
return hpos_target <= min(hpos_player, hpos_object) return hpos_target <= min(hpos_account, hpos_object)
elif gtmode: elif gtmode:
return hpos_target < hpos_player return hpos_target < hpos_account
else: else:
return hpos_target <= hpos_player return hpos_target <= hpos_account
elif not is_quell and permission in perms_player: elif not is_quell and permission in perms_account:
# if we get here, check player perms first, otherwise # if we get here, check account perms first, otherwise
# continue as normal # continue as normal
return True return True
@ -217,7 +217,7 @@ def perm_above(accessing_obj, accessed_obj, *args, **kwargs):
def pperm(accessing_obj, accessed_obj, *args, **kwargs): def pperm(accessing_obj, accessed_obj, *args, **kwargs):
""" """
The basic permission-checker only for Player objects. Ignores case. The basic permission-checker only for Account objects. Ignores case.
Usage: Usage:
pperm(<permission>) pperm(<permission>)
@ -227,17 +227,17 @@ def pperm(accessing_obj, accessed_obj, *args, **kwargs):
is part of _PERMISSION_HIERARCHY, permission is also granted is part of _PERMISSION_HIERARCHY, permission is also granted
to all ranks higher up in the hierarchy. to all ranks higher up in the hierarchy.
""" """
return perm(_to_player(accessing_obj), accessed_obj, *args, **kwargs) return perm(_to_account(accessing_obj), accessed_obj, *args, **kwargs)
def pperm_above(accessing_obj, accessed_obj, *args, **kwargs): def pperm_above(accessing_obj, accessed_obj, *args, **kwargs):
""" """
Only allow Player objects with a permission *higher* in the permission Only allow Account objects with a permission *higher* in the permission
hierarchy than the one given. If there is no such higher rank, hierarchy than the one given. If there is no such higher rank,
it's assumed we refer to superuser. If no hierarchy is defined, it's assumed we refer to superuser. If no hierarchy is defined,
this function has no meaning and returns False. this function has no meaning and returns False.
""" """
return perm_above(_to_player(accessing_obj), accessed_obj, *args, **kwargs) return perm_above(_to_account(accessing_obj), accessed_obj, *args, **kwargs)
def dbref(accessing_obj, accessed_obj, *args, **kwargs): def dbref(accessing_obj, accessed_obj, *args, **kwargs):
@ -263,9 +263,9 @@ def dbref(accessing_obj, accessed_obj, *args, **kwargs):
def pdbref(accessing_obj, accessed_obj, *args, **kwargs): def pdbref(accessing_obj, accessed_obj, *args, **kwargs):
""" """
Same as dbref, but making sure accessing_obj is a player. Same as dbref, but making sure accessing_obj is an account.
""" """
return dbref(_to_player(accessing_obj), accessed_obj, *args, **kwargs) return dbref(_to_account(accessing_obj), accessed_obj, *args, **kwargs)
def id(accessing_obj, accessed_obj, *args, **kwargs): def id(accessing_obj, accessed_obj, *args, **kwargs):
@ -274,8 +274,8 @@ def id(accessing_obj, accessed_obj, *args, **kwargs):
def pid(accessing_obj, accessed_obj, *args, **kwargs): def pid(accessing_obj, accessed_obj, *args, **kwargs):
"Alias to dbref, for Players" "Alias to dbref, for Accounts"
return dbref(_to_player(accessing_obj), accessed_obj, *args, **kwargs) return dbref(_to_account(accessing_obj), accessed_obj, *args, **kwargs)
# this is more efficient than multiple if ... elif statments # this is more efficient than multiple if ... elif statments
@ -566,15 +566,15 @@ def superuser(*args, **kwargs):
""" """
return False return False
def has_player(accessing_obj, accessed_obj, *args, **kwargs): def has_account(accessing_obj, accessed_obj, *args, **kwargs):
""" """
Only returns true if accessing_obj has_player is true, that is, Only returns true if accessing_obj has_account is true, that is,
this is a player-controlled object. It fails on actual players! this is an account-controlled object. It fails on actual accounts!
This is a useful lock for traverse-locking Exits to restrain NPC This is a useful lock for traverse-locking Exits to restrain NPC
mobiles from moving outside their areas. mobiles from moving outside their areas.
""" """
return hasattr(accessing_obj, "has_player") and accessing_obj.has_player return hasattr(accessing_obj, "has_account") and accessing_obj.has_account
def serversetting(accessing_obj, accessed_obj, *args, **kwargs): def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
""" """

View file

@ -271,10 +271,10 @@ class LockHandler(object):
def cache_lock_bypass(self, obj): def cache_lock_bypass(self, obj):
""" """
We cache superuser bypass checks here for efficiency. This We cache superuser bypass checks here for efficiency. This
needs to be re-run when a player is assigned to a character. needs to be re-run when an account is assigned to a character.
We need to grant access to superusers. We need to check both We need to grant access to superusers. We need to check both
directly on the object (players), through obj.player and using directly on the object (accounts), through obj.account and using
the get_player() method (this sits on serversessions, in some the get_account() method (this sits on serversessions, in some
rare cases where a check is done before the login process has rare cases where a check is done before the login process has
yet been fully finalized) yet been fully finalized)
@ -450,8 +450,8 @@ class LockHandler(object):
except AttributeError: except AttributeError:
# happens before session is initiated. # happens before session is initiated.
if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) or (hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser)
or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))): or (hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
return True return True
# no superuser or bypass -> normal lock operation # no superuser or bypass -> normal lock operation
@ -511,8 +511,8 @@ class LockHandler(object):
return True return True
except AttributeError: except AttributeError:
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) or (hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser)
or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser))): or (hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
return True return True
if not ":" in lockstring: if not ":" in lockstring:
lockstring = "%s:%s" % ("_dummy", lockstring) lockstring = "%s:%s" % ("_dummy", lockstring)

View file

@ -81,9 +81,9 @@ class ObjectDBAdmin(admin.ModelAdmin):
""" """
inlines = [ObjectTagInline, ObjectAttributeInline] inlines = [ObjectTagInline, ObjectAttributeInline]
list_display = ('id', 'db_key', 'db_player', 'db_typeclass_path') list_display = ('id', 'db_key', 'db_account', 'db_typeclass_path')
list_display_links = ('id', 'db_key') list_display_links = ('id', 'db_key')
ordering = ['db_player', 'db_typeclass_path', 'id'] ordering = ['db_account', 'db_typeclass_path', 'id']
search_fields = ['^db_key', 'db_typeclass_path'] search_fields = ['^db_key', 'db_typeclass_path']
raw_id_fields = ('db_destination', 'db_location', 'db_home') raw_id_fields = ('db_destination', 'db_location', 'db_home')

View file

@ -35,7 +35,7 @@ class ObjectDBManager(TypedObjectManager):
get_dbref_range get_dbref_range
object_totals object_totals
typeclass_search typeclass_search
get_object_with_player get_object_with_account
get_objs_with_key_and_typeclass get_objs_with_key_and_typeclass
get_objs_with_attr get_objs_with_attr
get_objs_with_attr_match get_objs_with_attr_match
@ -53,18 +53,18 @@ class ObjectDBManager(TypedObjectManager):
# ObjectManager Get methods # ObjectManager Get methods
# #
# player related # account related
def get_object_with_player(self, ostring, exact=True, candidates=None): def get_object_with_account(self, ostring, exact=True, candidates=None):
""" """
Search for an object based on its player's name or dbref. Search for an object based on its account's name or dbref.
Args: Args:
ostring (str or int): Search criterion or dbref. Searching ostring (str or int): Search criterion or dbref. Searching
for a player is sometimes initiated by appending an `*` to for an account is sometimes initiated by appending an `*` to
the beginning of the search criterion (e.g. in the beginning of the search criterion (e.g. in
local_and_global_search). This is stripped here. local_and_global_search). This is stripped here.
exact (bool, optional): Require an exact player match. exact (bool, optional): Require an exact account match.
candidates (list, optional): Only search among this list of possible candidates (list, optional): Only search among this list of possible
object candidates. object candidates.
@ -81,9 +81,9 @@ class ObjectDBManager(TypedObjectManager):
cand_restriction = candidates is not None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) cand_restriction = candidates is not None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates)
if obj]) or Q() if obj]) or Q()
if exact: if exact:
return self.filter(cand_restriction & Q(db_player__username__iexact=ostring)) return self.filter(cand_restriction & Q(db_account__username__iexact=ostring))
else: # fuzzy matching else: # fuzzy matching
ply_cands = self.filter(cand_restriction & Q(playerdb__username__istartswith=ostring) ply_cands = self.filter(cand_restriction & Q(accountdb__username__istartswith=ostring)
).values_list("db_key", flat=True) ).values_list("db_key", flat=True)
if candidates: if candidates:
index_matches = string_partial_matching(ply_cands, ostring, ret_index=True) index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
@ -503,7 +503,7 @@ class ObjectDBManager(TypedObjectManager):
def clear_all_sessids(self): def clear_all_sessids(self):
""" """
Clear the db_sessid field of all objects having also the Clear the db_sessid field of all objects having also the
db_player field set. db_account field set.
""" """
self.filter(db_sessid__isnull=False).update(db_sessid=None) self.filter(db_sessid__isnull=False).update(db_sessid=None)

View file

@ -141,16 +141,16 @@ class ObjectDB(TypedObject):
The ObjectDB adds the following properties: The ObjectDB adds the following properties:
- player - optional connected player (always together with sessid) - account - optional connected account (always together with sessid)
- sessid - optional connection session id (always together with player) - sessid - optional connection session id (always together with account)
- location - in-game location of object - location - in-game location of object
- home - safety location for object (handler) - home - safety location for object (handler)
- scripts - scripts assigned to object (handler from typeclass) - scripts - scripts assigned to object (handler from typeclass)
- cmdset - active cmdset on object (handler from typeclass) - cmdset - active cmdset on object (handler from typeclass)
- aliases - aliases for this object (property) - aliases - aliases for this object (property)
- nicks - nicknames for *other* things in Evennia (handler) - nicks - nicknames for *other* things in Evennia (handler)
- sessions - sessions connected to this object (see also player) - sessions - sessions connected to this object (see also account)
- has_player - bool if an active player is currently connected - has_account - bool if an active account is currently connected
- contents - other objects having this object as location - contents - other objects having this object as location
- exits - exits from this object - exits - exits from this object
@ -169,14 +169,14 @@ class ObjectDB(TypedObject):
# self.key instead). The wrappers are created at the metaclass level and # self.key instead). The wrappers are created at the metaclass level and
# will automatically save and cache the data more efficiently. # will automatically save and cache the data more efficiently.
# If this is a character object, the player is connected here. # If this is a character object, the account is connected here.
db_account = models.ForeignKey("accounts.AccountDB", null=True, verbose_name='account', on_delete=models.SET_NULL, db_account = models.ForeignKey("accounts.AccountDB", null=True, verbose_name='account', on_delete=models.SET_NULL,
help_text='an Account connected to this object, if any.') help_text='an Account connected to this object, if any.')
# the session id associated with this player, if any # the session id associated with this account, if any
db_sessid = models.CharField(null=True, max_length=32, validators=[validate_comma_separated_integer_list], db_sessid = models.CharField(null=True, max_length=32, validators=[validate_comma_separated_integer_list],
verbose_name="session id", verbose_name="session id",
help_text="csv list of session ids of connected Player, if any.") help_text="csv list of session ids of connected Account, if any.")
# The location in the game world. Since this one is likely # The location in the game world. Since this one is likely
# to change often, we set this with the 'location' property # to change often, we set this with the 'location' property
# to transparently handle Typeclassing. # to transparently handle Typeclassing.

View file

@ -1,6 +1,6 @@
""" """
This module defines the basic `DefaultObject` and its children This module defines the basic `DefaultObject` and its children
`DefaultCharacter`, `DefaultPlayer`, `DefaultRoom` and `DefaultExit`. `DefaultCharacter`, `DefaultAccount`, `DefaultRoom` and `DefaultExit`.
These are the (default) starting points for all in-game visible These are the (default) starting points for all in-game visible
entities. entities.
@ -205,9 +205,9 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
return ObjectSessionHandler(self) return ObjectSessionHandler(self)
@property @property
def has_player(self): def has_account(self):
""" """
Convenience property for checking if an active player is Convenience property for checking if an active account is
currently connected to this object. currently connected to this object.
""" """
@ -216,11 +216,11 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
@property @property
def is_superuser(self): def is_superuser(self):
""" """
Check if user has a player, and if so, if it is a superuser. Check if user has an account, and if so, if it is a superuser.
""" """
return self.db_player and self.db_player.is_superuser \ return self.db_account and self.db_account.is_superuser \
and not self.db_player.attributes.get("_quell") and not self.db_account.attributes.get("_quell")
def contents_get(self, exclude=None): def contents_get(self, exclude=None):
""" """
@ -259,7 +259,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
Displays the name of the object in a viewer-aware manner. Displays the name of the object in a viewer-aware manner.
Args: Args:
looker (TypedObject): The object or player that is looking looker (TypedObject): The object or account that is looking
at/getting inforamtion for this object. at/getting inforamtion for this object.
Returns: Returns:
@ -349,7 +349,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
otherwise it will return a list of 0, 1 or more matches. otherwise it will return a list of 0, 1 or more matches.
Notes: Notes:
To find Players, use eg. `evennia.player_search`. If To find Accounts, use eg. `evennia.account_search`. If
`quiet=False`, error messages will be handled by `quiet=False`, error messages will be handled by
`settings.SEARCH_AT_RESULT` and echoed automatically (on `settings.SEARCH_AT_RESULT` and echoed automatically (on
error, return will be `None`). If `quiet=True`, the error error, return will be `None`). If `quiet=True`, the error
@ -367,7 +367,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
if use_nicks: if use_nicks:
# do nick-replacement on search # do nick-replacement on search
searchdata = self.nicks.nickreplace(searchdata, categories=("object", "player"), include_player=True) searchdata = self.nicks.nickreplace(searchdata, categories=("object", "account"), include_account=True)
if (global_search or (is_string and searchdata.startswith("#") and if (global_search or (is_string and searchdata.startswith("#") and
len(searchdata) > 1 and searchdata[1:].isdigit())): len(searchdata) > 1 and searchdata[1:].isdigit())):
@ -405,19 +405,19 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
return _AT_SEARCH_RESULT(results, self, query=searchdata, return _AT_SEARCH_RESULT(results, self, query=searchdata,
nofound_string=nofound_string, multimatch_string=multimatch_string) nofound_string=nofound_string, multimatch_string=multimatch_string)
def search_player(self, searchdata, quiet=False): def search_account(self, searchdata, quiet=False):
""" """
Simple shortcut wrapper to search for players, not characters. Simple shortcut wrapper to search for accounts, not characters.
Args: Args:
searchdata (str): Search criterion - the key or dbref of the player searchdata (str): Search criterion - the key or dbref of the account
to search for. If this is "here" or "me", search to search for. If this is "here" or "me", search
for the player connected to this object. for the account connected to this object.
quiet (bool): Returns the results as a list rather than quiet (bool): Returns the results as a list rather than
echo eventual standard error messages. Default `False`. echo eventual standard error messages. Default `False`.
Returns: Returns:
result (Player, None or list): Just what is returned depends on result (Account, None or list): Just what is returned depends on
the `quiet` setting: the `quiet` setting:
- `quiet=True`: No match or multumatch auto-echoes errors - `quiet=True`: No match or multumatch auto-echoes errors
to self.msg, then returns `None`. The esults are passed to self.msg, then returns `None`. The esults are passed
@ -426,15 +426,15 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
unique match, this will be returned. unique match, this will be returned.
- `quiet=True`: No automatic error messaging is done, and - `quiet=True`: No automatic error messaging is done, and
what is returned is always a list with 0, 1 or more what is returned is always a list with 0, 1 or more
matching Players. matching Accounts.
""" """
if isinstance(searchdata, basestring): if isinstance(searchdata, basestring):
# searchdata is a string; wrap some common self-references # searchdata is a string; wrap some common self-references
if searchdata.lower() in ("me", "self",): if searchdata.lower() in ("me", "self",):
return [self.player] if quiet else self.player return [self.account] if quiet else self.account
results = self.player.__class__.objects.player_search(searchdata) results = self.account.__class__.objects.account_search(searchdata)
if quiet: if quiet:
return results return results
@ -445,7 +445,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
Do something as this object. This is never called normally, Do something as this object. This is never called normally,
it's only used when wanting specifically to let an object be it's only used when wanting specifically to let an object be
the caller of a command. It makes use of nicks of eventual the caller of a command. It makes use of nicks of eventual
connected players as well. connected accounts as well.
Args: Args:
raw_string (string): Raw command input raw_string (string): Raw command input
@ -473,7 +473,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
# nick replacement - we require full-word matching. # nick replacement - we require full-word matching.
# do text encoding conversion # do text encoding conversion
raw_string = to_unicode(raw_string) raw_string = to_unicode(raw_string)
raw_string = self.nicks.nickreplace(raw_string, categories=("inputline", "channel"), include_player=True) raw_string = self.nicks.nickreplace(raw_string, categories=("inputline", "channel"), include_account=True)
return cmdhandler.cmdhandler(self, raw_string, callertype="object", session=session, **kwargs) return cmdhandler.cmdhandler(self, raw_string, callertype="object", session=session, **kwargs)
def msg(self, text=None, from_obj=None, session=None, options=None, **kwargs): def msg(self, text=None, from_obj=None, session=None, options=None, **kwargs):
@ -750,7 +750,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
def clear_contents(self): def clear_contents(self):
""" """
Moves all objects (players/things) to their home location or Moves all objects (accounts/things) to their home location or
to default home. to default home.
""" """
# Gather up everything that thinks this is its location. # Gather up everything that thinks this is its location.
@ -781,13 +781,13 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
logger.log_err(string % (obj.name, obj.dbid)) logger.log_err(string % (obj.name, obj.dbid))
return return
if obj.has_player: if obj.has_account:
if home: if home:
string = "Your current location has ceased to exist," string = "Your current location has ceased to exist,"
string += " moving you to %s(#%d)." string += " moving you to %s(#%d)."
obj.msg(_(string) % (home.name, home.dbid)) obj.msg(_(string) % (home.name, home.dbid))
else: else:
# Famous last words: The player should never see this. # Famous last words: The account should never see this.
string = "This place should not exist ... contact an admin." string = "This place should not exist ... contact an admin."
obj.msg(_(string)) obj.msg(_(string))
obj.move_to(home) obj.move_to(home)
@ -853,16 +853,16 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
self.delete_iter += 1 self.delete_iter += 1
# See if we need to kick the player off. # See if we need to kick the account off.
for session in self.sessions.all(): for session in self.sessions.all():
session.msg(_("Your character %s has been destroyed.") % self.key) session.msg(_("Your character %s has been destroyed.") % self.key)
# no need to disconnect, Player just jumps to OOC mode. # no need to disconnect, Account just jumps to OOC mode.
# sever the connection (important!) # sever the connection (important!)
if self.player: if self.account:
for session in self.sessions.all(): for session in self.sessions.all():
self.player.unpuppet_object(session) self.account.unpuppet_object(session)
self.player = None self.account = None
for script in _ScriptDB.objects.get_all_scripts_on_obj(self): for script in _ScriptDB.objects.get_all_scripts_on_obj(self):
script.stop() script.stop()
@ -1042,19 +1042,19 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
have no cmdsets. have no cmdsets.
Kwargs: Kwargs:
caller (Session, Object or Player): The caller requesting caller (Session, Object or Account): The caller requesting
this cmdset. this cmdset.
""" """
pass pass
def at_pre_puppet(self, player, session=None, **kwargs): def at_pre_puppet(self, account, session=None, **kwargs):
""" """
Called just before a Player connects to this object to puppet Called just before an Account connects to this object to puppet
it. it.
Args: Args:
player (Player): This is the connecting player. account (Account): This is the connecting account.
session (Session): Session controlling the connection. session (Session): Session controlling the connection.
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
@ -1065,44 +1065,44 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
def at_post_puppet(self, **kwargs): def at_post_puppet(self, **kwargs):
""" """
Called just after puppeting has been completed and all Called just after puppeting has been completed and all
Player<->Object links have been established. Account<->Object links have been established.
Args: Args:
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
Note: Note:
You can use `self.player` and `self.sessions.get()` to get You can use `self.account` and `self.sessions.get()` to get
player and sessions at this point; the last entry in the account and sessions at this point; the last entry in the
list from `self.sessions.get()` is the latest Session list from `self.sessions.get()` is the latest Session
puppeting this Object. puppeting this Object.
""" """
self.player.db._last_puppet = self self.account.db._last_puppet = self
def at_pre_unpuppet(self, **kwargs): def at_pre_unpuppet(self, **kwargs):
""" """
Called just before beginning to un-connect a puppeting from Called just before beginning to un-connect a puppeting from
this Player. this Account.
Args: Args:
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
Note: Note:
You can use `self.player` and `self.sessions.get()` to get You can use `self.account` and `self.sessions.get()` to get
player and sessions at this point; the last entry in the account and sessions at this point; the last entry in the
list from `self.sessions.get()` is the latest Session list from `self.sessions.get()` is the latest Session
puppeting this Object. puppeting this Object.
""" """
pass pass
def at_post_unpuppet(self, player, session=None, **kwargs): def at_post_unpuppet(self, account, session=None, **kwargs):
""" """
Called just after the Player successfully disconnected from Called just after the Account successfully disconnected from
this object, severing all connections. this object, severing all connections.
Args: Args:
player (Player): The player object that just disconnected account (Account): The account object that just disconnected
from this object. from this object.
session (Session): Session id controlling the connection that session (Session): Session id controlling the connection that
just disconnected. just disconnected.
@ -1139,7 +1139,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
Args: Args:
result (bool): The outcome of the access call. result (bool): The outcome of the access call.
accessing_obj (Object or Player): The entity trying to gain access. accessing_obj (Object or Account): The entity trying to gain access.
access_type (str): The type of access that was requested. access_type (str): The type of access that was requested.
Kwargs: Kwargs:
@ -1238,8 +1238,8 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
""" """
if not source_location and self.location.has_player: if not source_location and self.location.has_account:
# This was created from nowhere and added to a player's # This was created from nowhere and added to an account's
# inventory; it's probably the result of a create command. # inventory; it's probably the result of a create command.
string = "You now have %s in your possession." % self.get_display_name(self.location) string = "You now have %s in your possession." % self.get_display_name(self.location)
self.location.msg(string) self.location.msg(string)
@ -1437,7 +1437,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
key = con.get_display_name(looker) key = con.get_display_name(looker)
if con.destination: if con.destination:
exits.append(key) exits.append(key)
elif con.has_player: elif con.has_account:
users.append("|c%s|n" % key) users.append("|c%s|n" % key)
else: else:
things.append(key) things.append(key)
@ -1576,7 +1576,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
class DefaultCharacter(DefaultObject): class DefaultCharacter(DefaultObject):
""" """
This implements an Object puppeted by a Session - that is, This implements an Object puppeted by a Session - that is,
a character avatar controlled by a player. a character avatar controlled by an account.
""" """
@ -1604,11 +1604,11 @@ class DefaultCharacter(DefaultObject):
if self.location.access(self, "view"): if self.location.access(self, "view"):
self.msg(self.at_look(self.location)) self.msg(self.at_look(self.location))
def at_pre_puppet(self, player, session=None, **kwargs): def at_pre_puppet(self, account, session=None, **kwargs):
""" """
Return the character from storage in None location in `at_post_unpuppet`. Return the character from storage in None location in `at_post_unpuppet`.
Args: Args:
player (Player): This is the connecting player. account (Account): This is the connecting account.
session (Session): Session controlling the connection. session (Session): Session controlling the connection.
""" """
if self.location is None: # Make sure character's location is never None before being puppeted. if self.location is None: # Make sure character's location is never None before being puppeted.
@ -1618,19 +1618,19 @@ class DefaultCharacter(DefaultObject):
if self.location: # If the character is verified to be somewhere, if self.location: # If the character is verified to be somewhere,
self.db.prelogout_location = self.location # save location again to be sure. self.db.prelogout_location = self.location # save location again to be sure.
else: else:
player.msg("|r%s has no location and no home is set.|n" % self, session=session) # Note to set home. account.msg("|r%s has no location and no home is set.|n" % self, session=session) # Note to set home.
def at_post_puppet(self, **kwargs): def at_post_puppet(self, **kwargs):
""" """
Called just after puppeting has been completed and all Called just after puppeting has been completed and all
Player<->Object links have been established. Account<->Object links have been established.
Args: Args:
**kwargs (dict): Arbitrary, optional arguments for users **kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default). overriding the call (unused by default).
Note: Note:
You can use `self.player` and `self.sessions.get()` to get You can use `self.account` and `self.sessions.get()` to get
player and sessions at this point; the last entry in the account and sessions at this point; the last entry in the
list from `self.sessions.get()` is the latest Session list from `self.sessions.get()` is the latest Session
puppeting this Object. puppeting this Object.
@ -1642,14 +1642,14 @@ class DefaultCharacter(DefaultObject):
obj.msg("%s has entered the game." % self.get_display_name(obj), from_obj=from_obj) obj.msg("%s has entered the game." % self.get_display_name(obj), from_obj=from_obj)
self.location.for_contents(message, exclude=[self], from_obj=self) self.location.for_contents(message, exclude=[self], from_obj=self)
def at_post_unpuppet(self, player, session=None, **kwargs): def at_post_unpuppet(self, account, session=None, **kwargs):
""" """
We stove away the character when the player goes ooc/logs off, We stove away the character when the account goes ooc/logs off,
otherwise the character object will remain in the room also otherwise the character object will remain in the room also
after the player logged off ("headless", so to say). after the account logged off ("headless", so to say).
Args: Args:
player (Player): The player object that just disconnected account (Account): The account object that just disconnected
from this object. from this object.
session (Session): Session controlling the connection that session (Session): Session controlling the connection that
just disconnected. just disconnected.
@ -1782,7 +1782,7 @@ class DefaultExit(DefaultObject):
Helper function for creating an exit command set + command. Helper function for creating an exit command set + command.
The command of this cmdset has the same name as the Exit The command of this cmdset has the same name as the Exit
object and allows the exit to react when the player enter the object and allows the exit to react when the account enter the
exit's name, triggering the movement between rooms. exit's name, triggering the movement between rooms.
Args: Args:

View file

@ -1,6 +1,6 @@
""" """
This sub-package holds the Scripts system. Scripts are database This sub-package holds the Scripts system. Scripts are database
entities that can store data both in connection to Objects and Players entities that can store data both in connection to Objects and Accounts
or globally. They may also have a timer-component to execute various or globally. They may also have a timer-component to execute various
timed effects. timed effects.

View file

@ -49,20 +49,20 @@ class ScriptDBManager(TypedObjectManager):
""" """
if not obj: if not obj:
return [] return []
player = _GA(_GA(obj, "__dbclass__"), "__name__") == "PlayerDB" account = _GA(_GA(obj, "__dbclass__"), "__name__") == "AccountDB"
if key: if key:
dbref = self.dbref(key) dbref = self.dbref(key)
if dbref or dbref == 0: if dbref or dbref == 0:
if player: if account:
return self.filter(db_player=obj, id=dbref) return self.filter(db_account=obj, id=dbref)
else: else:
return self.filter(db_obj=obj, id=dbref) return self.filter(db_obj=obj, id=dbref)
elif player: elif account:
return self.filter(db_player=obj, db_key=key) return self.filter(db_account=obj, db_key=key)
else: else:
return self.filter(db_obj=obj, db_key=key) return self.filter(db_obj=obj, db_key=key)
elif player: elif account:
return self.filter(db_player=obj) return self.filter(db_account=obj)
else: else:
return self.filter(db_obj=obj) return self.filter(db_obj=obj)

View file

@ -15,13 +15,13 @@ cleaning whatever effect they have had on the game object.
Common examples of uses of Scripts: Common examples of uses of Scripts:
- Load the default cmdset to the player object's cmdhandler - Load the default cmdset to the account object's cmdhandler
when logging in. when logging in.
- Switch to a different state, such as entering a text editor, - Switch to a different state, such as entering a text editor,
start combat or enter a dark room. start combat or enter a dark room.
- Merge a new cmdset with the default one for changing which - Merge a new cmdset with the default one for changing which
commands are available at a particular time commands are available at a particular time
- Give the player/object a time-limited bonus/effect - Give the account/object a time-limited bonus/effect
""" """
from builtins import object from builtins import object
@ -62,7 +62,7 @@ class ScriptDB(TypedObject):
The ScriptDB adds the following properties: The ScriptDB adds the following properties:
desc - optional description of script desc - optional description of script
obj - the object the script is linked to, if any obj - the object the script is linked to, if any
player - the player the script is linked to (exclusive with obj) account - the account the script is linked to (exclusive with obj)
interval - how often script should run interval - how often script should run
start_delay - if the script should start repeating right away start_delay - if the script should start repeating right away
repeats - how many times the script should repeat repeats - how many times the script should repeat
@ -122,18 +122,18 @@ class ScriptDB(TypedObject):
def __get_obj(self): def __get_obj(self):
""" """
Property wrapper that homogenizes access to either the Property wrapper that homogenizes access to either the
db_player or db_obj field, using the same object property db_account or db_obj field, using the same object property
name. name.
""" """
obj = _GA(self, "db_player") obj = _GA(self, "db_account")
if not obj: if not obj:
obj = _GA(self, "db_obj") obj = _GA(self, "db_obj")
return obj return obj
def __set_obj(self, value): def __set_obj(self, value):
""" """
Set player or obj to their right database field. If Set account or obj to their right database field. If
a dbref is given, assume ObjectDB. a dbref is given, assume ObjectDB.
""" """
@ -153,8 +153,8 @@ class ScriptDB(TypedObject):
except ObjectDoesNotExist: except ObjectDoesNotExist:
# maybe it is just a name that happens to look like a dbid # maybe it is just a name that happens to look like a dbid
pass pass
if value.__class__.__name__ == "PlayerDB": if value.__class__.__name__ == "AccountDB":
fname = "db_player" fname = "db_account"
_SA(self, fname, value) _SA(self, fname, value)
else: else:
fname = "db_obj" fname = "db_obj"

View file

@ -66,9 +66,9 @@ class ScriptHandler(object):
autostart (bool, optional): Start the script upon adding it. autostart (bool, optional): Start the script upon adding it.
""" """
if self.obj.__dbclass__.__name__ == "PlayerDB": if self.obj.__dbclass__.__name__ == "AccountDB":
# we add to a Player, not an Object # we add to an Account, not an Object
script = create.create_script(scriptclass, key=key, player=self.obj, script = create.create_script(scriptclass, key=key, account=self.obj,
autostart=autostart) autostart=autostart)
else: else:
# the normal - adding to an Object # the normal - adding to an Object

View file

@ -6,12 +6,12 @@ Both sides use this same protocol.
The separation works like this: The separation works like this:
Portal - (AMP client) handles protocols. It contains a list of connected Portal - (AMP client) handles protocols. It contains a list of connected
sessions in a dictionary for identifying the respective player sessions in a dictionary for identifying the respective account
connected. If it loses the AMP connection it will automatically connected. If it loses the AMP connection it will automatically
try to reconnect. try to reconnect.
Server - (AMP server) Handles all mud operations. The server holds its own list Server - (AMP server) Handles all mud operations. The server holds its own list
of sessions tied to player objects. This is synced against the portal of sessions tied to account objects. This is synced against the portal
at startup and when a session connects/disconnects at startup and when a session connects/disconnects
""" """

View file

@ -24,7 +24,7 @@ def check_errors(settings):
raise DeprecationWarning(deprstring % ( raise DeprecationWarning(deprstring % (
"CMDSET_DEFAULT", "CMDSET_CHARACTER")) "CMDSET_DEFAULT", "CMDSET_CHARACTER"))
if hasattr(settings, "CMDSET_OOC"): if hasattr(settings, "CMDSET_OOC"):
raise DeprecationWarning(deprstring % ("CMDSET_OOC", "CMDSET_PLAYER")) raise DeprecationWarning(deprstring % ("CMDSET_OOC", "CMDSET_ACCOUNT"))
if settings.WEBSERVER_ENABLED and not isinstance(settings.WEBSERVER_PORTS[0], tuple): if settings.WEBSERVER_ENABLED and not isinstance(settings.WEBSERVER_PORTS[0], tuple):
raise DeprecationWarning( raise DeprecationWarning(
"settings.WEBSERVER_PORTS must be on the form " "settings.WEBSERVER_PORTS must be on the form "
@ -46,8 +46,8 @@ def check_errors(settings):
raise DeprecationWarning(deprstring % "OBJECT_TYPECLASS_PATHS") raise DeprecationWarning(deprstring % "OBJECT_TYPECLASS_PATHS")
if hasattr(settings, "SCRIPT_TYPECLASS_PATHS"): if hasattr(settings, "SCRIPT_TYPECLASS_PATHS"):
raise DeprecationWarning(deprstring % "SCRIPT_TYPECLASS_PATHS") raise DeprecationWarning(deprstring % "SCRIPT_TYPECLASS_PATHS")
if hasattr(settings, "PLAYER_TYPECLASS_PATHS"): if hasattr(settings, "ACCOUNT_TYPECLASS_PATHS"):
raise DeprecationWarning(deprstring % "PLAYER_TYPECLASS_PATHS") raise DeprecationWarning(deprstring % "ACCOUNT_TYPECLASS_PATHS")
if hasattr(settings, "CHANNEL_TYPECLASS_PATHS"): if hasattr(settings, "CHANNEL_TYPECLASS_PATHS"):
raise DeprecationWarning(deprstring % "CHANNEL_TYPECLASS_PATHS") raise DeprecationWarning(deprstring % "CHANNEL_TYPECLASS_PATHS")
if hasattr(settings, "SEARCH_MULTIMATCH_SEPARATOR"): if hasattr(settings, "SEARCH_MULTIMATCH_SEPARATOR"):

View file

@ -132,15 +132,15 @@ ERROR_NO_GAMEDIR = \
WARNING_MOVING_SUPERUSER = \ WARNING_MOVING_SUPERUSER = \
""" """
WARNING: Evennia expects a Player superuser with id=1. No such WARNING: Evennia expects an Account superuser with id=1. No such
Player was found. However, another superuser ('{other_key}', Account was found. However, another superuser ('{other_key}',
id={other_id}) was found in the database. If you just created this id={other_id}) was found in the database. If you just created this
superuser and still see this text it is probably due to the superuser and still see this text it is probably due to the
database being flushed recently - in this case the database's database being flushed recently - in this case the database's
internal auto-counter might just start from some value higher than internal auto-counter might just start from some value higher than
one. one.
We will fix this by assigning the id 1 to Player '{other_key}'. We will fix this by assigning the id 1 to Account '{other_key}'.
Please confirm this is acceptable before continuing. Please confirm this is acceptable before continuing.
""" """
@ -182,7 +182,7 @@ RECREATED_SETTINGS = \
Note that if you were using an existing database, the password Note that if you were using an existing database, the password
salt of this new settings file will be different from the old one. salt of this new settings file will be different from the old one.
This means that any existing players may not be able to log in to This means that any existing accounts may not be able to log in to
their accounts with their old passwords. their accounts with their old passwords.
""" """
@ -270,7 +270,7 @@ HELP_ENTRY = \
adding new protocols or are debugging Evennia itself. adding new protocols or are debugging Evennia itself.
Reload with (5) to update the server with your changes without Reload with (5) to update the server with your changes without
disconnecting any players. disconnecting any accounts.
Note: Reload and stop are sometimes poorly supported in Windows. If you Note: Reload and stop are sometimes poorly supported in Windows. If you
have issues, log into the game to stop or restart the server instead. have issues, log into the game to stop or restart the server instead.
@ -581,11 +581,11 @@ def create_game_directory(dirname):
def create_superuser(): def create_superuser():
""" """
Create the superuser player Create the superuser account
""" """
print( print(
"\nCreate a superuser below. The superuser is Player #1, the 'owner' " "\nCreate a superuser below. The superuser is Account #1, the 'owner' "
"account of the server.\n") "account of the server.\n")
django.core.management.call_command("createsuperuser", interactive=True) django.core.management.call_command("createsuperuser", interactive=True)
@ -602,20 +602,20 @@ def check_database():
tables = connection.introspection.get_table_list(connection.cursor()) tables = connection.introspection.get_table_list(connection.cursor())
if not tables or not isinstance(tables[0], basestring): # django 1.8+ if not tables or not isinstance(tables[0], basestring): # django 1.8+
tables = [tableinfo.name for tableinfo in tables] tables = [tableinfo.name for tableinfo in tables]
if tables and u'players_playerdb' in tables: if tables and u'accounts_accountdb' in tables:
# database exists and seems set up. Initialize evennia. # database exists and seems set up. Initialize evennia.
evennia._init() evennia._init()
# Try to get Player#1 # Try to get Account#1
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
try: try:
PlayerDB.objects.get(id=1) AccountDB.objects.get(id=1)
except django.db.utils.OperationalError as e: except django.db.utils.OperationalError as e:
print(ERROR_DATABASE.format(traceback=e)) print(ERROR_DATABASE.format(traceback=e))
sys.exit() sys.exit()
except PlayerDB.DoesNotExist: except AccountDB.DoesNotExist:
# no superuser yet. We need to create it. # no superuser yet. We need to create it.
other_superuser = PlayerDB.objects.filter(is_superuser=True) other_superuser = AccountDB.objects.filter(is_superuser=True)
if other_superuser: if other_superuser:
# Another superuser was found, but not with id=1. This may # Another superuser was found, but not with id=1. This may
# happen if using flush (the auto-id starts at a higher # happen if using flush (the auto-id starts at a higher
@ -811,10 +811,10 @@ def error_check_python_modules():
print("Warning: CMDSET_UNLOGGED failed to load!") print("Warning: CMDSET_UNLOGGED failed to load!")
if not cmdsethandler.import_cmdset(settings.CMDSET_CHARACTER, None): if not cmdsethandler.import_cmdset(settings.CMDSET_CHARACTER, None):
print("Warning: CMDSET_CHARACTER failed to load") print("Warning: CMDSET_CHARACTER failed to load")
if not cmdsethandler.import_cmdset(settings.CMDSET_PLAYER, None): if not cmdsethandler.import_cmdset(settings.CMDSET_ACCOUNT, None):
print("Warning: CMDSET_PLAYER failed to load") print("Warning: CMDSET_ACCOUNT failed to load")
# typeclasses # typeclasses
_imp(settings.BASE_PLAYER_TYPECLASS) _imp(settings.BASE_ACCOUNT_TYPECLASS)
_imp(settings.BASE_OBJECT_TYPECLASS) _imp(settings.BASE_OBJECT_TYPECLASS)
_imp(settings.BASE_CHARACTER_TYPECLASS) _imp(settings.BASE_CHARACTER_TYPECLASS)
_imp(settings.BASE_ROOM_TYPECLASS) _imp(settings.BASE_ROOM_TYPECLASS)
@ -945,10 +945,10 @@ def run_dummyrunner(number_of_dummies):
Start an instance of the dummyrunner Start an instance of the dummyrunner
Args: Args:
number_of_dummies (int): The number of dummy players to start. number_of_dummies (int): The number of dummy accounts to start.
Notes: Notes:
The dummy players' behavior can be customized by adding a The dummy accounts' behavior can be customized by adding a
`dummyrunner_settings.py` config file in the game's conf/ `dummyrunner_settings.py` config file in the game's conf/
directory. directory.
@ -1215,7 +1215,7 @@ def main():
parser.add_argument( parser.add_argument(
'--dummyrunner', nargs=1, action='store', dest='dummyrunner', '--dummyrunner', nargs=1, action='store', dest='dummyrunner',
metavar="N", metavar="N",
help="Test a running server by connecting N dummy players to it.") help="Test a running server by connecting N dummy accounts to it.")
parser.add_argument( parser.add_argument(
'--settings', nargs=1, action='store', dest='altsettings', '--settings', nargs=1, action='store', dest='altsettings',
default=None, metavar="filename.py", default=None, metavar="filename.py",

View file

@ -10,7 +10,7 @@ from __future__ import print_function
import time import time
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.server.models import ServerConfig from evennia.server.models import ServerConfig
from evennia.utils import create, logger from evennia.utils import create, logger
@ -28,7 +28,7 @@ ERROR_NO_SUPERUSER = """
LIMBO_DESC = _(""" LIMBO_DESC = _("""
Welcome to your new |wEvennia|n-based game! Visit http://www.evennia.com if you need Welcome to your new |wEvennia|n-based game! Visit http://www.evennia.com if you need
help, want to contribute, report issues or just join the community. help, want to contribute, report issues or just join the community.
As Player #1 you can create a demo/tutorial area with |w@batchcommand tutorial_world.build|n. As Account #1 you can create a demo/tutorial area with |w@batchcommand tutorial_world.build|n.
""") """)
@ -36,55 +36,55 @@ WARNING_POSTGRESQL_FIX = """
PostgreSQL-psycopg2 compatibility fix: PostgreSQL-psycopg2 compatibility fix:
The in-game channels {chan1}, {chan2} and {chan3} were created, The in-game channels {chan1}, {chan2} and {chan3} were created,
but the superuser was not yet connected to them. Please use in but the superuser was not yet connected to them. Please use in
game commands to connect Player #1 to those channels when first game commands to connect Account #1 to those channels when first
logging in. logging in.
""" """
def get_god_player(): def get_god_account():
""" """
Creates the god user and don't take no for an answer. Creates the god user and don't take no for an answer.
""" """
try: try:
god_player = PlayerDB.objects.get(id=1) god_account = AccountDB.objects.get(id=1)
except PlayerDB.DoesNotExist: except AccountDB.DoesNotExist:
raise PlayerDB.DoesNotExist(ERROR_NO_SUPERUSER) raise AccountDB.DoesNotExist(ERROR_NO_SUPERUSER)
return god_player return god_account
def create_objects(): def create_objects():
""" """
Creates the #1 player and Limbo room. Creates the #1 account and Limbo room.
""" """
logger.log_info("Creating objects (Player #1 and Limbo room) ...") logger.log_info("Creating objects (Account #1 and Limbo room) ...")
# Set the initial User's account object's username on the #1 object. # 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. # This object is pure django and only holds name, email and password.
god_player = get_god_player() god_account = get_god_account()
# Create a Player 'user profile' object to hold eventual # Create an Account 'user profile' object to hold eventual
# mud-specific settings for the PlayerDB object. # mud-specific settings for the AccountDB object.
player_typeclass = settings.BASE_PLAYER_TYPECLASS account_typeclass = settings.BASE_ACCOUNT_TYPECLASS
# run all creation hooks on god_player (we must do so manually # run all creation hooks on god_account (we must do so manually
# since the manage.py command does not) # since the manage.py command does not)
god_player.swap_typeclass(player_typeclass, clean_attributes=True) god_account.swap_typeclass(account_typeclass, clean_attributes=True)
god_player.basetype_setup() god_account.basetype_setup()
god_player.at_player_creation() god_account.at_account_creation()
god_player.locks.add("examine:perm(Developer);edit:false();delete:false();boot:false();msg:all()") god_account.locks.add("examine:perm(Developer);edit:false();delete:false();boot:false();msg:all()")
# this is necessary for quelling to work correctly. # this is necessary for quelling to work correctly.
god_player.permissions.add("Developer") god_account.permissions.add("Developer")
# Limbo is the default "nowhere" starting room # Limbo is the default "nowhere" starting room
# Create the in-game god-character for player #1 and set # Create the in-game god-character for account #1 and set
# it to exist in Limbo. # it to exist in Limbo.
character_typeclass = settings.BASE_CHARACTER_TYPECLASS character_typeclass = settings.BASE_CHARACTER_TYPECLASS
god_character = create.create_object(character_typeclass, god_character = create.create_object(character_typeclass,
key=god_player.username, key=god_account.username,
nohome=True) nohome=True)
god_character.id = 1 god_character.id = 1
@ -93,13 +93,13 @@ def create_objects():
god_character.locks.add("examine:perm(Developer);edit:false();delete:false();boot:false();msg:all();puppet:false()") god_character.locks.add("examine:perm(Developer);edit:false();delete:false();boot:false();msg:all();puppet:false()")
god_character.permissions.add("Developer") god_character.permissions.add("Developer")
god_player.attributes.add("_first_login", True) god_account.attributes.add("_first_login", True)
god_player.attributes.add("_last_puppet", god_character) god_account.attributes.add("_last_puppet", god_character)
try: try:
god_player.db._playable_characters.append(god_character) god_account.db._playable_characters.append(god_character)
except AttributeError: except AttributeError:
god_player.db_playable_characters = [god_character] god_account.db_playable_characters = [god_character]
room_typeclass = settings.BASE_ROOM_TYPECLASS room_typeclass = settings.BASE_ROOM_TYPECLASS
limbo_obj = create.create_object(room_typeclass, _('Limbo'), nohome=True) limbo_obj = create.create_object(room_typeclass, _('Limbo'), nohome=True)
@ -123,7 +123,7 @@ def create_channels():
""" """
logger.log_info("Creating default channels ...") logger.log_info("Creating default channels ...")
goduser = get_god_player() goduser = get_god_account()
for channeldict in settings.DEFAULT_CHANNELS: for channeldict in settings.DEFAULT_CHANNELS:
channel = create.create_channel(**channeldict) channel = create.create_channel(**channeldict)
channel.connect(goduser) channel.connect(goduser)

View file

@ -23,7 +23,7 @@ from future.utils import viewkeys
import importlib import importlib
from django.conf import settings from django.conf import settings
from evennia.commands.cmdhandler import cmdhandler from evennia.commands.cmdhandler import cmdhandler
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.utils.logger import log_err from evennia.utils.logger import log_err
from evennia.utils.utils import to_str, to_unicode from evennia.utils.utils import to_str, to_unicode
@ -67,15 +67,15 @@ def text(session, *args, **kwargs):
if txt.strip() in _IDLE_COMMAND: if txt.strip() in _IDLE_COMMAND:
session.update_session_counters(idle=True) session.update_session_counters(idle=True)
return return
if session.player: if session.account:
# nick replacement # nick replacement
puppet = session.puppet puppet = session.puppet
if puppet: if puppet:
txt = puppet.nicks.nickreplace(txt, txt = puppet.nicks.nickreplace(txt,
categories=("inputline", "channel"), include_player=True) categories=("inputline", "channel"), include_account=True)
else: else:
txt = session.player.nicks.nickreplace(txt, txt = session.account.nicks.nickreplace(txt,
categories=("inputline", "channel"), include_player=False) categories=("inputline", "channel"), include_account=False)
kwargs.pop("options", None) kwargs.pop("options", None)
cmdhandler(session, txt, callertype="session", session=session, **kwargs) cmdhandler(session, txt, callertype="session", session=session, **kwargs)
session.update_session_counters() session.update_session_counters()
@ -105,7 +105,7 @@ def bot_data_in(session, *args, **kwargs):
return return
kwargs.pop("options", None) kwargs.pop("options", None)
# Trigger the execute_cmd method of the corresponding bot. # Trigger the execute_cmd method of the corresponding bot.
session.player.execute_cmd(session=session, txt=txt, **kwargs) session.account.execute_cmd(session=session, txt=txt, **kwargs)
session.update_session_counters() session.update_session_counters()
@ -153,10 +153,10 @@ def browser_sessid(session, *args, **kwargs):
uid = browsersession.get("logged_in", None) uid = browsersession.get("logged_in", None)
if uid: if uid:
try: try:
player = PlayerDB.objects.get(pk=uid) account = AccountDB.objects.get(pk=uid)
except Exception: except Exception:
return return
session.sessionhandler.login(session, player) session.sessionhandler.login(session, account)
@ -288,15 +288,15 @@ def login(session, *args, **kwargs):
in. This will also automatically throttle too quick attempts. in. This will also automatically throttle too quick attempts.
Kwargs: Kwargs:
name (str): Player name name (str): Account name
password (str): Plain-text password password (str): Plain-text password
""" """
if not session.logged_in and "name" in kwargs and "password" in kwargs: if not session.logged_in and "name" in kwargs and "password" in kwargs:
from evennia.commands.default.unloggedin import create_normal_player from evennia.commands.default.unloggedin import create_normal_account
player = create_normal_player(session, kwargs["name"], kwargs["password"]) account = create_normal_account(session, kwargs["name"], kwargs["password"])
if player: if account:
session.sessionhandler.login(session, player) session.sessionhandler.login(session, account)
_gettable = { _gettable = {
"name": lambda obj: obj.key, "name": lambda obj: obj.key,
@ -308,7 +308,7 @@ _gettable = {
def get_value(session, *args, **kwargs): def get_value(session, *args, **kwargs):
""" """
Return the value of a given attribute or db_property on the Return the value of a given attribute or db_property on the
session's current player or character. session's current account or character.
Kwargs: Kwargs:
name (str): Name of info value to return. Only names name (str): Name of info value to return. Only names
@ -317,7 +317,7 @@ def get_value(session, *args, **kwargs):
""" """
name = kwargs.get("name", "") name = kwargs.get("name", "")
obj = session.puppet or session.player obj = session.puppet or session.account
if name in _gettable: if name in _gettable:
session.msg(get_value={"name": name, "value": _gettable[name](obj)}) session.msg(get_value={"name": name, "value": _gettable[name](obj)})
@ -428,7 +428,7 @@ def unmonitor(session, *args, **kwargs):
def _on_webclient_options_change(**kwargs): def _on_webclient_options_change(**kwargs):
""" """
Called when the webclient options stored on the player changes. Called when the webclient options stored on the account changes.
Inform the interested clients of this change. Inform the interested clients of this change.
""" """
session = kwargs["session"] session = kwargs["session"]
@ -452,15 +452,15 @@ def webclient_options(session, *args, **kwargs):
that changes. that changes.
If kwargs is not empty, the key/values stored in there will be persisted If kwargs is not empty, the key/values stored in there will be persisted
to the player object. to the account object.
Kwargs: Kwargs:
<option name>: an option to save <option name>: an option to save
""" """
player = session.player account = session.account
clientoptions = settings.WEBCLIENT_OPTIONS.copy() clientoptions = settings.WEBCLIENT_OPTIONS.copy()
storedoptions = player.db._saved_webclient_options or {} storedoptions = account.db._saved_webclient_options or {}
clientoptions.update(storedoptions) clientoptions.update(storedoptions)
# The webclient adds a cmdid to every kwargs, but we don't need it. # The webclient adds a cmdid to every kwargs, but we don't need it.
@ -476,13 +476,13 @@ def webclient_options(session, *args, **kwargs):
# Create a monitor. If a monitor already exists then it will replace # Create a monitor. If a monitor already exists then it will replace
# the previous one since it would use the same idstring # the previous one since it would use the same idstring
from evennia.scripts.monitorhandler import MONITOR_HANDLER from evennia.scripts.monitorhandler import MONITOR_HANDLER
MONITOR_HANDLER.add(player, "_saved_webclient_options", MONITOR_HANDLER.add(account, "_saved_webclient_options",
_on_webclient_options_change, _on_webclient_options_change,
idstring=session.sessid, persistent=False, idstring=session.sessid, persistent=False,
session=session) session=session)
else: else:
# kwargs provided: persist them to the player object # kwargs provided: persist them to the account object
for key, value in kwargs.iteritems(): for key, value in kwargs.iteritems():
clientoptions[key] = value clientoptions[key] = value
player.db._saved_webclient_options = clientoptions account.db._saved_webclient_options = clientoptions

View file

@ -45,7 +45,7 @@ from twisted.python import components
from django.conf import settings from django.conf import settings
from evennia.server import session from evennia.server import session
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.utils import ansi from evennia.utils import ansi
from evennia.utils.utils import to_str from evennia.utils.utils import to_str
@ -61,21 +61,21 @@ CTRL_L = '\x0c'
class SshProtocol(Manhole, session.Session): class SshProtocol(Manhole, session.Session):
""" """
Each player connecting over ssh gets this protocol assigned to Each account connecting over ssh gets this protocol assigned to
them. All communication between game and player goes through them. All communication between game and account goes through
here. here.
""" """
def __init__(self, starttuple): def __init__(self, starttuple):
""" """
For setting up the player. If player is not None then we'll For setting up the account. If account is not None then we'll
login automatically. login automatically.
Args: Args:
starttuple (tuple): A (player, factory) tuple. starttuple (tuple): A (account, factory) tuple.
""" """
self.authenticated_player = starttuple[0] self.authenticated_account = starttuple[0]
# obs must not be called self.factory, that gets overwritten! # obs must not be called self.factory, that gets overwritten!
self.cfactory = starttuple[1] self.cfactory = starttuple[1]
@ -101,9 +101,9 @@ class SshProtocol(Manhole, session.Session):
self.init_session("ssh", client_address, self.cfactory.sessionhandler) self.init_session("ssh", client_address, self.cfactory.sessionhandler)
# since we might have authenticated already, we might set this here. # since we might have authenticated already, we might set this here.
if self.authenticated_player: if self.authenticated_account:
self.logged_in = True self.logged_in = True
self.uid = self.authenticated_player.user.id self.uid = self.authenticated_account.user.id
self.sessionhandler.connect(self) self.sessionhandler.connect(self)
def connectionMade(self): def connectionMade(self):
@ -313,10 +313,10 @@ class ExtraInfoAuthServer(SSHUserAuthServer):
self._ebPassword) self._ebPassword)
class PlayerDBPasswordChecker(object): class AccountDBPasswordChecker(object):
""" """
Checks the django db for the correct credentials for Checks the django db for the correct credentials for
username/password otherwise it returns the player or None which is username/password otherwise it returns the account or None which is
useful for the Realm. useful for the Realm.
""" """
@ -331,7 +331,7 @@ class PlayerDBPasswordChecker(object):
""" """
self.factory = factory self.factory = factory
super(PlayerDBPasswordChecker, self).__init__() super(AccountDBPasswordChecker, self).__init__()
def requestAvatarId(self, c): def requestAvatarId(self, c):
""" """
@ -341,10 +341,10 @@ class PlayerDBPasswordChecker(object):
up = credentials.IUsernamePassword(c, None) up = credentials.IUsernamePassword(c, None)
username = up.username username = up.username
password = up.password password = up.password
player = PlayerDB.objects.get_player_from_name(username) account = AccountDB.objects.get_account_from_name(username)
res = (None, self.factory) res = (None, self.factory)
if player and player.check_password(password): if account and account.check_password(password):
res = (player, self.factory) res = (account, self.factory)
return defer.succeed(res) return defer.succeed(res)
@ -462,6 +462,6 @@ def makeFactory(configdict):
factory.services = factory.services.copy() factory.services = factory.services.copy()
factory.services['ssh-userauth'] = ExtraInfoAuthServer factory.services['ssh-userauth'] = ExtraInfoAuthServer
factory.portal.registerChecker(PlayerDBPasswordChecker(factory)) factory.portal.registerChecker(AccountDBPasswordChecker(factory))
return factory return factory

View file

@ -15,7 +15,7 @@ full step-by-step setup help.
Basically (for testing default Evennia): Basically (for testing default Evennia):
- Use an empty/testing database. - Use an empty/testing database.
- set PERMISSION_PLAYER_DEFAULT = "Builder" - set PERMISSION_ACCOUNT_DEFAULT = "Builder"
- start server, eventually with profiling active - start server, eventually with profiling active
- launch this client runner - launch this client runner
@ -65,7 +65,7 @@ TIMESTEP = DUMMYRUNNER_SETTINGS.TIMESTEP
# chance of a client performing an action, per timestep. This helps to # chance of a client performing an action, per timestep. This helps to
# spread out usage randomly, like it would be in reality. # spread out usage randomly, like it would be in reality.
CHANCE_OF_ACTION = DUMMYRUNNER_SETTINGS.CHANCE_OF_ACTION CHANCE_OF_ACTION = DUMMYRUNNER_SETTINGS.CHANCE_OF_ACTION
# spread out the login action separately, having many players create accounts # spread out the login action separately, having many accounts create accounts
# and connect simultaneously is generally unlikely. # and connect simultaneously is generally unlikely.
CHANCE_OF_LOGIN = DUMMYRUNNER_SETTINGS.CHANCE_OF_LOGIN CHANCE_OF_LOGIN = DUMMYRUNNER_SETTINGS.CHANCE_OF_LOGIN
# Port to use, if not specified on command line # Port to use, if not specified on command line
@ -79,7 +79,7 @@ NLOGGED_IN = 0
INFO_STARTING = \ INFO_STARTING = \
""" """
Dummyrunner starting using {N} dummy player(s). If you don't see Dummyrunner starting using {N} dummy account(s). If you don't see
any connection messages, make sure that the Evennia server is any connection messages, make sure that the Evennia server is
running. running.
@ -95,7 +95,7 @@ ERROR_NO_MIXIN = \
from evennia.server.profiling.settings_mixin import * from evennia.server.profiling.settings_mixin import *
This will change the settings in the following way: This will change the settings in the following way:
- change PERMISSION_PLAYER_DEFAULT to 'Developer' to allow clients - change PERMISSION_ACCOUNT_DEFAULT to 'Developer' to allow clients
to test all commands to test all commands
- change PASSWORD_HASHERS to use a faster (but less safe) algorithm - change PASSWORD_HASHERS to use a faster (but less safe) algorithm
when creating large numbers of accounts at the same time when creating large numbers of accounts at the same time
@ -106,7 +106,7 @@ ERROR_NO_MIXIN = \
error completely. error completely.
Warning: Don't run dummyrunner on a production database! It will Warning: Don't run dummyrunner on a production database! It will
create a lot of spammy objects and player accounts! create a lot of spammy objects and account accounts!
""" """
@ -121,7 +121,7 @@ HELPTEXT = """
DO NOT RUN THIS ON A PRODUCTION SERVER! USE A CLEAN/TESTING DATABASE! DO NOT RUN THIS ON A PRODUCTION SERVER! USE A CLEAN/TESTING DATABASE!
This stand-alone program launches dummy telnet clients against a This stand-alone program launches dummy telnet clients against a
running Evennia server. The idea is to mimic real players logging in running Evennia server. The idea is to mimic real accounts logging in
and repeatedly doing resource-heavy commands so as to stress test the and repeatedly doing resource-heavy commands so as to stress test the
game. It uses the default command set to log in and issue commands, so game. It uses the default command set to log in and issue commands, so
if that was customized, some of the functionality will not be tested if that was customized, some of the functionality will not be tested
@ -136,9 +136,9 @@ Setup:
`evennia migrate`) `evennia migrate`)
2) in server/conf/settings.py, add 2) in server/conf/settings.py, add
PERMISSION_PLAYER_DEFAULT="Builder" PERMISSION_ACCOUNT_DEFAULT="Builder"
This is so that the dummy players can test building operations. This is so that the dummy accounts can test building operations.
You can also customize the dummyrunner by modifying a setting You can also customize the dummyrunner by modifying a setting
file specified by DUMMYRUNNER_SETTINGS_MODULE file specified by DUMMYRUNNER_SETTINGS_MODULE
@ -160,12 +160,12 @@ Setup:
Notes: Notes:
The dummyrunner tends to create a lot of players all at once, which is The dummyrunner tends to create a lot of accounts all at once, which is
a very heavy operation. This is not a realistic use-case - what you want a very heavy operation. This is not a realistic use-case - what you want
to test is performance during run. A large to test is performance during run. A large
number of clients here may lock up the client until all have been number of clients here may lock up the client until all have been
created. It may be better to connect multiple dummyrunners instead of created. It may be better to connect multiple dummyrunners instead of
starting one single one with a lot of players. Exactly what this number starting one single one with a lot of accounts. Exactly what this number
is depends on your computer power. So start with 10-20 clients and increase is depends on your computer power. So start with 10-20 clients and increase
until you see the initial login slows things too much. until you see the initial login slows things too much.
@ -223,7 +223,7 @@ def makeiter(obj):
class DummyClient(telnet.StatefulTelnetProtocol): class DummyClient(telnet.StatefulTelnetProtocol):
""" """
Handles connection to a running Evennia server, Handles connection to a running Evennia server,
mimicking a real player by sending commands on mimicking a real account by sending commands on
a timer. a timer.
""" """

View file

@ -2,7 +2,7 @@
Settings and actions for the dummyrunner Settings and actions for the dummyrunner
This module defines dummyrunner settings and sets up This module defines dummyrunner settings and sets up
the actions available to dummy players. the actions available to dummy accounts.
The settings are global variables: The settings are global variables:
@ -18,7 +18,7 @@ ACTIONS is a tuple
where the first entry is the function to call on first connect, with a where the first entry is the function to call on first connect, with a
chance of occurring given by CHANCE_OF_LOGIN. This function is usually chance of occurring given by CHANCE_OF_LOGIN. This function is usually
responsible for logging in the player. The second entry is always responsible for logging in the account. The second entry is always
called when the dummyrunner disconnects from the server and should called when the dummyrunner disconnects from the server and should
thus issue a logout command. The other entries are tuples (chance, thus issue a logout command. The other entries are tuples (chance,
func). They are picked randomly, their commonality based on the func). They are picked randomly, their commonality based on the
@ -61,7 +61,7 @@ TIMESTEP = 2
CHANCE_OF_ACTION = 0.5 CHANCE_OF_ACTION = 0.5
# Chance of a currently unlogged-in dummy performing its login # Chance of a currently unlogged-in dummy performing its login
# action every tick. This emulates not all players logging in # action every tick. This emulates not all accounts logging in
# at exactly the same time. # at exactly the same time.
CHANCE_OF_LOGIN = 1.0 CHANCE_OF_LOGIN = 1.0
@ -234,7 +234,7 @@ def c_moves_s(client):
# (0.1, c_creates_obj), # (0.1, c_creates_obj),
# #(0.01, c_creates_button), # #(0.01, c_creates_button),
# (0.2, c_moves)) # (0.2, c_moves))
## "passive player" definition ## "passive account" definition
#ACTIONS = ( c_login, #ACTIONS = ( c_login,
# c_logout, # c_logout,
# (0.7, c_looks), # (0.7, c_looks),
@ -244,11 +244,11 @@ def c_moves_s(client):
# #(0.1, c_creates_obj), # #(0.1, c_creates_obj),
# #(0.1, c_creates_button), # #(0.1, c_creates_button),
# #(0.4, c_moves)) # #(0.4, c_moves))
# "inactive player" definition # "inactive account" definition
#ACTIONS = (c_login_nodig, #ACTIONS = (c_login_nodig,
# c_logout, # c_logout,
# (1.0, c_idles)) # (1.0, c_idles))
## "normal player" definition ## "normal account" definition
ACTIONS = ( c_login, ACTIONS = ( c_login,
c_logout, c_logout,
(0.01, c_digs), (0.01, c_digs),

View file

@ -62,7 +62,7 @@ if __name__ == "__main__":
fig = pp.figure() fig = pp.figure()
ax1 = fig.add_subplot(111) ax1 = fig.add_subplot(111)
ax1.set_title("1000 bots (normal players with light building)") ax1.set_title("1000 bots (normal accounts with light building)")
ax1.set_xlabel("Time (mins)") ax1.set_xlabel("Time (mins)")
ax1.set_ylabel("Memory usage (MB)") ax1.set_ylabel("Memory usage (MB)")
ax1.plot(secs, rmem, "r", label="RMEM", lw=2) ax1.plot(secs, rmem, "r", label="RMEM", lw=2)

View file

@ -12,10 +12,10 @@ servers!
# the mixin is present # the mixin is present
DUMMYRUNNER_MIXIN = True DUMMYRUNNER_MIXIN = True
# a faster password hasher suitable for multiple simultaneous # a faster password hasher suitable for multiple simultaneous
# player creations. The default one is safer but deliberately # account creations. The default one is safer but deliberately
# very slow to make cracking harder. # very slow to make cracking harder.
PASSWORD_HASHERS = ( PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher', 'django.contrib.auth.hashers.MD5PasswordHasher',
) )
# make dummy clients able to test all commands # make dummy clients able to test all commands
PERMISSION_PLAYER_DEFAULT = "Developer" PERMISSION_ACCOUNT_DEFAULT = "Developer"

View file

@ -27,7 +27,7 @@ evennia._init()
from django.db import connection from django.db import connection
from django.conf import settings from django.conf import settings
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.scripts.models import ScriptDB from evennia.scripts.models import ScriptDB
from evennia.server.models import ServerConfig from evennia.server.models import ServerConfig
from evennia.server import initial_setup from evennia.server import initial_setup
@ -214,8 +214,8 @@ class Evennia(object):
already existing objects. already existing objects.
""" """
# setting names # setting names
settings_names = ("CMDSET_CHARACTER", "CMDSET_PLAYER", settings_names = ("CMDSET_CHARACTER", "CMDSET_ACCOUNT",
"BASE_PLAYER_TYPECLASS", "BASE_OBJECT_TYPECLASS", "BASE_ACCOUNT_TYPECLASS", "BASE_OBJECT_TYPECLASS",
"BASE_CHARACTER_TYPECLASS", "BASE_ROOM_TYPECLASS", "BASE_CHARACTER_TYPECLASS", "BASE_ROOM_TYPECLASS",
"BASE_EXIT_TYPECLASS", "BASE_SCRIPT_TYPECLASS", "BASE_EXIT_TYPECLASS", "BASE_SCRIPT_TYPECLASS",
"BASE_CHANNEL_TYPECLASS") "BASE_CHANNEL_TYPECLASS")
@ -228,16 +228,16 @@ class Evennia(object):
# run the update # run the update
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.comms.models import ChannelDB from evennia.comms.models import ChannelDB
#from evennia.players.models import PlayerDB #from evennia.accounts.models import AccountDB
for i, prev, curr in ((i, tup[0], tup[1]) for i, tup in enumerate(settings_compare) if i in mismatches): for i, prev, curr in ((i, tup[0], tup[1]) for i, tup in enumerate(settings_compare) if i in mismatches):
# update the database # update the database
print(" %s:\n '%s' changed to '%s'. Updating unchanged entries in database ..." % (settings_names[i], prev, curr)) print(" %s:\n '%s' changed to '%s'. Updating unchanged entries in database ..." % (settings_names[i], prev, curr))
if i == 0: if i == 0:
ObjectDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr) ObjectDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr)
if i == 1: if i == 1:
PlayerDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr) AccountDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr)
if i == 2: if i == 2:
PlayerDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr) AccountDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
if i in (3, 4, 5, 6): if i in (3, 4, 5, 6):
ObjectDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr) ObjectDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
if i == 7: if i == 7:
@ -247,7 +247,7 @@ class Evennia(object):
# store the new default and clean caches # store the new default and clean caches
ServerConfig.objects.conf(settings_names[i], curr) ServerConfig.objects.conf(settings_names[i], curr)
ObjectDB.flush_instance_cache() ObjectDB.flush_instance_cache()
PlayerDB.flush_instance_cache() AccountDB.flush_instance_cache()
ScriptDB.flush_instance_cache() ScriptDB.flush_instance_cache()
ChannelDB.flush_instance_cache() ChannelDB.flush_instance_cache()
# if this is the first start we might not have a "previous" # if this is the first start we might not have a "previous"
@ -283,13 +283,13 @@ class Evennia(object):
Called every server start Called every server start
""" """
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
#from evennia.players.models import PlayerDB #from evennia.accounts.models import AccountDB
#update eventual changed defaults #update eventual changed defaults
self.update_defaults() self.update_defaults()
[o.at_init() for o in ObjectDB.get_all_cached_instances()] [o.at_init() for o in ObjectDB.get_all_cached_instances()]
[p.at_init() for p in PlayerDB.get_all_cached_instances()] [p.at_init() for p in AccountDB.get_all_cached_instances()]
mode = self.getset_restart_mode() mode = self.getset_restart_mode()
@ -356,7 +356,7 @@ class Evennia(object):
mode = self.getset_restart_mode(mode) mode = self.getset_restart_mode(mode)
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
#from evennia.players.models import PlayerDB #from evennia.accounts.models import AccountDB
from evennia.server.models import ServerConfig from evennia.server.models import ServerConfig
from evennia.utils import gametime as _GAMETIME_MODULE from evennia.utils import gametime as _GAMETIME_MODULE
@ -364,7 +364,7 @@ class Evennia(object):
# call restart hooks # call restart hooks
ServerConfig.objects.conf("server_restart_mode", "reload") ServerConfig.objects.conf("server_restart_mode", "reload")
yield [o.at_server_reload() for o in ObjectDB.get_all_cached_instances()] yield [o.at_server_reload() for o in ObjectDB.get_all_cached_instances()]
yield [p.at_server_reload() for p in PlayerDB.get_all_cached_instances()] yield [p.at_server_reload() for p in AccountDB.get_all_cached_instances()]
yield [(s.pause(manual_pause=False), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances() if s.is_active] yield [(s.pause(manual_pause=False), s.at_server_reload()) for s in ScriptDB.get_all_cached_instances() if s.is_active]
yield self.sessions.all_sessions_portal_sync() yield self.sessions.all_sessions_portal_sync()
self.at_server_reload_stop() self.at_server_reload_stop()
@ -375,14 +375,14 @@ class Evennia(object):
if mode == 'reset': if mode == 'reset':
# like shutdown but don't unset the is_connected flag and don't disconnect sessions # like shutdown but don't unset the is_connected flag and don't disconnect sessions
yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()] yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()]
yield [p.at_server_shutdown() for p in PlayerDB.get_all_cached_instances()] yield [p.at_server_shutdown() for p in AccountDB.get_all_cached_instances()]
if self.amp_protocol: if self.amp_protocol:
yield self.sessions.all_sessions_portal_sync() yield self.sessions.all_sessions_portal_sync()
else: # shutdown else: # shutdown
yield [_SA(p, "is_connected", False) for p in PlayerDB.get_all_cached_instances()] yield [_SA(p, "is_connected", False) for p in AccountDB.get_all_cached_instances()]
yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()] yield [o.at_server_shutdown() for o in ObjectDB.get_all_cached_instances()]
yield [(p.unpuppet_all(), p.at_server_shutdown()) yield [(p.unpuppet_all(), p.at_server_shutdown())
for p in PlayerDB.get_all_cached_instances()] for p in AccountDB.get_all_cached_instances()]
yield ObjectDB.objects.clear_all_sessids() yield ObjectDB.objects.clear_all_sessids()
yield [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()] yield [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
ServerConfig.objects.conf("server_restart_mode", "reset") ServerConfig.objects.conf("server_restart_mode", "reset")
@ -482,7 +482,7 @@ class Evennia(object):
script.stop() script.stop()
if GUEST_ENABLED: if GUEST_ENABLED:
for guest in PlayerDB.objects.all().filter(db_typeclass_path=settings.BASE_GUEST_TYPECLASS): for guest in AccountDB.objects.all().filter(db_typeclass_path=settings.BASE_GUEST_TYPECLASS):
for character in guest.db._playable_characters: for character in guest.db._playable_characters:
if character: character.delete() if character: character.delete()
guest.delete() guest.delete()

View file

@ -152,18 +152,18 @@ class NAttributeHandler(object):
class ServerSession(Session): class ServerSession(Session):
""" """
This class represents a player's session and is a template for This class represents an account's session and is a template for
individual protocols to communicate with Evennia. individual protocols to communicate with Evennia.
Each player gets a session assigned to them whenever they connect Each account gets a session assigned to them whenever they connect
to the game server. All communication between game and player goes to the game server. All communication between game and account goes
through their session. through their session.
""" """
def __init__(self): def __init__(self):
"""Initiate to avoid AttributeErrors down the line""" """Initiate to avoid AttributeErrors down the line"""
self.puppet = None self.puppet = None
self.player = None self.account = None
self.cmdset_storage_string = "" self.cmdset_storage_string = ""
self.cmdset = CmdSetHandler(self, True) self.cmdset = CmdSetHandler(self, True)
@ -178,7 +178,7 @@ class ServerSession(Session):
""" """
This is called whenever a session has been resynced with the This is called whenever a session has been resynced with the
portal. At this point all relevant attributes have already portal. At this point all relevant attributes have already
been set and self.player been assigned (if applicable). been set and self.account been assigned (if applicable).
Since this is often called after a server restart we need to Since this is often called after a server restart we need to
set up the session as it was. set up the session as it was.
@ -201,23 +201,23 @@ class ServerSession(Session):
# hooks, echoes or access checks. # hooks, echoes or access checks.
obj = _ObjectDB.objects.get(id=self.puid) obj = _ObjectDB.objects.get(id=self.puid)
obj.sessions.add(self) obj.sessions.add(self)
obj.player = self.player obj.account = self.account
self.puid = obj.id self.puid = obj.id
self.puppet = obj self.puppet = obj
# obj.scripts.validate() # obj.scripts.validate()
obj.locks.cache_lock_bypass(obj) obj.locks.cache_lock_bypass(obj)
def at_login(self, player): def at_login(self, account):
""" """
Hook called by sessionhandler when the session becomes authenticated. Hook called by sessionhandler when the session becomes authenticated.
Args: Args:
player (Player): The player associated with the session. account (Account): The account associated with the session.
""" """
self.player = player self.account = account
self.uid = self.player.id self.uid = self.account.id
self.uname = self.player.username self.uname = self.account.username
self.logged_in = True self.logged_in = True
self.conn_time = time.time() self.conn_time = time.time()
self.puid = None self.puid = None
@ -230,12 +230,12 @@ class ServerSession(Session):
# can also see we are logged in. # can also see we are logged in.
csession = ClientSessionStore(session_key=self.csessid) csession = ClientSessionStore(session_key=self.csessid)
if not csession.get("logged_in"): if not csession.get("logged_in"):
csession["logged_in"] = player.id csession["logged_in"] = account.id
csession.save() csession.save()
# Update account's last login time. # Update account's last login time.
self.player.last_login = timezone.now() self.account.last_login = timezone.now()
self.player.save() self.account.save()
# add the session-level cmdset # add the session-level cmdset
self.cmdset = CmdSetHandler(self, True) self.cmdset = CmdSetHandler(self, True)
@ -246,34 +246,34 @@ class ServerSession(Session):
""" """
if self.logged_in: if self.logged_in:
player = self.player account = self.account
if self.puppet: if self.puppet:
player.unpuppet_object(self) account.unpuppet_object(self)
uaccount = player uaccount = account
uaccount.last_login = timezone.now() uaccount.last_login = timezone.now()
uaccount.save() uaccount.save()
# calling player hook # calling account hook
player.at_disconnect() account.at_disconnect()
self.logged_in = False self.logged_in = False
if not self.sessionhandler.sessions_from_player(player): if not self.sessionhandler.sessions_from_account(account):
# no more sessions connected to this player # no more sessions connected to this account
player.is_connected = False account.is_connected = False
# this may be used to e.g. delete player after disconnection etc # this may be used to e.g. delete account after disconnection etc
player.at_post_disconnect() account.at_post_disconnect()
# remove any webclient settings monitors associated with this # remove any webclient settings monitors associated with this
# session # session
MONITOR_HANDLER.remove(player, "_saved_webclient_options", MONITOR_HANDLER.remove(account, "_saved_webclient_options",
self.sessid) self.sessid)
def get_player(self): def get_account(self):
""" """
Get the player associated with this session Get the account associated with this session
Returns: Returns:
player (Player): The associated Player. account (Account): The associated Account.
""" """
return self.logged_in and self.player return self.logged_in and self.account
def get_puppet(self): def get_puppet(self):
""" """
@ -286,17 +286,17 @@ class ServerSession(Session):
return self.logged_in and self.puppet return self.logged_in and self.puppet
get_character = get_puppet get_character = get_puppet
def get_puppet_or_player(self): def get_puppet_or_account(self):
""" """
Get puppet or player. Get puppet or account.
Returns: Returns:
controller (Object or Player): The puppet if one exists, controller (Object or Account): The puppet if one exists,
otherwise return the player. otherwise return the account.
""" """
if self.logged_in: if self.logged_in:
return self.puppet if self.puppet else self.player return self.puppet if self.puppet else self.account
return None return None
def log(self, message, channel=True): def log(self, message, channel=True):
@ -343,7 +343,7 @@ class ServerSession(Session):
if not idle: if not idle:
# Increment the user's command counter. # Increment the user's command counter.
self.cmd_total += 1 self.cmd_total += 1
# Player-visible idle time, not used in idle timeout calcs. # Account-visible idle time, not used in idle timeout calcs.
self.cmd_last_visible = self.cmd_last self.cmd_last_visible = self.cmd_last
def update_flags(self, **kwargs): def update_flags(self, **kwargs):
@ -395,7 +395,7 @@ class ServerSession(Session):
def msg(self, text=None, **kwargs): def msg(self, text=None, **kwargs):
""" """
Wrapper to mimic msg() functionality of Objects and Players. Wrapper to mimic msg() functionality of Objects and Accounts.
Args: Args:
text (str): String input. text (str): String input.
@ -449,8 +449,8 @@ class ServerSession(Session):
""" """
symbol = "" symbol = ""
if self.logged_in and hasattr(self, "player") and self.player: if self.logged_in and hasattr(self, "account") and self.account:
symbol = "(#%s)" % self.player.id symbol = "(#%s)" % self.account.id
try: try:
if hasattr(self.address, '__iter__'): if hasattr(self.address, '__iter__'):
address = ":".join([str(part) for part in self.address]) address = ":".join([str(part) for part in self.address])

View file

@ -25,7 +25,7 @@ class Session(object):
respective hook methods should be connected to the methods unique respective hook methods should be connected to the methods unique
for the respective protocol so that there is a unified interface for the respective protocol so that there is a unified interface
to Evennia. to Evennia.
2. A Server session. This is the same for all connected players, 2. A Server session. This is the same for all connected accounts,
regardless of how they connect. regardless of how they connect.
The Portal and Server have their own respective sessionhandlers. These The Portal and Server have their own respective sessionhandlers. These
@ -123,11 +123,11 @@ class Session(object):
def at_sync(self): def at_sync(self):
""" """
Called after a session has been fully synced (including Called after a session has been fully synced (including
secondary operations such as setting self.player based secondary operations such as setting self.account based
on uid etc). on uid etc).
""" """
self.protocol_flags.update(self.player.attributs.get("_saved_protocol_flags"), {}) self.protocol_flags.update(self.account.attributs.get("_saved_protocol_flags"), {})
# access hooks # access hooks

View file

@ -33,7 +33,7 @@ except ImportError:
_INLINEFUNC_ENABLED = settings.INLINEFUNC_ENABLED _INLINEFUNC_ENABLED = settings.INLINEFUNC_ENABLED
# delayed imports # delayed imports
_PlayerDB = None _AccountDB = None
_ServerSession = None _ServerSession = None
_ServerConfig = None _ServerConfig = None
_ScriptDB = None _ScriptDB = None
@ -77,20 +77,20 @@ def delayed_import():
Helper method for delayed import of all needed entities. Helper method for delayed import of all needed entities.
""" """
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB global _ServerSession, _AccountDB, _ServerConfig, _ScriptDB
if not _ServerSession: if not _ServerSession:
# we allow optional arbitrary serversession class for overloading # we allow optional arbitrary serversession class for overloading
modulename, classname = settings.SERVER_SESSION_CLASS.rsplit(".", 1) modulename, classname = settings.SERVER_SESSION_CLASS.rsplit(".", 1)
_ServerSession = variable_from_module(modulename, classname) _ServerSession = variable_from_module(modulename, classname)
if not _PlayerDB: if not _AccountDB:
from evennia.players.models import PlayerDB as _PlayerDB from evennia.accounts.models import AccountDB as _AccountDB
if not _ServerConfig: if not _ServerConfig:
from evennia.server.models import ServerConfig as _ServerConfig from evennia.server.models import ServerConfig as _ServerConfig
if not _ScriptDB: if not _ScriptDB:
from evennia.scripts.models import ScriptDB as _ScriptDB from evennia.scripts.models import ScriptDB as _ScriptDB
# including once to avoid warnings in Python syntax checkers # including once to avoid warnings in Python syntax checkers
assert(_ServerSession) assert(_ServerSession)
assert(_PlayerDB) assert(_AccountDB)
assert(_ServerConfig) assert(_ServerConfig)
assert(_ScriptDB) assert(_ScriptDB)
@ -249,7 +249,7 @@ class ServerSessionHandler(SessionHandler):
A session register with the handler in two steps, first by A session register with the handler in two steps, first by
registering itself with the connect() method. This indicates an registering itself with the connect() method. This indicates an
non-authenticated session. Whenever the session is authenticated non-authenticated session. Whenever the session is authenticated
the session together with the related player is sent to the login() the session together with the related account is sent to the login()
method. method.
""" """
@ -277,7 +277,7 @@ class ServerSessionHandler(SessionHandler):
""" """
delayed_import() delayed_import()
global _ServerSession, _PlayerDB, _ScriptDB global _ServerSession, _AccountDB, _ScriptDB
sess = _ServerSession() sess = _ServerSession()
sess.sessionhandler = self sess.sessionhandler = self
@ -291,10 +291,10 @@ class ServerSessionHandler(SessionHandler):
# Session is already logged in. This can happen in the # Session is already logged in. This can happen in the
# case of auto-authenticating protocols like SSH or # case of auto-authenticating protocols like SSH or
# webclient's session sharing # webclient's session sharing
player = _PlayerDB.objects.get_player_from_uid(sess.uid) account = _AccountDB.objects.get_account_from_uid(sess.uid)
if player: if account:
# this will set player.is_connected too # this will set account.is_connected too
self.login(sess, player, force=True) self.login(sess, account, force=True)
return return
else: else:
sess.logged_in = False sess.logged_in = False
@ -336,7 +336,7 @@ class ServerSessionHandler(SessionHandler):
""" """
delayed_import() delayed_import()
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB global _ServerSession, _AccountDB, _ServerConfig, _ScriptDB
for sess in self.values(): for sess in self.values():
# we delete the old session to make sure to catch eventual # we delete the old session to make sure to catch eventual
@ -348,7 +348,7 @@ class ServerSessionHandler(SessionHandler):
sess.sessionhandler = self sess.sessionhandler = self
sess.load_sync_data(sessdict) sess.load_sync_data(sessdict)
if sess.uid: if sess.uid:
sess.player = _PlayerDB.objects.get_player_from_uid(sess.uid) sess.account = _AccountDB.objects.get_account_from_uid(sess.uid)
self[sessid] = sess self[sessid] = sess
sess.at_sync() sess.at_sync()
@ -403,7 +403,7 @@ class ServerSessionHandler(SessionHandler):
"network:"irc.freenode.net", "port": 6667}) "network:"irc.freenode.net", "port": 6667})
Notes: Notes:
The new session will use the supplied player-bot uid to The new session will use the supplied account-bot uid to
initiate an already logged-in connection. The Portal will initiate an already logged-in connection. The Portal will
treat this as a normal connection and henceforth so will treat this as a normal connection and henceforth so will
the Server. the Server.
@ -420,15 +420,15 @@ class ServerSessionHandler(SessionHandler):
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION,
operation=SSHUTD) operation=SSHUTD)
def login(self, session, player, force=False, testmode=False): def login(self, session, account, force=False, testmode=False):
""" """
Log in the previously unloggedin session and the player we by Log in the previously unloggedin session and the account we by
now should know is connected to it. After this point we assume now should know is connected to it. After this point we assume
the session to be logged in one way or another. the session to be logged in one way or another.
Args: Args:
session (Session): The Session to authenticate. session (Session): The Session to authenticate.
player (Player): The Player identified as associated with this Session. account (Account): The Account identified as associated with this Session.
force (bool): Login also if the session thinks it's already logged in force (bool): Login also if the session thinks it's already logged in
(this can happen for auto-authenticating protocols) (this can happen for auto-authenticating protocols)
testmode (bool, optional): This is used by unittesting for testmode (bool, optional): This is used by unittesting for
@ -440,28 +440,28 @@ class ServerSessionHandler(SessionHandler):
# don't log in a session that is already logged in. # don't log in a session that is already logged in.
return return
player.is_connected = True account.is_connected = True
# sets up and assigns all properties on the session # sets up and assigns all properties on the session
session.at_login(player) session.at_login(account)
# player init # account init
player.at_init() account.at_init()
# Check if this is the first time the *player* logs in # Check if this is the first time the *account* logs in
if player.db.FIRST_LOGIN: if account.db.FIRST_LOGIN:
player.at_first_login() account.at_first_login()
del player.db.FIRST_LOGIN del account.db.FIRST_LOGIN
player.at_pre_login() account.at_pre_login()
if _MULTISESSION_MODE == 0: if _MULTISESSION_MODE == 0:
# disconnect all previous sessions. # disconnect all previous sessions.
self.disconnect_duplicate_sessions(session) self.disconnect_duplicate_sessions(session)
nsess = len(self.sessions_from_player(player)) nsess = len(self.sessions_from_account(account))
string = "Logged in: {player} {address} ({nsessions} session(s) total)" string = "Logged in: {account} {address} ({nsessions} session(s) total)"
string = string.format(player=player,address=session.address, nsessions=nsess) string = string.format(account=account,address=session.address, nsessions=nsess)
session.log(string) session.log(string)
session.logged_in = True session.logged_in = True
# sync the portal to the session # sync the portal to the session
@ -469,7 +469,7 @@ class ServerSessionHandler(SessionHandler):
self.server.amp_protocol.send_AdminServer2Portal(session, self.server.amp_protocol.send_AdminServer2Portal(session,
operation=SLOGIN, operation=SLOGIN,
sessiondata={"logged_in": True}) sessiondata={"logged_in": True})
player.at_post_login(session=session) account.at_post_login(session=session)
def disconnect(self, session, reason="", sync_portal=True): def disconnect(self, session, reason="", sync_portal=True):
""" """
@ -488,11 +488,11 @@ class ServerSessionHandler(SessionHandler):
if not session: if not session:
return return
if hasattr(session, "player") and session.player: if hasattr(session, "account") and session.account:
# only log accounts logging off # only log accounts logging off
nsess = len(self.sessions_from_player(session.player)) - 1 nsess = len(self.sessions_from_account(session.account)) - 1
string = "Logged out: {player} {address} ({nsessions} sessions(s) remaining)" string = "Logged out: {account} {address} ({nsessions} sessions(s) remaining)"
string = string.format(player=session.player, address=session.address, nsessions=nsess) string = string.format(account=session.account, address=session.address, nsessions=nsess)
session.log(string) session.log(string)
session.at_disconnect() session.at_disconnect()
@ -575,28 +575,28 @@ class ServerSessionHandler(SessionHandler):
and (tcurr - session.cmd_last) > _IDLE_TIMEOUT): and (tcurr - session.cmd_last) > _IDLE_TIMEOUT):
self.disconnect(session, reason=reason) self.disconnect(session, reason=reason)
def player_count(self): def account_count(self):
""" """
Get the number of connected players (not sessions since a Get the number of connected accounts (not sessions since a
player may have more than one session depending on settings). account may have more than one session depending on settings).
Only logged-in players are counted here. Only logged-in accounts are counted here.
Returns: Returns:
nplayer (int): Number of connected players naccount (int): Number of connected accounts
""" """
return len(set(session.uid for session in self.values() if session.logged_in)) return len(set(session.uid for session in self.values() if session.logged_in))
def all_connected_players(self): def all_connected_accounts(self):
""" """
Get a unique list of connected and logged-in Players. Get a unique list of connected and logged-in Accounts.
Returns: Returns:
players (list): All conected Players (which may be fewer than the accounts (list): All conected Accounts (which may be fewer than the
amount of Sessions due to multi-playing). amount of Sessions due to multi-playing).
""" """
return list(set(session.player for session in self.values() if session.logged_in and session.player)) return list(set(session.account for session in self.values() if session.logged_in and session.account))
def session_from_sessid(self, sessid): def session_from_sessid(self, sessid):
""" """
@ -614,13 +614,13 @@ class ServerSessionHandler(SessionHandler):
return [self.get(sid) for sid in sessid if sid in self] return [self.get(sid) for sid in sessid if sid in self]
return self.get(sessid) return self.get(sessid)
def session_from_player(self, player, sessid): def session_from_account(self, account, sessid):
""" """
Given a player and a session id, return the actual session Given an account and a session id, return the actual session
object. object.
Args: Args:
player (Player): The Player to get the Session from. account (Account): The Account to get the Session from.
sessid (int or list): Session id(s). sessid (int or list): Session id(s).
Returns: Returns:
@ -628,21 +628,21 @@ class ServerSessionHandler(SessionHandler):
""" """
sessions = [self[sid] for sid in make_iter(sessid) sessions = [self[sid] for sid in make_iter(sessid)
if sid in self and self[sid].logged_in and player.uid == self[sid].uid] if sid in self and self[sid].logged_in and account.uid == self[sid].uid]
return sessions[0] if len(sessions) == 1 else sessions return sessions[0] if len(sessions) == 1 else sessions
def sessions_from_player(self, player): def sessions_from_account(self, account):
""" """
Given a player, return all matching sessions. Given an account, return all matching sessions.
Args: Args:
player (Player): Player to get sessions from. account (Account): Account to get sessions from.
Returns: Returns:
sessions (list): All Sessions associated with this player. sessions (list): All Sessions associated with this account.
""" """
uid = player.uid uid = account.uid
return [session for session in self.values() if session.logged_in and session.uid == uid] return [session for session in self.values() if session.logged_in and session.uid == uid]
def sessions_from_puppet(self, puppet): def sessions_from_puppet(self, puppet):

View file

@ -151,10 +151,10 @@ IDLE_TIMEOUT = -1
# command-name is given here; this is because the webclient needs a default # command-name is given here; this is because the webclient needs a default
# to send to avoid proxy timeouts. # to send to avoid proxy timeouts.
IDLE_COMMAND = "idle" IDLE_COMMAND = "idle"
# The set of encodings tried. A Player object may set an attribute "encoding" on # The set of encodings tried. An Account object may set an attribute "encoding" on
# itself to match the client used. If not set, or wrong encoding is # itself to match the client used. If not set, or wrong encoding is
# given, this list is tried, in order, aborting on the first match. # given, this list is tried, in order, aborting on the first match.
# Add sets for languages/regions your players are likely to use. # Add sets for languages/regions your accounts are likely to use.
# (see http://en.wikipedia.org/wiki/Character_encoding) # (see http://en.wikipedia.org/wiki/Character_encoding)
ENCODINGS = ["utf-8", "latin-1", "ISO-8859-1"] ENCODINGS = ["utf-8", "latin-1", "ISO-8859-1"]
# Regular expression applied to all output to a given session in order # Regular expression applied to all output to a given session in order
@ -314,7 +314,7 @@ SERVER_SERVICES_PLUGIN_MODULES = ["server.conf.server_services_plugins"]
# It will be called last in the startup sequence. # It will be called last in the startup sequence.
PORTAL_SERVICES_PLUGIN_MODULES = ["server.conf.portal_services_plugins"] PORTAL_SERVICES_PLUGIN_MODULES = ["server.conf.portal_services_plugins"]
# Module holding MSSP meta data. This is used by MUD-crawlers to determine # Module holding MSSP meta data. This is used by MUD-crawlers to determine
# what type of game you are running, how many players you have etc. # what type of game you are running, how many accounts you have etc.
MSSP_META_MODULE = "server.conf.mssp" MSSP_META_MODULE = "server.conf.mssp"
# Module for web plugins. # Module for web plugins.
WEB_PLUGINS_MODULE = "server.conf.web_plugins" WEB_PLUGINS_MODULE = "server.conf.web_plugins"
@ -345,14 +345,14 @@ COLOR_ANSI_EXTRA_MAP = []
# change this, it's recommended you do it before having created a lot of objects # change this, it's recommended you do it before having created a lot of objects
# (or simply reset the database after the change for simplicity). # (or simply reset the database after the change for simplicity).
# Command set used on session before player has logged in # Command set used on session before account has logged in
CMDSET_UNLOGGEDIN = "commands.default_cmdsets.UnloggedinCmdSet" CMDSET_UNLOGGEDIN = "commands.default_cmdsets.UnloggedinCmdSet"
# Command set used on the logged-in session # Command set used on the logged-in session
CMDSET_SESSION = "commands.default_cmdsets.SessionCmdSet" CMDSET_SESSION = "commands.default_cmdsets.SessionCmdSet"
# Default set for logged in player with characters (fallback) # Default set for logged in account with characters (fallback)
CMDSET_CHARACTER = "commands.default_cmdsets.CharacterCmdSet" CMDSET_CHARACTER = "commands.default_cmdsets.CharacterCmdSet"
# Command set for players without a character (ooc) # Command set for accounts without a character (ooc)
CMDSET_PLAYER = "commands.default_cmdsets.PlayerCmdSet" CMDSET_ACCOUNT = "commands.default_cmdsets.AccountCmdSet"
# Location to search for cmdsets if full path not given # Location to search for cmdsets if full path not given
CMDSET_PATHS = ["commands", "evennia", "contribs"] CMDSET_PATHS = ["commands", "evennia", "contribs"]
# Parent class for all default commands. Changing this class will # Parent class for all default commands. Changing this class will
@ -365,7 +365,7 @@ COMMAND_DEFAULT_CLASS = "evennia.commands.default.muxcommand.MuxCommand"
COMMAND_DEFAULT_ARG_REGEX = None COMMAND_DEFAULT_ARG_REGEX = None
# By default, Command.msg will only send data to the Session calling # By default, Command.msg will only send data to the Session calling
# the Command in the first place. If set, Command.msg will instead return # the Command in the first place. If set, Command.msg will instead return
# data to all Sessions connected to the Player/Character associated with # data to all Sessions connected to the Account/Character associated with
# calling the Command. This may be more intuitive for users in certain # calling the Command. This may be more intuitive for users in certain
# multisession modes. # multisession modes.
COMMAND_DEFAULT_MSG_ALL_SESSIONS = False COMMAND_DEFAULT_MSG_ALL_SESSIONS = False
@ -392,11 +392,11 @@ SERVER_SESSION_CLASS = "evennia.server.serversession.ServerSession"
# or start from the evennia library. # or start from the evennia library.
TYPECLASS_PATHS = ["typeclasses", "evennia", "evennia.contrib", "evennia.contrib.tutorial_examples"] TYPECLASS_PATHS = ["typeclasses", "evennia", "evennia.contrib", "evennia.contrib.tutorial_examples"]
# Typeclass for player objects (linked to a character) (fallback) # Typeclass for account objects (linked to a character) (fallback)
BASE_PLAYER_TYPECLASS = "typeclasses.players.Player" BASE_ACCOUNT_TYPECLASS = "typeclasses.accounts.Account"
# Typeclass and base for all objects (fallback) # Typeclass and base for all objects (fallback)
BASE_OBJECT_TYPECLASS = "typeclasses.objects.Object" BASE_OBJECT_TYPECLASS = "typeclasses.objects.Object"
# Typeclass for character objects linked to a player (fallback) # Typeclass for character objects linked to an account (fallback)
BASE_CHARACTER_TYPECLASS = "typeclasses.characters.Character" BASE_CHARACTER_TYPECLASS = "typeclasses.characters.Character"
# Typeclass for rooms (fallback) # Typeclass for rooms (fallback)
BASE_ROOM_TYPECLASS = "typeclasses.rooms.Room" BASE_ROOM_TYPECLASS = "typeclasses.rooms.Room"
@ -465,7 +465,7 @@ INLINEFUNC_MODULES = ["evennia.utils.inlinefuncs",
"server.conf.inlinefuncs"] "server.conf.inlinefuncs"]
###################################################################### ######################################################################
# Default Player setup and access # Default Account setup and access
###################################################################### ######################################################################
# Different Multisession modes allow a player (=account) to connect to the # Different Multisession modes allow a player (=account) to connect to the
@ -473,12 +473,12 @@ INLINEFUNC_MODULES = ["evennia.utils.inlinefuncs",
# only one character created to the same name as the account at first login. # only one character created to the same name as the account at first login.
# In modes 2,3 no default character will be created and the MAX_NR_CHARACTERS # In modes 2,3 no default character will be created and the MAX_NR_CHARACTERS
# value (below) defines how many characters the default char_create command # value (below) defines how many characters the default char_create command
# allow per player. # allow per account.
# 0 - single session, one player, one character, when a new session is # 0 - single session, one account, one character, when a new session is
# connected, the old one is disconnected # connected, the old one is disconnected
# 1 - multiple sessions, one player, one character, each session getting # 1 - multiple sessions, one account, one character, each session getting
# the same data # the same data
# 2 - multiple sessions, one player, many characters, one session per # 2 - multiple sessions, one account, many characters, one session per
# character (disconnects multiplets) # character (disconnects multiplets)
# 3 - like mode 2, except multiple sessions can puppet one character, each # 3 - like mode 2, except multiple sessions can puppet one character, each
# session getting the same data. # session getting the same data.
@ -491,12 +491,12 @@ MAX_NR_CHARACTERS = 1
# hierarchy includes access of all levels below it. Used by the perm()/pperm() # hierarchy includes access of all levels below it. Used by the perm()/pperm()
# lock functions, which accepts both plural and singular (Admin & Admins) # lock functions, which accepts both plural and singular (Admin & Admins)
PERMISSION_HIERARCHY = ["Guest", # note-only used if GUEST_ENABLED=True PERMISSION_HIERARCHY = ["Guest", # note-only used if GUEST_ENABLED=True
"Player", "Account",
"Helper", "Helper",
"Builder", "Builder",
"Admin", "Admin",
"Developer"] "Developer"]
# The default permission given to all new players # The default permission given to all new accounts
PERMISSION_PLAYER_DEFAULT = "Player" PERMISSION_PLAYER_DEFAULT = "Player"
# Default sizes for client window (in number of characters), if client # Default sizes for client window (in number of characters), if client
# is not supplying this on its own # is not supplying this on its own
@ -511,8 +511,8 @@ CLIENT_DEFAULT_HEIGHT = 45 # telnet standard is 24 but does anyone use such
# This enables guest logins, by default via "connect guest". Note that # This enables guest logins, by default via "connect guest". Note that
# you need to edit your login screen to inform about this possibility. # you need to edit your login screen to inform about this possibility.
GUEST_ENABLED = False GUEST_ENABLED = False
# Typeclass for guest player objects (linked to a character) # Typeclass for guest account objects (linked to a character)
BASE_GUEST_TYPECLASS = "typeclasses.players.Guest" BASE_GUEST_TYPECLASS = "typeclasses.accounts.Guest"
# The permission given to guests # The permission given to guests
PERMISSION_GUEST_DEFAULT = "Guests" PERMISSION_GUEST_DEFAULT = "Guests"
# The default home location used for guests. # The default home location used for guests.
@ -520,7 +520,7 @@ GUEST_HOME = DEFAULT_HOME
# The start position used for guest characters. # The start position used for guest characters.
GUEST_START_LOCATION = START_LOCATION GUEST_START_LOCATION = START_LOCATION
# The naming convention used for creating new guest # The naming convention used for creating new guest
# players/characters. The size of this list also determines how many # accounts/characters. The size of this list also determines how many
# guests may be on the game at once. The default is a maximum of nine # guests may be on the game at once. The default is a maximum of nine
# guests, named Guest1 through Guest9. # guests, named Guest1 through Guest9.
GUEST_LIST = ["Guest" + str(s+1) for s in range(9)] GUEST_LIST = ["Guest" + str(s+1) for s in range(9)]
@ -551,7 +551,7 @@ DEFAULT_CHANNELS = [
"desc": "Connection log", "desc": "Connection log",
"locks": "control:perm(Developer);listen:perm(Admin);send:false()"} "locks": "control:perm(Developer);listen:perm(Admin);send:false()"}
] ]
# Extra optional channel for receiving connection messages ("<player> has (dis)connected"). # Extra optional channel for receiving connection messages ("<account> has (dis)connected").
# While the MudInfo channel will also receieve this, this channel is meant for non-staffers. # While the MudInfo channel will also receieve this, this channel is meant for non-staffers.
CHANNEL_CONNECTINFO = None CHANNEL_CONNECTINFO = None
@ -716,7 +716,7 @@ INSTALLED_APPS = (
'evennia.utils.idmapper', 'evennia.utils.idmapper',
'evennia.server', 'evennia.server',
'evennia.typeclasses', 'evennia.typeclasses',
'evennia.players', 'evennia.accounts',
'evennia.accounts', 'evennia.accounts',
'evennia.objects', 'evennia.objects',
'evennia.comms', 'evennia.comms',
@ -726,7 +726,7 @@ INSTALLED_APPS = (
'evennia.web.webclient') 'evennia.web.webclient')
# The user profile extends the User object with more functionality; # The user profile extends the User object with more functionality;
# This should usually not be changed. # This should usually not be changed.
AUTH_USER_MODEL = "players.PlayerDB" AUTH_USER_MODEL = "accounts.AccountDB"
# Use a custom test runner that just tests Evennia-specific apps. # Use a custom test runner that just tests Evennia-specific apps.
TEST_RUNNER = 'evennia.server.tests.EvenniaTestSuiteRunner' TEST_RUNNER = 'evennia.server.tests.EvenniaTestSuiteRunner'

View file

@ -3,7 +3,7 @@
This sub-package defines the typeclass-system, a way to wrap database This sub-package defines the typeclass-system, a way to wrap database
access into almost-normal Python classes. Using typeclasses one can access into almost-normal Python classes. Using typeclasses one can
work in normal Python while having the luxury of persistent data work in normal Python while having the luxury of persistent data
storage at every turn. ObjectDB, ChannelDB, PlayerDB and ScriptDB all storage at every turn. ObjectDB, ChannelDB, AccountDB and ScriptDB all
inherit from the models in this package. Here is also were the inherit from the models in this package. Here is also were the
Attribute and Tag models are defined along with their handlers. Attribute and Tag models are defined along with their handlers.

View file

@ -113,13 +113,13 @@ class TagInline(admin.TabularInline):
and the 'model' and 'related_field' class attributes must be set. model should be the and the 'model' and 'related_field' class attributes must be set. model should be the
through model (ObjectDB_db_tag', for example), while related field should be the name through model (ObjectDB_db_tag', for example), while related field should be the name
of the field on that through model which points to the model being used: 'objectdb', of the field on that through model which points to the model being used: 'objectdb',
'msg', 'playerdb', etc. 'msg', 'accountdb', etc.
""" """
# Set this to the through model of your desired M2M when subclassing. # Set this to the through model of your desired M2M when subclassing.
model = None model = None
form = TagForm form = TagForm
formset = TagFormSet formset = TagFormSet
related_field = None # Must be 'objectdb', 'playerdb', 'msg', etc. Set when subclassing related_field = None # Must be 'objectdb', 'accountdb', 'msg', etc. Set when subclassing
raw_id_fields = ('tag',) raw_id_fields = ('tag',)
readonly_fields = ('tag',) readonly_fields = ('tag',)
extra = 0 extra = 0
@ -253,13 +253,13 @@ class AttributeInline(admin.TabularInline):
and the 'model' and 'related_field' class attributes must be set. model should be the and the 'model' and 'related_field' class attributes must be set. model should be the
through model (ObjectDB_db_tag', for example), while related field should be the name through model (ObjectDB_db_tag', for example), while related field should be the name
of the field on that through model which points to the model being used: 'objectdb', of the field on that through model which points to the model being used: 'objectdb',
'msg', 'playerdb', etc. 'msg', 'accountdb', etc.
""" """
# Set this to the through model of your desired M2M when subclassing. # Set this to the through model of your desired M2M when subclassing.
model = None model = None
form = AttributeForm form = AttributeForm
formset = AttributeFormSet formset = AttributeFormSet
related_field = None # Must be 'objectdb', 'playerdb', 'msg', etc. Set when subclassing related_field = None # Must be 'objectdb', 'accountdb', 'msg', etc. Set when subclassing
raw_id_fields = ('attribute',) raw_id_fields = ('attribute',)
readonly_fields = ('attribute',) readonly_fields = ('attribute',)
extra = 0 extra = 0

View file

@ -868,7 +868,7 @@ class NickHandler(AttributeHandler):
""" """
super(NickHandler, self).remove(key, category=category, **kwargs) super(NickHandler, self).remove(key, category=category, **kwargs)
def nickreplace(self, raw_string, categories=("inputline", "channel"), include_player=True): def nickreplace(self, raw_string, categories=("inputline", "channel"), include_account=True):
""" """
Apply nick replacement of entries in raw_string with nick replacement. Apply nick replacement of entries in raw_string with nick replacement.
@ -878,8 +878,8 @@ class NickHandler(AttributeHandler):
categories (tuple, optional): Replacement categories in categories (tuple, optional): Replacement categories in
which to perform the replacement, such as "inputline", which to perform the replacement, such as "inputline",
"channel" etc. "channel" etc.
include_player (bool, optional): Also include replacement include_account (bool, optional): Also include replacement
with nicks stored on the Player level. with nicks stored on the Account level.
kwargs (any, optional): Not used. kwargs (any, optional): Not used.
Returns: Returns:
@ -891,9 +891,9 @@ class NickHandler(AttributeHandler):
for category in make_iter(categories): for category in make_iter(categories):
nicks.update({nick.key: nick for nick in make_iter( nicks.update({nick.key: nick for nick in make_iter(
self.get(category=category, return_obj=True)) if nick and nick.key}) self.get(category=category, return_obj=True)) if nick and nick.key})
if include_player and self.obj.has_player: if include_account and self.obj.has_account:
for category in make_iter(categories): for category in make_iter(categories):
nicks.update({nick.key: nick for nick in make_iter(self.obj.player.nicks.get( nicks.update({nick.key: nick for nick in make_iter(self.obj.account.nicks.get(
category=category, return_obj=True)) if nick and nick.key}) category=category, return_obj=True)) if nick and nick.key})
for key, nick in nicks.iteritems(): for key, nick in nicks.iteritems():
nick_regex, template, _, _ = nick.value nick_regex, template, _, _ = nick.value

View file

@ -449,15 +449,15 @@ class TypedObject(SharedMemoryModel):
""" """
This performs an in-situ swap of the typeclass. This means This performs an in-situ swap of the typeclass. This means
that in-game, this object will suddenly be something else. that in-game, this object will suddenly be something else.
Player will not be affected. To 'move' a player to a different Account will not be affected. To 'move' an account to a different
object entirely (while retaining this object's type), use object entirely (while retaining this object's type), use
self.player.swap_object(). self.account.swap_object().
Note that this might be an error prone operation if the Note that this might be an error prone operation if the
old/new typeclass was heavily customized - your code old/new typeclass was heavily customized - your code
might expect one and not the other, so be careful to might expect one and not the other, so be careful to
bug test your code if using this feature! Often its easiest bug test your code if using this feature! Often its easiest
to create a new object and just swap the player over to to create a new object and just swap the account over to
that one instead. that one instead.
Args: Args:
@ -558,8 +558,8 @@ class TypedObject(SharedMemoryModel):
result (bool): If the permstring is passed or not. result (bool): If the permstring is passed or not.
""" """
if hasattr(self, "player"): if hasattr(self, "account"):
if self.player and self.player.is_superuser and not self.player.attributes.get("_quell"): if self.account and self.account.is_superuser and not self.account.attributes.get("_quell"):
return True return True
else: else:
if self.is_superuser and not self.attributes.get("_quell"): if self.is_superuser and not self.attributes.get("_quell"):
@ -676,7 +676,7 @@ class TypedObject(SharedMemoryModel):
Displays the name of the object in a viewer-aware manner. Displays the name of the object in a viewer-aware manner.
Args: Args:
looker (TypedObject): The object or player that is looking looker (TypedObject): The object or account that is looking
at/getting inforamtion for this object. at/getting inforamtion for this object.
Returns: Returns:
@ -707,7 +707,7 @@ class TypedObject(SharedMemoryModel):
not in your normal inventory listing. not in your normal inventory listing.
Args: Args:
looker (TypedObject): The object or player that is looking looker (TypedObject): The object or account that is looking
at/getting information for this object. at/getting information for this object.
Returns: Returns:

View file

@ -19,7 +19,7 @@ Models covered:
Help Help
Message Message
Channel Channel
Players Accounts
""" """
from django.conf import settings from django.conf import settings
from django.db import IntegrityError from django.db import IntegrityError
@ -35,8 +35,8 @@ _Script = None
_ScriptDB = None _ScriptDB = None
_HelpEntry = None _HelpEntry = None
_Msg = None _Msg = None
_Player = None _Account = None
_PlayerDB = None _AccountDB = None
_to_object = None _to_object = None
_ChannelDB = None _ChannelDB = None
_channelhandler = None _channelhandler = None
@ -44,7 +44,7 @@ _channelhandler = None
# limit symbol import from API # limit symbol import from API
__all__ = ("create_object", "create_script", "create_help_entry", __all__ = ("create_object", "create_script", "create_help_entry",
"create_message", "create_channel", "create_player") "create_message", "create_channel", "create_account")
_GA = object.__getattribute__ _GA = object.__getattribute__
@ -129,7 +129,7 @@ object = create_object
# #
# Script creation # Script creation
def create_script(typeclass=None, key=None, obj=None, player=None, locks=None, def create_script(typeclass=None, key=None, obj=None, account=None, locks=None,
interval=None, start_delay=None, repeats=None, interval=None, start_delay=None, repeats=None,
persistent=None, autostart=True, report_to=None, desc=None): persistent=None, autostart=True, report_to=None, desc=None):
""" """
@ -145,7 +145,7 @@ def create_script(typeclass=None, key=None, obj=None, player=None, locks=None,
#dbref will be set. #dbref will be set.
obj (Object): The entity on which this Script sits. If this obj (Object): The entity on which this Script sits. If this
is `None`, we are creating a "global" script. is `None`, we are creating a "global" script.
player (Player): The player on which this Script sits. It is account (Account): The account on which this Script sits. It is
exclusiv to `obj`. exclusiv to `obj`.
locks (str): one or more lockstrings, separated by semicolons. locks (str): one or more lockstrings, separated by semicolons.
interval (int): The triggering interval for this Script, in interval (int): The triggering interval for this Script, in
@ -180,7 +180,7 @@ def create_script(typeclass=None, key=None, obj=None, player=None, locks=None,
# validate input # validate input
kwarg = {} kwarg = {}
if key: kwarg["db_key"] = key if key: kwarg["db_key"] = key
if player: kwarg["db_player"] = dbid_to_obj(player, _ScriptDB) if account: kwarg["db_account"] = dbid_to_obj(account, _ScriptDB)
if obj: kwarg["db_obj"] = dbid_to_obj(obj, _ScriptDB) if obj: kwarg["db_obj"] = dbid_to_obj(obj, _ScriptDB)
if interval: kwarg["db_interval"] = interval if interval: kwarg["db_interval"] = interval
if start_delay: kwarg["db_start_delay"] = start_delay if start_delay: kwarg["db_start_delay"] = start_delay
@ -192,7 +192,7 @@ def create_script(typeclass=None, key=None, obj=None, player=None, locks=None,
new_script = typeclass(**kwarg) new_script = typeclass(**kwarg)
# store the call signature for the signal # store the call signature for the signal
new_script._createdict = dict(key=key, obj=obj, player=player, locks=locks, interval=interval, new_script._createdict = dict(key=key, obj=obj, account=account, locks=locks, interval=interval,
start_delay=start_delay, repeats=repeats, persistent=persistent, start_delay=start_delay, repeats=repeats, persistent=persistent,
autostart=autostart, report_to=report_to) autostart=autostart, report_to=report_to)
# this will trigger the save signal which in turn calls the # this will trigger the save signal which in turn calls the
@ -263,15 +263,15 @@ def create_message(senderobj, message, channels=None, receivers=None, locks=None
database-persistent communication between entites. database-persistent communication between entites.
Args: Args:
senderobj (Object or Player): The entity sending the Msg. senderobj (Object or Account): The entity sending the Msg.
message (str): Text with the message. Eventual headers, titles message (str): Text with the message. Eventual headers, titles
etc should all be included in this text string. Formatting etc should all be included in this text string. Formatting
will be retained. will be retained.
channels (Channel, key or list): A channel or a list of channels to channels (Channel, key or list): A channel or a list of channels to
send to. The channels may be actual channel objects or their send to. The channels may be actual channel objects or their
unique key strings. unique key strings.
receivers (Object, Player, str or list): A Player/Object to send receivers (Object, Account, str or list): An Account/Object to send
to, or a list of them. May be Player objects or playernames. to, or a list of them. May be Account objects or accountnames.
locks (str): Lock definition string. locks (str): Lock definition string.
header (str): Mime-type or other optional information for the message header (str): Mime-type or other optional information for the message
@ -310,7 +310,7 @@ def create_channel(key, aliases=None, desc=None,
""" """
Create A communication Channel. A Channel serves as a central hub Create A communication Channel. A Channel serves as a central hub
for distributing Msgs to groups of people without specifying the for distributing Msgs to groups of people without specifying the
receivers explicitly. Instead players may 'connect' to the channel receivers explicitly. Instead accounts may 'connect' to the channel
and follow the flow of messages. By default the channel allows and follow the flow of messages. By default the channel allows
access to all old messages, but this can be turned off with the access to all old messages, but this can be turned off with the
keep_log switch. keep_log switch.
@ -352,28 +352,28 @@ channel = create_channel
# #
# Player creation methods # Account creation methods
# #
def create_player(key, email, password, def create_account(key, email, password,
typeclass=None, typeclass=None,
is_superuser=False, is_superuser=False,
locks=None, permissions=None, locks=None, permissions=None,
report_to=None): report_to=None):
""" """
This creates a new player. This creates a new account.
Args: Args:
key (str): The player's name. This should be unique. key (str): The account's name. This should be unique.
email (str): Email on valid addr@addr.domain form. This is email (str): Email on valid addr@addr.domain form. This is
technically required but if set to `None`, an email of technically required but if set to `None`, an email of
`dummy@example.com` will be used as a placeholder. `dummy@example.com` will be used as a placeholder.
password (str): Password in cleartext. password (str): Password in cleartext.
Kwargs: Kwargs:
is_superuser (bool): Wether or not this player is to be a superuser is_superuser (bool): Wether or not this account is to be a superuser
locks (str): Lockstring. locks (str): Lockstring.
permission (list): List of permission strings. permission (list): List of permission strings.
report_to (Object): An object with a msg() method to report report_to (Object): An object with a msg() method to report
@ -389,42 +389,42 @@ def create_player(key, email, password,
operations and is thus not suitable for play-testing the game. operations and is thus not suitable for play-testing the game.
""" """
global _PlayerDB global _AccountDB
if not _PlayerDB: if not _AccountDB:
from evennia.players.models import PlayerDB as _PlayerDB from evennia.accounts.models import AccountDB as _AccountDB
typeclass = typeclass if typeclass else settings.BASE_PLAYER_TYPECLASS typeclass = typeclass if typeclass else settings.BASE_ACCOUNT_TYPECLASS
if isinstance(typeclass, basestring): if isinstance(typeclass, basestring):
# a path is given. Load the actual typeclass. # a path is given. Load the actual typeclass.
typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS) typeclass = class_from_module(typeclass, settings.TYPECLASS_PATHS)
# setup input for the create command. We use PlayerDB as baseclass # setup input for the create command. We use AccountDB as baseclass
# here to give us maximum freedom (the typeclasses will load # here to give us maximum freedom (the typeclasses will load
# correctly when each object is recovered). # correctly when each object is recovered).
if not email: if not email:
email = "dummy@example.com" email = "dummy@example.com"
if _PlayerDB.objects.filter(username__iexact=key): if _AccountDB.objects.filter(username__iexact=key):
raise ValueError("A Player with the name '%s' already exists." % key) raise ValueError("An Account with the name '%s' already exists." % key)
# this handles a given dbref-relocate to a player. # this handles a given dbref-relocate to an account.
report_to = dbid_to_obj(report_to, _PlayerDB) report_to = dbid_to_obj(report_to, _AccountDB)
# create the correct player entity, using the setup from # create the correct account entity, using the setup from
# base django auth. # base django auth.
now = timezone.now() now = timezone.now()
email = typeclass.objects.normalize_email(email) email = typeclass.objects.normalize_email(email)
new_player = typeclass(username=key, email=email, new_account = typeclass(username=key, email=email,
is_staff=is_superuser, is_superuser=is_superuser, is_staff=is_superuser, is_superuser=is_superuser,
last_login=now, date_joined=now) last_login=now, date_joined=now)
new_player.set_password(password) new_account.set_password(password)
new_player._createdict = dict(locks=locks, permissions=permissions, report_to=report_to) new_account._createdict = dict(locks=locks, permissions=permissions, report_to=report_to)
# saving will trigger the signal that calls the # saving will trigger the signal that calls the
# at_first_save hook on the typeclass, where the _createdict # at_first_save hook on the typeclass, where the _createdict
# can be used. # can be used.
new_player.save() new_account.save()
return new_player return new_account
# alias # alias
player = create_player account = create_account

View file

@ -373,7 +373,7 @@ def unpack_dbobj(item):
def pack_session(item): def pack_session(item):
""" """
Handle the safe serializion of Sessions objects (these contain Handle the safe serializion of Sessions objects (these contain
hidden references to database objects (players, puppets) so they hidden references to database objects (accounts, puppets) so they
can't be safely serialized). can't be safely serialized).
Args: Args:

View file

@ -242,13 +242,13 @@ class CmdEvMenuNode(Command):
caller = self.caller caller = self.caller
# we store Session on the menu since this can be hard to # we store Session on the menu since this can be hard to
# get in multisession environemtns if caller is a Player. # get in multisession environemtns if caller is an Account.
menu = caller.ndb._menutree menu = caller.ndb._menutree
if not menu: if not menu:
if _restore(caller): if _restore(caller):
return return
orig_caller = caller orig_caller = caller
caller = caller.player if hasattr(caller, "player") else None caller = caller.account if hasattr(caller, "account") else None
menu = caller.ndb._menutree if caller else None menu = caller.ndb._menutree if caller else None
if not menu: if not menu:
if caller and _restore(caller): if caller and _restore(caller):
@ -261,7 +261,7 @@ class CmdEvMenuNode(Command):
orig_caller.msg(err) # don't give the session as a kwarg here, direct to original orig_caller.msg(err) # don't give the session as a kwarg here, direct to original
raise EvMenuError(err) raise EvMenuError(err)
# we must do this after the caller with the menui has been correctly identified since it # we must do this after the caller with the menui has been correctly identified since it
# can be either Player, Object or Session (in the latter case this info will be superfluous). # can be either Account, Object or Session (in the latter case this info will be superfluous).
caller.ndb._menutree._session = self.session caller.ndb._menutree._session = self.session
# we have a menu, use it. # we have a menu, use it.
menu.parse_input(self.raw_string) menu.parse_input(self.raw_string)
@ -309,7 +309,7 @@ class EvMenu(object):
Initialize the menu tree and start the caller onto the first node. Initialize the menu tree and start the caller onto the first node.
Args: Args:
caller (Object, Player or Session): The user of the menu. caller (Object, Account or Session): The user of the menu.
menudata (str, module or dict): The full or relative path to the module menudata (str, module or dict): The full or relative path to the module
holding the menu tree data. All global functions in this module holding the menu tree data. All global functions in this module
whose name doesn't start with '_ ' will be parsed as menu nodes. whose name doesn't start with '_ ' will be parsed as menu nodes.
@ -361,7 +361,7 @@ class EvMenu(object):
startnode_input (str, optional): Send an input text to `startnode` as if startnode_input (str, optional): Send an input text to `startnode` as if
a user input text from a fictional previous node. When the server reloads, a user input text from a fictional previous node. When the server reloads,
the latest visited node will be re-run using this kwarg. the latest visited node will be re-run using this kwarg.
session (Session, optional): This is useful when calling EvMenu from a player session (Session, optional): This is useful when calling EvMenu from an account
in multisession mode > 2. Note that this session only really relevant in multisession mode > 2. Note that this session only really relevant
for the very first display of the first node - after that, EvMenu itself for the very first display of the first node - after that, EvMenu itself
will keep the session updated from the command input. So a persistent will keep the session updated from the command input. So a persistent
@ -777,7 +777,7 @@ class EvMenu(object):
Args: Args:
optionlist (list): List of (key, description) tuples for every optionlist (list): List of (key, description) tuples for every
option related to this node. option related to this node.
caller (Object, Player or None, optional): The caller of the node. caller (Object, Account or None, optional): The caller of the node.
Returns: Returns:
options (str): The formatted option display. options (str): The formatted option display.
@ -841,7 +841,7 @@ class EvMenu(object):
Args: Args:
nodetext (str): The node text as returned by `self.nodetext_formatter`. nodetext (str): The node text as returned by `self.nodetext_formatter`.
optionstext (str): The options display as returned by `self.options_formatter`. optionstext (str): The options display as returned by `self.options_formatter`.
caller (Object, Player or None, optional): The caller of the node. caller (Object, Account or None, optional): The caller of the node.
Returns: Returns:
node (str): The formatted node to display. node (str): The formatted node to display.
@ -874,9 +874,9 @@ class CmdGetInput(Command):
caller = self.caller caller = self.caller
try: try:
getinput = caller.ndb._getinput getinput = caller.ndb._getinput
if not getinput and hasattr(caller, "player"): if not getinput and hasattr(caller, "account"):
getinput = caller.player.ndb._getinput getinput = caller.account.ndb._getinput
caller = caller.player caller = caller.account
callback = getinput._callback callback = getinput._callback
caller.ndb._getinput._session = self.session caller.ndb._getinput._session = self.session
@ -925,7 +925,7 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs):
the caller. the caller.
Args: Args:
caller (Player or Object): The entity being asked caller (Account or Object): The entity being asked
the question. This should usually be an object the question. This should usually be an object
controlled by a user. controlled by a user.
prompt (str): This text will be shown to the user, prompt (str): This text will be shown to the user,
@ -940,7 +940,7 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs):
accept input. accept input.
session (Session, optional): This allows to specify the session (Session, optional): This allows to specify the
session to send the prompt to. It's usually only session to send the prompt to. It's usually only
needed if `caller` is a Player in multisession modes needed if `caller` is an Account in multisession modes
greater than 2. The session is then updated by the greater than 2. The session is then updated by the
command and is available (for example in callbacks) command and is available (for example in callbacks)
through `caller.ndb.getinput._session`. through `caller.ndb.getinput._session`.
@ -966,7 +966,7 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs):
`caller.ndb._getinput` is stored; this will be removed `caller.ndb._getinput` is stored; this will be removed
when the prompt finishes. when the prompt finishes.
If you need the specific Session of the caller (which If you need the specific Session of the caller (which
may not be easy to get if caller is a player in higher may not be easy to get if caller is an account in higher
multisession modes), then it is available in the multisession modes), then it is available in the
callback through `caller.ndb._getinput._session`. callback through `caller.ndb._getinput._session`.

View file

@ -62,8 +62,8 @@ class CmdMore(Command):
Implement the command Implement the command
""" """
more = self.caller.ndb._more more = self.caller.ndb._more
if not more and hasattr(self.caller, "player"): if not more and hasattr(self.caller, "account"):
more = self.caller.player.ndb._more more = self.caller.account.ndb._more
if not more: if not more:
self.caller.msg("Error in loading the pager. Contact an admin.") self.caller.msg("Error in loading the pager. Contact an admin.")
return return
@ -94,8 +94,8 @@ class CmdMoreLook(Command):
Implement the command Implement the command
""" """
more = self.caller.ndb._more more = self.caller.ndb._more
if not more and hasattr(self.caller, "player"): if not more and hasattr(self.caller, "account"):
more = self.caller.player.ndb._more more = self.caller.account.ndb._more
if not more: if not more:
self.caller.msg("Error in loading the pager. Contact an admin.") self.caller.msg("Error in loading the pager. Contact an admin.")
return return
@ -124,7 +124,7 @@ class EvMore(object):
Initialization of the text handler. Initialization of the text handler.
Args: Args:
caller (Object or Player): Entity reading the text. caller (Object or Account): Entity reading the text.
text (str): The text to put under paging. text (str): The text to put under paging.
always_page (bool, optional): If `False`, the always_page (bool, optional): If `False`, the
pager will only kick in if `text` is too big pager will only kick in if `text` is too big
@ -268,7 +268,7 @@ def msg(caller, text="", always_page=False, session=None, justify_kwargs=None, *
More-supported version of msg, mimicking the normal msg method. More-supported version of msg, mimicking the normal msg method.
Args: Args:
caller (Object or Player): Entity reading the text. caller (Object or Account): Entity reading the text.
text (str): The text to put under paging. text (str): The text to put under paging.
always_page (bool, optional): If `False`, the always_page (bool, optional): If `False`, the
pager will only kick in if `text` is too big pager will only kick in if `text` is too big

View file

@ -16,11 +16,11 @@ the database model and call its 'objects' property.
Also remember that all commands in this file return lists (also if Also remember that all commands in this file return lists (also if
there is only one match) unless noted otherwise. there is only one match) unless noted otherwise.
Example: To reach the search method 'get_object_with_player' Example: To reach the search method 'get_object_with_account'
in evennia/objects/managers.py: in evennia/objects/managers.py:
> from evennia.objects.models import ObjectDB > from evennia.objects.models import ObjectDB
> match = Object.objects.get_object_with_player(...) > match = Object.objects.get_object_with_account(...)
""" """
@ -30,15 +30,15 @@ Example: To reach the search method 'get_object_with_player'
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
# limit symbol import from API # limit symbol import from API
__all__ = ("search_object", "search_player", "search_script", __all__ = ("search_object", "search_account", "search_script",
"search_message", "search_channel", "search_help_entry", "search_message", "search_channel", "search_help_entry",
"search_object_tag", "search_script_tag", "search_player_tag", "search_object_tag", "search_script_tag", "search_account_tag",
"search_channel_tag") "search_channel_tag")
# import objects this way to avoid circular import problems # import objects this way to avoid circular import problems
ObjectDB = ContentType.objects.get(app_label="objects", model="objectdb").model_class() ObjectDB = ContentType.objects.get(app_label="objects", model="objectdb").model_class()
PlayerDB = ContentType.objects.get(app_label="players", model="playerdb").model_class() AccountDB = ContentType.objects.get(app_label="accounts", model="accountdb").model_class()
ScriptDB = ContentType.objects.get(app_label="scripts", model="scriptdb").model_class() ScriptDB = ContentType.objects.get(app_label="scripts", model="scriptdb").model_class()
Msg = ContentType.objects.get(app_label="comms", model="msg").model_class() Msg = ContentType.objects.get(app_label="comms", model="msg").model_class()
Channel = ContentType.objects.get(app_label="comms", model="channeldb").model_class() Channel = ContentType.objects.get(app_label="comms", model="channeldb").model_class()
@ -99,20 +99,20 @@ object_search = search_object
objects = search_objects objects = search_objects
# #
# Search for players # Search for accounts
# #
# player_search(self, ostring) # account_search(self, ostring)
# Searches for a particular player by name or # Searches for a particular account by name or
# database id. # database id.
# #
# ostring = a string or database id. # ostring = a string or database id.
# #
search_player = PlayerDB.objects.player_search search_account = AccountDB.objects.account_search
search_players = search_player search_accounts = search_account
player_search = search_player account_search = search_account
players = search_players accounts = search_accounts
# #
# Searching for scripts # Searching for scripts
@ -140,8 +140,8 @@ scripts = search_scripts
# Search the message database for particular messages. At least one # Search the message database for particular messages. At least one
# of the arguments must be given to do a search. # of the arguments must be given to do a search.
# #
# sender - get messages sent by a particular player # sender - get messages sent by a particular account
# receiver - get messages received by a certain player # receiver - get messages received by a certain account
# channel - get messages sent to a particular channel # channel - get messages sent to a particular channel
# freetext - Search for a text string in a message. # freetext - Search for a text string in a message.
# NOTE: This can potentially be slow, so make sure to supply # NOTE: This can potentially be slow, so make sure to supply
@ -190,7 +190,7 @@ help_entries = search_help
# Locate Attributes # Locate Attributes
# search_object_attribute(key, category, value, strvalue) (also search_attribute works) # search_object_attribute(key, category, value, strvalue) (also search_attribute works)
# search_player_attribute(key, category, value, strvalue) (also search_attribute works) # search_account_attribute(key, category, value, strvalue) (also search_attribute works)
# search_script_attribute(key, category, value, strvalue) (also search_attribute works) # search_script_attribute(key, category, value, strvalue) (also search_attribute works)
# search_channel_attribute(key, category, value, strvalue) (also search_attribute works) # search_channel_attribute(key, category, value, strvalue) (also search_attribute works)
@ -201,8 +201,8 @@ def search_object_attribute(key=None, category=None, value=None, strvalue=None):
return ObjectDB.objects.get_by_attribute(key=key, category=category, value=value, strvalue=strvalue) return ObjectDB.objects.get_by_attribute(key=key, category=category, value=value, strvalue=strvalue)
def search_player_attribute(key=None, category=None, value=None, strvalue=None): def search_account_attribute(key=None, category=None, value=None, strvalue=None):
return PlayerDB.objects.get_by_attribute(key=key, category=category, value=value, strvalue=strvalue) return AccountDB.objects.get_by_attribute(key=key, category=category, value=value, strvalue=strvalue)
def search_script_attribute(key=None, category=None, value=None, strvalue=None): def search_script_attribute(key=None, category=None, value=None, strvalue=None):
@ -218,7 +218,7 @@ search_attribute_object = ObjectDB.objects.get_attribute
# Locate Tags # Locate Tags
# search_object_tag(key=None, category=None) (also search_tag works) # search_object_tag(key=None, category=None) (also search_tag works)
# search_player_tag(key=None, category=None) # search_account_tag(key=None, category=None)
# search_script_tag(key=None, category=None) # search_script_tag(key=None, category=None)
# search_channel_tag(key=None, category=None) # search_channel_tag(key=None, category=None)
@ -246,9 +246,9 @@ def search_object_by_tag(key=None, category=None):
search_tag = search_object_by_tag # this is the most common case search_tag = search_object_by_tag # this is the most common case
def search_player_tag(key=None, category=None): def search_account_tag(key=None, category=None):
""" """
Find player based on tag or category. Find account based on tag or category.
Args: Args:
key (str, optional): The tag key to search for. key (str, optional): The tag key to search for.
@ -257,12 +257,12 @@ def search_player_tag(key=None, category=None):
tags will be searched. tags will be searched.
Returns: Returns:
matches (list): List of Players with tags matching matches (list): List of Accounts with tags matching
the search criteria, or an empty list if no the search criteria, or an empty list if no
matches were found. matches were found.
""" """
return PlayerDB.objects.get_by_tag(key=key, category=category) return AccountDB.objects.get_by_tag(key=key, category=category)
def search_script_tag(key=None, category=None): def search_script_tag(key=None, category=None):

View file

@ -2,7 +2,7 @@ from django.conf import settings
from django.test import TestCase from django.test import TestCase
from mock import Mock from mock import Mock
from evennia.objects.objects import DefaultObject, DefaultCharacter, DefaultRoom, DefaultExit from evennia.objects.objects import DefaultObject, DefaultCharacter, DefaultRoom, DefaultExit
from evennia.players.players import DefaultPlayer from evennia.accounts.accounts import DefaultAccount
from evennia.scripts.scripts import DefaultScript from evennia.scripts.scripts import DefaultScript
from evennia.server.serversession import ServerSession from evennia.server.serversession import ServerSession
from evennia.server.sessionhandler import SESSIONS from evennia.server.sessionhandler import SESSIONS
@ -18,7 +18,7 @@ class EvenniaTest(TestCase):
""" """
Base test for Evennia, sets up a basic environment. Base test for Evennia, sets up a basic environment.
""" """
player_typeclass = DefaultPlayer account_typeclass = DefaultAccount
object_typeclass = DefaultObject object_typeclass = DefaultObject
character_typeclass = DefaultCharacter character_typeclass = DefaultCharacter
exit_typeclass = DefaultExit exit_typeclass = DefaultExit
@ -29,8 +29,8 @@ class EvenniaTest(TestCase):
""" """
Sets up testing environment Sets up testing environment
""" """
self.player = create.create_player("TestPlayer", email="test@test.com", password="testpassword", typeclass=self.player_typeclass) self.account = create.create_account("TestAccount", email="test@test.com", password="testpassword", typeclass=self.account_typeclass)
self.player2 = create.create_player("TestPlayer2", email="test@test.com", password="testpassword", typeclass=self.player_typeclass) self.account2 = create.create_account("TestAccount2", email="test@test.com", password="testpassword", typeclass=self.account_typeclass)
self.room1 = create.create_object(self.room_typeclass, key="Room", nohome=True) self.room1 = create.create_object(self.room_typeclass, key="Room", nohome=True)
self.room1.db.desc = "room_desc" self.room1.db.desc = "room_desc"
settings.DEFAULT_HOME = "#%i" % self.room1.id # we must have a default home settings.DEFAULT_HOME = "#%i" % self.room1.id # we must have a default home
@ -41,12 +41,12 @@ class EvenniaTest(TestCase):
self.char1 = create.create_object(self.character_typeclass, key="Char", location=self.room1, home=self.room1) self.char1 = create.create_object(self.character_typeclass, key="Char", location=self.room1, home=self.room1)
self.char1.permissions.add("Developer") self.char1.permissions.add("Developer")
self.char2 = create.create_object(self.character_typeclass, key="Char2", location=self.room1, home=self.room1) self.char2 = create.create_object(self.character_typeclass, key="Char2", location=self.room1, home=self.room1)
self.char1.player = self.player self.char1.account = self.account
self.player.db._last_puppet = self.char1 self.account.db._last_puppet = self.char1
self.char2.player = self.player2 self.char2.account = self.account2
self.player2.db._last_puppet = self.char2 self.account2.db._last_puppet = self.char2
self.script = create.create_script(self.script_typeclass, key="Script") self.script = create.create_script(self.script_typeclass, key="Script")
self.player.permissions.add("Developer") self.account.permissions.add("Developer")
# set up a fake session # set up a fake session
@ -55,12 +55,12 @@ class EvenniaTest(TestCase):
dummysession.sessid = 1 dummysession.sessid = 1
SESSIONS.portal_connect(dummysession.get_sync_data()) # note that this creates a new Session! SESSIONS.portal_connect(dummysession.get_sync_data()) # note that this creates a new Session!
session = SESSIONS.session_from_sessid(1) # the real session session = SESSIONS.session_from_sessid(1) # the real session
SESSIONS.login(session, self.player, testmode=True) SESSIONS.login(session, self.account, testmode=True)
self.session = session self.session = session
def tearDown(self): def tearDown(self):
flush_cache() flush_cache()
del SESSIONS[self.session.sessid] del SESSIONS[self.session.sessid]
self.player.delete() self.account.delete()
self.player2.delete() self.account2.delete()
super(EvenniaTest, self).tearDown() super(EvenniaTest, self).tearDown()

View file

@ -386,7 +386,7 @@ class TestEvForm(TestCase):
u'| |\n' u'| |\n'
u'| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b' u'| Name: \x1b[0m\x1b[1m\x1b[32mTom\x1b[1m\x1b[32m \x1b'
u'[1m\x1b[32mthe\x1b[1m\x1b[32m \x1b[0m \x1b[0m ' u'[1m\x1b[32mthe\x1b[1m\x1b[32m \x1b[0m \x1b[0m '
u'Player: \x1b[0m\x1b[1m\x1b[33mGriatch ' u'Account: \x1b[0m\x1b[1m\x1b[33mGriatch '
u'\x1b[0m\x1b[0m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[0m\x1b[0m ' u'\x1b[0m\x1b[0m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[1m\x1b[32m\x1b[0m\x1b[0m '
u'|\n' u'|\n'
u'| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n' u'| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n'

View file

@ -1384,12 +1384,12 @@ def class_from_module(path, defaultpaths=None):
object_from_module = class_from_module object_from_module = class_from_module
def init_new_player(player): def init_new_account(account):
""" """
Deprecated. Deprecated.
""" """
from evennia.utils import logger from evennia.utils import logger
logger.log_dep("evennia.utils.utils.init_new_player is DEPRECATED and should not be used.") logger.log_dep("evennia.utils.utils.init_new_account is DEPRECATED and should not be used.")
def string_similarity(string1, string2): def string_similarity(string1, string2):

View file

@ -15,12 +15,12 @@ class CaseInsensitiveModelBackend(ModelBackend):
Args: Args:
username (str, optional): Name of user to authenticate. username (str, optional): Name of user to authenticate.
password (str, optional): Password of user password (str, optional): Password of user
autologin (Player, optional): If given, assume this is autologin (Account, optional): If given, assume this is
an already authenticated player and bypass authentication. an already authenticated account and bypass authentication.
""" """
if autologin: if autologin:
# Note: Setting .backend on player is critical in order to # Note: Setting .backend on account is critical in order to
# be allowed to call django.auth.login(player) later. This # be allowed to call django.auth.login(account) later. This
# is necessary for the auto-login feature of the webclient, # is necessary for the auto-login feature of the webclient,
# but it's important to make sure Django doesn't change this # but it's important to make sure Django doesn't change this
# requirement or the name of the property down the line. /Griatch # requirement or the name of the property down the line. /Griatch
@ -29,12 +29,12 @@ class CaseInsensitiveModelBackend(ModelBackend):
else: else:
# In this case .backend will be assigned automatically # In this case .backend will be assigned automatically
# somewhere along the way. # somewhere along the way.
Player = get_user_model() Account = get_user_model()
try: try:
player = Player.objects.get(username__iexact=username) account = Account.objects.get(username__iexact=username)
if player.check_password(password): if account.check_password(password):
return player return account
else: else:
return None return None
except Player.DoesNotExist: except Account.DoesNotExist:
return None return None

View file

@ -25,7 +25,7 @@ except AttributeError:
# Setup lists of the most relevant apps so # Setup lists of the most relevant apps so
# the adminsite becomes more readable. # the adminsite becomes more readable.
PLAYER_RELATED = ['Players'] ACCOUNT_RELATED = ['Accounts']
GAME_ENTITIES = ['Objects', 'Scripts', 'Comms', 'Help'] GAME_ENTITIES = ['Objects', 'Scripts', 'Comms', 'Help']
GAME_SETUP = ['Permissions', 'Config'] GAME_SETUP = ['Permissions', 'Config']
CONNECTIONS = ['Irc'] CONNECTIONS = ['Irc']
@ -46,7 +46,7 @@ def general_context(request):
return { return {
'game_name': GAME_NAME, 'game_name': GAME_NAME,
'game_slogan': GAME_SLOGAN, 'game_slogan': GAME_SLOGAN,
'evennia_userapps': PLAYER_RELATED, 'evennia_userapps': ACCOUNT_RELATED,
'evennia_entityapps': GAME_ENTITIES, 'evennia_entityapps': GAME_ENTITIES,
'evennia_setupapps': GAME_SETUP, 'evennia_setupapps': GAME_SETUP,
'evennia_connectapps': CONNECTIONS, 'evennia_connectapps': CONNECTIONS,

View file

@ -8,7 +8,7 @@ from __future__ import print_function
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth import login, authenticate from django.contrib.auth import login, authenticate
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.utils import logger from evennia.utils import logger
@ -18,24 +18,24 @@ def _shared_login(request):
""" """
csession = request.session csession = request.session
player = request.user account = request.user
sesslogin = csession.get("logged_in", None) sesslogin = csession.get("logged_in", None)
# check if user has authenticated to website # check if user has authenticated to website
if csession.session_key is None: if csession.session_key is None:
# this is necessary to build the sessid key # this is necessary to build the sessid key
csession.save() csession.save()
elif player.is_authenticated(): elif account.is_authenticated():
if not sesslogin: if not sesslogin:
# User has already authenticated to website # User has already authenticated to website
csession["logged_in"] = player.id csession["logged_in"] = account.id
elif sesslogin: elif sesslogin:
# The webclient has previously registered a login to this browser_session # The webclient has previously registered a login to this browser_session
player = PlayerDB.objects.get(id=sesslogin) account = AccountDB.objects.get(id=sesslogin)
try: try:
# calls our custom authenticate in web/utils/backends.py # calls our custom authenticate in web/utils/backends.py
player = authenticate(autologin=player) account = authenticate(autologin=account)
login(request, player) login(request, account)
except AttributeError: except AttributeError:
logger.log_trace() logger.log_trace()

View file

@ -13,7 +13,7 @@ from django.shortcuts import render
from evennia import SESSION_HANDLER from evennia import SESSION_HANDLER
from evennia.objects.models import ObjectDB from evennia.objects.models import ObjectDB
from evennia.players.models import PlayerDB from evennia.accounts.models import AccountDB
from evennia.utils import logger from evennia.utils import logger
from django.contrib.auth import login from django.contrib.auth import login
@ -27,22 +27,22 @@ def _shared_login(request):
""" """
csession = request.session csession = request.session
player = request.user account = request.user
sesslogin = csession.get("logged_in", None) sesslogin = csession.get("logged_in", None)
if csession.session_key is None: if csession.session_key is None:
# this is necessary to build the sessid key # this is necessary to build the sessid key
csession.save() csession.save()
elif player.is_authenticated(): elif account.is_authenticated():
if not sesslogin: if not sesslogin:
csession["logged_in"] = player.id csession["logged_in"] = account.id
elif sesslogin: elif sesslogin:
# The webclient has previously registered a login to this csession # The webclient has previously registered a login to this csession
player = PlayerDB.objects.get(id=sesslogin) account = AccountDB.objects.get(id=sesslogin)
try: try:
# calls our custom authenticate, in web/utils/backend.py # calls our custom authenticate, in web/utils/backend.py
authenticate(autologin=player) authenticate(autologin=account)
login(request, player) login(request, account)
except AttributeError: except AttributeError:
logger.log_trace() logger.log_trace()
@ -50,15 +50,15 @@ def _shared_login(request):
def _gamestats(): def _gamestats():
# Some misc. configurable stuff. # Some misc. configurable stuff.
# TODO: Move this to either SQL or settings.py based configuration. # TODO: Move this to either SQL or settings.py based configuration.
fpage_player_limit = 4 fpage_account_limit = 4
# A QuerySet of the most recently connected players. # A QuerySet of the most recently connected accounts.
recent_users = PlayerDB.objects.get_recently_connected_players()[:fpage_player_limit] recent_users = AccountDB.objects.get_recently_connected_accounts()[:fpage_account_limit]
nplyrs_conn_recent = len(recent_users) or "none" nplyrs_conn_recent = len(recent_users) or "none"
nplyrs = PlayerDB.objects.num_total_players() or "none" nplyrs = AccountDB.objects.num_total_accounts() or "none"
nplyrs_reg_recent = len(PlayerDB.objects.get_recently_created_players()) or "none" nplyrs_reg_recent = len(AccountDB.objects.get_recently_created_accounts()) or "none"
nsess = SESSION_HANDLER.player_count() nsess = SESSION_HANDLER.account_count()
# nsess = len(PlayerDB.objects.get_connected_players()) or "no one" # nsess = len(AccountDB.objects.get_connected_accounts()) or "no one"
nobjs = ObjectDB.objects.all().count() nobjs = ObjectDB.objects.all().count()
nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(db_typeclass_path=_BASE_CHAR_TYPECLASS).count() nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(db_typeclass_path=_BASE_CHAR_TYPECLASS).count()
@ -68,11 +68,11 @@ def _gamestats():
pagevars = { pagevars = {
"page_title": "Front Page", "page_title": "Front Page",
"players_connected_recent": recent_users, "accounts_connected_recent": recent_users,
"num_players_connected": nsess or "no one", "num_accounts_connected": nsess or "no one",
"num_players_registered": nplyrs or "no", "num_accounts_registered": nplyrs or "no",
"num_players_connected_recent": nplyrs_conn_recent or "no", "num_accounts_connected_recent": nplyrs_conn_recent or "no",
"num_players_registered_recent": nplyrs_reg_recent or "no one", "num_accounts_registered_recent": nplyrs_reg_recent or "no one",
"num_rooms": nrooms or "none", "num_rooms": nrooms or "none",
"num_exits": nexits or "no", "num_exits": nexits or "no",
"num_objects": nobjs or "none", "num_objects": nobjs or "none",
@ -116,7 +116,7 @@ def evennia_admin(request):
""" """
return render( return render(
request, 'evennia_admin.html', { request, 'evennia_admin.html', {
'playerdb': PlayerDB}) 'accountdb': AccountDB})
def admin_wrapper(request): def admin_wrapper(request):