mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 23:47:16 +02:00
Rename all instances of Player->Account.
This commit is contained in:
parent
a14e11640b
commit
5590ee2258
94 changed files with 1316 additions and 2327 deletions
|
|
@ -25,7 +25,7 @@ from builtins import object
|
|||
|
||||
# Typeclasses
|
||||
|
||||
DefaultPlayer = None
|
||||
DefaultAccount = None
|
||||
DefaultGuest = None
|
||||
DefaultObject = None
|
||||
DefaultCharacter = None
|
||||
|
|
@ -36,7 +36,7 @@ DefaultScript = None
|
|||
|
||||
# Database models
|
||||
ObjectDB = None
|
||||
PlayerDB = None
|
||||
AccountDB = None
|
||||
ScriptDB = None
|
||||
ChannelDB = None
|
||||
Msg = None
|
||||
|
|
@ -51,7 +51,7 @@ InterruptCommand = None
|
|||
# search functions
|
||||
search_object = None
|
||||
search_script = None
|
||||
search_player = None
|
||||
search_account = None
|
||||
search_channel = None
|
||||
search_message = None
|
||||
search_help = None
|
||||
|
|
@ -60,7 +60,7 @@ search_tag = None
|
|||
# create functions
|
||||
create_object = None
|
||||
create_script = None
|
||||
create_player = None
|
||||
create_account = None
|
||||
create_channel = None
|
||||
create_message = None
|
||||
create_help_entry = None
|
||||
|
|
@ -117,17 +117,17 @@ def _init():
|
|||
Evennia has fully initialized all its models. It sets up the API
|
||||
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 ObjectDB, PlayerDB, ScriptDB, ChannelDB, Msg
|
||||
global ObjectDB, AccountDB, ScriptDB, ChannelDB, Msg
|
||||
global Command, CmdSet, default_cmds, syscmdkeys, InterruptCommand
|
||||
global search_object, search_script, search_player, search_channel, search_help, search_tag
|
||||
global create_object, create_script, create_player, create_channel, create_message, create_help_entry
|
||||
global search_object, search_script, search_account, search_channel, search_help, search_tag
|
||||
global create_object, create_script, create_account, create_channel, create_message, create_help_entry
|
||||
global settings,lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
||||
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER
|
||||
|
||||
from .players.players import DefaultPlayer
|
||||
from .players.players import DefaultGuest
|
||||
from .accounts.accounts import DefaultAccount
|
||||
from .accounts.accounts import DefaultGuest
|
||||
from .objects.objects import DefaultObject
|
||||
from .objects.objects import DefaultCharacter
|
||||
from .objects.objects import DefaultRoom
|
||||
|
|
@ -137,7 +137,7 @@ def _init():
|
|||
|
||||
# Database models
|
||||
from .objects.models import ObjectDB
|
||||
from .players.models import PlayerDB
|
||||
from .accounts.models import AccountDB
|
||||
from .scripts.models import ScriptDB
|
||||
from .comms.models import ChannelDB
|
||||
from .comms.models import Msg
|
||||
|
|
@ -149,7 +149,7 @@ def _init():
|
|||
# search functions
|
||||
from .utils.search import search_object
|
||||
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_channel
|
||||
from .utils.search import search_help
|
||||
|
|
@ -158,7 +158,7 @@ def _init():
|
|||
# create functions
|
||||
from .utils.create import create_object
|
||||
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_message
|
||||
from .utils.create import create_help_entry
|
||||
|
|
@ -202,7 +202,7 @@ def _init():
|
|||
Links to instantiated database managers.
|
||||
|
||||
helpentry - HelpEntry.objects
|
||||
players - PlayerDB.objects
|
||||
accounts - AccountDB.objects
|
||||
scripts - ScriptDB.objects
|
||||
msgs - Msg.objects
|
||||
channels - Channel.objects
|
||||
|
|
@ -213,7 +213,7 @@ def _init():
|
|||
|
||||
"""
|
||||
from .help.models import HelpEntry
|
||||
from .players.models import PlayerDB
|
||||
from .accounts.models import AccountDB
|
||||
from .scripts.models import ScriptDB
|
||||
from .comms.models import Msg, ChannelDB
|
||||
from .objects.models import ObjectDB
|
||||
|
|
@ -223,7 +223,7 @@ def _init():
|
|||
|
||||
# create container's properties
|
||||
helpentries = HelpEntry.objects
|
||||
players = PlayerDB.objects
|
||||
accounts = AccountDB.objects
|
||||
scripts = ScriptDB.objects
|
||||
msgs = Msg.objects
|
||||
channels = ChannelDB.objects
|
||||
|
|
@ -232,7 +232,7 @@ def _init():
|
|||
attributes = Attribute.objects
|
||||
tags = Tag.objects
|
||||
# remove these so they are not visible as properties
|
||||
del HelpEntry, PlayerDB, ScriptDB, Msg, ChannelDB
|
||||
del HelpEntry, AccountDB, ScriptDB, Msg, ChannelDB
|
||||
#del ExternalChannelConnection
|
||||
del ObjectDB, ServerConfig, Tag, Attribute
|
||||
|
||||
|
|
@ -250,10 +250,10 @@ def _init():
|
|||
"""
|
||||
|
||||
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_session import SessionCmdSet
|
||||
from .commands.default.muxcommand import MuxCommand, MuxPlayerCommand
|
||||
from .commands.default.muxcommand import MuxCommand, MuxAccountCommand
|
||||
|
||||
def __init__(self):
|
||||
"populate the object with commands"
|
||||
|
|
@ -265,14 +265,14 @@ def _init():
|
|||
|
||||
from .commands.default import (admin, batchprocess,
|
||||
building, comms, general,
|
||||
player, help, system, unloggedin)
|
||||
account, help, system, unloggedin)
|
||||
add_cmds(admin)
|
||||
add_cmds(building)
|
||||
add_cmds(batchprocess)
|
||||
add_cmds(building)
|
||||
add_cmds(comms)
|
||||
add_cmds(general)
|
||||
add_cmds(player)
|
||||
add_cmds(account)
|
||||
add_cmds(help)
|
||||
add_cmds(system)
|
||||
add_cmds(unloggedin)
|
||||
|
|
@ -293,7 +293,7 @@ def _init():
|
|||
CMD_MULTIMATCH - multiple command matches were found
|
||||
CMD_CHANNEL - the command name is a channel name
|
||||
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.
|
||||
|
||||
To access in code, do 'from evennia import syscmdkeys' then
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ class AccountForm(forms.ModelForm):
|
|||
|
||||
db_typeclass_path = forms.CharField(
|
||||
label="Typeclass",
|
||||
initial=settings.BASE_PLAYER_TYPECLASS,
|
||||
initial=settings.BASE_ACCOUNT_TYPECLASS,
|
||||
widget=forms.TextInput(
|
||||
attrs={'size': '78'}),
|
||||
help_text="Required. Defines what 'type' of entity this is. This "
|
||||
|
|
@ -117,7 +117,7 @@ class AccountForm(forms.ModelForm):
|
|||
|
||||
db_permissions = forms.CharField(
|
||||
label="Permissions",
|
||||
initial=settings.PERMISSION_PLAYER_DEFAULT,
|
||||
initial=settings.PERMISSION_ACCOUNT_DEFAULT,
|
||||
required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={'size': '78'}),
|
||||
|
|
@ -137,7 +137,7 @@ class AccountForm(forms.ModelForm):
|
|||
"<i>type:lockfunction(args);type2:lockfunction2(args);...")
|
||||
db_cmdset_storage = forms.CharField(
|
||||
label="cmdset",
|
||||
initial=settings.CMDSET_PLAYER,
|
||||
initial=settings.CMDSET_ACCOUNT,
|
||||
widget=forms.TextInput(attrs={'size': '78'}),
|
||||
required=False,
|
||||
help_text="python path to account cmdset class (set in "
|
||||
|
|
@ -241,7 +241,7 @@ class AccountDBAdmin(BaseUserAdmin):
|
|||
obj.save()
|
||||
if not change:
|
||||
#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.at_account_creation()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
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.
|
||||
|
||||
commands.default contains all the default "mux-like" commands of
|
||||
|
|
|
|||
|
|
@ -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
|
||||
cmdsets. This includes cmdsets on exits.
|
||||
- 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.
|
||||
4. If the input string is empty -> check for CMD_NOINPUT command in
|
||||
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))
|
||||
|
||||
# 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 = (
|
||||
"""
|
||||
|
|
@ -210,7 +210,7 @@ def _process_input(caller, prompt, result, cmd, generator):
|
|||
part of yielding from a Command's `func`.
|
||||
|
||||
Args:
|
||||
caller (Character, Player or Session): the caller.
|
||||
caller (Character, Account or Session): the caller.
|
||||
prompt (basestring): The sent prompt.
|
||||
result (basestring): The unprocessed answer.
|
||||
cmd (Command): The command itself.
|
||||
|
|
@ -248,20 +248,20 @@ class ErrorReported(Exception):
|
|||
# Helper function
|
||||
|
||||
@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.
|
||||
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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:
|
||||
The cdmsets are merged in order or generality, so that the
|
||||
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:
|
||||
@inlineCallbacks
|
||||
def _get_channel_cmdset(player_or_obj):
|
||||
def _get_channel_cmdset(account_or_obj):
|
||||
"""
|
||||
Helper-method; Get channel-cmdsets
|
||||
"""
|
||||
# Create cmdset for all player's available channels
|
||||
# Create cmdset for all account's available channels
|
||||
try:
|
||||
channel_cmdset = yield CHANNELHANDLER.get_cmdset(player_or_obj)
|
||||
channel_cmdset = yield CHANNELHANDLER.get_cmdset(account_or_obj)
|
||||
returnValue([channel_cmdset])
|
||||
except Exception:
|
||||
_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)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
# the call-type lock is checked here, it makes sure a player
|
||||
# is not seeing e.g. the commands on a fellow player (which is why
|
||||
# the call-type lock is checked here, it makes sure an account
|
||||
# is not seeing e.g. the commands on a fellow account (which is why
|
||||
# the no_superuser_bypass must be True)
|
||||
local_obj_cmdsets = \
|
||||
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
|
||||
report_to = session
|
||||
current, cmdsets = yield _get_cmdsets(session)
|
||||
if player: # this automatically implies logged-in
|
||||
pcurrent, player_cmdsets = yield _get_cmdsets(player)
|
||||
cmdsets += player_cmdsets
|
||||
if account: # this automatically implies logged-in
|
||||
pcurrent, account_cmdsets = yield _get_cmdsets(account)
|
||||
cmdsets += account_cmdsets
|
||||
current = current + pcurrent
|
||||
if 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)
|
||||
cmdsets += channel_cmdsets
|
||||
if not current.no_channels:
|
||||
channel_cmdsets = yield _get_channel_cmdset(player)
|
||||
channel_cmdsets = yield _get_channel_cmdset(account)
|
||||
cmdsets += channel_cmdsets
|
||||
|
||||
elif callertype == "player":
|
||||
# we are calling the command from the player level
|
||||
report_to = player
|
||||
current, cmdsets = yield _get_cmdsets(player)
|
||||
elif callertype == "account":
|
||||
# we are calling the command from the account level
|
||||
report_to = account
|
||||
current, cmdsets = yield _get_cmdsets(account)
|
||||
if obj:
|
||||
ocurrent, obj_cmdsets = yield _get_cmdsets(obj)
|
||||
current = current + ocurrent
|
||||
|
|
@ -395,7 +395,7 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype, raw_string):
|
|||
# also objs may have channels
|
||||
cmdsets += yield _get_channel_cmdset(obj)
|
||||
if not current.no_channels:
|
||||
cmdsets += yield _get_channel_cmdset(player)
|
||||
cmdsets += yield _get_channel_cmdset(account)
|
||||
|
||||
elif callertype == "object":
|
||||
# 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.
|
||||
|
||||
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
|
||||
depends on the game state.
|
||||
raw_string (str): The command string as given on the command line.
|
||||
_testing (bool, optional): Used for debug purposes and decides if we
|
||||
should actually execute the command or not. If True, the
|
||||
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
|
||||
Session is the caller, it will merge its own cmdset into
|
||||
cmdsets from both Player and eventual puppeted Object (and
|
||||
cmdsets in its room etc). A Player will only include its own
|
||||
cmdsets from both Account and eventual puppeted Object (and
|
||||
cmdsets in its room etc). An Account will only include its own
|
||||
cmdset and the Objects and so on. Merge order is the same
|
||||
order, so that Object cmdsets are merged in last, giving them
|
||||
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.
|
||||
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)
|
||||
|
|
@ -513,7 +513,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
"""
|
||||
|
||||
@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
|
||||
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).
|
||||
cmdset (CmdSet): Command sert the command belongs to (if any)..
|
||||
session (Session): Session of caller (if any).
|
||||
player (Player): Player of caller (if any).
|
||||
account (Account): Account of caller (if any).
|
||||
|
||||
Returns:
|
||||
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.cmdset = cmdset
|
||||
cmd.session = session
|
||||
cmd.player = player
|
||||
cmd.account = account
|
||||
cmd.raw_string = unformatted_raw_string
|
||||
#cmd.obj # set via on-object cmdset handler for each command,
|
||||
# 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)
|
||||
|
||||
session, player, obj = session, None, None
|
||||
session, account, obj = session, None, None
|
||||
if callertype == "session":
|
||||
session = called_by
|
||||
player = session.player
|
||||
account = session.account
|
||||
obj = session.puppet
|
||||
elif callertype == "player":
|
||||
player = called_by
|
||||
elif callertype == "account":
|
||||
account = called_by
|
||||
if session:
|
||||
obj = yield session.puppet
|
||||
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)
|
||||
# the caller will be the one to receive messages and excert its permissions.
|
||||
# we assign the caller with preference 'bottom up'
|
||||
caller = obj or player or session
|
||||
# The error_to is the default recipient for errors. Tries to make sure a player
|
||||
caller = obj or account or session
|
||||
# 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.
|
||||
error_to = obj or session or player
|
||||
error_to = obj or session or account
|
||||
|
||||
try: # catch bugs in cmdhandler itself
|
||||
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)
|
||||
cmdset = None
|
||||
session = session
|
||||
player = player
|
||||
account = account
|
||||
|
||||
else:
|
||||
# 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)
|
||||
if not cmdset:
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
|
||||
except ErrorReported as exc:
|
||||
|
|
@ -738,7 +738,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
|
||||
if syscmd:
|
||||
ret = yield _run_command(syscmd, syscmd.key, sysarg,
|
||||
unformatted_raw_string, cmdset, session, player)
|
||||
unformatted_raw_string, cmdset, session, account)
|
||||
returnValue(ret)
|
||||
elif sysarg:
|
||||
# return system arg
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
Args:
|
||||
raw_string (str): The unparsed text entered by the caller.
|
||||
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
|
||||
list of same-named command matches. If this is given, it suggests
|
||||
this is not the first time this function was called: normally
|
||||
|
|
|
|||
|
|
@ -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
|
||||
non-destructive way. This makes them very powerful for implementing
|
||||
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
|
||||
Set theory.
|
||||
|
|
@ -110,9 +110,9 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
merger (i.e. A above) automatically taking
|
||||
precedence. But if allow_duplicates is true, the
|
||||
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,
|
||||
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
|
||||
more than one 'ball' in the room has the same 'kick'
|
||||
command defined on it, so it may offer a chance to
|
||||
|
|
@ -134,7 +134,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
commands
|
||||
no_channels - ignore the name of channels when matching against
|
||||
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)
|
||||
|
||||
|
||||
|
|
@ -167,9 +167,9 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
Creates a new CmdSet instance.
|
||||
|
||||
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
|
||||
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.
|
||||
key (str, optional): The idenfier for this cmdset. This
|
||||
helps if wanting to selectively remov cmdsets.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
doublets). This temporary but up-to-date merger of CmdSet is jointly
|
||||
called the Current Cmset. It is this Current CmdSet that the
|
||||
commandhandler looks through whenever a player enters a command (it
|
||||
also adds CmdSets from objects in the room in real-time). All player
|
||||
commandhandler looks through whenever an account enters a command (it
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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,
|
||||
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
|
||||
|
|
@ -37,7 +37,7 @@ and have this completely replace the default cmdset.
|
|||
|
||||
Another example: Say you want your players to be able to go
|
||||
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
|
||||
commands for throwing your line, reeling in, etc? Most players won't
|
||||
(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
|
||||
CommandSet called 'Fishing'. Whenever the player gives the command
|
||||
'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
|
||||
custom 'fishing variant' of throw. What has happened is that the
|
||||
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:
|
||||
path (str): The path to the command set to load.
|
||||
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)
|
||||
emit_to_obj (Object, optional): If given, error is emitted to
|
||||
this object (in addition to logging)
|
||||
|
|
|
|||
|
|
@ -152,14 +152,14 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
is_exit = False
|
||||
# define the command not only by key but by the regex form of its arguments
|
||||
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).
|
||||
msg_all_sessions = settings.COMMAND_DEFAULT_MSG_ALL_SESSIONS
|
||||
|
||||
# auto-set (by Evennia on command instantiation) are:
|
||||
# obj - which object this command is defined on
|
||||
# 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):
|
||||
"""
|
||||
|
|
@ -307,7 +307,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
session=None, **kwargs):
|
||||
"""
|
||||
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.
|
||||
|
||||
Args:
|
||||
|
|
@ -340,7 +340,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
Args:
|
||||
raw_string (str): Execute this string as a command input.
|
||||
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.
|
||||
|
||||
Kwargs:
|
||||
|
|
@ -443,7 +443,7 @@ class Command(with_metaclass(CommandMeta, object)):
|
|||
commands the caller can use.
|
||||
|
||||
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).
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -16,22 +16,22 @@ COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
|||
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
|
||||
|
||||
# limit members for API inclusion
|
||||
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelPlayer",
|
||||
__all__ = ("CmdBoot", "CmdBan", "CmdUnban", "CmdDelAccount",
|
||||
"CmdEmit", "CmdNewPassword", "CmdPerm", "CmdWall")
|
||||
|
||||
|
||||
class CmdBoot(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
kick a player from the server.
|
||||
kick an account from the server.
|
||||
|
||||
Usage
|
||||
@boot[/switches] <player obj> [: reason]
|
||||
@boot[/switches] <account obj> [: reason]
|
||||
|
||||
Switches:
|
||||
quiet - Silently boot without informing player
|
||||
quiet - Silently boot without informing account
|
||||
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.
|
||||
"""
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
args = self.args
|
||||
|
||||
if not args:
|
||||
caller.msg("Usage: @boot[/switches] <player> [:reason]")
|
||||
caller.msg("Usage: @boot[/switches] <account> [:reason]")
|
||||
return
|
||||
|
||||
if ':' in args:
|
||||
|
|
@ -64,10 +64,10 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
boot_list.append(sess)
|
||||
break
|
||||
else:
|
||||
# Boot by player object
|
||||
pobj = search.player_search(args)
|
||||
# Boot by account object
|
||||
pobj = search.account_search(args)
|
||||
if not pobj:
|
||||
caller.msg("Player %s was not found." % args)
|
||||
caller.msg("Account %s was not found." % args)
|
||||
return
|
||||
pobj = pobj[0]
|
||||
if not pobj.access(caller, 'boot'):
|
||||
|
|
@ -75,12 +75,12 @@ class CmdBoot(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
# 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:
|
||||
boot_list.append(match)
|
||||
|
||||
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
|
||||
|
||||
# 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:
|
||||
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.*
|
||||
|
|
@ -118,7 +118,7 @@ def list_bans(banlist):
|
|||
|
||||
class CmdBan(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
ban a player from the server
|
||||
ban an account from the server
|
||||
|
||||
Usage:
|
||||
@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
|
||||
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
|
||||
delete a player with @delplayer. If banned by name, that player
|
||||
It is often preferable to ban an account from the server than to
|
||||
delete an account with @delaccount. If banned by name, that account
|
||||
account can no longer be logged into.
|
||||
|
||||
IP (Internet Protocol) address banning allows blocking all access
|
||||
|
|
@ -206,12 +206,12 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdUnban(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
remove a ban from a player
|
||||
remove a ban from an account
|
||||
|
||||
Usage:
|
||||
@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
|
||||
list of bans. Use the numbers in this list to select which one to
|
||||
unban.
|
||||
|
|
@ -249,23 +249,23 @@ class CmdUnban(COMMAND_DEFAULT_CLASS):
|
|||
(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:
|
||||
@delplayer[/switch] <name> [: reason]
|
||||
@delaccount[/switch] <name> [: reason]
|
||||
|
||||
Switch:
|
||||
delobj - also delete the player's currently
|
||||
delobj - also delete the account's currently
|
||||
assigned in-game object.
|
||||
|
||||
Completely deletes a user from the server database,
|
||||
making their nick and e-mail again available.
|
||||
"""
|
||||
|
||||
key = "@delplayer"
|
||||
locks = "cmd:perm(delplayer) or perm(Developer)"
|
||||
key = "@delaccount"
|
||||
locks = "cmd:perm(delaccount) or perm(Developer)"
|
||||
help_category = "Admin"
|
||||
|
||||
def func(self):
|
||||
|
|
@ -274,49 +274,49 @@ class CmdDelPlayer(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
args = self.args
|
||||
|
||||
if hasattr(caller, 'player'):
|
||||
caller = caller.player
|
||||
if hasattr(caller, 'account'):
|
||||
caller = caller.account
|
||||
|
||||
if not args:
|
||||
self.msg("Usage: @delplayer <player/user name or #id> [: reason]")
|
||||
self.msg("Usage: @delaccount <account/user name or #id> [: reason]")
|
||||
return
|
||||
|
||||
reason = ""
|
||||
if ':' in args:
|
||||
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.
|
||||
players = search.player_search(args)
|
||||
accounts = search.account_search(args)
|
||||
|
||||
if not players:
|
||||
self.msg('Could not find a player by that name.')
|
||||
if not accounts:
|
||||
self.msg('Could not find an account by that name.')
|
||||
return
|
||||
|
||||
if len(players) > 1:
|
||||
if len(accounts) > 1:
|
||||
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)
|
||||
return
|
||||
|
||||
# one single match
|
||||
|
||||
player = players.pop()
|
||||
account = accounts.pop()
|
||||
|
||||
if not player.access(caller, 'delete'):
|
||||
string = "You don't have the permissions to delete that player."
|
||||
if not account.access(caller, 'delete'):
|
||||
string = "You don't have the permissions to delete that account."
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
uname = player.username
|
||||
# boot the player then delete
|
||||
self.msg("Informing and disconnecting player ...")
|
||||
uname = account.username
|
||||
# boot the account then delete
|
||||
self.msg("Informing and disconnecting account ...")
|
||||
string = "\nYour account '%s' is being *permanently* deleted.\n" % uname
|
||||
if reason:
|
||||
string += " Reason given:\n '%s'" % reason
|
||||
player.msg(string)
|
||||
player.delete()
|
||||
self.msg("Player %s was successfully deleted." % uname)
|
||||
account.msg(string)
|
||||
account.delete()
|
||||
self.msg("Account %s was successfully deleted." % uname)
|
||||
|
||||
|
||||
class CmdEmit(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -330,14 +330,14 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Switches:
|
||||
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
|
||||
|
||||
Emits a message to the selected objects or to
|
||||
your immediate surroundings. If the object is a room,
|
||||
send to its contents. @remit and @pemit are just
|
||||
limited forms of @emit, for sending to rooms and
|
||||
to players respectively.
|
||||
to accounts respectively.
|
||||
"""
|
||||
key = "@emit"
|
||||
aliases = ["@pemit", "@remit"]
|
||||
|
|
@ -359,7 +359,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
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
|
||||
|
||||
# we check which command was used to force the switches
|
||||
|
|
@ -367,7 +367,7 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
rooms_only = True
|
||||
send_to_contents = True
|
||||
elif self.cmdstring == '@pemit':
|
||||
players_only = True
|
||||
accounts_only = True
|
||||
|
||||
if not self.rhs:
|
||||
message = self.args
|
||||
|
|
@ -384,8 +384,8 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
if rooms_only and obj.location is not None:
|
||||
caller.msg("%s is not a room. Ignored." % objname)
|
||||
continue
|
||||
if players_only and not obj.has_player:
|
||||
caller.msg("%s has no active player. Ignored." % objname)
|
||||
if accounts_only and not obj.has_account:
|
||||
caller.msg("%s has no active account. Ignored." % objname)
|
||||
continue
|
||||
if obj.access(caller, 'tell'):
|
||||
obj.msg(message)
|
||||
|
|
@ -400,12 +400,12 @@ class CmdEmit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
change the password of a player
|
||||
change the password of an account
|
||||
|
||||
Usage:
|
||||
@userpassword <user obj> = <new password>
|
||||
|
||||
Set a player's password.
|
||||
Set an account's password.
|
||||
"""
|
||||
|
||||
key = "@userpassword"
|
||||
|
|
@ -421,32 +421,32 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("Usage: @userpassword <user obj> = <new password>")
|
||||
return
|
||||
|
||||
# the player search also matches 'me' etc.
|
||||
player = caller.search_player(self.lhs)
|
||||
if not player:
|
||||
# the account search also matches 'me' etc.
|
||||
account = caller.search_account(self.lhs)
|
||||
if not account:
|
||||
return
|
||||
player.set_password(self.rhs)
|
||||
player.save()
|
||||
self.msg("%s - new password set to '%s'." % (player.name, self.rhs))
|
||||
if player.character != caller:
|
||||
player.msg("%s has changed your password to '%s'." % (caller.name,
|
||||
account.set_password(self.rhs)
|
||||
account.save()
|
||||
self.msg("%s - new password set to '%s'." % (account.name, self.rhs))
|
||||
if account.character != caller:
|
||||
account.msg("%s has changed your password to '%s'." % (caller.name,
|
||||
self.rhs))
|
||||
|
||||
|
||||
class CmdPerm(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
set the permissions of a player/object
|
||||
set the permissions of an account/object
|
||||
|
||||
Usage:
|
||||
@perm[/switch] <object> [= <permission>[,<permission>,...]]
|
||||
@perm[/switch] *<player> [= <permission>[,<permission>,...]]
|
||||
@perm[/switch] *<account> [= <permission>[,<permission>,...]]
|
||||
|
||||
Switches:
|
||||
del : delete the given permission from <object> or <player>.
|
||||
player : set permission on a player (same as adding * to name)
|
||||
del : delete the given permission from <object> or <account>.
|
||||
account : set permission on an account (same as adding * to name)
|
||||
|
||||
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"
|
||||
aliases = "@setperm"
|
||||
|
|
@ -465,11 +465,11 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
return
|
||||
|
||||
playermode = 'player' in self.switches or lhs.startswith('*')
|
||||
accountmode = 'account' in self.switches or lhs.startswith('*')
|
||||
lhs = lhs.lstrip("*")
|
||||
|
||||
if playermode:
|
||||
obj = caller.search_player(lhs)
|
||||
if accountmode:
|
||||
obj = caller.search_account(lhs)
|
||||
else:
|
||||
obj = caller.search(lhs, global_search=True)
|
||||
if not obj:
|
||||
|
|
@ -485,19 +485,19 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
string += "<None>"
|
||||
else:
|
||||
string += ", ".join(obj.permissions.all())
|
||||
if (hasattr(obj, 'player') and
|
||||
hasattr(obj.player, 'is_superuser') and
|
||||
obj.player.is_superuser):
|
||||
if (hasattr(obj, 'account') and
|
||||
hasattr(obj.account, 'is_superuser') and
|
||||
obj.account.is_superuser):
|
||||
string += "\n(... but this object is currently controlled by a SUPERUSER! "
|
||||
string += "All access checks are passed automatically.)"
|
||||
caller.msg(string)
|
||||
return
|
||||
|
||||
# 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):
|
||||
caller.msg("You are not allowed to edit this %s's permissions."
|
||||
% ("player" if playermode else "object"))
|
||||
% ("account" if accountmode else "object"))
|
||||
return
|
||||
|
||||
caller_result = []
|
||||
|
|
@ -528,7 +528,7 @@ class CmdPerm(COMMAND_DEFAULT_CLASS):
|
|||
caller_result.append("\nPermission '%s' is already defined on %s." % (rhs, obj.name))
|
||||
else:
|
||||
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))
|
||||
target_result.append("\n%s gives you (%s, %s) the permission '%s'."
|
||||
% (caller.name, obj.name, plystring, rhs))
|
||||
|
|
@ -544,7 +544,7 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
@wall <message>
|
||||
|
||||
Announces a message to all connected players.
|
||||
Announces a message to all connected accounts.
|
||||
"""
|
||||
key = "@wall"
|
||||
locks = "cmd:perm(wall) or perm(Admin)"
|
||||
|
|
@ -556,5 +556,5 @@ class CmdWall(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg("Usage: @wall <message>")
|
||||
return
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
switches:
|
||||
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:
|
||||
@destroy house, roof, door, 44-78
|
||||
@destroy 5-10, flower, 45
|
||||
|
|
@ -640,8 +640,8 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
objname = obj.name
|
||||
if not (obj.access(caller, "control") or obj.access(caller, 'delete')):
|
||||
return "\nYou don't have permission to delete %s." % objname
|
||||
if obj.player and not 'override' in self.switches:
|
||||
return "\nObject %s is controlled by an active player. Use /override to delete anyway." % objname
|
||||
if obj.account and not 'override' in self.switches:
|
||||
return "\nObject %s is controlled by an active account. Use /override to delete anyway." % objname
|
||||
if obj.dbid == int(settings.DEFAULT_HOME.lstrip("#")):
|
||||
return "\nYou are trying to delete |c%s|n, which is set as DEFAULT_HOME. " \
|
||||
"Re-point settings.DEFAULT_HOME to another " \
|
||||
|
|
@ -1108,7 +1108,7 @@ class CmdName(ObjManipCommand):
|
|||
@name obj = name;alias1;alias2
|
||||
|
||||
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:
|
||||
objname = self.lhs_objs[0]['name']
|
||||
if objname.startswith("*"):
|
||||
# player mode
|
||||
obj = caller.player.search(objname.lstrip("*"))
|
||||
# account mode
|
||||
obj = caller.account.search(objname.lstrip("*"))
|
||||
if obj:
|
||||
if self.rhs_objs[0]['aliases']:
|
||||
caller.msg("Players can't have aliases.")
|
||||
caller.msg("Accounts can't have aliases.")
|
||||
return
|
||||
newname = self.rhs
|
||||
if not newname:
|
||||
caller.msg("No name defined!")
|
||||
return
|
||||
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
|
||||
obj.username = newname
|
||||
obj.save()
|
||||
caller.msg("Player's name changed to '%s'." % newname)
|
||||
caller.msg("Account's name changed to '%s'." % newname)
|
||||
return
|
||||
# object search, also with *
|
||||
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.
|
||||
|
||||
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
|
||||
comparisons later (e.g. obj.db.value = 2, if value is stored as a
|
||||
string this will always fail).
|
||||
|
|
@ -1381,13 +1381,13 @@ def _convert_from_string(cmd, strobj):
|
|||
|
||||
class CmdSetAttribute(ObjManipCommand):
|
||||
"""
|
||||
set attribute on an object or player
|
||||
set attribute on an object or account
|
||||
|
||||
Usage:
|
||||
@set <obj>/<attr> = <value>
|
||||
@set <obj>/<attr> =
|
||||
@set <obj>/<attr>
|
||||
@set *<player>/attr = <value>
|
||||
@set *<account>/attr = <value>
|
||||
|
||||
Switch:
|
||||
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
|
||||
placed on whether certain objects can have attributes set by certain
|
||||
players.
|
||||
accounts.
|
||||
|
||||
This function is expected to display its own error message.
|
||||
|
||||
|
|
@ -1505,7 +1505,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
attrs = self.lhs_objattr[0]['attrs']
|
||||
|
||||
if objname.startswith('*'):
|
||||
obj = caller.search_player(objname.lstrip('*'))
|
||||
obj = caller.search_account(objname.lstrip('*'))
|
||||
else:
|
||||
obj = caller.search(objname)
|
||||
if not obj:
|
||||
|
|
@ -1831,17 +1831,17 @@ class CmdExamine(ObjManipCommand):
|
|||
|
||||
Usage:
|
||||
examine [<object>[/attrname]]
|
||||
examine [*<player>[/attrname]]
|
||||
examine [*<account>[/attrname]]
|
||||
|
||||
Switch:
|
||||
player - examine a Player (same as adding *)
|
||||
account - examine an Account (same as adding *)
|
||||
object - examine an Object (useful when OOC)
|
||||
|
||||
The examine command shows detailed game info about an
|
||||
object and optionally a specific attribute on it.
|
||||
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"
|
||||
|
|
@ -1850,7 +1850,7 @@ class CmdExamine(ObjManipCommand):
|
|||
help_category = "Building"
|
||||
arg_regex = r"(/\w+?(\s|$))|\s|$"
|
||||
|
||||
player_mode = False
|
||||
account_mode = False
|
||||
|
||||
def list_attribute(self, crop, attr, value):
|
||||
"""
|
||||
|
|
@ -1910,15 +1910,15 @@ class CmdExamine(ObjManipCommand):
|
|||
for sess in obj.sessions.all()))
|
||||
if hasattr(obj, "email") and obj.email:
|
||||
string += "\n|wEmail|n: |c%s|n" % obj.email
|
||||
if hasattr(obj, "has_player") and obj.has_player:
|
||||
string += "\n|wPlayer|n: |c%s|n" % obj.player.name
|
||||
perms = obj.player.permissions.all()
|
||||
if obj.player.is_superuser:
|
||||
if hasattr(obj, "has_account") and obj.has_account:
|
||||
string += "\n|wAccount|n: |c%s|n" % obj.account.name
|
||||
perms = obj.account.permissions.all()
|
||||
if obj.account.is_superuser:
|
||||
perms = ["<Superuser>"]
|
||||
elif not perms:
|
||||
perms = ["<None>"]
|
||||
string += "\n|wPlayer Perms|n: %s" % (", ".join(perms))
|
||||
if obj.player.attributes.has("_quell"):
|
||||
string += "\n|wAccount Perms|n: %s" % (", ".join(perms))
|
||||
if obj.account.attributes.has("_quell"):
|
||||
string += " |r(quelled)|n"
|
||||
string += "\n|wTypeclass|n: %s (%s)" % (obj.typename,
|
||||
obj.typeclass_path)
|
||||
|
|
@ -1961,16 +1961,16 @@ class CmdExamine(ObjManipCommand):
|
|||
|
||||
# this gets all components of the currently merged set
|
||||
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 hasattr(obj, "player") and obj.player:
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.player.cmdset.all()])
|
||||
if hasattr(obj, "account") and obj.account:
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()])
|
||||
if obj.sessions.count():
|
||||
# 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
|
||||
# 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).
|
||||
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:
|
||||
try:
|
||||
# we have to protect this since many objects don't have sessions.
|
||||
|
|
@ -2011,7 +2011,7 @@ class CmdExamine(ObjManipCommand):
|
|||
for content in obj.contents:
|
||||
if content.destination:
|
||||
exits.append(content)
|
||||
elif content.player:
|
||||
elif content.account:
|
||||
pobjs.append(content)
|
||||
else:
|
||||
things.append(content)
|
||||
|
|
@ -2051,7 +2051,7 @@ class CmdExamine(ObjManipCommand):
|
|||
self.msg(caller.at_look(obj))
|
||||
return
|
||||
# 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:
|
||||
self.msg("You need to supply a target to examine.")
|
||||
return
|
||||
|
|
@ -2063,13 +2063,13 @@ class CmdExamine(ObjManipCommand):
|
|||
obj_name = objdef['name']
|
||||
obj_attrs = objdef['attrs']
|
||||
|
||||
self.player_mode = utils.inherits_from(caller, "evennia.players.players.DefaultPlayer") or \
|
||||
"player" in self.switches or obj_name.startswith('*')
|
||||
if self.player_mode:
|
||||
self.account_mode = utils.inherits_from(caller, "evennia.accounts.accounts.DefaultAccount") or \
|
||||
"account" in self.switches or obj_name.startswith('*')
|
||||
if self.account_mode:
|
||||
try:
|
||||
obj = caller.search_player(obj_name.lstrip('*'))
|
||||
obj = caller.search_account(obj_name.lstrip('*'))
|
||||
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)
|
||||
else:
|
||||
obj = caller.search(obj_name)
|
||||
|
|
@ -2089,12 +2089,12 @@ class CmdExamine(ObjManipCommand):
|
|||
else:
|
||||
if obj.sessions.count():
|
||||
mergemode = "session"
|
||||
elif self.player_mode:
|
||||
mergemode = "player"
|
||||
elif self.account_mode:
|
||||
mergemode = "account"
|
||||
else:
|
||||
mergemode = "object"
|
||||
# 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):
|
||||
|
|
@ -2102,7 +2102,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
search the database for objects
|
||||
|
||||
Usage:
|
||||
@find[/switches] <name or dbref or *player> [= dbrefmin[-dbrefmax]]
|
||||
@find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]
|
||||
|
||||
Switches:
|
||||
room - only look for rooms (location=None)
|
||||
|
|
@ -2111,7 +2111,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
exact- only exact matches are returned.
|
||||
|
||||
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
|
||||
limits matches to within the given dbrefs range, or above/below if only
|
||||
one is given.
|
||||
|
|
@ -2148,22 +2148,22 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
high = max(low, high)
|
||||
|
||||
is_dbref = utils.dbref(searchstring)
|
||||
is_player = searchstring.startswith("*")
|
||||
is_account = searchstring.startswith("*")
|
||||
|
||||
restrictions = ""
|
||||
if self.switches:
|
||||
restrictions = ", %s" % (",".join(self.switches))
|
||||
|
||||
if is_dbref or is_player:
|
||||
if is_dbref or is_account:
|
||||
|
||||
if is_dbref:
|
||||
# a dbref search
|
||||
result = caller.search(searchstring, global_search=True, quiet=True)
|
||||
string = "|wExact dbref match|n(#%i-#%i%s):" % (low, high, restrictions)
|
||||
else:
|
||||
# a player search
|
||||
# an account search
|
||||
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)
|
||||
|
||||
if "room" in switches:
|
||||
|
|
@ -2181,7 +2181,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
result=result[0]
|
||||
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
|
||||
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
|
||||
if "exact" in switches:
|
||||
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:
|
||||
caller.msg("Did not find object to teleport.")
|
||||
return
|
||||
if obj_to_teleport.has_player:
|
||||
if obj_to_teleport.has_account:
|
||||
caller.msg("Cannot teleport a puppeted object "
|
||||
"(%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
|
||||
caller.msg("Teleported %s -> None-location." % obj_to_teleport)
|
||||
if obj_to_teleport.location and not tel_quietly:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
"""
|
||||
This module ties together all the commands default Character objects have
|
||||
available (i.e. IC commands). Note that some commands, such as
|
||||
communication-commands are instead put on the player level, in the
|
||||
Player cmdset. Player commands remain available also to Characters.
|
||||
communication-commands are instead put on the account level, in the
|
||||
Account cmdset. Account commands remain available also to Characters.
|
||||
"""
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import general, help, admin, system
|
||||
|
|
@ -41,7 +41,7 @@ class CharacterCmdSet(CmdSet):
|
|||
self.add(system.CmdPy())
|
||||
self.add(system.CmdScripts())
|
||||
self.add(system.CmdObjects())
|
||||
self.add(system.CmdPlayers())
|
||||
self.add(system.CmdAccounts())
|
||||
self.add(system.CmdService())
|
||||
self.add(system.CmdAbout())
|
||||
self.add(system.CmdTime())
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
This module stores session-level commands.
|
||||
"""
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import player
|
||||
from evennia.commands.default import account
|
||||
|
||||
class SessionCmdSet(CmdSet):
|
||||
"""
|
||||
|
|
@ -13,4 +13,4 @@ class SessionCmdSet(CmdSet):
|
|||
|
||||
def at_cmdset_creation(self):
|
||||
"Populate the cmdset"
|
||||
self.add(player.CmdSessions())
|
||||
self.add(account.CmdSessions())
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@
|
|||
Comsystem command module.
|
||||
|
||||
Comm commands are OOC commands and intended to be made available to
|
||||
the Player at all times (they go into the PlayerCmdSet). So we
|
||||
make sure to homogenize self.caller to always be the player object
|
||||
the Account at all times (they go into the AccountCmdSet). So we
|
||||
make sure to homogenize self.caller to always be the account object
|
||||
for easy handling.
|
||||
|
||||
"""
|
||||
from past.builtins import cmp
|
||||
from django.conf import settings
|
||||
from evennia.comms.models import ChannelDB, Msg
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.players import bots
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.accounts import bots
|
||||
from evennia.comms.channelhandler import CHANNELHANDLER
|
||||
from evennia.locks.lockhandler import LockException
|
||||
from evennia.utils import create, utils, evtable
|
||||
|
|
@ -69,14 +69,14 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:not pperm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement the command"""
|
||||
|
||||
caller = self.caller
|
||||
args = self.args
|
||||
player = caller
|
||||
account = caller
|
||||
|
||||
if not args:
|
||||
self.msg("Usage: addcom [alias =] channelname.")
|
||||
|
|
@ -96,21 +96,21 @@ class CmdAddCom(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# 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)
|
||||
return
|
||||
|
||||
string = ""
|
||||
if not channel.has_connection(player):
|
||||
if not channel.has_connection(account):
|
||||
# we want to connect as well.
|
||||
if not channel.connect(player):
|
||||
# if this would have returned True, the player is connected
|
||||
if not channel.connect(account):
|
||||
# if this would have returned True, the account is connected
|
||||
self.msg("%s: You are not allowed to join this channel." % channel.key)
|
||||
return
|
||||
else:
|
||||
string += "You now listen to the channel %s. " % channel.key
|
||||
else:
|
||||
if channel.unmute(player):
|
||||
if channel.unmute(account):
|
||||
string += "You unmute channel %s." % channel.key
|
||||
else:
|
||||
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)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implementing the command. """
|
||||
|
||||
caller = self.caller
|
||||
player = caller
|
||||
account = caller
|
||||
|
||||
if not self.args:
|
||||
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)
|
||||
if channel:
|
||||
# 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.")
|
||||
return
|
||||
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))
|
||||
if nick and nick.pk and nick.value[3].lower() == chkey]:
|
||||
nick.delete()
|
||||
disconnect = channel.disconnect(player)
|
||||
disconnect = channel.disconnect(account)
|
||||
if disconnect:
|
||||
wipednicks = " Eventual aliases were removed." if delnicks else ""
|
||||
self.msg("You stop listening to channel '%s'.%s" % (channel.key, wipednicks))
|
||||
|
|
@ -209,7 +209,7 @@ class CmdAllCom(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Runs the function"""
|
||||
|
|
@ -273,7 +273,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd: not pperm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function"""
|
||||
|
|
@ -345,7 +345,7 @@ class CmdCdestroy(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd: not pperm(channel_banned)"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Destroy objects cleanly."""
|
||||
|
|
@ -372,15 +372,15 @@ class CmdCdestroy(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:
|
||||
@cboot[/quiet] <channel> = <player> [:reason]
|
||||
@cboot[/quiet] <channel> = <account> [:reason]
|
||||
|
||||
Switches:
|
||||
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"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""implement the function"""
|
||||
|
||||
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)
|
||||
return
|
||||
|
||||
|
|
@ -404,12 +404,12 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
reason = ""
|
||||
if ":" in self.rhs:
|
||||
playername, reason = self.rhs.rsplit(":", 1)
|
||||
searchstring = playername.lstrip('*')
|
||||
accountname, reason = self.rhs.rsplit(":", 1)
|
||||
searchstring = accountname.lstrip('*')
|
||||
else:
|
||||
searchstring = self.rhs.lstrip('*')
|
||||
player = self.caller.search(searchstring, player=True)
|
||||
if not player:
|
||||
account = self.caller.search(searchstring, account=True)
|
||||
if not account:
|
||||
return
|
||||
if reason:
|
||||
reason = " (reason: %s)" % reason
|
||||
|
|
@ -417,20 +417,20 @@ class CmdCBoot(COMMAND_DEFAULT_CLASS):
|
|||
string = "You don't control this channel."
|
||||
self.msg(string)
|
||||
return
|
||||
if player not in channel.db_subscriptions.all():
|
||||
string = "Player %s is not connected to channel %s." % (player.key, channel.key)
|
||||
if account not in channel.db_subscriptions.all():
|
||||
string = "Account %s is not connected to channel %s." % (account.key, channel.key)
|
||||
self.msg(string)
|
||||
return
|
||||
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)
|
||||
# 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
|
||||
player.character.nicks.get(category="channel") or []
|
||||
account.character.nicks.get(category="channel") or []
|
||||
if nick.value[3].lower() == channel.key]:
|
||||
nick.delete()
|
||||
# disconnect player
|
||||
channel.disconnect(player)
|
||||
# disconnect account
|
||||
channel.disconnect(account)
|
||||
CHANNELHANDLER.update()
|
||||
|
||||
|
||||
|
|
@ -453,11 +453,11 @@ class CmdCemit(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@cemit"
|
||||
aliases = ["@cmsg"]
|
||||
locks = "cmd: not pperm(channel_banned) and pperm(Player)"
|
||||
locks = "cmd: not pperm(channel_banned) and pperm(Account)"
|
||||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement function"""
|
||||
|
|
@ -496,7 +496,7 @@ class CmdCWho(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""implement function"""
|
||||
|
|
@ -530,11 +530,11 @@ class CmdChannelCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
key = "@ccreate"
|
||||
aliases = "channelcreate"
|
||||
locks = "cmd:not pperm(channel_banned) and pperm(Player)"
|
||||
locks = "cmd:not pperm(channel_banned) and pperm(Account)"
|
||||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement the command"""
|
||||
|
|
@ -587,7 +587,7 @@ class CmdClock(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""run the function"""
|
||||
|
|
@ -639,7 +639,7 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""Implement command"""
|
||||
|
|
@ -666,10 +666,10 @@ class CmdCdesc(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
class CmdPage(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
send a private message to another player
|
||||
send a private message to another account
|
||||
|
||||
Usage:
|
||||
page[/switches] [<player>,<player>,... = <message>]
|
||||
page[/switches] [<account>,<account>,... = <message>]
|
||||
tell ''
|
||||
page <number>
|
||||
|
||||
|
|
@ -687,12 +687,12 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
help_category = "Comms"
|
||||
|
||||
# this is used by the COMMAND_DEFAULT_CLASS parent
|
||||
player_caller = True
|
||||
account_caller = True
|
||||
|
||||
def func(self):
|
||||
"""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
|
||||
|
||||
# get the messages we've sent (not to channels)
|
||||
|
|
@ -718,7 +718,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
try:
|
||||
number = int(self.args)
|
||||
except ValueError:
|
||||
self.msg("Usage: tell [<player> = msg]")
|
||||
self.msg("Usage: tell [<account> = msg]")
|
||||
return
|
||||
|
||||
if len(pages) > number:
|
||||
|
|
@ -767,7 +767,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("Noone found to page.")
|
||||
return
|
||||
|
||||
header = "|wPlayer|n |c%s|n |wpages:|n" % caller.key
|
||||
header = "|wAccount|n |c%s|n |wpages:|n" % caller.key
|
||||
message = self.rhs
|
||||
|
||||
# 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,
|
||||
receivers=recobjs)
|
||||
|
||||
# tell the players they got a message.
|
||||
# tell the accounts they got a message.
|
||||
received = []
|
||||
rstrings = []
|
||||
for pobj in recobjs:
|
||||
|
|
@ -805,7 +805,7 @@ def _list_bots():
|
|||
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:
|
||||
from evennia.utils.evtable import EvTable
|
||||
table = EvTable("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
|
||||
|
|
@ -836,7 +836,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
Example:
|
||||
@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
|
||||
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:
|
||||
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)
|
||||
if not matches and dbref:
|
||||
# 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:
|
||||
matches[0].delete()
|
||||
self.msg("IRC connection destroyed.")
|
||||
|
|
@ -906,16 +906,16 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
irc_ssl = "ssl" in self.switches
|
||||
|
||||
# create a new bot
|
||||
bot = PlayerDB.objects.filter(username__iexact=botname)
|
||||
bot = AccountDB.objects.filter(username__iexact=botname)
|
||||
if bot:
|
||||
# re-use an existing bot
|
||||
bot = bot[0]
|
||||
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
|
||||
else:
|
||||
try:
|
||||
bot = create.create_player(botname, None, None, typeclass=botclass)
|
||||
bot = create.create_account(botname, None, None, typeclass=botclass)
|
||||
except Exception as err:
|
||||
self.msg("|rError, could not create the bot:|n '%s'." % err)
|
||||
return
|
||||
|
|
@ -963,7 +963,7 @@ class CmdIRCStatus(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
matches = None
|
||||
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:
|
||||
self.msg("No matching IRC-bot found. Use @ircstatus without arguments to list active bots.")
|
||||
return
|
||||
|
|
@ -1038,7 +1038,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if 'list' in self.switches:
|
||||
# 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:
|
||||
from evennia.utils.evtable import EvTable
|
||||
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:
|
||||
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:
|
||||
# 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:
|
||||
matches[0].delete()
|
||||
self.msg("RSS connection destroyed.")
|
||||
|
|
@ -1072,14 +1072,14 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
botname = "rssbot-%s" % url
|
||||
# create a new bot
|
||||
bot = PlayerDB.objects.filter(username__iexact=botname)
|
||||
bot = AccountDB.objects.filter(username__iexact=botname)
|
||||
if bot:
|
||||
# re-use existing bot
|
||||
bot = bot[0]
|
||||
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
|
||||
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)
|
||||
self.msg("RSS reporter created. Fetching RSS.")
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class CmdLook(COMMAND_DEFAULT_CLASS):
|
|||
Usage:
|
||||
look
|
||||
look <obj>
|
||||
look *<player>
|
||||
look *<account>
|
||||
|
||||
Observes your location or objects in your vicinity.
|
||||
"""
|
||||
|
|
@ -86,7 +86,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
Switches:
|
||||
inputline - replace on the inputline (default)
|
||||
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
|
||||
clearall - clear all nicks
|
||||
list - show all defined aliases (also "nicks" works)
|
||||
|
|
@ -121,7 +121,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
caller = self.caller
|
||||
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 [])
|
||||
|
||||
|
|
@ -441,7 +441,7 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
|
||||
if not self.lhs or not self.rhs:
|
||||
caller.msg("Usage: whisper <player> = <message>")
|
||||
caller.msg("Usage: whisper <account> = <message>")
|
||||
return
|
||||
|
||||
receiver = caller.search(self.lhs)
|
||||
|
|
@ -529,15 +529,15 @@ class CmdAccess(COMMAND_DEFAULT_CLASS):
|
|||
hierarchy_full = settings.PERMISSION_HIERARCHY
|
||||
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>"
|
||||
pperms = "<Superuser>"
|
||||
else:
|
||||
cperms = ", ".join(caller.permissions.all())
|
||||
pperms = ", ".join(caller.player.permissions.all())
|
||||
pperms = ", ".join(caller.account.permissions.all())
|
||||
|
||||
string += "\n|wYour access|n:"
|
||||
string += "\nCharacter |c%s|n: %s" % (caller.key, cperms)
|
||||
if hasattr(caller, 'player'):
|
||||
string += "\nPlayer |c%s|n: %s" % (caller.player.key, pperms)
|
||||
if hasattr(caller, 'account'):
|
||||
string += "\nAccount |c%s|n: %s" % (caller.account.key, pperms)
|
||||
caller.msg(string)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class CmdHelp(Command):
|
|||
|
||||
if self.session.protocol_key in ("websocket", "ajax/comet"):
|
||||
try:
|
||||
options = self.player.db._saved_webclient_options
|
||||
options = self.account.db._saved_webclient_options
|
||||
if options and options["helppopup"]:
|
||||
usemore = False
|
||||
except KeyError:
|
||||
|
|
@ -128,12 +128,12 @@ class CmdHelp(Command):
|
|||
Helper method. If this return True, the given cmd
|
||||
auto-help will be viewable in the help listing.
|
||||
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.
|
||||
|
||||
Args:
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
"""
|
||||
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.commands.command import Command
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("MuxCommand", "MuxPlayerCommand")
|
||||
__all__ = ("MuxCommand", "MuxAccountCommand")
|
||||
|
||||
|
||||
class MuxCommand(Command):
|
||||
|
|
@ -128,17 +128,17 @@ class MuxCommand(Command):
|
|||
self.rhs = rhs
|
||||
self.rhslist = rhslist
|
||||
|
||||
# if the class has the player_caller property set on itself, we make
|
||||
# sure that self.caller is always the player if possible. We also create
|
||||
# if the class has the account_caller property set on itself, we make
|
||||
# sure that self.caller is always the account if possible. We also create
|
||||
# a special property "character" for the puppeted object, if any. This
|
||||
# is convenient for commands defined on the Player only.
|
||||
if hasattr(self, "player_caller") and self.player_caller:
|
||||
# is convenient for commands defined on the Account only.
|
||||
if hasattr(self, "account_caller") and self.account_caller:
|
||||
if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
self.caller = self.caller.player
|
||||
elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
|
||||
# caller was already a Player
|
||||
self.caller = self.caller.account
|
||||
elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
||||
# caller was already an Account
|
||||
self.character = self.caller.get_puppet(self.session)
|
||||
else:
|
||||
self.character = None
|
||||
|
|
@ -177,32 +177,32 @@ class MuxCommand(Command):
|
|||
self.caller.msg(string)
|
||||
|
||||
|
||||
class MuxPlayerCommand(MuxCommand):
|
||||
class MuxAccountCommand(MuxCommand):
|
||||
"""
|
||||
This is an on-Player version of the MuxCommand. Since these commands sit
|
||||
on Players rather than on Characters/Objects, we need to check
|
||||
This is an on-Account version of the MuxCommand. Since these commands sit
|
||||
on Accounts rather than on Characters/Objects, we need to check
|
||||
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
|
||||
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
|
||||
character is actually attached to this Player and Session.
|
||||
character is actually attached to this Account and Session.
|
||||
"""
|
||||
def parse(self):
|
||||
"""
|
||||
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"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
self.caller = self.caller.player
|
||||
elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
|
||||
# caller was already a Player
|
||||
self.caller = self.caller.account
|
||||
elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
||||
# caller was already an Account
|
||||
self.character = self.caller.get_puppet(self.session)
|
||||
else:
|
||||
self.character = None
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -17,7 +17,7 @@ from django.conf import settings
|
|||
from evennia.server.sessionhandler import SESSIONS
|
||||
from evennia.scripts.models import ScriptDB
|
||||
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.eveditor import EvEditor
|
||||
from evennia.utils.evtable import EvTable
|
||||
|
|
@ -455,24 +455,24 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg(string)
|
||||
|
||||
|
||||
class CmdPlayers(COMMAND_DEFAULT_CLASS):
|
||||
class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
list all registered players
|
||||
list all registered accounts
|
||||
|
||||
Usage:
|
||||
@players [nr]
|
||||
@accounts [nr]
|
||||
|
||||
Lists statistics about the Players registered with the game.
|
||||
It will list the <nr> amount of latest registered players
|
||||
Lists statistics about the Accounts registered with the game.
|
||||
It will list the <nr> amount of latest registered accounts
|
||||
If not given, <nr> defaults to 10.
|
||||
"""
|
||||
key = "@players"
|
||||
aliases = ["@listplayers"]
|
||||
locks = "cmd:perm(listplayers) or perm(Admin)"
|
||||
key = "@accounts"
|
||||
aliases = ["@listaccounts"]
|
||||
locks = "cmd:perm(listaccounts) or perm(Admin)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
"""List the players"""
|
||||
"""List the accounts"""
|
||||
|
||||
caller = self.caller
|
||||
if self.args and self.args.isdigit():
|
||||
|
|
@ -480,21 +480,21 @@ class CmdPlayers(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
nlim = 10
|
||||
|
||||
nplayers = PlayerDB.objects.count()
|
||||
naccounts = AccountDB.objects.count()
|
||||
|
||||
# typeclass table
|
||||
dbtotals = PlayerDB.objects.object_totals()
|
||||
dbtotals = AccountDB.objects.object_totals()
|
||||
typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
|
||||
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
|
||||
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")
|
||||
for ply in plyrs:
|
||||
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|wLast %s Players created:|n\n%s" % (min(nplayers, nlim), latesttable)
|
||||
string = "\n|wAccount typeclass distribution:|n\n%s" % typetable
|
||||
string += "\n|wLast %s Accounts created:|n\n%s" % (min(naccounts, nlim), latesttable)
|
||||
caller.msg(string)
|
||||
|
||||
|
||||
|
|
@ -644,7 +644,7 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
|||
"""
|
||||
key = "@time"
|
||||
aliases = "@uptime"
|
||||
locks = "cmd:perm(time) or perm(Player)"
|
||||
locks = "cmd:perm(time) or perm(Account)"
|
||||
help_category = "System"
|
||||
|
||||
def func(self):
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from mock import Mock
|
|||
|
||||
from evennia.commands.default.cmdset_character import CharacterCmdSet
|
||||
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.utils import ansi, utils
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
|
|
@ -63,7 +63,7 @@ class CommandTest(EvenniaTest):
|
|||
cmdobj.args = args
|
||||
cmdobj.cmdset = cmdset
|
||||
cmdobj.session = SESSIONS.session_from_sessid(1)
|
||||
cmdobj.player = self.player
|
||||
cmdobj.account = self.account
|
||||
cmdobj.raw_string = cmdobj.key + " " + args
|
||||
cmdobj.obj = obj or (caller if caller else self.char1)
|
||||
# test
|
||||
|
|
@ -119,10 +119,10 @@ class TestGeneral(CommandTest):
|
|||
|
||||
def test_nick(self):
|
||||
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.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"))
|
||||
|
||||
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).")
|
||||
|
||||
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):
|
||||
self.call(admin.CmdBan(), "Char", "NameBan char was added.")
|
||||
|
||||
|
||||
class TestPlayer(CommandTest):
|
||||
class TestAccount(CommandTest):
|
||||
|
||||
def test_ooc_look(self):
|
||||
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:
|
||||
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):
|
||||
self.call(player.CmdOOC(), "", "You go OOC.", caller=self.player)
|
||||
self.call(account.CmdOOC(), "", "You go OOC.", caller=self.account)
|
||||
|
||||
def test_ic(self):
|
||||
self.player.unpuppet_object(self.session)
|
||||
self.call(player.CmdIC(), "Char", "You become Char.", caller=self.player, receiver=self.char1)
|
||||
self.account.unpuppet_object(self.session)
|
||||
self.call(account.CmdIC(), "Char", "You become Char.", caller=self.account, receiver=self.char1)
|
||||
|
||||
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):
|
||||
self.call(player.CmdOption(), "", "Client settings", caller=self.player)
|
||||
self.call(account.CmdOption(), "", "Client settings", caller=self.account)
|
||||
|
||||
def test_who(self):
|
||||
self.call(player.CmdWho(), "", "Players:", caller=self.player)
|
||||
self.call(account.CmdWho(), "", "Accounts:", caller=self.account)
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
|
|
@ -290,39 +290,39 @@ class TestComms(CommandTest):
|
|||
|
||||
def setUp(self):
|
||||
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):
|
||||
self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.player)
|
||||
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", 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.account)
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
# 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):
|
||||
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):
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from collections import defaultdict
|
|||
from random import getrandbits
|
||||
from django.conf import settings
|
||||
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.server.models import ServerConfig
|
||||
from evennia.comms.models import ChannelDB
|
||||
|
|
@ -25,7 +25,7 @@ MULTISESSION_MODE = settings.MULTISESSION_MODE
|
|||
CONNECTION_SCREEN_MODULE = settings.CONNECTION_SCREEN_MODULE
|
||||
|
||||
# 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
|
||||
# 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
|
||||
|
||||
|
||||
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:
|
||||
session (Session): the session which will use the guest player/character.
|
||||
session (Session): the session which will use the guest account/character.
|
||||
|
||||
Returns:
|
||||
GUEST_ENABLED (boolean), player (Player):
|
||||
GUEST_ENABLED (boolean), account (Account):
|
||||
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.
|
||||
if not settings.GUEST_ENABLED:
|
||||
|
|
@ -105,25 +105,25 @@ def create_guest_player(session):
|
|||
|
||||
try:
|
||||
# Find an available guest name.
|
||||
playername = None
|
||||
accountname = None
|
||||
for name in settings.GUEST_LIST:
|
||||
if not PlayerDB.objects.filter(username__iexact=playername).count():
|
||||
playername = name
|
||||
if not AccountDB.objects.filter(username__iexact=accountname).count():
|
||||
accountname = name
|
||||
break
|
||||
if not playername:
|
||||
if not accountname:
|
||||
session.msg("All guest accounts are in use. Please try again later.")
|
||||
return True, None
|
||||
else:
|
||||
# build a new player with the found guest playername
|
||||
# build a new account with the found guest accountname
|
||||
password = "%016x" % getrandbits(64)
|
||||
home = ObjectDB.objects.get_id(settings.GUEST_HOME)
|
||||
permissions = settings.PERMISSION_GUEST_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
ptypeclass = settings.BASE_GUEST_TYPECLASS
|
||||
new_player = _create_player(session, playername, password, permissions, ptypeclass)
|
||||
if new_player:
|
||||
_create_character(session, new_player, typeclass, home, permissions)
|
||||
return True, new_player
|
||||
new_account = _create_account(session, accountname, password, permissions, ptypeclass)
|
||||
if new_account:
|
||||
_create_character(session, new_account, typeclass, home, permissions)
|
||||
return True, new_account
|
||||
|
||||
except Exception:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
|
|
@ -134,17 +134,17 @@ def create_guest_player(session):
|
|||
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:
|
||||
session (Session): the session which is requesting to create a player.
|
||||
name (str): the name that the player wants to use for login.
|
||||
password (str): the password desired by this player, for login.
|
||||
session (Session): the session which is requesting to create an account.
|
||||
name (str): the name that the account wants to use for login.
|
||||
password (str): the password desired by this account, for login.
|
||||
|
||||
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.
|
||||
if _throttle(session, maxlim=5, timeout=5*60):
|
||||
|
|
@ -153,22 +153,22 @@ def create_normal_player(session, name, password):
|
|||
return None
|
||||
|
||||
# Match account name and check password
|
||||
player = authenticate(username=name, password=password)
|
||||
account = authenticate(username=name, password=password)
|
||||
|
||||
if not player:
|
||||
# No playername or password match
|
||||
if not account:
|
||||
# No accountname or password match
|
||||
session.msg("Incorrect login information given.")
|
||||
# this just updates the throttle
|
||||
_throttle(session)
|
||||
# calls player hook for a failed login if possible.
|
||||
player = PlayerDB.objects.get_player_from_name(name)
|
||||
if player:
|
||||
player.at_failed_login(session)
|
||||
# calls account hook for a failed login if possible.
|
||||
account = AccountDB.objects.get_account_from_name(name)
|
||||
if account:
|
||||
account.at_failed_login(session)
|
||||
return None
|
||||
|
||||
# Check IP and/or name 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
|
||||
any(tup[2].match(session.address) for tup in bans if tup[2])):
|
||||
# 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.")
|
||||
return None
|
||||
|
||||
return player
|
||||
return account
|
||||
|
||||
|
||||
class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -186,8 +186,8 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
connect to the game
|
||||
|
||||
Usage (at login screen):
|
||||
connect playername password
|
||||
connect "player name" "pass word"
|
||||
connect accountname password
|
||||
connect "account name" "pass word"
|
||||
|
||||
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
|
||||
a session object instead of a source_object like all
|
||||
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
|
||||
|
||||
|
|
@ -222,9 +222,9 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
parts = parts[0].split(None, 1)
|
||||
# Guest login
|
||||
if len(parts) == 1 and parts[0].lower() == "guest":
|
||||
enabled, new_player = create_guest_player(session)
|
||||
if new_player:
|
||||
session.sessionhandler.login(session, new_player)
|
||||
enabled, new_account = create_guest_account(session)
|
||||
if new_account:
|
||||
session.sessionhandler.login(session, new_account)
|
||||
if enabled:
|
||||
return
|
||||
|
||||
|
|
@ -233,20 +233,20 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
name, password = parts
|
||||
player = create_normal_player(session, name, password)
|
||||
if player:
|
||||
session.sessionhandler.login(session, player)
|
||||
account = create_normal_account(session, name, password)
|
||||
if account:
|
||||
session.sessionhandler.login(session, account)
|
||||
|
||||
|
||||
class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
create a new player account
|
||||
create a new account account
|
||||
|
||||
Usage (at login screen):
|
||||
create <playername> <password>
|
||||
create "player name" "pass word"
|
||||
create <accountname> <password>
|
||||
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.
|
||||
"""
|
||||
|
|
@ -271,25 +271,25 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
"\nIf <name> or <password> contains spaces, enclose it in double quotes."
|
||||
session.msg(string)
|
||||
return
|
||||
playername, password = parts
|
||||
accountname, password = parts
|
||||
|
||||
# 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
|
||||
# module (except not allowing spaces, for convenience of
|
||||
# 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)
|
||||
return
|
||||
# strip excessive spaces in playername
|
||||
playername = re.sub(r"\s+", " ", playername).strip()
|
||||
if PlayerDB.objects.filter(username__iexact=playername):
|
||||
# player already exists (we also ignore capitalization here)
|
||||
session.msg("Sorry, there is already a player with the name '%s'." % playername)
|
||||
# strip excessive spaces in accountname
|
||||
accountname = re.sub(r"\s+", " ", accountname).strip()
|
||||
if AccountDB.objects.filter(username__iexact=accountname):
|
||||
# account already exists (we also ignore capitalization here)
|
||||
session.msg("Sorry, there is already an account with the name '%s'." % accountname)
|
||||
return
|
||||
# Reserve playernames found in GUEST_LIST
|
||||
if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST):
|
||||
string = "\n\r That name is reserved. Please choose another Playername."
|
||||
# Reserve accountnames found in 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 Accountname."
|
||||
session.msg(string)
|
||||
return
|
||||
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
|
||||
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
|
||||
any(tup[2].match(session.address) for tup in bans if tup[2])):
|
||||
# this is a banned IP or name!
|
||||
|
|
@ -311,22 +311,22 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
session.sessionhandler.disconnect(session, "Good bye! Disconnecting.")
|
||||
return
|
||||
|
||||
# everything's ok. Create the new player account.
|
||||
# everything's ok. Create the new account account.
|
||||
try:
|
||||
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
new_player = _create_player(session, playername, password, permissions)
|
||||
if new_player:
|
||||
new_account = _create_account(session, accountname, password, permissions)
|
||||
if new_account:
|
||||
if MULTISESSION_MODE < 2:
|
||||
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.
|
||||
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>'."
|
||||
else:
|
||||
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:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
|
|
@ -344,7 +344,7 @@ class CmdUnconnectedQuit(COMMAND_DEFAULT_CLASS):
|
|||
quit
|
||||
|
||||
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.
|
||||
"""
|
||||
key = "quit"
|
||||
|
|
@ -516,50 +516,50 @@ class CmdUnconnectedScreenreader(COMMAND_DEFAULT_CLASS):
|
|||
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:
|
||||
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:
|
||||
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()
|
||||
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
|
||||
# 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"])
|
||||
if not pchannel or not pchannel.connect(new_player):
|
||||
string = "New player '%s' could not connect to public channel!" % new_player.key
|
||||
if not pchannel or not pchannel.connect(new_account):
|
||||
string = "New account '%s' could not connect to public channel!" % new_account.key
|
||||
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.
|
||||
"""
|
||||
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
|
||||
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.id, new_player.id))
|
||||
(new_character.id, new_account.id))
|
||||
|
||||
# If no description is set, set a default description
|
||||
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
|
||||
new_player.db._last_puppet = new_character
|
||||
new_account.db._last_puppet = new_character
|
||||
except Exception as e:
|
||||
session.msg("There was an error creating the Character:\n%s\n If this problem persists, contact an admin." % e)
|
||||
logger.log_trace()
|
||||
|
|
|
|||
|
|
@ -266,15 +266,15 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
deferred.addCallback(_callback)
|
||||
return deferred
|
||||
|
||||
def test_from_player(self):
|
||||
from evennia.commands.default.cmdset_player import PlayerCmdSet
|
||||
def test_from_account(self):
|
||||
from evennia.commands.default.cmdset_account import AccountCmdSet
|
||||
a = self.cmdset_a
|
||||
a.no_channels = True
|
||||
self.set_cmdsets(self.player, a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.player, None, self.player, None, "player", "")
|
||||
self.set_cmdsets(self.account, a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.account, None, self.account, None, "account", "")
|
||||
# get_and_merge_cmdsets converts to lower-case internally.
|
||||
def _callback(cmdset):
|
||||
pcmdset = PlayerCmdSet()
|
||||
pcmdset = AccountCmdSet()
|
||||
pcmdset.at_cmdset_creation()
|
||||
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"]
|
||||
self.assertTrue(all(cmd.key in pcmds for cmd in cmdset.commands))
|
||||
|
|
@ -305,18 +305,18 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
|
||||
def test_autocmdsets(self):
|
||||
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
|
||||
testchannel = evennia.create_channel("channeltest", locks="listen:all();send:all()")
|
||||
CHANNEL_HANDLER.add(testchannel)
|
||||
CHANNEL_HANDLER.update()
|
||||
self.assertTrue(testchannel.connect(self.player))
|
||||
self.assertTrue(testchannel.has_connection(self.player))
|
||||
self.assertTrue(testchannel.connect(self.account))
|
||||
self.assertTrue(testchannel.has_connection(self.account))
|
||||
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)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.player, self.char1, "session", "")
|
||||
self.set_cmdsets(self.account, a, b, c, d)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.account, self.char1, "session", "")
|
||||
def _callback(cmdset):
|
||||
pcmdset = PlayerCmdSet()
|
||||
pcmdset = AccountCmdSet()
|
||||
pcmdset.at_cmdset_creation()
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class ChannelCommand(command.Command):
|
|||
self.msg(string % channelkey)
|
||||
return
|
||||
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)
|
||||
if unmuted:
|
||||
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)
|
||||
return
|
||||
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)
|
||||
if muted:
|
||||
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))
|
||||
tail_log_file(log_file, self.history_start, 20, callback=send_msg)
|
||||
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:
|
||||
self.msg("You currently have %s muted." % channel)
|
||||
return
|
||||
|
|
@ -144,7 +144,7 @@ class ChannelCommand(command.Command):
|
|||
Let users know that this command is for communicating on a channel.
|
||||
|
||||
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:
|
||||
A string with identifying information to disambiguate the object, conventionally with a preceding space.
|
||||
|
|
|
|||
|
|
@ -62,26 +62,26 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
|
||||
def has_connection(self, subscriber):
|
||||
"""
|
||||
Checks so this player is actually listening
|
||||
Checks so this account is actually listening
|
||||
to this channel.
|
||||
|
||||
Args:
|
||||
subscriber (Player or Object): Entity to check.
|
||||
subscriber (Account or Object): Entity to check.
|
||||
|
||||
Returns:
|
||||
has_sub (bool): Whether the subscriber is subscribing to
|
||||
this channel or not.
|
||||
|
||||
Notes:
|
||||
This will first try Player subscribers and only try Object
|
||||
if the Player fails.
|
||||
This will first try Account subscribers and only try Object
|
||||
if the Account fails.
|
||||
|
||||
"""
|
||||
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
|
||||
# by default only allow Players to subscribe.
|
||||
has_sub = self.subscriptions.has(subscriber.player)
|
||||
# by default only allow Accounts to subscribe.
|
||||
has_sub = self.subscriptions.has(subscriber.account)
|
||||
return has_sub
|
||||
|
||||
@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]
|
||||
if subs:
|
||||
# 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:
|
||||
string = "<None>"
|
||||
return string
|
||||
|
|
@ -106,7 +106,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
but may use channel commands.
|
||||
|
||||
Args:
|
||||
subscriber (Object or Player): Subscriber to mute.
|
||||
subscriber (Object or Account): Subscriber to mute.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
but may use channel commands.
|
||||
|
||||
Args:
|
||||
subscriber (Object or Player): The subscriber to unmute.
|
||||
subscriber (Object or Account): The subscriber to unmute.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
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.
|
||||
|
||||
Args:
|
||||
subscriber (Player or Object): the entity to subscribe
|
||||
subscriber (Account or Object): the entity to subscribe
|
||||
to this channel.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
|
@ -171,7 +171,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
Disconnect entity from this channel.
|
||||
|
||||
Args:
|
||||
subscriber (Player of Object): the
|
||||
subscriber (Account of Object): the
|
||||
entity to disconnect.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
|
@ -265,7 +265,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
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:
|
||||
subs = self.subscriptions.online()
|
||||
else:
|
||||
|
|
@ -276,7 +276,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
continue
|
||||
try:
|
||||
# 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})
|
||||
except AttributeError as e:
|
||||
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,
|
||||
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
|
||||
done before calling this method. The optional keywords are not used if
|
||||
persistent is False.
|
||||
|
|
@ -300,10 +300,10 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
(if persistent=False) or it will be used together with `header`
|
||||
and `senders` keywords to create a Msg instance on the fly.
|
||||
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.
|
||||
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.
|
||||
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
|
||||
|
|
@ -311,8 +311,8 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
message only (note that for unlogged channels, a `True` value here will
|
||||
create a new log file only for this message).
|
||||
online (bool, optional) - If this is set true, only messages people who are
|
||||
online. Otherwise, messages all players connected. This can
|
||||
make things faster, but may not trigger listeners on players
|
||||
online. Otherwise, messages all accounts connected. This can
|
||||
make things faster, but may not trigger listeners on accounts
|
||||
that are offline.
|
||||
emit (bool, optional) - Signals to the message formatter that this message is
|
||||
not to be directly associated with a name.
|
||||
|
|
@ -389,7 +389,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
Notes:
|
||||
This function exists separately so that external sources
|
||||
can use it to format source names in the same manner as
|
||||
normal object/player names.
|
||||
normal object/account names.
|
||||
|
||||
"""
|
||||
if not senders:
|
||||
|
|
@ -432,7 +432,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
"""
|
||||
Hook method. Used for formatting external messages. This is
|
||||
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.
|
||||
|
||||
Args:
|
||||
|
|
@ -495,7 +495,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
|
||||
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:
|
||||
joiner (object): The joining object.
|
||||
|
|
@ -523,7 +523,7 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
|
||||
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:
|
||||
leaver (object): The leaving object.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from evennia.typeclasses.managers import (TypedObjectManager, TypeclassManager)
|
|||
from evennia.utils import logger
|
||||
|
||||
_GA = object.__getattribute__
|
||||
_PlayerDB = None
|
||||
_AccountDB = None
|
||||
_ObjectDB = None
|
||||
_ChannelDB = None
|
||||
_SESSIONS = None
|
||||
|
|
@ -57,7 +57,7 @@ def dbref(inp, reqhash=True):
|
|||
|
||||
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
|
||||
|
||||
Args:
|
||||
|
|
@ -65,14 +65,14 @@ def identify_object(inp):
|
|||
|
||||
Returns:
|
||||
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.
|
||||
|
||||
"""
|
||||
if hasattr(inp, "__dbclass__"):
|
||||
clsname = inp.__dbclass__.__name__
|
||||
if clsname == "PlayerDB":
|
||||
return inp, "player"
|
||||
if clsname == "AccountDB":
|
||||
return inp, "account"
|
||||
elif clsname == "ObjectDB":
|
||||
return inp ,"object"
|
||||
elif clsname == "ChannelDB":
|
||||
|
|
@ -85,14 +85,14 @@ def identify_object(inp):
|
|||
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.
|
||||
|
||||
Args:
|
||||
inp (any): The input object/string
|
||||
objtype (str): Either 'player' or 'channel'.
|
||||
objtype (str): Either 'account' or 'channel'.
|
||||
|
||||
Returns:
|
||||
obj (object): The correct object related to `inp`.
|
||||
|
|
@ -101,17 +101,17 @@ def to_object(inp, objtype='player'):
|
|||
obj, typ = identify_object(inp)
|
||||
if typ == objtype:
|
||||
return obj
|
||||
if objtype == 'player':
|
||||
if objtype == 'account':
|
||||
if typ == 'object':
|
||||
return obj.player
|
||||
return obj.account
|
||||
if typ == 'string':
|
||||
return _PlayerDB.objects.get(user_username__iexact=obj)
|
||||
return _AccountDB.objects.get(user_username__iexact=obj)
|
||||
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))
|
||||
raise CommError()
|
||||
elif objtype == 'object':
|
||||
if typ == 'player':
|
||||
if typ == 'account':
|
||||
return obj.obj
|
||||
if typ == 'string':
|
||||
return _ObjectDB.objects.get(db_key__iexact=obj)
|
||||
|
|
@ -158,7 +158,7 @@ class MsgManager(TypedObjectManager):
|
|||
|
||||
Returns:
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
@ -183,10 +183,10 @@ class MsgManager(TypedObjectManager):
|
|||
def get_messages_by_sender(self, sender, exclude_channel_messages=False):
|
||||
"""
|
||||
Get all messages sent by one entity - this could be either a
|
||||
player or an object
|
||||
account or an object
|
||||
|
||||
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
|
||||
not aimed at a channel (that is, private tells for example)
|
||||
|
||||
|
|
@ -200,9 +200,9 @@ class MsgManager(TypedObjectManager):
|
|||
obj, typ = identify_object(sender)
|
||||
if exclude_channel_messages:
|
||||
# explicitly exclude channel recipients
|
||||
if typ == 'player':
|
||||
return list(self.filter(db_sender_players=obj,
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_players=obj))
|
||||
if typ == 'account':
|
||||
return list(self.filter(db_sender_accounts=obj,
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_accounts=obj))
|
||||
elif typ == 'object':
|
||||
return list(self.filter(db_sender_objects=obj,
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_objects=obj))
|
||||
|
|
@ -210,8 +210,8 @@ class MsgManager(TypedObjectManager):
|
|||
raise CommError
|
||||
else:
|
||||
# get everything, channel or not
|
||||
if typ == 'player':
|
||||
return list(self.filter(db_sender_players=obj).exclude(db_hide_from_players=obj))
|
||||
if typ == 'account':
|
||||
return list(self.filter(db_sender_accounts=obj).exclude(db_hide_from_accounts=obj))
|
||||
elif typ == 'object':
|
||||
return list(self.filter(db_sender_objects=obj).exclude(db_hide_from_objects=obj))
|
||||
else:
|
||||
|
|
@ -222,7 +222,7 @@ class MsgManager(TypedObjectManager):
|
|||
Get all messages sent to one given recipient.
|
||||
|
||||
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:
|
||||
messages (list): Matching messages.
|
||||
|
|
@ -232,8 +232,8 @@ class MsgManager(TypedObjectManager):
|
|||
|
||||
"""
|
||||
obj, typ = identify_object(recipient)
|
||||
if typ == 'player':
|
||||
return list(self.filter(db_receivers_players=obj).exclude(db_hide_from_players=obj))
|
||||
if typ == 'account':
|
||||
return list(self.filter(db_receivers_accounts=obj).exclude(db_hide_from_accounts=obj))
|
||||
elif typ == 'object':
|
||||
return list(self.filter(db_receivers_objects=obj).exclude(db_hide_from_objects=obj))
|
||||
elif typ == 'channel':
|
||||
|
|
@ -260,9 +260,9 @@ class MsgManager(TypedObjectManager):
|
|||
one of the arguments must be given to do a search.
|
||||
|
||||
Args:
|
||||
sender (Object or Player, optional): Get messages sent by a particular player or object
|
||||
receiver (Object, Player or Channel, optional): Get messages
|
||||
received by a certain player,object or channel
|
||||
sender (Object or Account, optional): Get messages sent by a particular account or object
|
||||
receiver (Object, Account or Channel, optional): Get messages
|
||||
received by a certain account,object or channel
|
||||
freetext (str): Search for a text string in a message. NOTE:
|
||||
This can potentially be slow, so make sure to supply one of
|
||||
the other arguments to limit the search.
|
||||
|
|
@ -287,16 +287,16 @@ class MsgManager(TypedObjectManager):
|
|||
|
||||
# filter by sender
|
||||
sender, styp = identify_object(sender)
|
||||
if styp == 'player':
|
||||
sender_restrict = Q(db_sender_players=sender) & ~Q(db_hide_from_players=sender)
|
||||
if styp == 'account':
|
||||
sender_restrict = Q(db_sender_accounts=sender) & ~Q(db_hide_from_accounts=sender)
|
||||
elif styp == 'object':
|
||||
sender_restrict = Q(db_sender_objects=sender) & ~Q(db_hide_from_objects=sender)
|
||||
else:
|
||||
sender_restrict = Q()
|
||||
# filter by receiver
|
||||
receiver, rtyp = identify_object(receiver)
|
||||
if rtyp == 'player':
|
||||
receiver_restrict = Q(db_receivers_players=receiver) & ~Q(db_hide_from_players=receiver)
|
||||
if rtyp == 'account':
|
||||
receiver_restrict = Q(db_receivers_accounts=receiver) & ~Q(db_hide_from_accounts=receiver)
|
||||
elif rtyp == 'object':
|
||||
receiver_restrict = Q(db_receivers_objects=receiver) & ~Q(db_hide_from_objects=receiver)
|
||||
elif rtyp == 'channel':
|
||||
|
|
@ -369,14 +369,14 @@ class ChannelDBManager(TypedObjectManager):
|
|||
Return all channels a given entity is subscribed to.
|
||||
|
||||
Args:
|
||||
subscriber (Object or Player): The one subscribing.
|
||||
subscriber (Object or Account): The one subscribing.
|
||||
|
||||
Returns:
|
||||
subscriptions (list): Channel subscribed to.
|
||||
|
||||
"""
|
||||
clsname = subscriber.__dbclass__.__name__
|
||||
if clsname == "PlayerDB":
|
||||
if clsname == "AccountDB":
|
||||
return subscriber.subscription_set.all()
|
||||
if clsname == "ObjectDB":
|
||||
return subscriber.object_subscription_set.all()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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
|
||||
necessary to easily be able to delete connections on the fly).
|
||||
"""
|
||||
|
|
@ -48,16 +48,16 @@ _CHANNELHANDLER = None
|
|||
class Msg(SharedMemoryModel):
|
||||
"""
|
||||
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
|
||||
accessed via specific handler methods):
|
||||
|
||||
- db_sender_players: Player senders
|
||||
- db_sender_accounts: Account senders
|
||||
- db_sender_objects: Object senders
|
||||
- db_sender_scripts: Script senders
|
||||
- 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_scripts: Receiveing scripts
|
||||
- db_receivers_channels: Receiving channels
|
||||
|
|
@ -77,7 +77,7 @@ class Msg(SharedMemoryModel):
|
|||
# These databse fields are all set using their corresponding properties,
|
||||
# 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
|
||||
# a message is allowed, there may be more than one "author"
|
||||
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,
|
||||
help_text='access locks on this message.')
|
||||
|
||||
# these can be used to filter/hide a given message from supplied objects/players/channels
|
||||
db_hide_from_players = models.ManyToManyField("players.PlayerDB", related_name='hide_from_players_set', blank=True)
|
||||
# these can be used to filter/hide a given message from supplied objects/accounts/channels
|
||||
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)
|
||||
|
|
@ -156,7 +156,7 @@ class Msg(SharedMemoryModel):
|
|||
#@property
|
||||
def __senders_get(self):
|
||||
"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_scripts.all()) + \
|
||||
self.extra_senders
|
||||
|
|
@ -177,15 +177,15 @@ class Msg(SharedMemoryModel):
|
|||
clsname = sender.__dbclass__.__name__
|
||||
if clsname == "ObjectDB":
|
||||
self.db_sender_objects.add(sender)
|
||||
elif clsname == "PlayerDB":
|
||||
self.db_sender_players.add(sender)
|
||||
elif clsname == "AccountDB":
|
||||
self.db_sender_accounts.add(sender)
|
||||
elif clsname == "ScriptDB":
|
||||
self.db_sender_scripts.add(sender)
|
||||
|
||||
#@sender.deleter
|
||||
def __senders_del(self):
|
||||
"Deleter. Clears all senders"
|
||||
self.db_sender_players.clear()
|
||||
self.db_sender_accounts.clear()
|
||||
self.db_sender_objects.clear()
|
||||
self.db_sender_scripts.clear()
|
||||
self.db_sender_external = ""
|
||||
|
|
@ -198,7 +198,7 @@ class Msg(SharedMemoryModel):
|
|||
Remove a single sender or a list of senders.
|
||||
|
||||
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):
|
||||
|
|
@ -212,19 +212,19 @@ class Msg(SharedMemoryModel):
|
|||
clsname = sender.__dbclass__.__name__
|
||||
if clsname == "ObjectDB":
|
||||
self.db_sender_objects.remove(sender)
|
||||
elif clsname == "PlayerDB":
|
||||
self.db_sender_players.remove(sender)
|
||||
elif clsname == "AccountDB":
|
||||
self.db_sender_accounts.remove(sender)
|
||||
elif clsname == "ScriptDB":
|
||||
self.db_sender_players.remove(sender)
|
||||
self.db_sender_accounts.remove(sender)
|
||||
|
||||
# receivers property
|
||||
#@property
|
||||
def __receivers_get(self):
|
||||
"""
|
||||
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_scripts.all()) + \
|
||||
list(self.db_receivers_channels.all())
|
||||
|
|
@ -243,8 +243,8 @@ class Msg(SharedMemoryModel):
|
|||
clsname = receiver.__dbclass__.__name__
|
||||
if clsname == "ObjectDB":
|
||||
self.db_receivers_objects.add(receiver)
|
||||
elif clsname == "PlayerDB":
|
||||
self.db_receivers_players.add(receiver)
|
||||
elif clsname == "AccountDB":
|
||||
self.db_receivers_accounts.add(receiver)
|
||||
elif clsname == "ScriptDB":
|
||||
self.db_receivers_scripts.add(receiver)
|
||||
elif clsname == "ChannelDB":
|
||||
|
|
@ -254,7 +254,7 @@ class Msg(SharedMemoryModel):
|
|||
#@receivers.deleter
|
||||
def __receivers_del(self):
|
||||
"Deleter. Clears all receivers"
|
||||
self.db_receivers_players.clear()
|
||||
self.db_receivers_accounts.clear()
|
||||
self.db_receivers_objects.clear()
|
||||
self.db_receivers_scripts.clear()
|
||||
self.db_receivers_channels.clear()
|
||||
|
|
@ -266,7 +266,7 @@ class Msg(SharedMemoryModel):
|
|||
Remove a single receiver or a list of receivers.
|
||||
|
||||
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):
|
||||
|
|
@ -277,8 +277,8 @@ class Msg(SharedMemoryModel):
|
|||
clsname = receiver.__dbclass__.__name__
|
||||
if clsname == "ObjectDB":
|
||||
self.db_receivers_objects.remove(receiver)
|
||||
elif clsname == "PlayerDB":
|
||||
self.db_receivers_players.remove(receiver)
|
||||
elif clsname == "AccountDB":
|
||||
self.db_receivers_accounts.remove(receiver)
|
||||
elif clsname == "ScriptDB":
|
||||
self.db_receivers_scripts.remove(receiver)
|
||||
elif clsname == "ChannelDB":
|
||||
|
|
@ -309,9 +309,9 @@ class Msg(SharedMemoryModel):
|
|||
def __hide_from_get(self):
|
||||
"""
|
||||
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
|
||||
def __hide_from_set(self, hiders):
|
||||
|
|
@ -322,8 +322,8 @@ class Msg(SharedMemoryModel):
|
|||
if not hasattr(hider, "__dbclass__"):
|
||||
raise ValueError("This is a not a typeclassed object!")
|
||||
clsname = hider.__dbclass__.__name__
|
||||
if clsname == "PlayerDB":
|
||||
self.db_hide_from_players.add(hider.__dbclass__)
|
||||
if clsname == "AccountDB":
|
||||
self.db_hide_from_accounts.add(hider.__dbclass__)
|
||||
elif clsname == "ObjectDB":
|
||||
self.db_hide_from_objects.add(hider.__dbclass__)
|
||||
elif clsname == "ChannelDB":
|
||||
|
|
@ -332,7 +332,7 @@ class Msg(SharedMemoryModel):
|
|||
#@hide_from_sender.deleter
|
||||
def __hide_from_del(self):
|
||||
"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_channels.clear()
|
||||
self.save()
|
||||
|
|
@ -353,7 +353,7 @@ class Msg(SharedMemoryModel):
|
|||
Checks lock access.
|
||||
|
||||
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.
|
||||
default (bool): Fallback to use if `access_type` lock is not defined.
|
||||
|
||||
|
|
@ -383,13 +383,13 @@ class TempMsg(object):
|
|||
|
||||
Args:
|
||||
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.
|
||||
message (str, optional): Message to send.
|
||||
header (str, optional): Header of message.
|
||||
type (str, optional): Message class, if any.
|
||||
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 []
|
||||
|
|
@ -419,7 +419,7 @@ class TempMsg(object):
|
|||
Remove a sender or a list of senders.
|
||||
|
||||
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):
|
||||
|
|
@ -433,7 +433,7 @@ class TempMsg(object):
|
|||
Remove a receiver or a list of receivers
|
||||
|
||||
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):
|
||||
|
|
@ -447,7 +447,7 @@ class TempMsg(object):
|
|||
Checks lock access.
|
||||
|
||||
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.
|
||||
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
|
||||
channel and hides away which type of entity is
|
||||
subscribing (Player or Object)
|
||||
subscribing (Account or Object)
|
||||
"""
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
|
|
@ -483,7 +483,7 @@ class SubscriptionHandler(object):
|
|||
self._cache = None
|
||||
|
||||
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()})
|
||||
|
||||
def has(self, entity):
|
||||
|
|
@ -491,12 +491,12 @@ class SubscriptionHandler(object):
|
|||
Check if the given entity subscribe to this channel
|
||||
|
||||
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
|
||||
of the entity.
|
||||
|
||||
Returns:
|
||||
subscriber (Player, Object or None): The given
|
||||
subscriber (Account, Object or None): The given
|
||||
subscriber.
|
||||
|
||||
"""
|
||||
|
|
@ -509,7 +509,7 @@ class SubscriptionHandler(object):
|
|||
Subscribe an entity to this channel.
|
||||
|
||||
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.
|
||||
|
||||
Note:
|
||||
|
|
@ -527,7 +527,7 @@ class SubscriptionHandler(object):
|
|||
# chooses the right type
|
||||
if clsname == "ObjectDB":
|
||||
self.obj.db_object_subscriptions.add(subscriber)
|
||||
elif clsname == "PlayerDB":
|
||||
elif clsname == "AccountDB":
|
||||
self.obj.db_subscriptions.add(subscriber)
|
||||
_CHANNELHANDLER.cached_cmdsets.pop(subscriber, None)
|
||||
self._recache()
|
||||
|
|
@ -537,7 +537,7 @@ class SubscriptionHandler(object):
|
|||
Remove a subscriber from the channel.
|
||||
|
||||
Args:
|
||||
entity (Player, Object or list): The entity or
|
||||
entity (Account, Object or list): The entity or
|
||||
entities to un-subscribe from the channel.
|
||||
|
||||
"""
|
||||
|
|
@ -548,7 +548,7 @@ class SubscriptionHandler(object):
|
|||
if subscriber:
|
||||
clsname = subscriber.__dbclass__.__name__
|
||||
# chooses the right type
|
||||
if clsname == "PlayerDB":
|
||||
if clsname == "AccountDB":
|
||||
self.obj.db_subscriptions.remove(entity)
|
||||
elif clsname == "ObjectDB":
|
||||
self.obj.db_object_subscriptions.remove(entity)
|
||||
|
|
@ -561,7 +561,7 @@ class SubscriptionHandler(object):
|
|||
|
||||
Returns:
|
||||
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:
|
||||
|
|
@ -570,17 +570,17 @@ class SubscriptionHandler(object):
|
|||
|
||||
def online(self):
|
||||
"""
|
||||
Get all online players from our cache
|
||||
Get all online accounts from our cache
|
||||
Returns:
|
||||
subscribers (list): Subscribers who are online or
|
||||
are puppeted by an online player.
|
||||
are puppeted by an online account.
|
||||
"""
|
||||
subs = []
|
||||
for obj in self.all():
|
||||
if hasattr(obj, 'player'):
|
||||
if not obj.player:
|
||||
if hasattr(obj, 'account'):
|
||||
if not obj.account:
|
||||
continue
|
||||
obj = obj.player
|
||||
obj = obj.account
|
||||
if not obj.is_connected:
|
||||
continue
|
||||
subs.append(obj)
|
||||
|
|
@ -604,7 +604,7 @@ class ChannelDB(TypedObject):
|
|||
The Channel class defines the following database fields
|
||||
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.
|
||||
- db_object_subscriptions: The Object subscriptions.
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ class CmdTradeBase(Command):
|
|||
if ':' in self.args:
|
||||
self.args, self.emote = [part.strip() for part in self.args.rsplit(":", 1)]
|
||||
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]'
|
||||
else:
|
||||
self.str_other = '%s says, "' % self.caller.key + self.emote + '"\n [%s]'
|
||||
|
|
@ -766,7 +766,7 @@ class CmdTrade(Command):
|
|||
if ':' in self.args:
|
||||
self.args, emote = [part.strip() for part in self.args.rsplit(":", 1)]
|
||||
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)
|
||||
else:
|
||||
theiremote = '%s says, "%s"\n ' % (self.caller.key, emote)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ necessary anymore - the ooclook and @charcreate commands in that mode
|
|||
replaces this module with better functionality. This remains here for
|
||||
inspiration.
|
||||
|
||||
This is a simple character creation commandset for the Player level.
|
||||
It shows some more info and gives the Player the option to create a
|
||||
This is a simple character creation commandset for the Account level.
|
||||
It shows some more info and gives the Account the option to create a
|
||||
character without any more customizations than their name (further
|
||||
options are unique for each game anyway).
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ cmdset.
|
|||
Installation:
|
||||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
@ -39,7 +39,7 @@ class CmdOOCLook(default_cmds.CmdLook):
|
|||
look
|
||||
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
|
||||
"self".
|
||||
|
||||
|
|
@ -56,24 +56,24 @@ class CmdOOCLook(default_cmds.CmdLook):
|
|||
"""
|
||||
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
|
||||
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,
|
||||
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
|
||||
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
|
||||
if hasattr(self.caller, "player"):
|
||||
self.caller = self.caller.player
|
||||
if hasattr(self.caller, "account"):
|
||||
self.caller = self.caller.account
|
||||
|
||||
if not self.character:
|
||||
# ooc mode, we are players
|
||||
# ooc mode, we are accounts
|
||||
|
||||
avail_chars = self.caller.db._character_dbrefs
|
||||
if self.args:
|
||||
|
|
@ -139,13 +139,13 @@ class CmdOOCCharacterCreate(Command):
|
|||
attribute on ourselves to remember it.
|
||||
"""
|
||||
|
||||
# making sure caller is really a player
|
||||
# making sure caller is really an account
|
||||
self.character = None
|
||||
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
|
||||
if hasattr(self.caller, "player"):
|
||||
self.caller = self.caller.player
|
||||
if hasattr(self.caller, "account"):
|
||||
self.caller = self.caller.account
|
||||
|
||||
if not self.args:
|
||||
self.caller.msg("Usage: create <character name>")
|
||||
|
|
@ -161,7 +161,7 @@ class CmdOOCCharacterCreate(Command):
|
|||
if not new_character:
|
||||
self.caller.msg("|rThe Character couldn't be created. This is a bug. Please contact an admin.")
|
||||
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.id, self.caller.id))
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ class CmdOOCCharacterCreate(Command):
|
|||
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.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from twisted.web.http_headers import Headers
|
|||
from twisted.web.iweb import IBodyProducer
|
||||
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.utils import get_evennia_version, logger
|
||||
|
||||
|
|
@ -97,8 +97,8 @@ class EvenniaGameIndexClient(object):
|
|||
'web_client_url': egi_config.get('web_client_url') or '',
|
||||
|
||||
# Game stats
|
||||
'connected_player_count': SESSIONS.player_count(),
|
||||
'total_player_count': PlayerDB.objects.num_total_players() or 0,
|
||||
'connected_account_count': SESSIONS.account_count(),
|
||||
'total_account_count': AccountDB.objects.num_total_accounts() or 0,
|
||||
|
||||
# System info
|
||||
'evennia_version': get_evennia_version(),
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ the module given by settings.CONNECTION_SCREEN_MODULE.
|
|||
"""
|
||||
import re
|
||||
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.server.models import ServerConfig
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ class CmdUnconnectedConnect(MuxCommand):
|
|||
have a unique position in that their `func()` receives
|
||||
a session object instead of a `source_object` like all
|
||||
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
|
||||
|
|
@ -90,22 +90,22 @@ class CmdUnconnectedConnect(MuxCommand):
|
|||
password = arglist[1]
|
||||
|
||||
# Match an email address to an account.
|
||||
player = PlayerDB.objects.get_player_from_email(email)
|
||||
# No playername match
|
||||
if not player:
|
||||
account = AccountDB.objects.get_account_from_email(email)
|
||||
# No accountname match
|
||||
if not account:
|
||||
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 += "using the 'create' command."
|
||||
session.msg(string)
|
||||
return
|
||||
# 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.")
|
||||
return
|
||||
|
||||
# Check IP and/or name 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])):
|
||||
# this is a banned IP or name!
|
||||
string = "|rYou have been banned and cannot continue from here."
|
||||
|
|
@ -115,7 +115,7 @@ class CmdUnconnectedConnect(MuxCommand):
|
|||
return
|
||||
|
||||
# actually do the login. This will call all hooks.
|
||||
session.sessionhandler.login(session, player)
|
||||
session.sessionhandler.login(session, account)
|
||||
|
||||
|
||||
class CmdUnconnectedCreate(MuxCommand):
|
||||
|
|
@ -123,9 +123,9 @@ class CmdUnconnectedCreate(MuxCommand):
|
|||
Create a new account.
|
||||
|
||||
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"
|
||||
|
|
@ -134,36 +134,36 @@ class CmdUnconnectedCreate(MuxCommand):
|
|||
|
||||
def parse(self):
|
||||
"""
|
||||
The parser must handle the multiple-word player
|
||||
The parser must handle the multiple-word account
|
||||
name enclosed in quotes:
|
||||
connect "Long name with many words" my@myserv.com mypassw
|
||||
"""
|
||||
super(CmdUnconnectedCreate, self).parse()
|
||||
|
||||
self.playerinfo = []
|
||||
self.accountinfo = []
|
||||
if len(self.arglist) < 3:
|
||||
return
|
||||
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()
|
||||
email = self.arglist.pop()
|
||||
# what remains is the playername.
|
||||
playername = " ".join(self.arglist)
|
||||
# what remains is the accountname.
|
||||
accountname = " ".join(self.arglist)
|
||||
else:
|
||||
playername, email, password = self.arglist
|
||||
accountname, email, password = self.arglist
|
||||
|
||||
playername = playername.replace('"', '') # remove "
|
||||
playername = playername.replace("'", "")
|
||||
self.playerinfo = (playername, email, password)
|
||||
accountname = accountname.replace('"', '') # remove "
|
||||
accountname = accountname.replace("'", "")
|
||||
self.accountinfo = (accountname, email, password)
|
||||
|
||||
def func(self):
|
||||
"""Do checks and create account"""
|
||||
|
||||
session = self.caller
|
||||
try:
|
||||
playername, email, password = self.playerinfo
|
||||
accountname, email, password = self.accountinfo
|
||||
except ValueError:
|
||||
string = "\n\r Usage (without <>): create \"<playername>\" <email> <password>"
|
||||
string = "\n\r Usage (without <>): create \"<accountname>\" <email> <password>"
|
||||
session.msg(string)
|
||||
return
|
||||
if not email or not password:
|
||||
|
|
@ -174,26 +174,26 @@ class CmdUnconnectedCreate(MuxCommand):
|
|||
session.msg("'%s' is not a valid e-mail address." % email)
|
||||
return
|
||||
# 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
|
||||
# module (except not allowing spaces, for convenience of
|
||||
# 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)
|
||||
return
|
||||
# strip excessive spaces in playername
|
||||
playername = re.sub(r"\s+", " ", playername).strip()
|
||||
if PlayerDB.objects.filter(username__iexact=playername):
|
||||
# player already exists (we also ignore capitalization here)
|
||||
session.msg("Sorry, there is already a player with the name '%s'." % playername)
|
||||
# strip excessive spaces in accountname
|
||||
accountname = re.sub(r"\s+", " ", accountname).strip()
|
||||
if AccountDB.objects.filter(username__iexact=accountname):
|
||||
# account already exists (we also ignore capitalization here)
|
||||
session.msg("Sorry, there is already an account with the name '%s'." % accountname)
|
||||
return
|
||||
if PlayerDB.objects.get_player_from_email(email):
|
||||
# email already set on a player
|
||||
session.msg("Sorry, there is already a player with that email address.")
|
||||
if AccountDB.objects.get_account_from_email(email):
|
||||
# email already set on an account
|
||||
session.msg("Sorry, there is already an account with that email address.")
|
||||
return
|
||||
# Reserve playernames found in GUEST_LIST
|
||||
if settings.GUEST_LIST and playername.lower() in (guest.lower() for guest in settings.GUEST_LIST):
|
||||
string = "\n\r That name is reserved. Please choose another Playername."
|
||||
# Reserve accountnames found in 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 Accountname."
|
||||
session.msg(string)
|
||||
return
|
||||
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
|
||||
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])):
|
||||
# this is a banned IP or name!
|
||||
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.
|
||||
try:
|
||||
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
new_player = default_unloggedin._create_player(session, playername, password, permissions, email=email)
|
||||
if new_player:
|
||||
new_account = default_unloggedin._create_account(session, accountname, password, permissions, email=email)
|
||||
if new_account:
|
||||
if MULTISESSION_MODE < 2:
|
||||
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.
|
||||
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>'."
|
||||
else:
|
||||
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:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
|
|
@ -243,7 +243,7 @@ class CmdUnconnectedCreate(MuxCommand):
|
|||
class CmdUnconnectedQuit(MuxCommand):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
key = "quit"
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class CallbackHandler(object):
|
|||
Args:
|
||||
callback_name (str): the name of the callback to add.
|
||||
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?
|
||||
parameters (str, optional): optional parameters.
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ class CallbackHandler(object):
|
|||
callback_name (str): the name of the callback to edit.
|
||||
number (int): the callback number to be changed.
|
||||
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?
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
on user permission.
|
||||
|
||||
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).
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ class EventHandler(DefaultScript):
|
|||
obj (Object): the Evennia typeclassed object to be extended.
|
||||
callback_name (str): the name of the callback to add.
|
||||
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?
|
||||
parameters (str, optional): optional parameters.
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ class EventHandler(DefaultScript):
|
|||
callback_name (str): the name of the callback to edit.
|
||||
number (int): the callback number to be changed.
|
||||
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?
|
||||
|
||||
Raises:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
arrives in the shop of a shopkeeper (assuming the shopkeeper is
|
||||
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:
|
||||
character: the character connected to this event.
|
||||
|
|
@ -100,9 +100,9 @@ Variables you can use in this event:
|
|||
"""
|
||||
|
||||
CHARACTER_PUPPETED = """
|
||||
When the character has been puppeted by a player.
|
||||
This event is called when a player has just puppeted this character.
|
||||
This can commonly happen when a player connects onto this character,
|
||||
When the character has been puppeted by an account.
|
||||
This event is called when an account has just puppeted this character.
|
||||
This can commonly happen when an account connects onto this character,
|
||||
or when puppeting to a NPC or free character.
|
||||
|
||||
Variables you can use in this event:
|
||||
|
|
@ -151,8 +151,8 @@ Variables you can use in this event:
|
|||
|
||||
CHARACTER_UNPUPPETED = """
|
||||
When the character is about to be un-puppeted.
|
||||
This event is called when a player is about to un-puppet the
|
||||
character, which can happen if the player is disconnecting or
|
||||
This event is called when an account is about to un-puppet the
|
||||
character, which can happen if the account is disconnecting or
|
||||
changing puppets.
|
||||
|
||||
Variables you can use in this event:
|
||||
|
|
@ -244,8 +244,8 @@ class EventCharacter(DefaultCharacter):
|
|||
|
||||
"""
|
||||
|
||||
if not source_location and self.location.has_player:
|
||||
# This was created from nowhere and added to a player's
|
||||
if not source_location and self.location.has_account:
|
||||
# This was created from nowhere and added to an account's
|
||||
# inventory; it's probably the result of a create command.
|
||||
string = "You now have %s in your possession." % self.get_display_name(self.location)
|
||||
self.location.msg(string)
|
||||
|
|
@ -357,11 +357,11 @@ class EventCharacter(DefaultCharacter):
|
|||
def at_post_puppet(self):
|
||||
"""
|
||||
Called just after puppeting has been completed and all
|
||||
Player<->Object links have been established.
|
||||
Account<->Object links have been established.
|
||||
|
||||
Note:
|
||||
You can use `self.player` and `self.sessions.get()` to get
|
||||
player and sessions at this point; the last entry in the
|
||||
You can use `self.account` and `self.sessions.get()` to get
|
||||
account and sessions at this point; the last entry in the
|
||||
list from `self.sessions.get()` is the latest Session
|
||||
puppeting this Object.
|
||||
|
||||
|
|
@ -378,11 +378,11 @@ class EventCharacter(DefaultCharacter):
|
|||
def at_pre_unpuppet(self):
|
||||
"""
|
||||
Called just before beginning to un-connect a puppeting from
|
||||
this Player.
|
||||
this Account.
|
||||
|
||||
Note:
|
||||
You can use `self.player` and `self.sessions.get()` to get
|
||||
player and sessions at this point; the last entry in the
|
||||
You can use `self.account` and `self.sessions.get()` to get
|
||||
account and sessions at this point; the last entry in the
|
||||
list from `self.sessions.get()` is the latest Session
|
||||
puppeting this Object.
|
||||
|
||||
|
|
@ -683,7 +683,7 @@ Variables you can use in this event:
|
|||
ROOM_PUPPETED_IN = """
|
||||
After the character has been puppeted in this room.
|
||||
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,
|
||||
if it's a room, will see this event fire.
|
||||
|
||||
|
|
@ -733,7 +733,7 @@ Variables you can use in this event:
|
|||
ROOM_UNPUPPETED_IN = """
|
||||
Before the character is un-puppeted in this room.
|
||||
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
|
||||
room, will see this event fire.
|
||||
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ class CmdExtendedLook(default_cmds.CmdLook):
|
|||
look
|
||||
look <obj>
|
||||
look <room detail>
|
||||
look *<player>
|
||||
look *<account>
|
||||
|
||||
Observes your location, details at your location or objects in your vicinity.
|
||||
"""
|
||||
|
|
@ -315,7 +315,7 @@ class CmdExtendedLook(default_cmds.CmdLook):
|
|||
return
|
||||
|
||||
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
|
||||
if not looking_at_obj.access(caller, "view"):
|
||||
caller.msg("Could not find '%s'." % args)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ A simple Brandymail style @mail system that uses the Msg class from Evennia Core
|
|||
|
||||
Installation:
|
||||
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
|
||||
from evennia import ObjectDB, PlayerDB
|
||||
from evennia import ObjectDB, AccountDB
|
||||
from evennia import default_cmds
|
||||
from evennia.utils import create, evtable, make_iter
|
||||
from evennia.comms.models import Msg
|
||||
|
|
@ -27,17 +27,17 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
Commands that allow either IC or OOC communications
|
||||
|
||||
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 <players>=<subject>/<message>
|
||||
- Sends a message to the comma separated list of players.
|
||||
@mail <accounts>=<subject>/<message>
|
||||
- Sends a message to the comma separated list of accounts.
|
||||
|
||||
@mail/delete <#> - Deletes a specific message
|
||||
|
||||
@mail/forward <player list>=<#>[/<Message>]
|
||||
- Forwards an existing message to the specified list of players,
|
||||
@mail/forward <account list>=<#>[/<Message>]
|
||||
- Forwards an existing message to the specified list of accounts,
|
||||
original message is delivered with optional Message prepended.
|
||||
|
||||
@mail/reply <#>=<message>
|
||||
|
|
@ -65,7 +65,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
Search a list of targets of the same type as caller.
|
||||
|
||||
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.
|
||||
|
||||
Returns:
|
||||
|
|
@ -73,10 +73,10 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
|
||||
"""
|
||||
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))
|
||||
else:
|
||||
matches = list(PlayerDB.objects.filter(username__iregex=nameregex))
|
||||
matches = list(AccountDB.objects.filter(username__iregex=nameregex))
|
||||
return matches
|
||||
|
||||
def get_all_mail(self):
|
||||
|
|
@ -89,10 +89,10 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
# mail_messages = Msg.objects.get_by_tag(category="mail")
|
||||
# messages = []
|
||||
try:
|
||||
player = self.caller.player
|
||||
account = self.caller.account
|
||||
except AttributeError:
|
||||
player = self.caller
|
||||
messages = Msg.objects.get_by_tag(category="mail").filter(db_receivers_players=player)
|
||||
account = self.caller
|
||||
messages = Msg.objects.get_by_tag(category="mail").filter(db_receivers_accounts=account)
|
||||
return messages
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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:
|
||||
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.")
|
||||
return
|
||||
else:
|
||||
caller.msg("No valid players found. Cannot send message.")
|
||||
caller.msg("No valid accounts found. Cannot send message.")
|
||||
return
|
||||
|
||||
def func(self):
|
||||
|
|
@ -142,7 +142,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
elif "forward" in self.switches:
|
||||
try:
|
||||
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
|
||||
elif not self.lhs:
|
||||
self.caller.msg("You must define a message to forward.")
|
||||
|
|
@ -176,7 +176,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
except IndexError:
|
||||
self.caller.msg("Message does not exixt.")
|
||||
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:
|
||||
try:
|
||||
if not self.rhs:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ called and so on until the map is completed. Building instructions are passed
|
|||
the following arguments:
|
||||
x - The rooms position on the maps x 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)
|
||||
room_dict - A dictionary containing room references returned by build
|
||||
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.db.desc = "Basic forest room."
|
||||
|
||||
# Send a message to the player
|
||||
# Send a message to the account
|
||||
kwargs["caller"].msg(room.key + " " + room.dbref)
|
||||
|
||||
# This is generally mandatory.
|
||||
|
|
@ -143,7 +143,7 @@ def example1_build_mountains(x, y, **kwargs):
|
|||
rock = create_object(key="Rock", location=room)
|
||||
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)
|
||||
|
||||
# This is generally mandatory.
|
||||
|
|
@ -167,7 +167,7 @@ def example1_build_temple(x, y, **kwargs):
|
|||
"keeping the sound level only just below thunderous. "
|
||||
"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)
|
||||
|
||||
# This is generally mandatory.
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ CMDSET_UNLOGGEDIN = "contrib.menu_login.UnloggedinCmdSet"
|
|||
When you'll reload the server, new sessions will connect to the new
|
||||
login system, where they will be able to:
|
||||
|
||||
* Enter their username, assuming they have an existing player.
|
||||
* Enter 'NEW' to create a new player.
|
||||
* Enter their username, assuming they have an existing account.
|
||||
* Enter 'NEW' to create a new account.
|
||||
|
||||
The top-level functions in this file are menu nodes (as described in
|
||||
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
|
||||
down the menu tree. From there, users can either enter a
|
||||
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)
|
||||
|
|
@ -79,7 +79,7 @@ def start(caller):
|
|||
|
||||
|
||||
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
|
||||
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()
|
||||
player = managers.players.get_player_from_name(string_input)
|
||||
if player is None:
|
||||
account = managers.accounts.get_account_from_name(string_input)
|
||||
if account is None:
|
||||
text = dedent("""
|
||||
|rThe username '{}' doesn't exist. Have you created it?|n
|
||||
Try another name or leave empty to go back.
|
||||
|
|
@ -100,8 +100,8 @@ def username(caller, string_input):
|
|||
{"key": "_default",
|
||||
"goto": "username"})
|
||||
else:
|
||||
caller.ndb._menutree.player = player
|
||||
text = "Enter the password for the {} account.".format(player.name)
|
||||
caller.ndb._menutree.account = account
|
||||
text = "Enter the password for the {} account.".format(account.name)
|
||||
# Disables echo for the password
|
||||
caller.msg("", options={"echo": False})
|
||||
options = (
|
||||
|
|
@ -115,7 +115,7 @@ def username(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
|
||||
'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
|
||||
|
||||
player = menutree.player
|
||||
account = menutree.account
|
||||
password_attempts = menutree.password_attempts \
|
||||
if hasattr(menutree, "password_attempts") else 0
|
||||
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]))
|
||||
|
||||
if not player.check_password(string_input):
|
||||
if not account.check_password(string_input):
|
||||
# Didn't enter a correct password
|
||||
password_attempts += 1
|
||||
if password_attempts > 2:
|
||||
|
|
@ -173,7 +173,7 @@ def ask_password(caller, string_input):
|
|||
text = ""
|
||||
options = {}
|
||||
caller.msg("", options={"echo": True})
|
||||
caller.sessionhandler.login(caller, player)
|
||||
caller.sessionhandler.login(caller, account)
|
||||
|
||||
return text, options
|
||||
|
||||
|
|
@ -201,10 +201,10 @@ def create_username(caller, string_input):
|
|||
"""
|
||||
menutree = caller.ndb._menutree
|
||||
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 player:
|
||||
# If an account with that name exists, a new one will not be created
|
||||
if account:
|
||||
text = dedent("""
|
||||
|rThe account {} already exists.|n
|
||||
Enter another username or leave blank to go back.
|
||||
|
|
@ -229,7 +229,7 @@ def create_username(caller, string_input):
|
|||
"goto": "create_username"})
|
||||
else:
|
||||
# a valid username - continue getting the password
|
||||
menutree.playername = string_input
|
||||
menutree.accountname = string_input
|
||||
# Disables echo for entering password
|
||||
caller.msg("", options={"echo": False})
|
||||
# Redirects to the creation of a password
|
||||
|
|
@ -259,7 +259,7 @@ def create_password(caller, string_input):
|
|||
"goto": "create_password"})
|
||||
|
||||
password = string_input.strip()
|
||||
playername = menutree.playername
|
||||
accountname = menutree.accountname
|
||||
|
||||
if len(password) < LEN_PASSWD:
|
||||
# The password is too short
|
||||
|
|
@ -273,15 +273,15 @@ def create_password(caller, string_input):
|
|||
from evennia.commands.default import unloggedin
|
||||
# We make use of the helper functions from the default set here.
|
||||
try:
|
||||
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
new_player = unloggedin._create_player(caller, playername,
|
||||
new_account = unloggedin._create_account(caller, accountname,
|
||||
password, permissions)
|
||||
if new_player:
|
||||
if new_account:
|
||||
if settings.MULTISESSION_MODE < 2:
|
||||
default_home = ObjectDB.objects.get_id(
|
||||
settings.DEFAULT_HOME)
|
||||
unloggedin._create_character(caller, new_player,
|
||||
unloggedin._create_character(caller, new_account,
|
||||
typeclass, default_home, permissions)
|
||||
except Exception:
|
||||
# We are in the middle between logged in and -not, so we have
|
||||
|
|
@ -297,7 +297,7 @@ def create_password(caller, string_input):
|
|||
text = ""
|
||||
caller.msg("|gWelcome, your new account has been created!|n")
|
||||
caller.msg("", options={"echo": True})
|
||||
caller.sessionhandler.login(caller, new_player)
|
||||
caller.sessionhandler.login(caller, new_account)
|
||||
|
||||
return text, options
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ class UnloggedinCmdSet(CmdSet):
|
|||
class CmdUnloggedinLook(Command):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
key = syscmdkeys.CMD_LOGINSTART
|
||||
|
|
|
|||
|
|
@ -1210,7 +1210,7 @@ class ContribRPObject(DefaultObject):
|
|||
otherwise it will return a list of 0, 1 or more matches.
|
||||
|
||||
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
|
||||
`settings.SEARCH_AT_RESULT` and echoed automatically (on
|
||||
error, return will be `None`). If `quiet=True`, the error
|
||||
|
|
@ -1228,7 +1228,7 @@ class ContribRPObject(DefaultObject):
|
|||
|
||||
if use_nicks:
|
||||
# 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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Kwargs:
|
||||
|
|
@ -1342,7 +1342,7 @@ class ContribRPObject(DefaultObject):
|
|||
key = con.get_display_name(looker, pose=True)
|
||||
if con.destination:
|
||||
exits.append(key)
|
||||
elif con.has_player:
|
||||
elif con.has_account:
|
||||
users.append(key)
|
||||
else:
|
||||
things.append(key)
|
||||
|
|
@ -1383,7 +1383,7 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
|
|||
Displays the name of the object in a viewer-aware manner.
|
||||
|
||||
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.
|
||||
|
||||
Kwargs:
|
||||
|
|
|
|||
|
|
@ -395,13 +395,13 @@ class TestWilderness(EvenniaTest):
|
|||
# Pretend that both char1 and char2 are connected...
|
||||
self.char1.sessions.add(1)
|
||||
self.char2.sessions.add(1)
|
||||
self.assertTrue(self.char1.has_player)
|
||||
self.assertTrue(self.char2.has_player)
|
||||
self.assertTrue(self.char1.has_account)
|
||||
self.assertTrue(self.char2.has_account)
|
||||
|
||||
wilderness.create_wilderness()
|
||||
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)
|
||||
w.move_obj(self.char1, (0, 0))
|
||||
self.assertEquals(len(w.db.unused_rooms), 0)
|
||||
|
|
@ -442,15 +442,15 @@ from evennia.contrib import chargen
|
|||
class TestChargen(CommandTest):
|
||||
|
||||
def test_ooclook(self):
|
||||
self.call(chargen.CmdOOCLook(), "foo", "You have no characters to look at", caller=self.player)
|
||||
self.call(chargen.CmdOOCLook(), "", "You, TestPlayer, are an OOC ghost without form.", caller=self.player)
|
||||
self.call(chargen.CmdOOCLook(), "foo", "You have no characters to look at", caller=self.account)
|
||||
self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.", caller=self.account)
|
||||
|
||||
def test_charcreate(self):
|
||||
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "The character testchar was successfully created!", caller=self.player)
|
||||
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "Character testchar already exists.", caller=self.player)
|
||||
self.assertTrue(self.player.db._character_dbrefs)
|
||||
self.call(chargen.CmdOOCLook(), "", "You, TestPlayer, are an OOC ghost without form.",caller=self.player)
|
||||
self.call(chargen.CmdOOCLook(), "testchar", "testchar(", 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.account)
|
||||
self.assertTrue(self.account.db._character_dbrefs)
|
||||
self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.",caller=self.account)
|
||||
self.call(chargen.CmdOOCLook(), "testchar", "testchar(", caller=self.account)
|
||||
|
||||
# Testing clothing contrib
|
||||
from evennia.contrib import clothing
|
||||
|
|
@ -600,9 +600,9 @@ class TestEmailLogin(CommandTest):
|
|||
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.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):
|
||||
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):
|
||||
self.call(email_login.CmdUnconnectedLook(), "", "==========")
|
||||
def test_unconnectedhelp(self):
|
||||
|
|
@ -628,19 +628,19 @@ from evennia.contrib import mail
|
|||
|
||||
class TestMail(CommandTest):
|
||||
def test_mail(self):
|
||||
self.call(mail.CmdMail(), "2", "'2' is not a valid mail id.", caller=self.player)
|
||||
self.call(mail.CmdMail(), "", "There are no messages in your inbox.", 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.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 2", "You sent your message.", caller=self.char2)
|
||||
self.call(mail.CmdMail(), "TestPlayer2=Message 2",
|
||||
"You have received a new @mail from TestPlayer2(player 2)|You sent your message.", caller=self.player2)
|
||||
self.call(mail.CmdMail(), "TestPlayer=Message 1", "You sent your message.", caller=self.player2)
|
||||
self.call(mail.CmdMail(), "TestPlayer=Message 2", "You sent your message.", caller=self.player2)
|
||||
self.call(mail.CmdMail(), "", "| ID: From: Subject:", caller=self.player)
|
||||
self.call(mail.CmdMail(), "2", "From: TestPlayer2", caller=self.player)
|
||||
self.call(mail.CmdMail(), "/forward TestPlayer2 = 1/Forward message", "You sent your message.|Message forwarded.", caller=self.player)
|
||||
self.call(mail.CmdMail(), "/reply 2=Reply Message2", "You sent your message.", caller=self.player)
|
||||
self.call(mail.CmdMail(), "/delete 2", "Message 2 deleted", caller=self.player)
|
||||
self.call(mail.CmdMail(), "TestAccount2=Message 2",
|
||||
"You have received a new @mail from TestAccount2(account 2)|You sent your message.", caller=self.account2)
|
||||
self.call(mail.CmdMail(), "TestAccount=Message 1", "You sent your message.", caller=self.account2)
|
||||
self.call(mail.CmdMail(), "TestAccount=Message 2", "You sent your message.", caller=self.account2)
|
||||
self.call(mail.CmdMail(), "", "| ID: From: Subject:", caller=self.account)
|
||||
self.call(mail.CmdMail(), "2", "From: TestAccount2", caller=self.account)
|
||||
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.account)
|
||||
self.call(mail.CmdMail(), "/delete 2", "Message 2 deleted", caller=self.account)
|
||||
|
||||
# test map builder contrib
|
||||
|
||||
|
|
|
|||
|
|
@ -297,17 +297,17 @@ class LidOpenCmdSet(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.
|
||||
"""
|
||||
key = "BlindCmdSet"
|
||||
# we want it to completely replace all normal commands
|
||||
# until the timed script removes it again.
|
||||
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.
|
||||
# (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
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
|
|
|
|||
|
|
@ -100,17 +100,17 @@ class BlindedState(DefaultScript):
|
|||
"""
|
||||
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
|
||||
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):
|
||||
"""
|
||||
We set up the script here.
|
||||
"""
|
||||
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.start_delay = True # we don't want it to stop until after 20s.
|
||||
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
|
||||
replace the other cmdsets on the stack while it is active
|
||||
(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
|
||||
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
|
||||
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
|
||||
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*.
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
|
|
@ -250,7 +250,7 @@ class DeactivateButtonEvent(DefaultScript):
|
|||
"""
|
||||
# closing the lid will also add the ClosedState script
|
||||
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.
|
||||
self.obj.db.lid_locked = True
|
||||
# breaking the lamp also sets a correct desc
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ class Mob(tut_objects.TutorialObject):
|
|||
|
||||
"""
|
||||
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
|
||||
|
||||
def set_alive(self, *args, **kwargs):
|
||||
|
|
@ -290,9 +290,9 @@ class Mob(tut_objects.TutorialObject):
|
|||
"""
|
||||
Called repeatedly during patrolling mode. In this mode, the
|
||||
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
|
||||
allowing player-controlled characters to move normally.
|
||||
allowing account-controlled characters to move normally.
|
||||
"""
|
||||
if random.random() < 0.01 and self.db.irregular_msgs:
|
||||
self.location.msg_contents(random.choice(self.db.irregular_msgs))
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
|
|||
The CrumblingWall can be examined in various ways, but only if a
|
||||
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
|
||||
certain attribute is set on the trying player.
|
||||
certain attribute is set on the trying account.
|
||||
|
||||
Important attribute
|
||||
destination - this property must be set to make this a valid exit
|
||||
|
|
@ -701,7 +701,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
|
|||
self.reset()
|
||||
|
||||
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)
|
||||
|
||||
def reset(self):
|
||||
|
|
@ -868,7 +868,7 @@ class Weapon(TutorialObject):
|
|||
When reset, the weapon is simply deleted, unless it has a place
|
||||
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.key)
|
||||
self.delete()
|
||||
|
|
@ -1032,7 +1032,7 @@ class WeaponRack(TutorialObject):
|
|||
Attributes to set on this object:
|
||||
available_weapons: list of prototype-keys from
|
||||
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
|
||||
grab another one.
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class CmdTutorialLook(default_cmds.CmdLook):
|
|||
Usage:
|
||||
look <obj>
|
||||
look <room detail>
|
||||
look *<player>
|
||||
look *<account>
|
||||
|
||||
Observes your location, details at your location or objects
|
||||
in your vicinity.
|
||||
|
|
@ -182,7 +182,7 @@ class CmdTutorialLook(default_cmds.CmdLook):
|
|||
return
|
||||
|
||||
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
|
||||
if not looking_at_obj.access(caller, "view"):
|
||||
caller.msg("Could not find '%s'." % args)
|
||||
|
|
@ -232,7 +232,7 @@ class TutorialRoom(DefaultRoom):
|
|||
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
|
||||
for obj in self.contents_get(exclude=new_arrival):
|
||||
if hasattr(obj, "at_new_arrival"):
|
||||
|
|
@ -362,7 +362,7 @@ class IntroRoom(TutorialRoom):
|
|||
super(IntroRoom, self).at_object_creation()
|
||||
self.db.tutorial_info = "The first room of the tutorial. " \
|
||||
"This assigns the health Attribute to "\
|
||||
"the player."
|
||||
"the account."
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
"""
|
||||
|
|
@ -372,7 +372,7 @@ class IntroRoom(TutorialRoom):
|
|||
# setup character for the tutorial
|
||||
health = self.db.char_health or 20
|
||||
|
||||
if character.has_player:
|
||||
if character.has_account:
|
||||
character.db.health = 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
|
||||
# several steps to cross. It is complete with custom commands and a
|
||||
# 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.
|
||||
#
|
||||
# Since one can enter the bridge room from both ends, it is
|
||||
|
|
@ -537,7 +537,7 @@ class CmdLookBridge(Command):
|
|||
BRIDGE_POS_MESSAGES[bridge_position],
|
||||
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:
|
||||
# we create the You see: message manually here
|
||||
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
|
||||
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
|
||||
will take several steps to cross it, despite it being represented
|
||||
by only a single room.
|
||||
|
|
@ -659,7 +659,7 @@ class BridgeRoom(WeatherRoom):
|
|||
This hook is called by the engine whenever the player is moved
|
||||
into this room.
|
||||
"""
|
||||
if character.has_player:
|
||||
if character.has_account:
|
||||
# we only run this if the entered object is indeed a player object.
|
||||
# check so our east/west exits are correctly defined.
|
||||
wexit = search_object(self.db.west_exit)
|
||||
|
|
@ -682,7 +682,7 @@ class BridgeRoom(WeatherRoom):
|
|||
"""
|
||||
This is triggered when the player leaves the bridge room.
|
||||
"""
|
||||
if character.has_player:
|
||||
if character.has_account:
|
||||
# clean up the position attribute
|
||||
del character.db.tutorial_bridge_position
|
||||
|
||||
|
|
@ -876,7 +876,7 @@ class DarkRoom(TutorialRoom):
|
|||
self.locks.add("view:all()")
|
||||
self.cmdset.remove(DarkCmdSet)
|
||||
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
|
||||
char.msg("The room is lit up.")
|
||||
else:
|
||||
|
|
@ -884,7 +884,7 @@ class DarkRoom(TutorialRoom):
|
|||
self.db.is_lit = False
|
||||
self.locks.add("view:false()")
|
||||
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:
|
||||
char.msg("You are Superuser, so you are not affected by the dark state.")
|
||||
else:
|
||||
|
|
@ -895,7 +895,7 @@ class DarkRoom(TutorialRoom):
|
|||
"""
|
||||
Called when an object enters the room.
|
||||
"""
|
||||
if obj.has_player:
|
||||
if obj.has_account:
|
||||
# a puppeted object, that is, a Character
|
||||
self._heal(obj)
|
||||
# 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 room.
|
||||
"""
|
||||
if not character.has_player:
|
||||
if not character.has_account:
|
||||
# only act on player characters.
|
||||
return
|
||||
# determine if the puzzle is a success or not
|
||||
|
|
@ -1020,7 +1020,7 @@ class OutroRoom(TutorialRoom):
|
|||
"""
|
||||
Do cleanup.
|
||||
"""
|
||||
if character.has_player:
|
||||
if character.has_account:
|
||||
del character.db.health_max
|
||||
del character.db.health
|
||||
del character.db.last_climbed
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ class WildernessScript(DefaultScript):
|
|||
old_room.wilderness.at_after_object_leave(obj)
|
||||
else:
|
||||
for item in old_room.contents:
|
||||
if item.has_player:
|
||||
if item.has_account:
|
||||
# There is still a player in the old room.
|
||||
# Let's create a new room and not touch that old
|
||||
# room.
|
||||
|
|
@ -419,7 +419,7 @@ class WildernessScript(DefaultScript):
|
|||
return
|
||||
|
||||
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
|
||||
# it just yet
|
||||
break
|
||||
|
|
@ -457,7 +457,7 @@ class WildernessScript(DefaultScript):
|
|||
class WildernessRoom(DefaultRoom):
|
||||
"""
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
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.rhslist = rhslist
|
||||
#
|
||||
# # if the class has the player_caller property set on itself, we make
|
||||
# # sure that self.caller is always the player if possible. We also create
|
||||
# # if the class has the account_caller property set on itself, we make
|
||||
# # sure that self.caller is always the account if possible. We also create
|
||||
# # a special property "character" for the puppeted object, if any. This
|
||||
# # is convenient for commands defined on the Player only.
|
||||
# if hasattr(self, "player_caller") and self.player_caller:
|
||||
# # is convenient for commands defined on the Account only.
|
||||
# if hasattr(self, "account_caller") and self.account_caller:
|
||||
# if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
||||
# # caller is an Object/Character
|
||||
# self.character = self.caller
|
||||
# self.caller = self.caller.player
|
||||
# elif utils.inherits_from(self.caller, "evennia.players.players.DefaultPlayer"):
|
||||
# # caller was already a Player
|
||||
# self.caller = self.caller.account
|
||||
# elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
||||
# # caller was already an Account
|
||||
# self.character = self.caller.get_puppet(self.session)
|
||||
# else:
|
||||
# self.character = None
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
|||
"""
|
||||
The `CharacterCmdSet` contains general in-game commands like `look`,
|
||||
`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"
|
||||
|
||||
|
|
@ -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
|
||||
combined with the `CharacterCmdSet` when the Player puppets a
|
||||
This is the cmdset available to the Account at all times. It is
|
||||
combined with the `CharacterCmdSet` when the Account puppets a
|
||||
Character. It holds game-account-specific commands, channel
|
||||
commands, etc.
|
||||
"""
|
||||
key = "DefaultPlayer"
|
||||
key = "DefaultAccount"
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""
|
||||
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.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
connection to the game. So a user logged into the game with 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.
|
||||
|
||||
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
|
||||
individual protocols to communicate with Evennia.
|
||||
|
||||
Each player gets one or more sessions assigned to them whenever they connect
|
||||
to the game server. All communication between game and player goes
|
||||
Each account gets one or more sessions assigned to them whenever they connect
|
||||
to the game server. All communication between game and account goes
|
||||
through their session(s).
|
||||
"""
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Channel
|
||||
|
||||
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
|
||||
distribution systems.
|
||||
|
||||
|
|
@ -18,9 +18,9 @@ class Channel(DefaultChannel):
|
|||
"""
|
||||
Working methods:
|
||||
at_channel_creation() - called once, when the channel is created
|
||||
has_connection(player) - check if the given player listens to this channel
|
||||
connect(player) - connect player to this channel
|
||||
disconnect(player) - disconnect player from channel
|
||||
has_connection(account) - check if the given account listens to this channel
|
||||
connect(account) - connect account to this channel
|
||||
disconnect(account) - disconnect account from channel
|
||||
access(access_obj, access_type='listen', default=False) - check the
|
||||
access on this channel (default access_type is listen)
|
||||
delete() - delete this channel
|
||||
|
|
@ -33,8 +33,8 @@ class Channel(DefaultChannel):
|
|||
tempmsg(msg, header=None, senders=None) - wrapper for sending non-persistent
|
||||
messages.
|
||||
distribute_message(msg, online=False) - send a message to all
|
||||
connected players on channel, optionally sending only
|
||||
to players that are currently online (optimized for very large sends)
|
||||
connected accounts on channel, optionally sending only
|
||||
to accounts that are currently online (optimized for very large sends)
|
||||
|
||||
Useful hooks:
|
||||
channel_prefix(msg, emit=False) - how the channel should be
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
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
|
||||
is setup to be the "default" character type created by the default
|
||||
creation commands.
|
||||
|
|
@ -19,14 +19,14 @@ class Character(DefaultCharacter):
|
|||
and its commands only be called by itself, not anyone else.
|
||||
(to change things, use at_object_creation() instead).
|
||||
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
|
||||
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.
|
||||
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.
|
||||
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
|
||||
|
|
|
|||
|
|
@ -40,16 +40,16 @@ class Object(DefaultObject):
|
|||
date_created (string) - time stamp of object creation
|
||||
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 (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.
|
||||
location (Object) - current location. Is None if this is a room
|
||||
home (Object) - safety start-location
|
||||
sessions (list of Sessions, read-only) - returns all sessions connected
|
||||
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
|
||||
object (including exits)
|
||||
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)
|
||||
|
||||
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)
|
||||
msg(text=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
|
||||
not normally used unless the cmdset is created
|
||||
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
|
||||
at_post_puppet() - (player-controlled objects only) called just
|
||||
after completing connection player<->object
|
||||
at_pre_unpuppet() - (player-controlled objects only) called just
|
||||
at_post_puppet() - (account-controlled objects only) called just
|
||||
after completing connection account<->object
|
||||
at_pre_unpuppet() - (account-controlled objects only) called just
|
||||
before un-puppeting
|
||||
at_post_unpuppet(player) - (player-controlled objects only) called just
|
||||
after disconnecting player<->object link
|
||||
at_post_unpuppet(account) - (account-controlled objects only) called just
|
||||
after disconnecting account<->object link
|
||||
at_server_reload() - called before server is reloaded
|
||||
at_server_shutdown() - called just before server is fully shut down
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -28,38 +28,38 @@ MUX Name: Affects: Effect:
|
|||
DefaultLock: Exits: controls who may traverse the exit to
|
||||
its destination.
|
||||
Evennia: "traverse:<lockfunc()>"
|
||||
Rooms: controls whether the player sees the
|
||||
Rooms: controls whether the account sees the
|
||||
SUCC or FAIL message for the room
|
||||
following the room description when
|
||||
looking at the room.
|
||||
Evennia: Custom typeclass
|
||||
Players/Things: controls who may GET the object.
|
||||
Accounts/Things: controls who may GET the object.
|
||||
Evennia: "get:<lockfunc()"
|
||||
EnterLock: Players/Things: controls who may ENTER the object
|
||||
EnterLock: Accounts/Things: controls who may ENTER the object
|
||||
Evennia:
|
||||
GetFromLock: All but Exits: controls who may gets things from a
|
||||
given location.
|
||||
Evennia:
|
||||
GiveLock: Players/Things: controls who may give the object.
|
||||
GiveLock: Accounts/Things: controls who may give the object.
|
||||
Evennia:
|
||||
LeaveLock: Players/Things: controls who may LEAVE the object.
|
||||
LeaveLock: Accounts/Things: controls who may LEAVE the object.
|
||||
Evennia:
|
||||
LinkLock: All but Exits: controls who may link to the location
|
||||
if the location is LINK_OK (for linking
|
||||
exits or setting drop-tos) or ABODE (for
|
||||
setting homes)
|
||||
Evennia:
|
||||
MailLock: Players: controls who may @mail the player.
|
||||
MailLock: Accounts: controls who may @mail the account.
|
||||
Evennia:
|
||||
OpenLock: All but Exits: controls who may open an exit.
|
||||
Evennia:
|
||||
PageLock: Players: controls who may page the player.
|
||||
PageLock: Accounts: controls who may page the account.
|
||||
Evennia: "send:<lockfunc()>"
|
||||
ParentLock: All: controls who may make @parent links to
|
||||
the object.
|
||||
Evennia: Typeclasses and
|
||||
"puppet:<lockstring()>"
|
||||
ReceiveLock: Players/Things: controls who may give things to the
|
||||
ReceiveLock: Accounts/Things: controls who may give things to the
|
||||
object.
|
||||
Evennia:
|
||||
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]
|
||||
|
||||
|
||||
def _to_player(accessing_obj):
|
||||
"Helper function. Makes sure an accessing object is a player object"
|
||||
def _to_account(accessing_obj):
|
||||
"Helper function. Makes sure an accessing object is an account object"
|
||||
if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject"):
|
||||
# an object. Convert to player.
|
||||
accessing_obj = accessing_obj.player
|
||||
# an object. Convert to account.
|
||||
accessing_obj = accessing_obj.account
|
||||
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,
|
||||
permission is also granted to all ranks higher up in the hierarchy.
|
||||
|
||||
If accessing_object is an Object controlled by a Player, the
|
||||
permissions of the Player is used unless the Attribute _quell
|
||||
If accessing_object is an Object controlled by an Account, the
|
||||
permissions of the Account is used unless the Attribute _quell
|
||||
is set to True on the Object. In this case however, the
|
||||
LOWEST hieararcy-permission of the Player/Object-pair will be used
|
||||
(this is order to avoid Players potentially escalating their own permissions
|
||||
LOWEST hieararcy-permission of the Account/Object-pair will be used
|
||||
(this is order to avoid Accounts potentially escalating their own permissions
|
||||
by use of a higher-level Object)
|
||||
|
||||
"""
|
||||
|
|
@ -166,30 +166,30 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
except (AttributeError, IndexError):
|
||||
return False
|
||||
|
||||
if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and accessing_obj.player:
|
||||
player = accessing_obj.player
|
||||
if utils.inherits_from(accessing_obj, "evennia.objects.objects.DefaultObject") and accessing_obj.account:
|
||||
account = accessing_obj.account
|
||||
# we strip eventual plural forms, so Builders == Builder
|
||||
perms_player = [p.lower().rstrip("s") for p in player.permissions.all()]
|
||||
is_quell = player.attributes.get("_quell")
|
||||
perms_account = [p.lower().rstrip("s") for p in account.permissions.all()]
|
||||
is_quell = account.attributes.get("_quell")
|
||||
|
||||
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_player = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_player]
|
||||
hpos_player = hpos_player and hpos_player[-1] or -1
|
||||
hpos_account = [hpos for hpos, hperm in enumerate(_PERMISSION_HIERARCHY) if hperm in perms_account]
|
||||
hpos_account = hpos_account and hpos_account[-1] or -1
|
||||
if is_quell:
|
||||
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
|
||||
if gtmode:
|
||||
return hpos_target < min(hpos_player, hpos_object)
|
||||
return hpos_target < min(hpos_account, hpos_object)
|
||||
else:
|
||||
return hpos_target <= min(hpos_player, hpos_object)
|
||||
return hpos_target <= min(hpos_account, hpos_object)
|
||||
elif gtmode:
|
||||
return hpos_target < hpos_player
|
||||
return hpos_target < hpos_account
|
||||
else:
|
||||
return hpos_target <= hpos_player
|
||||
elif not is_quell and permission in perms_player:
|
||||
# if we get here, check player perms first, otherwise
|
||||
return hpos_target <= hpos_account
|
||||
elif not is_quell and permission in perms_account:
|
||||
# if we get here, check account perms first, otherwise
|
||||
# continue as normal
|
||||
return True
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ def perm_above(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:
|
||||
pperm(<permission>)
|
||||
|
|
@ -227,17 +227,17 @@ def pperm(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
is part of _PERMISSION_HIERARCHY, permission is also granted
|
||||
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):
|
||||
"""
|
||||
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,
|
||||
it's assumed we refer to superuser. If no hierarchy is defined,
|
||||
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):
|
||||
|
|
@ -263,9 +263,9 @@ def dbref(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):
|
||||
|
|
@ -274,8 +274,8 @@ def id(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
|
||||
|
||||
def pid(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"Alias to dbref, for Players"
|
||||
return dbref(_to_player(accessing_obj), accessed_obj, *args, **kwargs)
|
||||
"Alias to dbref, for Accounts"
|
||||
return dbref(_to_account(accessing_obj), accessed_obj, *args, **kwargs)
|
||||
|
||||
|
||||
# this is more efficient than multiple if ... elif statments
|
||||
|
|
@ -566,15 +566,15 @@ def superuser(*args, **kwargs):
|
|||
"""
|
||||
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,
|
||||
this is a player-controlled object. It fails on actual players!
|
||||
Only returns true if accessing_obj has_account is true, that is,
|
||||
this is an account-controlled object. It fails on actual accounts!
|
||||
|
||||
This is a useful lock for traverse-locking Exits to restrain NPC
|
||||
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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -271,10 +271,10 @@ class LockHandler(object):
|
|||
def cache_lock_bypass(self, obj):
|
||||
"""
|
||||
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
|
||||
directly on the object (players), through obj.player and using
|
||||
the get_player() method (this sits on serversessions, in some
|
||||
directly on the object (accounts), through obj.account and using
|
||||
the get_account() method (this sits on serversessions, in some
|
||||
rare cases where a check is done before the login process has
|
||||
yet been fully finalized)
|
||||
|
||||
|
|
@ -450,8 +450,8 @@ class LockHandler(object):
|
|||
except AttributeError:
|
||||
# happens before session is initiated.
|
||||
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, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_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_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
|
||||
return True
|
||||
|
||||
# no superuser or bypass -> normal lock operation
|
||||
|
|
@ -511,8 +511,8 @@ class LockHandler(object):
|
|||
return True
|
||||
except AttributeError:
|
||||
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, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_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_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
|
||||
return True
|
||||
if not ":" in lockstring:
|
||||
lockstring = "%s:%s" % ("_dummy", lockstring)
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ class ObjectDBAdmin(admin.ModelAdmin):
|
|||
"""
|
||||
|
||||
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')
|
||||
ordering = ['db_player', 'db_typeclass_path', 'id']
|
||||
ordering = ['db_account', 'db_typeclass_path', 'id']
|
||||
search_fields = ['^db_key', 'db_typeclass_path']
|
||||
raw_id_fields = ('db_destination', 'db_location', 'db_home')
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class ObjectDBManager(TypedObjectManager):
|
|||
get_dbref_range
|
||||
object_totals
|
||||
typeclass_search
|
||||
get_object_with_player
|
||||
get_object_with_account
|
||||
get_objs_with_key_and_typeclass
|
||||
get_objs_with_attr
|
||||
get_objs_with_attr_match
|
||||
|
|
@ -53,18 +53,18 @@ class ObjectDBManager(TypedObjectManager):
|
|||
# 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:
|
||||
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
|
||||
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
|
||||
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)
|
||||
if obj]) or Q()
|
||||
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
|
||||
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)
|
||||
if candidates:
|
||||
index_matches = string_partial_matching(ply_cands, ostring, ret_index=True)
|
||||
|
|
@ -503,7 +503,7 @@ class ObjectDBManager(TypedObjectManager):
|
|||
def clear_all_sessids(self):
|
||||
"""
|
||||
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -141,16 +141,16 @@ class ObjectDB(TypedObject):
|
|||
|
||||
The ObjectDB adds the following properties:
|
||||
|
||||
- player - optional connected player (always together with sessid)
|
||||
- sessid - optional connection session id (always together with player)
|
||||
- account - optional connected account (always together with sessid)
|
||||
- sessid - optional connection session id (always together with account)
|
||||
- location - in-game location of object
|
||||
- home - safety location for object (handler)
|
||||
- scripts - scripts assigned to object (handler from typeclass)
|
||||
- cmdset - active cmdset on object (handler from typeclass)
|
||||
- aliases - aliases for this object (property)
|
||||
- nicks - nicknames for *other* things in Evennia (handler)
|
||||
- sessions - sessions connected to this object (see also player)
|
||||
- has_player - bool if an active player is currently connected
|
||||
- sessions - sessions connected to this object (see also account)
|
||||
- has_account - bool if an active account is currently connected
|
||||
- contents - other objects having this object as location
|
||||
- exits - exits from this object
|
||||
|
||||
|
|
@ -169,14 +169,14 @@ class ObjectDB(TypedObject):
|
|||
# self.key instead). The wrappers are created at the metaclass level and
|
||||
# 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,
|
||||
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],
|
||||
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
|
||||
# to change often, we set this with the 'location' property
|
||||
# to transparently handle Typeclassing.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
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
|
||||
entities.
|
||||
|
||||
|
|
@ -205,9 +205,9 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
return ObjectSessionHandler(self)
|
||||
|
||||
@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.
|
||||
|
||||
"""
|
||||
|
|
@ -216,11 +216,11 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
@property
|
||||
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 \
|
||||
and not self.db_player.attributes.get("_quell")
|
||||
return self.db_account and self.db_account.is_superuser \
|
||||
and not self.db_account.attributes.get("_quell")
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Returns:
|
||||
|
|
@ -349,7 +349,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
otherwise it will return a list of 0, 1 or more matches.
|
||||
|
||||
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
|
||||
`settings.SEARCH_AT_RESULT` and echoed automatically (on
|
||||
error, return will be `None`). If `quiet=True`, the error
|
||||
|
|
@ -367,7 +367,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
|
||||
if use_nicks:
|
||||
# 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
|
||||
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,
|
||||
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:
|
||||
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
|
||||
for the player connected to this object.
|
||||
for the account connected to this object.
|
||||
quiet (bool): Returns the results as a list rather than
|
||||
echo eventual standard error messages. Default `False`.
|
||||
|
||||
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:
|
||||
- `quiet=True`: No match or multumatch auto-echoes errors
|
||||
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.
|
||||
- `quiet=True`: No automatic error messaging is done, and
|
||||
what is returned is always a list with 0, 1 or more
|
||||
matching Players.
|
||||
matching Accounts.
|
||||
|
||||
"""
|
||||
if isinstance(searchdata, basestring):
|
||||
# searchdata is a string; wrap some common self-references
|
||||
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:
|
||||
return results
|
||||
|
|
@ -445,7 +445,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
Do something as this object. This is never called normally,
|
||||
it's only used when wanting specifically to let an object be
|
||||
the caller of a command. It makes use of nicks of eventual
|
||||
connected players as well.
|
||||
connected accounts as well.
|
||||
|
||||
Args:
|
||||
raw_string (string): Raw command input
|
||||
|
|
@ -473,7 +473,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
# nick replacement - we require full-word matching.
|
||||
# do text encoding conversion
|
||||
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)
|
||||
|
||||
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):
|
||||
"""
|
||||
Moves all objects (players/things) to their home location or
|
||||
Moves all objects (accounts/things) to their home location or
|
||||
to default home.
|
||||
"""
|
||||
# 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))
|
||||
return
|
||||
|
||||
if obj.has_player:
|
||||
if obj.has_account:
|
||||
if home:
|
||||
string = "Your current location has ceased to exist,"
|
||||
string += " moving you to %s(#%d)."
|
||||
obj.msg(_(string) % (home.name, home.dbid))
|
||||
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."
|
||||
obj.msg(_(string))
|
||||
obj.move_to(home)
|
||||
|
|
@ -853,16 +853,16 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
|
||||
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():
|
||||
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!)
|
||||
if self.player:
|
||||
if self.account:
|
||||
for session in self.sessions.all():
|
||||
self.player.unpuppet_object(session)
|
||||
self.player = None
|
||||
self.account.unpuppet_object(session)
|
||||
self.account = None
|
||||
|
||||
for script in _ScriptDB.objects.get_all_scripts_on_obj(self):
|
||||
script.stop()
|
||||
|
|
@ -1042,19 +1042,19 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
have no cmdsets.
|
||||
|
||||
Kwargs:
|
||||
caller (Session, Object or Player): The caller requesting
|
||||
caller (Session, Object or Account): The caller requesting
|
||||
this cmdset.
|
||||
|
||||
"""
|
||||
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.
|
||||
|
||||
Args:
|
||||
player (Player): This is the connecting player.
|
||||
account (Account): This is the connecting account.
|
||||
session (Session): Session controlling the connection.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
|
@ -1065,44 +1065,44 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
def at_post_puppet(self, **kwargs):
|
||||
"""
|
||||
Called just after puppeting has been completed and all
|
||||
Player<->Object links have been established.
|
||||
Account<->Object links have been established.
|
||||
|
||||
Args:
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
Note:
|
||||
You can use `self.player` and `self.sessions.get()` to get
|
||||
player and sessions at this point; the last entry in the
|
||||
You can use `self.account` and `self.sessions.get()` to get
|
||||
account and sessions at this point; the last entry in the
|
||||
list from `self.sessions.get()` is the latest Session
|
||||
puppeting this Object.
|
||||
|
||||
"""
|
||||
self.player.db._last_puppet = self
|
||||
self.account.db._last_puppet = self
|
||||
|
||||
def at_pre_unpuppet(self, **kwargs):
|
||||
"""
|
||||
Called just before beginning to un-connect a puppeting from
|
||||
this Player.
|
||||
this Account.
|
||||
|
||||
Args:
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
Note:
|
||||
You can use `self.player` and `self.sessions.get()` to get
|
||||
player and sessions at this point; the last entry in the
|
||||
You can use `self.account` and `self.sessions.get()` to get
|
||||
account and sessions at this point; the last entry in the
|
||||
list from `self.sessions.get()` is the latest Session
|
||||
puppeting this Object.
|
||||
|
||||
"""
|
||||
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.
|
||||
|
||||
Args:
|
||||
player (Player): The player object that just disconnected
|
||||
account (Account): The account object that just disconnected
|
||||
from this object.
|
||||
session (Session): Session id controlling the connection that
|
||||
just disconnected.
|
||||
|
|
@ -1139,7 +1139,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
|
||||
Args:
|
||||
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.
|
||||
|
||||
Kwargs:
|
||||
|
|
@ -1238,8 +1238,8 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
|
||||
"""
|
||||
|
||||
if not source_location and self.location.has_player:
|
||||
# This was created from nowhere and added to a player's
|
||||
if not source_location and self.location.has_account:
|
||||
# This was created from nowhere and added to an account's
|
||||
# inventory; it's probably the result of a create command.
|
||||
string = "You now have %s in your possession." % self.get_display_name(self.location)
|
||||
self.location.msg(string)
|
||||
|
|
@ -1437,7 +1437,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
key = con.get_display_name(looker)
|
||||
if con.destination:
|
||||
exits.append(key)
|
||||
elif con.has_player:
|
||||
elif con.has_account:
|
||||
users.append("|c%s|n" % key)
|
||||
else:
|
||||
things.append(key)
|
||||
|
|
@ -1576,7 +1576,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
class DefaultCharacter(DefaultObject):
|
||||
"""
|
||||
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"):
|
||||
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`.
|
||||
Args:
|
||||
player (Player): This is the connecting player.
|
||||
account (Account): This is the connecting account.
|
||||
session (Session): Session controlling the connection.
|
||||
"""
|
||||
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,
|
||||
self.db.prelogout_location = self.location # save location again to be sure.
|
||||
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):
|
||||
"""
|
||||
Called just after puppeting has been completed and all
|
||||
Player<->Object links have been established.
|
||||
Account<->Object links have been established.
|
||||
|
||||
Args:
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
Note:
|
||||
You can use `self.player` and `self.sessions.get()` to get
|
||||
player and sessions at this point; the last entry in the
|
||||
You can use `self.account` and `self.sessions.get()` to get
|
||||
account and sessions at this point; the last entry in the
|
||||
list from `self.sessions.get()` is the latest Session
|
||||
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)
|
||||
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
|
||||
after the player logged off ("headless", so to say).
|
||||
after the account logged off ("headless", so to say).
|
||||
|
||||
Args:
|
||||
player (Player): The player object that just disconnected
|
||||
account (Account): The account object that just disconnected
|
||||
from this object.
|
||||
session (Session): Session controlling the connection that
|
||||
just disconnected.
|
||||
|
|
@ -1782,7 +1782,7 @@ class DefaultExit(DefaultObject):
|
|||
Helper function for creating an exit command set + command.
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
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
|
||||
timed effects.
|
||||
|
||||
|
|
|
|||
|
|
@ -49,20 +49,20 @@ class ScriptDBManager(TypedObjectManager):
|
|||
"""
|
||||
if not obj:
|
||||
return []
|
||||
player = _GA(_GA(obj, "__dbclass__"), "__name__") == "PlayerDB"
|
||||
account = _GA(_GA(obj, "__dbclass__"), "__name__") == "AccountDB"
|
||||
if key:
|
||||
dbref = self.dbref(key)
|
||||
if dbref or dbref == 0:
|
||||
if player:
|
||||
return self.filter(db_player=obj, id=dbref)
|
||||
if account:
|
||||
return self.filter(db_account=obj, id=dbref)
|
||||
else:
|
||||
return self.filter(db_obj=obj, id=dbref)
|
||||
elif player:
|
||||
return self.filter(db_player=obj, db_key=key)
|
||||
elif account:
|
||||
return self.filter(db_account=obj, db_key=key)
|
||||
else:
|
||||
return self.filter(db_obj=obj, db_key=key)
|
||||
elif player:
|
||||
return self.filter(db_player=obj)
|
||||
elif account:
|
||||
return self.filter(db_account=obj)
|
||||
else:
|
||||
return self.filter(db_obj=obj)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ cleaning whatever effect they have had on the game object.
|
|||
|
||||
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.
|
||||
- Switch to a different state, such as entering a text editor,
|
||||
start combat or enter a dark room.
|
||||
- Merge a new cmdset with the default one for changing which
|
||||
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
|
||||
|
|
@ -62,7 +62,7 @@ class ScriptDB(TypedObject):
|
|||
The ScriptDB adds the following properties:
|
||||
desc - optional description of script
|
||||
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
|
||||
start_delay - if the script should start repeating right away
|
||||
repeats - how many times the script should repeat
|
||||
|
|
@ -122,18 +122,18 @@ class ScriptDB(TypedObject):
|
|||
def __get_obj(self):
|
||||
"""
|
||||
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.
|
||||
|
||||
"""
|
||||
obj = _GA(self, "db_player")
|
||||
obj = _GA(self, "db_account")
|
||||
if not obj:
|
||||
obj = _GA(self, "db_obj")
|
||||
return obj
|
||||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
@ -153,8 +153,8 @@ class ScriptDB(TypedObject):
|
|||
except ObjectDoesNotExist:
|
||||
# maybe it is just a name that happens to look like a dbid
|
||||
pass
|
||||
if value.__class__.__name__ == "PlayerDB":
|
||||
fname = "db_player"
|
||||
if value.__class__.__name__ == "AccountDB":
|
||||
fname = "db_account"
|
||||
_SA(self, fname, value)
|
||||
else:
|
||||
fname = "db_obj"
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@ class ScriptHandler(object):
|
|||
autostart (bool, optional): Start the script upon adding it.
|
||||
|
||||
"""
|
||||
if self.obj.__dbclass__.__name__ == "PlayerDB":
|
||||
# we add to a Player, not an Object
|
||||
script = create.create_script(scriptclass, key=key, player=self.obj,
|
||||
if self.obj.__dbclass__.__name__ == "AccountDB":
|
||||
# we add to an Account, not an Object
|
||||
script = create.create_script(scriptclass, key=key, account=self.obj,
|
||||
autostart=autostart)
|
||||
else:
|
||||
# the normal - adding to an Object
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ Both sides use this same protocol.
|
|||
The separation works like this:
|
||||
|
||||
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
|
||||
try to reconnect.
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ def check_errors(settings):
|
|||
raise DeprecationWarning(deprstring % (
|
||||
"CMDSET_DEFAULT", "CMDSET_CHARACTER"))
|
||||
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):
|
||||
raise DeprecationWarning(
|
||||
"settings.WEBSERVER_PORTS must be on the form "
|
||||
|
|
@ -46,8 +46,8 @@ def check_errors(settings):
|
|||
raise DeprecationWarning(deprstring % "OBJECT_TYPECLASS_PATHS")
|
||||
if hasattr(settings, "SCRIPT_TYPECLASS_PATHS"):
|
||||
raise DeprecationWarning(deprstring % "SCRIPT_TYPECLASS_PATHS")
|
||||
if hasattr(settings, "PLAYER_TYPECLASS_PATHS"):
|
||||
raise DeprecationWarning(deprstring % "PLAYER_TYPECLASS_PATHS")
|
||||
if hasattr(settings, "ACCOUNT_TYPECLASS_PATHS"):
|
||||
raise DeprecationWarning(deprstring % "ACCOUNT_TYPECLASS_PATHS")
|
||||
if hasattr(settings, "CHANNEL_TYPECLASS_PATHS"):
|
||||
raise DeprecationWarning(deprstring % "CHANNEL_TYPECLASS_PATHS")
|
||||
if hasattr(settings, "SEARCH_MULTIMATCH_SEPARATOR"):
|
||||
|
|
|
|||
|
|
@ -132,15 +132,15 @@ ERROR_NO_GAMEDIR = \
|
|||
|
||||
WARNING_MOVING_SUPERUSER = \
|
||||
"""
|
||||
WARNING: Evennia expects a Player superuser with id=1. No such
|
||||
Player was found. However, another superuser ('{other_key}',
|
||||
WARNING: Evennia expects an Account superuser with id=1. No such
|
||||
Account was found. However, another superuser ('{other_key}',
|
||||
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
|
||||
database being flushed recently - in this case the database's
|
||||
internal auto-counter might just start from some value higher than
|
||||
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.
|
||||
"""
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ RECREATED_SETTINGS = \
|
|||
|
||||
Note that if you were using an existing database, the password
|
||||
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.
|
||||
"""
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ HELP_ENTRY = \
|
|||
adding new protocols or are debugging Evennia itself.
|
||||
|
||||
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
|
||||
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():
|
||||
"""
|
||||
Create the superuser player
|
||||
Create the superuser account
|
||||
|
||||
"""
|
||||
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")
|
||||
django.core.management.call_command("createsuperuser", interactive=True)
|
||||
|
||||
|
|
@ -602,20 +602,20 @@ def check_database():
|
|||
tables = connection.introspection.get_table_list(connection.cursor())
|
||||
if not tables or not isinstance(tables[0], basestring): # django 1.8+
|
||||
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.
|
||||
evennia._init()
|
||||
# Try to get Player#1
|
||||
from evennia.players.models import PlayerDB
|
||||
# Try to get Account#1
|
||||
from evennia.accounts.models import AccountDB
|
||||
try:
|
||||
PlayerDB.objects.get(id=1)
|
||||
AccountDB.objects.get(id=1)
|
||||
except django.db.utils.OperationalError as e:
|
||||
print(ERROR_DATABASE.format(traceback=e))
|
||||
sys.exit()
|
||||
except PlayerDB.DoesNotExist:
|
||||
except AccountDB.DoesNotExist:
|
||||
# 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:
|
||||
# Another superuser was found, but not with id=1. This may
|
||||
# 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!")
|
||||
if not cmdsethandler.import_cmdset(settings.CMDSET_CHARACTER, None):
|
||||
print("Warning: CMDSET_CHARACTER failed to load")
|
||||
if not cmdsethandler.import_cmdset(settings.CMDSET_PLAYER, None):
|
||||
print("Warning: CMDSET_PLAYER failed to load")
|
||||
if not cmdsethandler.import_cmdset(settings.CMDSET_ACCOUNT, None):
|
||||
print("Warning: CMDSET_ACCOUNT failed to load")
|
||||
# typeclasses
|
||||
_imp(settings.BASE_PLAYER_TYPECLASS)
|
||||
_imp(settings.BASE_ACCOUNT_TYPECLASS)
|
||||
_imp(settings.BASE_OBJECT_TYPECLASS)
|
||||
_imp(settings.BASE_CHARACTER_TYPECLASS)
|
||||
_imp(settings.BASE_ROOM_TYPECLASS)
|
||||
|
|
@ -945,10 +945,10 @@ def run_dummyrunner(number_of_dummies):
|
|||
Start an instance of the dummyrunner
|
||||
|
||||
Args:
|
||||
number_of_dummies (int): The number of dummy players to start.
|
||||
number_of_dummies (int): The number of dummy accounts to start.
|
||||
|
||||
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/
|
||||
directory.
|
||||
|
||||
|
|
@ -1215,7 +1215,7 @@ def main():
|
|||
parser.add_argument(
|
||||
'--dummyrunner', nargs=1, action='store', dest='dummyrunner',
|
||||
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(
|
||||
'--settings', nargs=1, action='store', dest='altsettings',
|
||||
default=None, metavar="filename.py",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from __future__ import print_function
|
|||
import time
|
||||
from django.conf import settings
|
||||
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.utils import create, logger
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ ERROR_NO_SUPERUSER = """
|
|||
LIMBO_DESC = _("""
|
||||
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.
|
||||
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:
|
||||
The in-game channels {chan1}, {chan2} and {chan3} were created,
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
def get_god_player():
|
||||
def get_god_account():
|
||||
"""
|
||||
Creates the god user and don't take no for an answer.
|
||||
|
||||
"""
|
||||
try:
|
||||
god_player = PlayerDB.objects.get(id=1)
|
||||
except PlayerDB.DoesNotExist:
|
||||
raise PlayerDB.DoesNotExist(ERROR_NO_SUPERUSER)
|
||||
return god_player
|
||||
god_account = AccountDB.objects.get(id=1)
|
||||
except AccountDB.DoesNotExist:
|
||||
raise AccountDB.DoesNotExist(ERROR_NO_SUPERUSER)
|
||||
return god_account
|
||||
|
||||
|
||||
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.
|
||||
# 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
|
||||
# mud-specific settings for the PlayerDB object.
|
||||
player_typeclass = settings.BASE_PLAYER_TYPECLASS
|
||||
# Create an Account 'user profile' object to hold eventual
|
||||
# mud-specific settings for the AccountDB object.
|
||||
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)
|
||||
god_player.swap_typeclass(player_typeclass, clean_attributes=True)
|
||||
god_player.basetype_setup()
|
||||
god_player.at_player_creation()
|
||||
god_player.locks.add("examine:perm(Developer);edit:false();delete:false();boot:false();msg:all()")
|
||||
god_account.swap_typeclass(account_typeclass, clean_attributes=True)
|
||||
god_account.basetype_setup()
|
||||
god_account.at_account_creation()
|
||||
god_account.locks.add("examine:perm(Developer);edit:false();delete:false();boot:false();msg:all()")
|
||||
# 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
|
||||
|
||||
# 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.
|
||||
character_typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
god_character = create.create_object(character_typeclass,
|
||||
key=god_player.username,
|
||||
key=god_account.username,
|
||||
nohome=True)
|
||||
|
||||
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.permissions.add("Developer")
|
||||
|
||||
god_player.attributes.add("_first_login", True)
|
||||
god_player.attributes.add("_last_puppet", god_character)
|
||||
god_account.attributes.add("_first_login", True)
|
||||
god_account.attributes.add("_last_puppet", god_character)
|
||||
|
||||
try:
|
||||
god_player.db._playable_characters.append(god_character)
|
||||
god_account.db._playable_characters.append(god_character)
|
||||
except AttributeError:
|
||||
god_player.db_playable_characters = [god_character]
|
||||
god_account.db_playable_characters = [god_character]
|
||||
|
||||
room_typeclass = settings.BASE_ROOM_TYPECLASS
|
||||
limbo_obj = create.create_object(room_typeclass, _('Limbo'), nohome=True)
|
||||
|
|
@ -123,7 +123,7 @@ def create_channels():
|
|||
"""
|
||||
logger.log_info("Creating default channels ...")
|
||||
|
||||
goduser = get_god_player()
|
||||
goduser = get_god_account()
|
||||
for channeldict in settings.DEFAULT_CHANNELS:
|
||||
channel = create.create_channel(**channeldict)
|
||||
channel.connect(goduser)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from future.utils import viewkeys
|
|||
import importlib
|
||||
from django.conf import settings
|
||||
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.utils import to_str, to_unicode
|
||||
|
||||
|
|
@ -67,15 +67,15 @@ def text(session, *args, **kwargs):
|
|||
if txt.strip() in _IDLE_COMMAND:
|
||||
session.update_session_counters(idle=True)
|
||||
return
|
||||
if session.player:
|
||||
if session.account:
|
||||
# nick replacement
|
||||
puppet = session.puppet
|
||||
if puppet:
|
||||
txt = puppet.nicks.nickreplace(txt,
|
||||
categories=("inputline", "channel"), include_player=True)
|
||||
categories=("inputline", "channel"), include_account=True)
|
||||
else:
|
||||
txt = session.player.nicks.nickreplace(txt,
|
||||
categories=("inputline", "channel"), include_player=False)
|
||||
txt = session.account.nicks.nickreplace(txt,
|
||||
categories=("inputline", "channel"), include_account=False)
|
||||
kwargs.pop("options", None)
|
||||
cmdhandler(session, txt, callertype="session", session=session, **kwargs)
|
||||
session.update_session_counters()
|
||||
|
|
@ -105,7 +105,7 @@ def bot_data_in(session, *args, **kwargs):
|
|||
return
|
||||
kwargs.pop("options", None)
|
||||
# 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()
|
||||
|
||||
|
||||
|
|
@ -153,10 +153,10 @@ def browser_sessid(session, *args, **kwargs):
|
|||
uid = browsersession.get("logged_in", None)
|
||||
if uid:
|
||||
try:
|
||||
player = PlayerDB.objects.get(pk=uid)
|
||||
account = AccountDB.objects.get(pk=uid)
|
||||
except Exception:
|
||||
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.
|
||||
|
||||
Kwargs:
|
||||
name (str): Player name
|
||||
name (str): Account name
|
||||
password (str): Plain-text password
|
||||
|
||||
"""
|
||||
if not session.logged_in and "name" in kwargs and "password" in kwargs:
|
||||
from evennia.commands.default.unloggedin import create_normal_player
|
||||
player = create_normal_player(session, kwargs["name"], kwargs["password"])
|
||||
if player:
|
||||
session.sessionhandler.login(session, player)
|
||||
from evennia.commands.default.unloggedin import create_normal_account
|
||||
account = create_normal_account(session, kwargs["name"], kwargs["password"])
|
||||
if account:
|
||||
session.sessionhandler.login(session, account)
|
||||
|
||||
_gettable = {
|
||||
"name": lambda obj: obj.key,
|
||||
|
|
@ -308,7 +308,7 @@ _gettable = {
|
|||
def get_value(session, *args, **kwargs):
|
||||
"""
|
||||
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:
|
||||
name (str): Name of info value to return. Only names
|
||||
|
|
@ -317,7 +317,7 @@ def get_value(session, *args, **kwargs):
|
|||
|
||||
"""
|
||||
name = kwargs.get("name", "")
|
||||
obj = session.puppet or session.player
|
||||
obj = session.puppet or session.account
|
||||
if name in _gettable:
|
||||
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):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
session = kwargs["session"]
|
||||
|
|
@ -452,15 +452,15 @@ def webclient_options(session, *args, **kwargs):
|
|||
that changes.
|
||||
|
||||
If kwargs is not empty, the key/values stored in there will be persisted
|
||||
to the player object.
|
||||
to the account object.
|
||||
|
||||
Kwargs:
|
||||
<option name>: an option to save
|
||||
"""
|
||||
player = session.player
|
||||
account = session.account
|
||||
|
||||
clientoptions = settings.WEBCLIENT_OPTIONS.copy()
|
||||
storedoptions = player.db._saved_webclient_options or {}
|
||||
storedoptions = account.db._saved_webclient_options or {}
|
||||
clientoptions.update(storedoptions)
|
||||
|
||||
# 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
|
||||
# the previous one since it would use the same idstring
|
||||
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,
|
||||
idstring=session.sessid, persistent=False,
|
||||
session=session)
|
||||
else:
|
||||
# kwargs provided: persist them to the player object
|
||||
# kwargs provided: persist them to the account object
|
||||
for key, value in kwargs.iteritems():
|
||||
clientoptions[key] = value
|
||||
|
||||
player.db._saved_webclient_options = clientoptions
|
||||
account.db._saved_webclient_options = clientoptions
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ from twisted.python import components
|
|||
from django.conf import settings
|
||||
|
||||
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.utils import to_str
|
||||
|
||||
|
|
@ -61,21 +61,21 @@ CTRL_L = '\x0c'
|
|||
|
||||
class SshProtocol(Manhole, session.Session):
|
||||
"""
|
||||
Each player connecting over ssh gets this protocol assigned to
|
||||
them. All communication between game and player goes through
|
||||
Each account connecting over ssh gets this protocol assigned to
|
||||
them. All communication between game and account goes through
|
||||
here.
|
||||
|
||||
"""
|
||||
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.
|
||||
|
||||
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!
|
||||
self.cfactory = starttuple[1]
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ class SshProtocol(Manhole, session.Session):
|
|||
self.init_session("ssh", client_address, self.cfactory.sessionhandler)
|
||||
|
||||
# since we might have authenticated already, we might set this here.
|
||||
if self.authenticated_player:
|
||||
if self.authenticated_account:
|
||||
self.logged_in = True
|
||||
self.uid = self.authenticated_player.user.id
|
||||
self.uid = self.authenticated_account.user.id
|
||||
self.sessionhandler.connect(self)
|
||||
|
||||
def connectionMade(self):
|
||||
|
|
@ -313,10 +313,10 @@ class ExtraInfoAuthServer(SSHUserAuthServer):
|
|||
self._ebPassword)
|
||||
|
||||
|
||||
class PlayerDBPasswordChecker(object):
|
||||
class AccountDBPasswordChecker(object):
|
||||
"""
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
@ -331,7 +331,7 @@ class PlayerDBPasswordChecker(object):
|
|||
|
||||
"""
|
||||
self.factory = factory
|
||||
super(PlayerDBPasswordChecker, self).__init__()
|
||||
super(AccountDBPasswordChecker, self).__init__()
|
||||
|
||||
def requestAvatarId(self, c):
|
||||
"""
|
||||
|
|
@ -341,10 +341,10 @@ class PlayerDBPasswordChecker(object):
|
|||
up = credentials.IUsernamePassword(c, None)
|
||||
username = up.username
|
||||
password = up.password
|
||||
player = PlayerDB.objects.get_player_from_name(username)
|
||||
account = AccountDB.objects.get_account_from_name(username)
|
||||
res = (None, self.factory)
|
||||
if player and player.check_password(password):
|
||||
res = (player, self.factory)
|
||||
if account and account.check_password(password):
|
||||
res = (account, self.factory)
|
||||
return defer.succeed(res)
|
||||
|
||||
|
||||
|
|
@ -462,6 +462,6 @@ def makeFactory(configdict):
|
|||
factory.services = factory.services.copy()
|
||||
factory.services['ssh-userauth'] = ExtraInfoAuthServer
|
||||
|
||||
factory.portal.registerChecker(PlayerDBPasswordChecker(factory))
|
||||
factory.portal.registerChecker(AccountDBPasswordChecker(factory))
|
||||
|
||||
return factory
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ full step-by-step setup help.
|
|||
Basically (for testing default Evennia):
|
||||
|
||||
- Use an empty/testing database.
|
||||
- set PERMISSION_PLAYER_DEFAULT = "Builder"
|
||||
- set PERMISSION_ACCOUNT_DEFAULT = "Builder"
|
||||
- start server, eventually with profiling active
|
||||
- launch this client runner
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ TIMESTEP = DUMMYRUNNER_SETTINGS.TIMESTEP
|
|||
# chance of a client performing an action, per timestep. This helps to
|
||||
# spread out usage randomly, like it would be in reality.
|
||||
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.
|
||||
CHANCE_OF_LOGIN = DUMMYRUNNER_SETTINGS.CHANCE_OF_LOGIN
|
||||
# Port to use, if not specified on command line
|
||||
|
|
@ -79,7 +79,7 @@ NLOGGED_IN = 0
|
|||
|
||||
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
|
||||
running.
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ ERROR_NO_MIXIN = \
|
|||
from evennia.server.profiling.settings_mixin import *
|
||||
|
||||
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
|
||||
- change PASSWORD_HASHERS to use a faster (but less safe) algorithm
|
||||
when creating large numbers of accounts at the same time
|
||||
|
|
@ -106,7 +106,7 @@ ERROR_NO_MIXIN = \
|
|||
error completely.
|
||||
|
||||
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!
|
||||
|
||||
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
|
||||
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
|
||||
|
|
@ -136,9 +136,9 @@ Setup:
|
|||
`evennia migrate`)
|
||||
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
|
||||
file specified by DUMMYRUNNER_SETTINGS_MODULE
|
||||
|
||||
|
|
@ -160,12 +160,12 @@ Setup:
|
|||
|
||||
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
|
||||
to test is performance during run. A large
|
||||
number of clients here may lock up the client until all have been
|
||||
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
|
||||
until you see the initial login slows things too much.
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ def makeiter(obj):
|
|||
class DummyClient(telnet.StatefulTelnetProtocol):
|
||||
"""
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Settings and actions for the dummyrunner
|
||||
|
||||
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:
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ ACTIONS is a tuple
|
|||
|
||||
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
|
||||
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
|
||||
thus issue a logout command. The other entries are tuples (chance,
|
||||
func). They are picked randomly, their commonality based on the
|
||||
|
|
@ -61,7 +61,7 @@ TIMESTEP = 2
|
|||
CHANCE_OF_ACTION = 0.5
|
||||
|
||||
# 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.
|
||||
CHANCE_OF_LOGIN = 1.0
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ def c_moves_s(client):
|
|||
# (0.1, c_creates_obj),
|
||||
# #(0.01, c_creates_button),
|
||||
# (0.2, c_moves))
|
||||
## "passive player" definition
|
||||
## "passive account" definition
|
||||
#ACTIONS = ( c_login,
|
||||
# c_logout,
|
||||
# (0.7, c_looks),
|
||||
|
|
@ -244,11 +244,11 @@ def c_moves_s(client):
|
|||
# #(0.1, c_creates_obj),
|
||||
# #(0.1, c_creates_button),
|
||||
# #(0.4, c_moves))
|
||||
# "inactive player" definition
|
||||
# "inactive account" definition
|
||||
#ACTIONS = (c_login_nodig,
|
||||
# c_logout,
|
||||
# (1.0, c_idles))
|
||||
## "normal player" definition
|
||||
## "normal account" definition
|
||||
ACTIONS = ( c_login,
|
||||
c_logout,
|
||||
(0.01, c_digs),
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ if __name__ == "__main__":
|
|||
|
||||
fig = pp.figure()
|
||||
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_ylabel("Memory usage (MB)")
|
||||
ax1.plot(secs, rmem, "r", label="RMEM", lw=2)
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ servers!
|
|||
# the mixin is present
|
||||
DUMMYRUNNER_MIXIN = True
|
||||
# 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.
|
||||
PASSWORD_HASHERS = (
|
||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||
)
|
||||
# make dummy clients able to test all commands
|
||||
PERMISSION_PLAYER_DEFAULT = "Developer"
|
||||
PERMISSION_ACCOUNT_DEFAULT = "Developer"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ evennia._init()
|
|||
from django.db import connection
|
||||
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.server.models import ServerConfig
|
||||
from evennia.server import initial_setup
|
||||
|
|
@ -214,8 +214,8 @@ class Evennia(object):
|
|||
already existing objects.
|
||||
"""
|
||||
# setting names
|
||||
settings_names = ("CMDSET_CHARACTER", "CMDSET_PLAYER",
|
||||
"BASE_PLAYER_TYPECLASS", "BASE_OBJECT_TYPECLASS",
|
||||
settings_names = ("CMDSET_CHARACTER", "CMDSET_ACCOUNT",
|
||||
"BASE_ACCOUNT_TYPECLASS", "BASE_OBJECT_TYPECLASS",
|
||||
"BASE_CHARACTER_TYPECLASS", "BASE_ROOM_TYPECLASS",
|
||||
"BASE_EXIT_TYPECLASS", "BASE_SCRIPT_TYPECLASS",
|
||||
"BASE_CHANNEL_TYPECLASS")
|
||||
|
|
@ -228,16 +228,16 @@ class Evennia(object):
|
|||
# run the update
|
||||
from evennia.objects.models import ObjectDB
|
||||
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):
|
||||
# update the database
|
||||
print(" %s:\n '%s' changed to '%s'. Updating unchanged entries in database ..." % (settings_names[i], prev, curr))
|
||||
if i == 0:
|
||||
ObjectDB.objects.filter(db_cmdset_storage__exact=prev).update(db_cmdset_storage=curr)
|
||||
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:
|
||||
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):
|
||||
ObjectDB.objects.filter(db_typeclass_path__exact=prev).update(db_typeclass_path=curr)
|
||||
if i == 7:
|
||||
|
|
@ -247,7 +247,7 @@ class Evennia(object):
|
|||
# store the new default and clean caches
|
||||
ServerConfig.objects.conf(settings_names[i], curr)
|
||||
ObjectDB.flush_instance_cache()
|
||||
PlayerDB.flush_instance_cache()
|
||||
AccountDB.flush_instance_cache()
|
||||
ScriptDB.flush_instance_cache()
|
||||
ChannelDB.flush_instance_cache()
|
||||
# if this is the first start we might not have a "previous"
|
||||
|
|
@ -283,13 +283,13 @@ class Evennia(object):
|
|||
Called every server start
|
||||
"""
|
||||
from evennia.objects.models import ObjectDB
|
||||
#from evennia.players.models import PlayerDB
|
||||
#from evennia.accounts.models import AccountDB
|
||||
|
||||
#update eventual changed defaults
|
||||
self.update_defaults()
|
||||
|
||||
[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()
|
||||
|
||||
|
|
@ -356,7 +356,7 @@ class Evennia(object):
|
|||
mode = self.getset_restart_mode(mode)
|
||||
|
||||
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.utils import gametime as _GAMETIME_MODULE
|
||||
|
||||
|
|
@ -364,7 +364,7 @@ class Evennia(object):
|
|||
# call restart hooks
|
||||
ServerConfig.objects.conf("server_restart_mode", "reload")
|
||||
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 self.sessions.all_sessions_portal_sync()
|
||||
self.at_server_reload_stop()
|
||||
|
|
@ -375,14 +375,14 @@ class Evennia(object):
|
|||
if mode == 'reset':
|
||||
# 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 [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:
|
||||
yield self.sessions.all_sessions_portal_sync()
|
||||
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 [(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 [(s.pause(manual_pause=False), s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
|
||||
ServerConfig.objects.conf("server_restart_mode", "reset")
|
||||
|
|
@ -482,7 +482,7 @@ class Evennia(object):
|
|||
script.stop()
|
||||
|
||||
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:
|
||||
if character: character.delete()
|
||||
guest.delete()
|
||||
|
|
|
|||
|
|
@ -152,18 +152,18 @@ class NAttributeHandler(object):
|
|||
|
||||
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.
|
||||
|
||||
Each player gets a session assigned to them whenever they connect
|
||||
to the game server. All communication between game and player goes
|
||||
Each account gets a session assigned to them whenever they connect
|
||||
to the game server. All communication between game and account goes
|
||||
through their session.
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
"""Initiate to avoid AttributeErrors down the line"""
|
||||
self.puppet = None
|
||||
self.player = None
|
||||
self.account = None
|
||||
self.cmdset_storage_string = ""
|
||||
self.cmdset = CmdSetHandler(self, True)
|
||||
|
||||
|
|
@ -178,7 +178,7 @@ class ServerSession(Session):
|
|||
"""
|
||||
This is called whenever a session has been resynced with the
|
||||
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
|
||||
set up the session as it was.
|
||||
|
|
@ -201,23 +201,23 @@ class ServerSession(Session):
|
|||
# hooks, echoes or access checks.
|
||||
obj = _ObjectDB.objects.get(id=self.puid)
|
||||
obj.sessions.add(self)
|
||||
obj.player = self.player
|
||||
obj.account = self.account
|
||||
self.puid = obj.id
|
||||
self.puppet = obj
|
||||
# obj.scripts.validate()
|
||||
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.
|
||||
|
||||
Args:
|
||||
player (Player): The player associated with the session.
|
||||
account (Account): The account associated with the session.
|
||||
|
||||
"""
|
||||
self.player = player
|
||||
self.uid = self.player.id
|
||||
self.uname = self.player.username
|
||||
self.account = account
|
||||
self.uid = self.account.id
|
||||
self.uname = self.account.username
|
||||
self.logged_in = True
|
||||
self.conn_time = time.time()
|
||||
self.puid = None
|
||||
|
|
@ -230,12 +230,12 @@ class ServerSession(Session):
|
|||
# can also see we are logged in.
|
||||
csession = ClientSessionStore(session_key=self.csessid)
|
||||
if not csession.get("logged_in"):
|
||||
csession["logged_in"] = player.id
|
||||
csession["logged_in"] = account.id
|
||||
csession.save()
|
||||
|
||||
# Update account's last login time.
|
||||
self.player.last_login = timezone.now()
|
||||
self.player.save()
|
||||
self.account.last_login = timezone.now()
|
||||
self.account.save()
|
||||
|
||||
# add the session-level cmdset
|
||||
self.cmdset = CmdSetHandler(self, True)
|
||||
|
|
@ -246,34 +246,34 @@ class ServerSession(Session):
|
|||
|
||||
"""
|
||||
if self.logged_in:
|
||||
player = self.player
|
||||
account = self.account
|
||||
if self.puppet:
|
||||
player.unpuppet_object(self)
|
||||
uaccount = player
|
||||
account.unpuppet_object(self)
|
||||
uaccount = account
|
||||
uaccount.last_login = timezone.now()
|
||||
uaccount.save()
|
||||
# calling player hook
|
||||
player.at_disconnect()
|
||||
# calling account hook
|
||||
account.at_disconnect()
|
||||
self.logged_in = False
|
||||
if not self.sessionhandler.sessions_from_player(player):
|
||||
# no more sessions connected to this player
|
||||
player.is_connected = False
|
||||
# this may be used to e.g. delete player after disconnection etc
|
||||
player.at_post_disconnect()
|
||||
if not self.sessionhandler.sessions_from_account(account):
|
||||
# no more sessions connected to this account
|
||||
account.is_connected = False
|
||||
# this may be used to e.g. delete account after disconnection etc
|
||||
account.at_post_disconnect()
|
||||
# remove any webclient settings monitors associated with this
|
||||
# session
|
||||
MONITOR_HANDLER.remove(player, "_saved_webclient_options",
|
||||
MONITOR_HANDLER.remove(account, "_saved_webclient_options",
|
||||
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:
|
||||
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):
|
||||
"""
|
||||
|
|
@ -286,17 +286,17 @@ class ServerSession(Session):
|
|||
return self.logged_in and self.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:
|
||||
controller (Object or Player): The puppet if one exists,
|
||||
otherwise return the player.
|
||||
controller (Object or Account): The puppet if one exists,
|
||||
otherwise return the account.
|
||||
|
||||
"""
|
||||
if self.logged_in:
|
||||
return self.puppet if self.puppet else self.player
|
||||
return self.puppet if self.puppet else self.account
|
||||
return None
|
||||
|
||||
def log(self, message, channel=True):
|
||||
|
|
@ -343,7 +343,7 @@ class ServerSession(Session):
|
|||
if not idle:
|
||||
# Increment the user's command counter.
|
||||
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
|
||||
|
||||
def update_flags(self, **kwargs):
|
||||
|
|
@ -395,7 +395,7 @@ class ServerSession(Session):
|
|||
|
||||
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:
|
||||
text (str): String input.
|
||||
|
|
@ -449,8 +449,8 @@ class ServerSession(Session):
|
|||
|
||||
"""
|
||||
symbol = ""
|
||||
if self.logged_in and hasattr(self, "player") and self.player:
|
||||
symbol = "(#%s)" % self.player.id
|
||||
if self.logged_in and hasattr(self, "account") and self.account:
|
||||
symbol = "(#%s)" % self.account.id
|
||||
try:
|
||||
if hasattr(self.address, '__iter__'):
|
||||
address = ":".join([str(part) for part in self.address])
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Session(object):
|
|||
respective hook methods should be connected to the methods unique
|
||||
for the respective protocol so that there is a unified interface
|
||||
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.
|
||||
|
||||
The Portal and Server have their own respective sessionhandlers. These
|
||||
|
|
@ -123,11 +123,11 @@ class Session(object):
|
|||
def at_sync(self):
|
||||
"""
|
||||
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).
|
||||
|
||||
"""
|
||||
self.protocol_flags.update(self.player.attributs.get("_saved_protocol_flags"), {})
|
||||
self.protocol_flags.update(self.account.attributs.get("_saved_protocol_flags"), {})
|
||||
|
||||
# access hooks
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ except ImportError:
|
|||
_INLINEFUNC_ENABLED = settings.INLINEFUNC_ENABLED
|
||||
|
||||
# delayed imports
|
||||
_PlayerDB = None
|
||||
_AccountDB = None
|
||||
_ServerSession = None
|
||||
_ServerConfig = None
|
||||
_ScriptDB = None
|
||||
|
|
@ -77,20 +77,20 @@ def delayed_import():
|
|||
Helper method for delayed import of all needed entities.
|
||||
|
||||
"""
|
||||
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB
|
||||
global _ServerSession, _AccountDB, _ServerConfig, _ScriptDB
|
||||
if not _ServerSession:
|
||||
# we allow optional arbitrary serversession class for overloading
|
||||
modulename, classname = settings.SERVER_SESSION_CLASS.rsplit(".", 1)
|
||||
_ServerSession = variable_from_module(modulename, classname)
|
||||
if not _PlayerDB:
|
||||
from evennia.players.models import PlayerDB as _PlayerDB
|
||||
if not _AccountDB:
|
||||
from evennia.accounts.models import AccountDB as _AccountDB
|
||||
if not _ServerConfig:
|
||||
from evennia.server.models import ServerConfig as _ServerConfig
|
||||
if not _ScriptDB:
|
||||
from evennia.scripts.models import ScriptDB as _ScriptDB
|
||||
# including once to avoid warnings in Python syntax checkers
|
||||
assert(_ServerSession)
|
||||
assert(_PlayerDB)
|
||||
assert(_AccountDB)
|
||||
assert(_ServerConfig)
|
||||
assert(_ScriptDB)
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
A session register with the handler in two steps, first by
|
||||
registering itself with the connect() method. This indicates an
|
||||
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.
|
||||
|
||||
"""
|
||||
|
|
@ -277,7 +277,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
"""
|
||||
delayed_import()
|
||||
global _ServerSession, _PlayerDB, _ScriptDB
|
||||
global _ServerSession, _AccountDB, _ScriptDB
|
||||
|
||||
sess = _ServerSession()
|
||||
sess.sessionhandler = self
|
||||
|
|
@ -291,10 +291,10 @@ class ServerSessionHandler(SessionHandler):
|
|||
# Session is already logged in. This can happen in the
|
||||
# case of auto-authenticating protocols like SSH or
|
||||
# webclient's session sharing
|
||||
player = _PlayerDB.objects.get_player_from_uid(sess.uid)
|
||||
if player:
|
||||
# this will set player.is_connected too
|
||||
self.login(sess, player, force=True)
|
||||
account = _AccountDB.objects.get_account_from_uid(sess.uid)
|
||||
if account:
|
||||
# this will set account.is_connected too
|
||||
self.login(sess, account, force=True)
|
||||
return
|
||||
else:
|
||||
sess.logged_in = False
|
||||
|
|
@ -336,7 +336,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
"""
|
||||
delayed_import()
|
||||
global _ServerSession, _PlayerDB, _ServerConfig, _ScriptDB
|
||||
global _ServerSession, _AccountDB, _ServerConfig, _ScriptDB
|
||||
|
||||
for sess in self.values():
|
||||
# we delete the old session to make sure to catch eventual
|
||||
|
|
@ -348,7 +348,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
sess.sessionhandler = self
|
||||
sess.load_sync_data(sessdict)
|
||||
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
|
||||
sess.at_sync()
|
||||
|
||||
|
|
@ -403,7 +403,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
"network:"irc.freenode.net", "port": 6667})
|
||||
|
||||
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
|
||||
treat this as a normal connection and henceforth so will
|
||||
the Server.
|
||||
|
|
@ -420,15 +420,15 @@ class ServerSessionHandler(SessionHandler):
|
|||
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION,
|
||||
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
|
||||
the session to be logged in one way or another.
|
||||
|
||||
Args:
|
||||
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
|
||||
(this can happen for auto-authenticating protocols)
|
||||
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.
|
||||
return
|
||||
|
||||
player.is_connected = True
|
||||
account.is_connected = True
|
||||
|
||||
# sets up and assigns all properties on the session
|
||||
session.at_login(player)
|
||||
session.at_login(account)
|
||||
|
||||
# player init
|
||||
player.at_init()
|
||||
# account init
|
||||
account.at_init()
|
||||
|
||||
# Check if this is the first time the *player* logs in
|
||||
if player.db.FIRST_LOGIN:
|
||||
player.at_first_login()
|
||||
del player.db.FIRST_LOGIN
|
||||
# Check if this is the first time the *account* logs in
|
||||
if account.db.FIRST_LOGIN:
|
||||
account.at_first_login()
|
||||
del account.db.FIRST_LOGIN
|
||||
|
||||
player.at_pre_login()
|
||||
account.at_pre_login()
|
||||
|
||||
if _MULTISESSION_MODE == 0:
|
||||
# disconnect all previous sessions.
|
||||
self.disconnect_duplicate_sessions(session)
|
||||
|
||||
nsess = len(self.sessions_from_player(player))
|
||||
string = "Logged in: {player} {address} ({nsessions} session(s) total)"
|
||||
string = string.format(player=player,address=session.address, nsessions=nsess)
|
||||
nsess = len(self.sessions_from_account(account))
|
||||
string = "Logged in: {account} {address} ({nsessions} session(s) total)"
|
||||
string = string.format(account=account,address=session.address, nsessions=nsess)
|
||||
session.log(string)
|
||||
session.logged_in = True
|
||||
# sync the portal to the session
|
||||
|
|
@ -469,7 +469,7 @@ class ServerSessionHandler(SessionHandler):
|
|||
self.server.amp_protocol.send_AdminServer2Portal(session,
|
||||
operation=SLOGIN,
|
||||
sessiondata={"logged_in": True})
|
||||
player.at_post_login(session=session)
|
||||
account.at_post_login(session=session)
|
||||
|
||||
def disconnect(self, session, reason="", sync_portal=True):
|
||||
"""
|
||||
|
|
@ -488,11 +488,11 @@ class ServerSessionHandler(SessionHandler):
|
|||
if not session:
|
||||
return
|
||||
|
||||
if hasattr(session, "player") and session.player:
|
||||
if hasattr(session, "account") and session.account:
|
||||
# only log accounts logging off
|
||||
nsess = len(self.sessions_from_player(session.player)) - 1
|
||||
string = "Logged out: {player} {address} ({nsessions} sessions(s) remaining)"
|
||||
string = string.format(player=session.player, address=session.address, nsessions=nsess)
|
||||
nsess = len(self.sessions_from_account(session.account)) - 1
|
||||
string = "Logged out: {account} {address} ({nsessions} sessions(s) remaining)"
|
||||
string = string.format(account=session.account, address=session.address, nsessions=nsess)
|
||||
session.log(string)
|
||||
|
||||
session.at_disconnect()
|
||||
|
|
@ -575,28 +575,28 @@ class ServerSessionHandler(SessionHandler):
|
|||
and (tcurr - session.cmd_last) > _IDLE_TIMEOUT):
|
||||
self.disconnect(session, reason=reason)
|
||||
|
||||
def player_count(self):
|
||||
def account_count(self):
|
||||
"""
|
||||
Get the number of connected players (not sessions since a
|
||||
player may have more than one session depending on settings).
|
||||
Only logged-in players are counted here.
|
||||
Get the number of connected accounts (not sessions since a
|
||||
account may have more than one session depending on settings).
|
||||
Only logged-in accounts are counted here.
|
||||
|
||||
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))
|
||||
|
||||
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:
|
||||
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).
|
||||
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
|
@ -614,13 +614,13 @@ class ServerSessionHandler(SessionHandler):
|
|||
return [self.get(sid) for sid in sessid if sid in self]
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
Returns:
|
||||
|
|
@ -628,21 +628,21 @@ class ServerSessionHandler(SessionHandler):
|
|||
|
||||
"""
|
||||
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
|
||||
|
||||
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:
|
||||
player (Player): Player to get sessions from.
|
||||
account (Account): Account to get sessions from.
|
||||
|
||||
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]
|
||||
|
||||
def sessions_from_puppet(self, puppet):
|
||||
|
|
|
|||
|
|
@ -151,10 +151,10 @@ IDLE_TIMEOUT = -1
|
|||
# command-name is given here; this is because the webclient needs a default
|
||||
# to send to avoid proxy timeouts.
|
||||
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
|
||||
# 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)
|
||||
ENCODINGS = ["utf-8", "latin-1", "ISO-8859-1"]
|
||||
# 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.
|
||||
PORTAL_SERVICES_PLUGIN_MODULES = ["server.conf.portal_services_plugins"]
|
||||
# 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"
|
||||
# Module for 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
|
||||
# (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"
|
||||
# Command set used on the logged-in session
|
||||
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"
|
||||
# Command set for players without a character (ooc)
|
||||
CMDSET_PLAYER = "commands.default_cmdsets.PlayerCmdSet"
|
||||
# Command set for accounts without a character (ooc)
|
||||
CMDSET_ACCOUNT = "commands.default_cmdsets.AccountCmdSet"
|
||||
# Location to search for cmdsets if full path not given
|
||||
CMDSET_PATHS = ["commands", "evennia", "contribs"]
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# multisession modes.
|
||||
COMMAND_DEFAULT_MSG_ALL_SESSIONS = False
|
||||
|
|
@ -392,11 +392,11 @@ SERVER_SESSION_CLASS = "evennia.server.serversession.ServerSession"
|
|||
# or start from the evennia library.
|
||||
TYPECLASS_PATHS = ["typeclasses", "evennia", "evennia.contrib", "evennia.contrib.tutorial_examples"]
|
||||
|
||||
# Typeclass for player objects (linked to a character) (fallback)
|
||||
BASE_PLAYER_TYPECLASS = "typeclasses.players.Player"
|
||||
# Typeclass for account objects (linked to a character) (fallback)
|
||||
BASE_ACCOUNT_TYPECLASS = "typeclasses.accounts.Account"
|
||||
# Typeclass and base for all objects (fallback)
|
||||
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"
|
||||
# Typeclass for rooms (fallback)
|
||||
BASE_ROOM_TYPECLASS = "typeclasses.rooms.Room"
|
||||
|
|
@ -465,7 +465,7 @@ INLINEFUNC_MODULES = ["evennia.utils.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
|
||||
|
|
@ -473,12 +473,12 @@ INLINEFUNC_MODULES = ["evennia.utils.inlinefuncs",
|
|||
# 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
|
||||
# value (below) defines how many characters the default char_create command
|
||||
# allow per player.
|
||||
# 0 - single session, one player, one character, when a new session is
|
||||
# allow per account.
|
||||
# 0 - single session, one account, one character, when a new session is
|
||||
# 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
|
||||
# 2 - multiple sessions, one player, many characters, one session per
|
||||
# 2 - multiple sessions, one account, many characters, one session per
|
||||
# character (disconnects multiplets)
|
||||
# 3 - like mode 2, except multiple sessions can puppet one character, each
|
||||
# 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()
|
||||
# lock functions, which accepts both plural and singular (Admin & Admins)
|
||||
PERMISSION_HIERARCHY = ["Guest", # note-only used if GUEST_ENABLED=True
|
||||
"Player",
|
||||
"Account",
|
||||
"Helper",
|
||||
"Builder",
|
||||
"Admin",
|
||||
"Developer"]
|
||||
# The default permission given to all new players
|
||||
# The default permission given to all new accounts
|
||||
PERMISSION_PLAYER_DEFAULT = "Player"
|
||||
# Default sizes for client window (in number of characters), if client
|
||||
# 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
|
||||
# you need to edit your login screen to inform about this possibility.
|
||||
GUEST_ENABLED = False
|
||||
# Typeclass for guest player objects (linked to a character)
|
||||
BASE_GUEST_TYPECLASS = "typeclasses.players.Guest"
|
||||
# Typeclass for guest account objects (linked to a character)
|
||||
BASE_GUEST_TYPECLASS = "typeclasses.accounts.Guest"
|
||||
# The permission given to guests
|
||||
PERMISSION_GUEST_DEFAULT = "Guests"
|
||||
# The default home location used for guests.
|
||||
|
|
@ -520,7 +520,7 @@ GUEST_HOME = DEFAULT_HOME
|
|||
# The start position used for guest characters.
|
||||
GUEST_START_LOCATION = START_LOCATION
|
||||
# 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, named Guest1 through Guest9.
|
||||
GUEST_LIST = ["Guest" + str(s+1) for s in range(9)]
|
||||
|
|
@ -551,7 +551,7 @@ DEFAULT_CHANNELS = [
|
|||
"desc": "Connection log",
|
||||
"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.
|
||||
CHANNEL_CONNECTINFO = None
|
||||
|
||||
|
|
@ -716,7 +716,7 @@ INSTALLED_APPS = (
|
|||
'evennia.utils.idmapper',
|
||||
'evennia.server',
|
||||
'evennia.typeclasses',
|
||||
'evennia.players',
|
||||
'evennia.accounts',
|
||||
'evennia.accounts',
|
||||
'evennia.objects',
|
||||
'evennia.comms',
|
||||
|
|
@ -726,7 +726,7 @@ INSTALLED_APPS = (
|
|||
'evennia.web.webclient')
|
||||
# The user profile extends the User object with more functionality;
|
||||
# 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.
|
||||
TEST_RUNNER = 'evennia.server.tests.EvenniaTestSuiteRunner'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
This sub-package defines the typeclass-system, a way to wrap database
|
||||
access into almost-normal Python classes. Using typeclasses one can
|
||||
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
|
||||
Attribute and Tag models are defined along with their handlers.
|
||||
|
||||
|
|
|
|||
|
|
@ -113,13 +113,13 @@ class TagInline(admin.TabularInline):
|
|||
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
|
||||
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.
|
||||
model = None
|
||||
form = TagForm
|
||||
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',)
|
||||
readonly_fields = ('tag',)
|
||||
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
|
||||
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',
|
||||
'msg', 'playerdb', etc.
|
||||
'msg', 'accountdb', etc.
|
||||
"""
|
||||
# Set this to the through model of your desired M2M when subclassing.
|
||||
model = None
|
||||
form = AttributeForm
|
||||
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',)
|
||||
readonly_fields = ('attribute',)
|
||||
extra = 0
|
||||
|
|
|
|||
|
|
@ -868,7 +868,7 @@ class NickHandler(AttributeHandler):
|
|||
"""
|
||||
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.
|
||||
|
||||
|
|
@ -878,8 +878,8 @@ class NickHandler(AttributeHandler):
|
|||
categories (tuple, optional): Replacement categories in
|
||||
which to perform the replacement, such as "inputline",
|
||||
"channel" etc.
|
||||
include_player (bool, optional): Also include replacement
|
||||
with nicks stored on the Player level.
|
||||
include_account (bool, optional): Also include replacement
|
||||
with nicks stored on the Account level.
|
||||
kwargs (any, optional): Not used.
|
||||
|
||||
Returns:
|
||||
|
|
@ -891,9 +891,9 @@ class NickHandler(AttributeHandler):
|
|||
for category in make_iter(categories):
|
||||
nicks.update({nick.key: nick for nick in make_iter(
|
||||
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):
|
||||
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})
|
||||
for key, nick in nicks.iteritems():
|
||||
nick_regex, template, _, _ = nick.value
|
||||
|
|
|
|||
|
|
@ -449,15 +449,15 @@ class TypedObject(SharedMemoryModel):
|
|||
"""
|
||||
This performs an in-situ swap of the typeclass. This means
|
||||
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
|
||||
self.player.swap_object().
|
||||
self.account.swap_object().
|
||||
|
||||
Note that this might be an error prone operation if the
|
||||
old/new typeclass was heavily customized - your code
|
||||
might expect one and not the other, so be careful to
|
||||
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.
|
||||
|
||||
Args:
|
||||
|
|
@ -558,8 +558,8 @@ class TypedObject(SharedMemoryModel):
|
|||
result (bool): If the permstring is passed or not.
|
||||
|
||||
"""
|
||||
if hasattr(self, "player"):
|
||||
if self.player and self.player.is_superuser and not self.player.attributes.get("_quell"):
|
||||
if hasattr(self, "account"):
|
||||
if self.account and self.account.is_superuser and not self.account.attributes.get("_quell"):
|
||||
return True
|
||||
else:
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Returns:
|
||||
|
|
@ -707,7 +707,7 @@ class TypedObject(SharedMemoryModel):
|
|||
not in your normal inventory listing.
|
||||
|
||||
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.
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Models covered:
|
|||
Help
|
||||
Message
|
||||
Channel
|
||||
Players
|
||||
Accounts
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.db import IntegrityError
|
||||
|
|
@ -35,8 +35,8 @@ _Script = None
|
|||
_ScriptDB = None
|
||||
_HelpEntry = None
|
||||
_Msg = None
|
||||
_Player = None
|
||||
_PlayerDB = None
|
||||
_Account = None
|
||||
_AccountDB = None
|
||||
_to_object = None
|
||||
_ChannelDB = None
|
||||
_channelhandler = None
|
||||
|
|
@ -44,7 +44,7 @@ _channelhandler = None
|
|||
|
||||
# limit symbol import from API
|
||||
__all__ = ("create_object", "create_script", "create_help_entry",
|
||||
"create_message", "create_channel", "create_player")
|
||||
"create_message", "create_channel", "create_account")
|
||||
|
||||
_GA = object.__getattribute__
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ object = create_object
|
|||
#
|
||||
# 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,
|
||||
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.
|
||||
obj (Object): The entity on which this Script sits. If this
|
||||
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`.
|
||||
locks (str): one or more lockstrings, separated by semicolons.
|
||||
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
|
||||
kwarg = {}
|
||||
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 interval: kwarg["db_interval"] = interval
|
||||
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)
|
||||
|
||||
# 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,
|
||||
autostart=autostart, report_to=report_to)
|
||||
# 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.
|
||||
|
||||
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
|
||||
etc should all be included in this text string. Formatting
|
||||
will be retained.
|
||||
channels (Channel, key or list): A channel or a list of channels to
|
||||
send to. The channels may be actual channel objects or their
|
||||
unique key strings.
|
||||
receivers (Object, Player, str or list): A Player/Object to send
|
||||
to, or a list of them. May be Player objects or playernames.
|
||||
receivers (Object, Account, str or list): An Account/Object to send
|
||||
to, or a list of them. May be Account objects or accountnames.
|
||||
locks (str): Lock definition string.
|
||||
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
|
||||
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
|
||||
access to all old messages, but this can be turned off with the
|
||||
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,
|
||||
is_superuser=False,
|
||||
locks=None, permissions=None,
|
||||
report_to=None):
|
||||
|
||||
"""
|
||||
This creates a new player.
|
||||
This creates a new account.
|
||||
|
||||
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
|
||||
technically required but if set to `None`, an email of
|
||||
`dummy@example.com` will be used as a placeholder.
|
||||
password (str): Password in cleartext.
|
||||
|
||||
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.
|
||||
permission (list): List of permission strings.
|
||||
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.
|
||||
|
||||
"""
|
||||
global _PlayerDB
|
||||
if not _PlayerDB:
|
||||
from evennia.players.models import PlayerDB as _PlayerDB
|
||||
global _AccountDB
|
||||
if not _AccountDB:
|
||||
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):
|
||||
# a path is given. Load the actual typeclass.
|
||||
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
|
||||
# correctly when each object is recovered).
|
||||
|
||||
if not email:
|
||||
email = "dummy@example.com"
|
||||
if _PlayerDB.objects.filter(username__iexact=key):
|
||||
raise ValueError("A Player with the name '%s' already exists." % key)
|
||||
if _AccountDB.objects.filter(username__iexact=key):
|
||||
raise ValueError("An Account with the name '%s' already exists." % key)
|
||||
|
||||
# this handles a given dbref-relocate to a player.
|
||||
report_to = dbid_to_obj(report_to, _PlayerDB)
|
||||
# this handles a given dbref-relocate to an account.
|
||||
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.
|
||||
now = timezone.now()
|
||||
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,
|
||||
last_login=now, date_joined=now)
|
||||
new_player.set_password(password)
|
||||
new_player._createdict = dict(locks=locks, permissions=permissions, report_to=report_to)
|
||||
new_account.set_password(password)
|
||||
new_account._createdict = dict(locks=locks, permissions=permissions, report_to=report_to)
|
||||
# saving will trigger the signal that calls the
|
||||
# at_first_save hook on the typeclass, where the _createdict
|
||||
# can be used.
|
||||
new_player.save()
|
||||
return new_player
|
||||
new_account.save()
|
||||
return new_account
|
||||
|
||||
# alias
|
||||
player = create_player
|
||||
account = create_account
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ def unpack_dbobj(item):
|
|||
def pack_session(item):
|
||||
"""
|
||||
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).
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -242,13 +242,13 @@ class CmdEvMenuNode(Command):
|
|||
|
||||
caller = self.caller
|
||||
# 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
|
||||
if not menu:
|
||||
if _restore(caller):
|
||||
return
|
||||
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
|
||||
if not menu:
|
||||
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
|
||||
raise EvMenuError(err)
|
||||
# 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
|
||||
# we have a menu, use it.
|
||||
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.
|
||||
|
||||
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
|
||||
holding the menu tree data. All global functions in this module
|
||||
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
|
||||
a user input text from a fictional previous node. When the server reloads,
|
||||
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
|
||||
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
|
||||
|
|
@ -777,7 +777,7 @@ class EvMenu(object):
|
|||
Args:
|
||||
optionlist (list): List of (key, description) tuples for every
|
||||
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:
|
||||
options (str): The formatted option display.
|
||||
|
|
@ -841,7 +841,7 @@ class EvMenu(object):
|
|||
Args:
|
||||
nodetext (str): The node text as returned by `self.nodetext_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:
|
||||
node (str): The formatted node to display.
|
||||
|
|
@ -874,9 +874,9 @@ class CmdGetInput(Command):
|
|||
caller = self.caller
|
||||
try:
|
||||
getinput = caller.ndb._getinput
|
||||
if not getinput and hasattr(caller, "player"):
|
||||
getinput = caller.player.ndb._getinput
|
||||
caller = caller.player
|
||||
if not getinput and hasattr(caller, "account"):
|
||||
getinput = caller.account.ndb._getinput
|
||||
caller = caller.account
|
||||
callback = getinput._callback
|
||||
|
||||
caller.ndb._getinput._session = self.session
|
||||
|
|
@ -925,7 +925,7 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs):
|
|||
the caller.
|
||||
|
||||
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
|
||||
controlled by a 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.
|
||||
session (Session, optional): This allows to specify the
|
||||
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
|
||||
command and is available (for example in callbacks)
|
||||
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
|
||||
when the prompt finishes.
|
||||
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
|
||||
callback through `caller.ndb._getinput._session`.
|
||||
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ class CmdMore(Command):
|
|||
Implement the command
|
||||
"""
|
||||
more = self.caller.ndb._more
|
||||
if not more and hasattr(self.caller, "player"):
|
||||
more = self.caller.player.ndb._more
|
||||
if not more and hasattr(self.caller, "account"):
|
||||
more = self.caller.account.ndb._more
|
||||
if not more:
|
||||
self.caller.msg("Error in loading the pager. Contact an admin.")
|
||||
return
|
||||
|
|
@ -94,8 +94,8 @@ class CmdMoreLook(Command):
|
|||
Implement the command
|
||||
"""
|
||||
more = self.caller.ndb._more
|
||||
if not more and hasattr(self.caller, "player"):
|
||||
more = self.caller.player.ndb._more
|
||||
if not more and hasattr(self.caller, "account"):
|
||||
more = self.caller.account.ndb._more
|
||||
if not more:
|
||||
self.caller.msg("Error in loading the pager. Contact an admin.")
|
||||
return
|
||||
|
|
@ -124,7 +124,7 @@ class EvMore(object):
|
|||
Initialization of the text handler.
|
||||
|
||||
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.
|
||||
always_page (bool, optional): If `False`, the
|
||||
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.
|
||||
|
||||
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.
|
||||
always_page (bool, optional): If `False`, the
|
||||
pager will only kick in if `text` is too big
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ the database model and call its 'objects' property.
|
|||
Also remember that all commands in this file return lists (also if
|
||||
there is only one match) unless noted otherwise.
|
||||
|
||||
Example: To reach the search method 'get_object_with_player'
|
||||
Example: To reach the search method 'get_object_with_account'
|
||||
in evennia/objects/managers.py:
|
||||
|
||||
> 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
|
||||
|
||||
# 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_object_tag", "search_script_tag", "search_player_tag",
|
||||
"search_object_tag", "search_script_tag", "search_account_tag",
|
||||
"search_channel_tag")
|
||||
|
||||
|
||||
# import objects this way to avoid circular import problems
|
||||
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()
|
||||
Msg = ContentType.objects.get(app_label="comms", model="msg").model_class()
|
||||
Channel = ContentType.objects.get(app_label="comms", model="channeldb").model_class()
|
||||
|
|
@ -99,20 +99,20 @@ object_search = search_object
|
|||
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.
|
||||
#
|
||||
# ostring = a string or database id.
|
||||
#
|
||||
|
||||
search_player = PlayerDB.objects.player_search
|
||||
search_players = search_player
|
||||
player_search = search_player
|
||||
players = search_players
|
||||
search_account = AccountDB.objects.account_search
|
||||
search_accounts = search_account
|
||||
account_search = search_account
|
||||
accounts = search_accounts
|
||||
|
||||
#
|
||||
# Searching for scripts
|
||||
|
|
@ -140,8 +140,8 @@ scripts = search_scripts
|
|||
# Search the message database for particular messages. At least one
|
||||
# of the arguments must be given to do a search.
|
||||
#
|
||||
# sender - get messages sent by a particular player
|
||||
# receiver - get messages received by a certain player
|
||||
# sender - get messages sent by a particular account
|
||||
# receiver - get messages received by a certain account
|
||||
# channel - get messages sent to a particular channel
|
||||
# freetext - Search for a text string in a message.
|
||||
# NOTE: This can potentially be slow, so make sure to supply
|
||||
|
|
@ -190,7 +190,7 @@ help_entries = search_help
|
|||
# Locate Attributes
|
||||
|
||||
# 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_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)
|
||||
|
||||
|
||||
def search_player_attribute(key=None, category=None, value=None, strvalue=None):
|
||||
return PlayerDB.objects.get_by_attribute(key=key, category=category, value=value, strvalue=strvalue)
|
||||
def search_account_attribute(key=None, category=None, value=None, strvalue=None):
|
||||
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):
|
||||
|
|
@ -218,7 +218,7 @@ search_attribute_object = ObjectDB.objects.get_attribute
|
|||
# Locate Tags
|
||||
|
||||
# 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_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
|
||||
|
||||
|
||||
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:
|
||||
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.
|
||||
|
||||
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
|
||||
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):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from django.conf import settings
|
|||
from django.test import TestCase
|
||||
from mock import Mock
|
||||
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.server.serversession import ServerSession
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
|
|
@ -18,7 +18,7 @@ class EvenniaTest(TestCase):
|
|||
"""
|
||||
Base test for Evennia, sets up a basic environment.
|
||||
"""
|
||||
player_typeclass = DefaultPlayer
|
||||
account_typeclass = DefaultAccount
|
||||
object_typeclass = DefaultObject
|
||||
character_typeclass = DefaultCharacter
|
||||
exit_typeclass = DefaultExit
|
||||
|
|
@ -29,8 +29,8 @@ class EvenniaTest(TestCase):
|
|||
"""
|
||||
Sets up testing environment
|
||||
"""
|
||||
self.player = create.create_player("TestPlayer", email="test@test.com", password="testpassword", typeclass=self.player_typeclass)
|
||||
self.player2 = create.create_player("TestPlayer2", 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.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.db.desc = "room_desc"
|
||||
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.permissions.add("Developer")
|
||||
self.char2 = create.create_object(self.character_typeclass, key="Char2", location=self.room1, home=self.room1)
|
||||
self.char1.player = self.player
|
||||
self.player.db._last_puppet = self.char1
|
||||
self.char2.player = self.player2
|
||||
self.player2.db._last_puppet = self.char2
|
||||
self.char1.account = self.account
|
||||
self.account.db._last_puppet = self.char1
|
||||
self.char2.account = self.account2
|
||||
self.account2.db._last_puppet = self.char2
|
||||
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
|
||||
|
||||
|
|
@ -55,12 +55,12 @@ class EvenniaTest(TestCase):
|
|||
dummysession.sessid = 1
|
||||
SESSIONS.portal_connect(dummysession.get_sync_data()) # note that this creates a new 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
|
||||
|
||||
def tearDown(self):
|
||||
flush_cache()
|
||||
del SESSIONS[self.session.sessid]
|
||||
self.player.delete()
|
||||
self.player2.delete()
|
||||
self.account.delete()
|
||||
self.account2.delete()
|
||||
super(EvenniaTest, self).tearDown()
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ class TestEvForm(TestCase):
|
|||
u'| |\n'
|
||||
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'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'|\n'
|
||||
u'| \x1b[0m\x1b[1m\x1b[32mBouncer\x1b[0m \x1b[0m |\n'
|
||||
|
|
|
|||
|
|
@ -1384,12 +1384,12 @@ def class_from_module(path, defaultpaths=None):
|
|||
object_from_module = class_from_module
|
||||
|
||||
|
||||
def init_new_player(player):
|
||||
def init_new_account(account):
|
||||
"""
|
||||
Deprecated.
|
||||
"""
|
||||
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):
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ class CaseInsensitiveModelBackend(ModelBackend):
|
|||
Args:
|
||||
username (str, optional): Name of user to authenticate.
|
||||
password (str, optional): Password of user
|
||||
autologin (Player, optional): If given, assume this is
|
||||
an already authenticated player and bypass authentication.
|
||||
autologin (Account, optional): If given, assume this is
|
||||
an already authenticated account and bypass authentication.
|
||||
"""
|
||||
if autologin:
|
||||
# Note: Setting .backend on player is critical in order to
|
||||
# be allowed to call django.auth.login(player) later. This
|
||||
# Note: Setting .backend on account is critical in order to
|
||||
# be allowed to call django.auth.login(account) later. This
|
||||
# is necessary for the auto-login feature of the webclient,
|
||||
# but it's important to make sure Django doesn't change this
|
||||
# requirement or the name of the property down the line. /Griatch
|
||||
|
|
@ -29,12 +29,12 @@ class CaseInsensitiveModelBackend(ModelBackend):
|
|||
else:
|
||||
# In this case .backend will be assigned automatically
|
||||
# somewhere along the way.
|
||||
Player = get_user_model()
|
||||
Account = get_user_model()
|
||||
try:
|
||||
player = Player.objects.get(username__iexact=username)
|
||||
if player.check_password(password):
|
||||
return player
|
||||
account = Account.objects.get(username__iexact=username)
|
||||
if account.check_password(password):
|
||||
return account
|
||||
else:
|
||||
return None
|
||||
except Player.DoesNotExist:
|
||||
except Account.DoesNotExist:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ except AttributeError:
|
|||
# Setup lists of the most relevant apps so
|
||||
# the adminsite becomes more readable.
|
||||
|
||||
PLAYER_RELATED = ['Players']
|
||||
ACCOUNT_RELATED = ['Accounts']
|
||||
GAME_ENTITIES = ['Objects', 'Scripts', 'Comms', 'Help']
|
||||
GAME_SETUP = ['Permissions', 'Config']
|
||||
CONNECTIONS = ['Irc']
|
||||
|
|
@ -46,7 +46,7 @@ def general_context(request):
|
|||
return {
|
||||
'game_name': GAME_NAME,
|
||||
'game_slogan': GAME_SLOGAN,
|
||||
'evennia_userapps': PLAYER_RELATED,
|
||||
'evennia_userapps': ACCOUNT_RELATED,
|
||||
'evennia_entityapps': GAME_ENTITIES,
|
||||
'evennia_setupapps': GAME_SETUP,
|
||||
'evennia_connectapps': CONNECTIONS,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from __future__ import print_function
|
|||
from django.shortcuts import render
|
||||
from django.contrib.auth import login, authenticate
|
||||
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.utils import logger
|
||||
|
||||
|
||||
|
|
@ -18,24 +18,24 @@ def _shared_login(request):
|
|||
|
||||
"""
|
||||
csession = request.session
|
||||
player = request.user
|
||||
account = request.user
|
||||
sesslogin = csession.get("logged_in", None)
|
||||
|
||||
# check if user has authenticated to website
|
||||
if csession.session_key is None:
|
||||
# this is necessary to build the sessid key
|
||||
csession.save()
|
||||
elif player.is_authenticated():
|
||||
elif account.is_authenticated():
|
||||
if not sesslogin:
|
||||
# User has already authenticated to website
|
||||
csession["logged_in"] = player.id
|
||||
csession["logged_in"] = account.id
|
||||
elif sesslogin:
|
||||
# The webclient has previously registered a login to this browser_session
|
||||
player = PlayerDB.objects.get(id=sesslogin)
|
||||
account = AccountDB.objects.get(id=sesslogin)
|
||||
try:
|
||||
# calls our custom authenticate in web/utils/backends.py
|
||||
player = authenticate(autologin=player)
|
||||
login(request, player)
|
||||
account = authenticate(autologin=account)
|
||||
login(request, account)
|
||||
except AttributeError:
|
||||
logger.log_trace()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from django.shortcuts import render
|
|||
|
||||
from evennia import SESSION_HANDLER
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.players.models import PlayerDB
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.utils import logger
|
||||
|
||||
from django.contrib.auth import login
|
||||
|
|
@ -27,22 +27,22 @@ def _shared_login(request):
|
|||
|
||||
"""
|
||||
csession = request.session
|
||||
player = request.user
|
||||
account = request.user
|
||||
sesslogin = csession.get("logged_in", None)
|
||||
|
||||
if csession.session_key is None:
|
||||
# this is necessary to build the sessid key
|
||||
csession.save()
|
||||
elif player.is_authenticated():
|
||||
elif account.is_authenticated():
|
||||
if not sesslogin:
|
||||
csession["logged_in"] = player.id
|
||||
csession["logged_in"] = account.id
|
||||
elif sesslogin:
|
||||
# The webclient has previously registered a login to this csession
|
||||
player = PlayerDB.objects.get(id=sesslogin)
|
||||
account = AccountDB.objects.get(id=sesslogin)
|
||||
try:
|
||||
# calls our custom authenticate, in web/utils/backend.py
|
||||
authenticate(autologin=player)
|
||||
login(request, player)
|
||||
authenticate(autologin=account)
|
||||
login(request, account)
|
||||
except AttributeError:
|
||||
logger.log_trace()
|
||||
|
||||
|
|
@ -50,15 +50,15 @@ def _shared_login(request):
|
|||
def _gamestats():
|
||||
# Some misc. configurable stuff.
|
||||
# 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.
|
||||
recent_users = PlayerDB.objects.get_recently_connected_players()[:fpage_player_limit]
|
||||
# A QuerySet of the most recently connected accounts.
|
||||
recent_users = AccountDB.objects.get_recently_connected_accounts()[:fpage_account_limit]
|
||||
nplyrs_conn_recent = len(recent_users) or "none"
|
||||
nplyrs = PlayerDB.objects.num_total_players() or "none"
|
||||
nplyrs_reg_recent = len(PlayerDB.objects.get_recently_created_players()) or "none"
|
||||
nsess = SESSION_HANDLER.player_count()
|
||||
# nsess = len(PlayerDB.objects.get_connected_players()) or "no one"
|
||||
nplyrs = AccountDB.objects.num_total_accounts() or "none"
|
||||
nplyrs_reg_recent = len(AccountDB.objects.get_recently_created_accounts()) or "none"
|
||||
nsess = SESSION_HANDLER.account_count()
|
||||
# nsess = len(AccountDB.objects.get_connected_accounts()) or "no one"
|
||||
|
||||
nobjs = ObjectDB.objects.all().count()
|
||||
nrooms = ObjectDB.objects.filter(db_location__isnull=True).exclude(db_typeclass_path=_BASE_CHAR_TYPECLASS).count()
|
||||
|
|
@ -68,11 +68,11 @@ def _gamestats():
|
|||
|
||||
pagevars = {
|
||||
"page_title": "Front Page",
|
||||
"players_connected_recent": recent_users,
|
||||
"num_players_connected": nsess or "no one",
|
||||
"num_players_registered": nplyrs or "no",
|
||||
"num_players_connected_recent": nplyrs_conn_recent or "no",
|
||||
"num_players_registered_recent": nplyrs_reg_recent or "no one",
|
||||
"accounts_connected_recent": recent_users,
|
||||
"num_accounts_connected": nsess or "no one",
|
||||
"num_accounts_registered": nplyrs or "no",
|
||||
"num_accounts_connected_recent": nplyrs_conn_recent or "no",
|
||||
"num_accounts_registered_recent": nplyrs_reg_recent or "no one",
|
||||
"num_rooms": nrooms or "none",
|
||||
"num_exits": nexits or "no",
|
||||
"num_objects": nobjs or "none",
|
||||
|
|
@ -116,7 +116,7 @@ def evennia_admin(request):
|
|||
"""
|
||||
return render(
|
||||
request, 'evennia_admin.html', {
|
||||
'playerdb': PlayerDB})
|
||||
'accountdb': AccountDB})
|
||||
|
||||
|
||||
def admin_wrapper(request):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue