Fixed bugs and allowed for logging in using one character. Added a simple command for creating a new character.
This commit is contained in:
parent
f1767251c6
commit
b26c3ab872
11 changed files with 204 additions and 111 deletions
|
|
@ -23,6 +23,7 @@ class OOCCmdSet(CmdSet):
|
||||||
self.add(general.CmdOOCLook())
|
self.add(general.CmdOOCLook())
|
||||||
self.add(general.CmdIC())
|
self.add(general.CmdIC())
|
||||||
self.add(general.CmdOOC())
|
self.add(general.CmdOOC())
|
||||||
|
self.add(general.CmdCharCreate())
|
||||||
self.add(general.CmdEncoding())
|
self.add(general.CmdEncoding())
|
||||||
self.add(general.CmdQuit())
|
self.add(general.CmdQuit())
|
||||||
self.add(general.CmdPassword())
|
self.add(general.CmdPassword())
|
||||||
|
|
@ -34,6 +35,7 @@ class OOCCmdSet(CmdSet):
|
||||||
self.add(system.CmdReload())
|
self.add(system.CmdReload())
|
||||||
self.add(system.CmdReset())
|
self.add(system.CmdReset())
|
||||||
self.add(system.CmdShutdown())
|
self.add(system.CmdShutdown())
|
||||||
|
self.add(system.CmdPy())
|
||||||
|
|
||||||
# Admin commands
|
# Admin commands
|
||||||
self.add(admin.CmdDelPlayer())
|
self.add(admin.CmdDelPlayer())
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ now.
|
||||||
import time
|
import time
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.server.sessionhandler import SESSIONS
|
from src.server.sessionhandler import SESSIONS
|
||||||
from src.utils import utils, search
|
from src.utils import utils, search, create
|
||||||
from src.objects.models import ObjectNick as Nick
|
from src.objects.models import ObjectNick as Nick
|
||||||
from src.commands.default.muxcommand import MuxCommand, MuxCommandOOC
|
from src.commands.default.muxcommand import MuxCommand, MuxCommandOOC
|
||||||
|
|
||||||
|
|
@ -573,7 +573,7 @@ class CmdEncoding(MuxCommand):
|
||||||
Common encodings are utf-8 (default), latin-1, ISO-8859-1 etc.
|
Common encodings are utf-8 (default), latin-1, ISO-8859-1 etc.
|
||||||
|
|
||||||
If you don't submit an encoding, the current encoding will be displayed instead.
|
If you don't submit an encoding, the current encoding will be displayed instead.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = "@encoding"
|
key = "@encoding"
|
||||||
aliases = "@encode"
|
aliases = "@encode"
|
||||||
|
|
@ -649,7 +649,62 @@ class CmdAccess(MuxCommand):
|
||||||
string += "\nPlayer {c%s{n: %s" % (caller.player.key, pperms)
|
string += "\nPlayer {c%s{n: %s" % (caller.player.key, pperms)
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
class CmdColorTest(MuxCommand):
|
||||||
|
"""
|
||||||
|
testing colors
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
@color ansi|xterm256
|
||||||
|
|
||||||
|
Print a color map along with in-mud color codes, while testing 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"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"Show color tables"
|
||||||
|
|
||||||
|
if not self.args or not self.args in ("ansi", "xterm256"):
|
||||||
|
self.caller.msg("Usage: @color ansi|xterm256")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.args == "ansi":
|
||||||
|
from src.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[:-1]]
|
||||||
|
hi = "%ch"
|
||||||
|
col2 = ["%s%s{n" % (code, code.replace("%", "%%")) for code, _ in ap.mux_ansi_map[:-2]]
|
||||||
|
col3 = ["%s%s{n" % (hi+code, (hi+code).replace("%", "%%")) for code, _ in ap.mux_ansi_map[:-2]]
|
||||||
|
table = utils.format_table([col1, col2, col3], extra_space=1)
|
||||||
|
string = "ANSI colors:"
|
||||||
|
for row in table:
|
||||||
|
string += "\n" + "".join(row)
|
||||||
|
print string
|
||||||
|
self.caller.msg(string)
|
||||||
|
self.caller.msg("{{X and %%cx are black-on-black)")
|
||||||
|
elif self.args == "xterm256":
|
||||||
|
table = [[],[],[],[],[],[],[],[],[],[],[],[]]
|
||||||
|
for ir in range(6):
|
||||||
|
for ig in range(6):
|
||||||
|
for ib in range(6):
|
||||||
|
# foreground table
|
||||||
|
table[ir].append("%%c%i%i%i%s{n" % (ir,ig,ib, "{{%i%i%i" % (ir,ig,ib)))
|
||||||
|
# background table
|
||||||
|
table[6+ir].append("%%cb%i%i%i%%c%i%i%i%s{n" % (ir,ig,ib,
|
||||||
|
5-ir,5-ig,5-ib,
|
||||||
|
"{{b%i%i%i" % (ir,ig,ib)))
|
||||||
|
table = utils.format_table(table)
|
||||||
|
string = "Xterm256 colors:"
|
||||||
|
for row in table:
|
||||||
|
string += "\n" + "".join(row)
|
||||||
|
self.caller.msg(string)
|
||||||
|
self.caller.msg("(e.g. %%c123 and %%cb123 also work)")
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
@ -724,6 +779,49 @@ class CmdOOCLook(MuxCommandOOC, CmdLook):
|
||||||
else:
|
else:
|
||||||
self.no_look_target()
|
self.no_look_target()
|
||||||
|
|
||||||
|
class CmdCharCreate(MuxCommandOOC):
|
||||||
|
"""
|
||||||
|
Create a character
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
@charcreate <charname> [= desc]
|
||||||
|
|
||||||
|
Create a new character, optionally giving it a description.
|
||||||
|
"""
|
||||||
|
key = "@charcreate"
|
||||||
|
locks = "cmd:all()"
|
||||||
|
help_category = "General"
|
||||||
|
|
||||||
|
MAX_NR_CHARACTERS = 2
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"create the new character"
|
||||||
|
player = self.caller
|
||||||
|
if not self.args:
|
||||||
|
player.msg("Usage: @charcreate <charname> [= description]")
|
||||||
|
return
|
||||||
|
key = self.lhs
|
||||||
|
desc = self.rhs
|
||||||
|
if not player.db._created_chars:
|
||||||
|
lockstring = "attrread:perm(Admins);attredit:perm(Admins);attrcreate:perm(Admins)"
|
||||||
|
player.set_attribute("_created_chars", [], lockstring=lockstring)
|
||||||
|
if len(player.db._created_chars) >= self.MAX_NR_CHARACTERS:
|
||||||
|
player.msg("You may only create a maximum of %i characters." % self.MAX_NR_CHARACTERS)
|
||||||
|
return
|
||||||
|
# create the character
|
||||||
|
from src.objects.models import ObjectDB
|
||||||
|
|
||||||
|
default_home = ObjectDB.objects.get_id(settings.CHARACTER_DEFAULT_HOME)
|
||||||
|
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||||
|
permissions = settings.PERMISSION_PLAYER_DEFAULT
|
||||||
|
|
||||||
|
new_character = create.create_object(typeclass, key=key, location=default_home,
|
||||||
|
home=default_home, permissions=permissions)
|
||||||
|
player.db._created_chars.append(new_character)
|
||||||
|
if desc:
|
||||||
|
new_character.db.desc = desc
|
||||||
|
player.msg("Created new character %s." % new_character.key)
|
||||||
|
|
||||||
|
|
||||||
class CmdIC(MuxCommandOOC):
|
class CmdIC(MuxCommandOOC):
|
||||||
"""
|
"""
|
||||||
|
|
@ -753,6 +851,7 @@ class CmdIC(MuxCommandOOC):
|
||||||
Simple puppet method
|
Simple puppet method
|
||||||
"""
|
"""
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
sessid = self.sessid
|
||||||
old_character = self.character
|
old_character = self.character
|
||||||
|
|
||||||
new_character = None
|
new_character = None
|
||||||
|
|
@ -769,16 +868,21 @@ class CmdIC(MuxCommandOOC):
|
||||||
else:
|
else:
|
||||||
# the search method handles error messages etc.
|
# the search method handles error messages etc.
|
||||||
return
|
return
|
||||||
if new_character.player:
|
# permission checks
|
||||||
if new_character.player == caller:
|
if caller.get_character(sessid=sessid, character=new_character):
|
||||||
caller.msg("{RYou already are {c%s{n." % new_character.name)
|
caller.msg("{RYou already act as {c%s{n." % new_character.name)
|
||||||
else:
|
|
||||||
caller.msg("{c%s{r is already acted by another player.{n" % new_character.name)
|
|
||||||
return
|
return
|
||||||
|
if new_character.player:
|
||||||
|
if new_character.sessid == sessid:
|
||||||
|
caller.msg("{RYou already act as {c%s{n from another session." % new_character.name)
|
||||||
|
return
|
||||||
|
elif not caller.get_character(character=new_character):
|
||||||
|
caller.msg("{c%s{r is already acted by another player.{n" % new_character.name)
|
||||||
|
return
|
||||||
if not new_character.access(caller, "puppet"):
|
if not new_character.access(caller, "puppet"):
|
||||||
caller.msg("{rYou may not become %s.{n" % new_character.name)
|
caller.msg("{rYou may not become %s.{n" % new_character.name)
|
||||||
return
|
return
|
||||||
if caller.swap_character(new_character):
|
if caller.connect_character(new_character, sessid=sessid):
|
||||||
new_character.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
new_character.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
||||||
caller.db.last_puppet = old_character
|
caller.db.last_puppet = old_character
|
||||||
if not new_character.location:
|
if not new_character.location:
|
||||||
|
|
@ -819,79 +923,22 @@ class CmdOOC(MuxCommandOOC):
|
||||||
if utils.inherits_from(caller, "src.objects.objects.Object"):
|
if utils.inherits_from(caller, "src.objects.objects.Object"):
|
||||||
caller = self.caller.player
|
caller = self.caller.player
|
||||||
|
|
||||||
if not caller.character:
|
old_char = caller.get_character(sessid=self.sessid)
|
||||||
|
if not old_char:
|
||||||
string = "You are already OOC."
|
string = "You are already OOC."
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
caller.db.last_puppet = caller.character
|
caller.db.last_puppet = old_char
|
||||||
# save location as if we were disconnecting from the game entirely.
|
# save location as if we were disconnecting from the game entirely.
|
||||||
if caller.character.location:
|
if old_char.location:
|
||||||
caller.character.location.msg_contents("%s has left the game." % caller.character.key, exclude=[caller.character])
|
old_char.location.msg_contents("%s has left the game." % old_char.key, exclude=[old_char])
|
||||||
caller.character.db.prelogout_location = caller.character.location
|
old_char.db.prelogout_location = old_char.location
|
||||||
caller.character.location = None
|
old_char.location = None
|
||||||
|
|
||||||
# disconnect
|
# disconnect
|
||||||
caller.character.player = None
|
caller.disconnect_character(caller)
|
||||||
caller.character = None
|
|
||||||
|
|
||||||
caller.msg("\n{GYou go OOC.{n\n")
|
caller.msg("\n{GYou go OOC.{n\n")
|
||||||
caller.execute_cmd("look")
|
caller.execute_cmd("look")
|
||||||
|
|
||||||
class CmdColorTest(MuxCommand):
|
|
||||||
"""
|
|
||||||
testing colors
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
@color ansi|xterm256
|
|
||||||
|
|
||||||
Print a color map along with in-mud color codes, while testing 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"
|
|
||||||
|
|
||||||
def func(self):
|
|
||||||
"Show color tables"
|
|
||||||
|
|
||||||
if not self.args or not self.args in ("ansi", "xterm256"):
|
|
||||||
self.caller.msg("Usage: @color ansi|xterm256")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.args == "ansi":
|
|
||||||
from src.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[:-1]]
|
|
||||||
hi = "%ch"
|
|
||||||
col2 = ["%s%s{n" % (code, code.replace("%", "%%")) for code, _ in ap.mux_ansi_map[:-2]]
|
|
||||||
col3 = ["%s%s{n" % (hi+code, (hi+code).replace("%", "%%")) for code, _ in ap.mux_ansi_map[:-2]]
|
|
||||||
table = utils.format_table([col1, col2, col3], extra_space=1)
|
|
||||||
string = "ANSI colors:"
|
|
||||||
for row in table:
|
|
||||||
string += "\n" + "".join(row)
|
|
||||||
print string
|
|
||||||
self.caller.msg(string)
|
|
||||||
self.caller.msg("{{X and %%cx are black-on-black)")
|
|
||||||
elif self.args == "xterm256":
|
|
||||||
table = [[],[],[],[],[],[],[],[],[],[],[],[]]
|
|
||||||
for ir in range(6):
|
|
||||||
for ig in range(6):
|
|
||||||
for ib in range(6):
|
|
||||||
# foreground table
|
|
||||||
table[ir].append("%%c%i%i%i%s{n" % (ir,ig,ib, "{{%i%i%i" % (ir,ig,ib)))
|
|
||||||
# background table
|
|
||||||
table[6+ir].append("%%cb%i%i%i%%c%i%i%i%s{n" % (ir,ig,ib,
|
|
||||||
5-ir,5-ig,5-ib,
|
|
||||||
"{{b%i%i%i" % (ir,ig,ib)))
|
|
||||||
table = utils.format_table(table)
|
|
||||||
string = "Xterm256 colors:"
|
|
||||||
for row in table:
|
|
||||||
string += "\n" + "".join(row)
|
|
||||||
self.caller.msg(string)
|
|
||||||
self.caller.msg("(e.g. %%c123 and %%cb123 also work)")
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,6 @@ class MuxCommandOOC(MuxCommand):
|
||||||
self.caller = self.caller.player
|
self.caller = self.caller.player
|
||||||
elif hasattr(self.caller, "character"):
|
elif hasattr(self.caller, "character"):
|
||||||
# caller was already a Player
|
# caller was already a Player
|
||||||
self.character = self.caller.character
|
self.character = self.caller.get_character(sessid=self.sessid)
|
||||||
else:
|
else:
|
||||||
self.character = None
|
self.character = None
|
||||||
|
|
|
||||||
|
|
@ -146,11 +146,13 @@ class CmdPy(MuxCommand):
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# check if caller is a player
|
||||||
|
|
||||||
# import useful variables
|
# import useful variables
|
||||||
import ev
|
import ev
|
||||||
available_vars = {'self':caller,
|
available_vars = {'self':caller,
|
||||||
'me':caller,
|
'me':caller,
|
||||||
'here':caller.location,
|
'here':hasattr(caller, "location") and caller.location or None,
|
||||||
'ev':ev,
|
'ev':ev,
|
||||||
'inherits_from':utils.inherits_from}
|
'inherits_from':utils.inherits_from}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -365,3 +365,12 @@ class ObjectManager(TypedObjectManager):
|
||||||
ScriptDB.objects.copy_script(script, new_obj=new_object.dbobj)
|
ScriptDB.objects.copy_script(script, new_obj=new_object.dbobj)
|
||||||
|
|
||||||
return new_object
|
return new_object
|
||||||
|
|
||||||
|
|
||||||
|
def clear_all_sessids(self):
|
||||||
|
"""
|
||||||
|
Clear the db_sessid field of all objects having also the db_player field
|
||||||
|
set.
|
||||||
|
"""
|
||||||
|
self.filter(db_sessid__isnull=False).update(db_sessid=None)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ class Object(TypeClass):
|
||||||
ignore_errors=ignore_errors,
|
ignore_errors=ignore_errors,
|
||||||
player=player)
|
player=player)
|
||||||
|
|
||||||
def execute_cmd(self, raw_string):
|
def execute_cmd(self, raw_string, sessid=None):
|
||||||
"""
|
"""
|
||||||
Do something as this object. This command transparently
|
Do something as this object. This command transparently
|
||||||
lets its typeclass execute the command. Evennia also calls
|
lets its typeclass execute the command. Evennia also calls
|
||||||
|
|
@ -209,6 +209,7 @@ class Object(TypeClass):
|
||||||
|
|
||||||
Argument:
|
Argument:
|
||||||
raw_string (string) - raw command input
|
raw_string (string) - raw command input
|
||||||
|
sessid (int) - id of session executing the command. This sets the sessid property on the command.
|
||||||
|
|
||||||
Returns Deferred - this is an asynchronous Twisted object that will
|
Returns Deferred - this is an asynchronous Twisted object that will
|
||||||
not fire until the command has actually finished executing. To overload
|
not fire until the command has actually finished executing. To overload
|
||||||
|
|
@ -219,7 +220,7 @@ class Object(TypeClass):
|
||||||
This return is not used at all by Evennia by default, but might be useful
|
This return is not used at all by Evennia by default, but might be useful
|
||||||
for coders intending to implement some sort of nested command structure.
|
for coders intending to implement some sort of nested command structure.
|
||||||
"""
|
"""
|
||||||
return self.dbobj.execute_cmd(raw_string)
|
return self.dbobj.execute_cmd(raw_string, sessid=sessid)
|
||||||
|
|
||||||
def msg(self, message, from_obj=None, data=None):
|
def msg(self, message, from_obj=None, data=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -391,7 +391,7 @@ class PlayerDB(TypedObject):
|
||||||
if sessid:
|
if sessid:
|
||||||
session = _GA(self, "get_session")(sessid)
|
session = _GA(self, "get_session")(sessid)
|
||||||
if session:
|
if session:
|
||||||
char = _GA(self, "get_character")(sessid)
|
char = _GA(self, "get_character")(sessid=sessid)
|
||||||
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data):
|
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data):
|
||||||
# if hook returns false, cancel send
|
# if hook returns false, cancel send
|
||||||
return
|
return
|
||||||
|
|
@ -412,7 +412,7 @@ class PlayerDB(TypedObject):
|
||||||
data - dictionary of optional data
|
data - dictionary of optional data
|
||||||
session - session sending this data
|
session - session sending this data
|
||||||
"""
|
"""
|
||||||
character = _GA(self, "get_character")(sessid)
|
character = _GA(self, "get_character")(sessid=sessid)
|
||||||
if character:
|
if character:
|
||||||
# execute command on character
|
# execute command on character
|
||||||
_GA(character, "execute_cmd")(ingoing_string, sessid=sessid)
|
_GA(character, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||||
|
|
@ -427,9 +427,11 @@ class PlayerDB(TypedObject):
|
||||||
linked to the player using self.connect_character().
|
linked to the player using self.connect_character().
|
||||||
|
|
||||||
force - drop existing connection to other character
|
force - drop existing connection to other character
|
||||||
|
|
||||||
|
Returns True if connection was successful, False otherwise
|
||||||
"""
|
"""
|
||||||
# first check if we already have a character tied to this session
|
# first check if we already have a character tied to this session
|
||||||
char = _GA(self, "get_character")(sessid=sessid)
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
if char:
|
if char:
|
||||||
if force and char != character:
|
if force and char != character:
|
||||||
_GA(self, "disconnect_session_from_character")(sessid)
|
_GA(self, "disconnect_session_from_character")(sessid)
|
||||||
|
|
@ -452,22 +454,27 @@ class PlayerDB(TypedObject):
|
||||||
del character.db.FIRST_LOGIN
|
del character.db.FIRST_LOGIN
|
||||||
character.at_pre_login()
|
character.at_pre_login()
|
||||||
character.at_post_login()
|
character.at_post_login()
|
||||||
|
return True
|
||||||
|
|
||||||
def disconnect_session_from_character(self, sessid):
|
def disconnect_session_from_character(self, sessid):
|
||||||
"""
|
"""
|
||||||
Disconnect a session from the characterm (still keeping the
|
Disconnect a session from the characterm (still keeping the
|
||||||
connection to the Player)
|
connection to the Player)
|
||||||
|
returns the newly disconnected character, if it existed
|
||||||
"""
|
"""
|
||||||
char = _GA(self, "get_character")(sessid=sessid)
|
if not sessid:
|
||||||
|
return
|
||||||
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
if char:
|
if char:
|
||||||
# call hook before disconnecting
|
# call hook before disconnecting
|
||||||
character.at_disconnect()
|
_GA(char.typeclass, "at_disconnect")()
|
||||||
del char.sessid
|
del char.sessid
|
||||||
# update cache
|
# update cache
|
||||||
cache = get_prop_cache(self, "_characters") or {}
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
if sessid in cache:
|
if sessid in cache:
|
||||||
del cache[sessid]
|
del cache[sessid]
|
||||||
set_prop_cache(self, "_characters", cache)
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
return char
|
||||||
|
|
||||||
def get_session(self, sessid):
|
def get_session(self, sessid):
|
||||||
"""
|
"""
|
||||||
|
|
@ -479,9 +486,9 @@ class PlayerDB(TypedObject):
|
||||||
"Return all sessions connected to this player"
|
"Return all sessions connected to this player"
|
||||||
return SESSIONS.sessions_from_player(self)
|
return SESSIONS.sessions_from_player(self)
|
||||||
|
|
||||||
def get_character(self, sessid=None, character=None):
|
def get_character(self, sessid=None, character=None, return_dbobj=False):
|
||||||
"""
|
"""
|
||||||
Get the character connected to this player
|
Get the character connected to this player and sessid
|
||||||
|
|
||||||
sessid - return character connected to this sessid,
|
sessid - return character connected to this sessid,
|
||||||
character - return character if connected to this player, else None.
|
character - return character if connected to this player, else None.
|
||||||
|
|
@ -497,17 +504,18 @@ class PlayerDB(TypedObject):
|
||||||
if not char:
|
if not char:
|
||||||
char = _GA(self, "db_objs").filter(db_player=self, db_sessid=sessid) or None
|
char = _GA(self, "db_objs").filter(db_player=self, db_sessid=sessid) or None
|
||||||
if char:
|
if char:
|
||||||
cache[sessid] = char[0]
|
char = char[0]
|
||||||
|
cache[sessid] = char
|
||||||
set_prop_cache(self, "_characters", cache)
|
set_prop_cache(self, "_characters", cache)
|
||||||
if character:
|
if character:
|
||||||
return char == character.dbobj or None
|
return char and (char == character.dbobj and (return_dbobj and char or char.typeclass)) or None
|
||||||
return char
|
return char and (return_dbobj and char or char.typeclass) or None
|
||||||
elif character:
|
elif character:
|
||||||
char = _GA(self, "db_objs").filter(character)
|
char = _GA(self, "db_objs").filter(id=_GA(character.dbobj, "id"))
|
||||||
return char and char[0] or None
|
return char and (return_dbobj and char[0] or char[0].typeclass) or None
|
||||||
else:
|
else:
|
||||||
# no sessid given - return all available characters
|
# no sessid given - return all available characters
|
||||||
return list(self.db_objs.all())
|
return list(return_dbobj and o or o.typeclass for o in self.db_objs.all())
|
||||||
|
|
||||||
def get_all_characters(self):
|
def get_all_characters(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -515,30 +523,37 @@ class PlayerDB(TypedObject):
|
||||||
"""
|
"""
|
||||||
return _GA(self, "get_character")(sessid=None, character=None)
|
return _GA(self, "get_character")(sessid=None, character=None)
|
||||||
|
|
||||||
def connect_character(self, char):
|
def connect_character(self, character, sessid=None):
|
||||||
"""
|
"""
|
||||||
Use the Player to connect a Character to a session. Note that
|
Use the Player to connect a Character to a session. Note that
|
||||||
we don't do any access checks at this point. Note that if the
|
we don't do any access checks at this point. Note that if the
|
||||||
game was fully restarted (including the Portal), this must be
|
game was fully restarted (including the Portal), this must be
|
||||||
used, since sessids will have changed as players reconnect.
|
used, since sessids will have changed as players reconnect.
|
||||||
|
|
||||||
|
if sessid is given, also connect the sessid to the character.
|
||||||
"""
|
"""
|
||||||
# first disconnect any other character from this session
|
# first disconnect any other character from this session
|
||||||
char = char.dbobj
|
char = character.dbobj
|
||||||
_GA(self, "disconnect_character")(char)
|
_GA(self, "disconnect_character")(char)
|
||||||
char = char.dbobj
|
|
||||||
char.player = self
|
char.player = self
|
||||||
_GA(self, "db_objs").add(char)
|
_GA(self, "db_objs").add(char)
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
|
if sessid:
|
||||||
|
return _GA(self, "connect_session_to_character")(sessid=sessid, character=char)
|
||||||
|
return True
|
||||||
|
|
||||||
def disconnect_character(self, char):
|
def disconnect_character(self, character):
|
||||||
"""
|
"""
|
||||||
Disconnect a character from this player, either based
|
Disconnect a character from this player, either based
|
||||||
on sessid or by giving the character object directly
|
on sessid or by giving the character object directly
|
||||||
|
|
||||||
|
Returns newly disconnected character.
|
||||||
"""
|
"""
|
||||||
char = char.dbobj
|
if not character:
|
||||||
key = char and char.key or None
|
return
|
||||||
char = _GA(self, "get_character")(key=key)
|
char = _GA(self, "get_character")(character=character, return_dbobj=True)
|
||||||
if char:
|
if char:
|
||||||
|
_GA(self, "disconnect_session_from_character")(char.sessid)
|
||||||
_GA(self, "db_objs").remove(char)
|
_GA(self, "db_objs").remove(char)
|
||||||
del char.player
|
del char.player
|
||||||
del char.sessid
|
del char.sessid
|
||||||
|
|
@ -547,16 +562,23 @@ class PlayerDB(TypedObject):
|
||||||
cache = get_prop_cache(self, "_characters") or {}
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
[cache.pop(sessid) for sessid,stored_char in cache.items() if stored_char==char]
|
[cache.pop(sessid) for sessid,stored_char in cache.items() if stored_char==char]
|
||||||
set_prop_cache(self, "_characters", cache)
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
return char
|
||||||
|
|
||||||
|
|
||||||
def disconnect_all_characters(self):
|
def disconnect_all_characters(self):
|
||||||
for char in self.db_objs.all():
|
for char in self.db_objs.all():
|
||||||
_GA(self, "disconnect_character")(char)
|
_GA(self, "disconnect_character")(char)
|
||||||
|
|
||||||
def swap_character(self, new_character, delete_old_character=False):
|
def swap_character(self, old_character, new_character):
|
||||||
"""
|
"""
|
||||||
Swaps character, if possible
|
Swaps character between sessions, if possible
|
||||||
"""
|
"""
|
||||||
return _GA(self, "__class__").objects.swap_character(self, new_character, delete_old_character=delete_old_character)
|
this_sessid = old_character.sessid
|
||||||
|
other_sessd = new_character.sessid
|
||||||
|
this_char = _GA(self, "disconnect_session_from_character")(this_sessid)
|
||||||
|
other_char = _GA(self, "disconnect_session_from_character")(other_sessid)
|
||||||
|
_GA(self, "connect_session_to_character")(this_sessid, other_char)
|
||||||
|
_GA(self, "connect_session_to_character")(other_sessid, this_char)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
"Make sure to delete user also when deleting player - the two may never exist separately."
|
"Make sure to delete user also when deleting player - the two may never exist separately."
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ class Player(TypeClass):
|
||||||
a command on a Character, the character automatically stores and
|
a command on a Character, the character automatically stores and
|
||||||
handles the sessid).
|
handles the sessid).
|
||||||
"""
|
"""
|
||||||
self.dbobj.msg(outgoing_string, from_obj=from_obj, data=data)
|
self.dbobj.msg(outgoing_string, from_obj=from_obj, data=data, sessid=sessid)
|
||||||
|
|
||||||
def swap_character(self, new_character, delete_old_character=False):
|
def swap_character(self, new_character, delete_old_character=False):
|
||||||
"""
|
"""
|
||||||
|
|
@ -115,7 +115,7 @@ class Player(TypeClass):
|
||||||
"""
|
"""
|
||||||
return self.dbobj.swap_character(new_character, delete_old_character=delete_old_character)
|
return self.dbobj.swap_character(new_character, delete_old_character=delete_old_character)
|
||||||
|
|
||||||
def execute_cmd(self, raw_string):
|
def execute_cmd(self, raw_string, sessid=None):
|
||||||
"""
|
"""
|
||||||
Do something as this object. This command transparently
|
Do something as this object. This command transparently
|
||||||
lets its typeclass execute the command. Evennia also calls
|
lets its typeclass execute the command. Evennia also calls
|
||||||
|
|
@ -123,6 +123,7 @@ class Player(TypeClass):
|
||||||
|
|
||||||
Argument:
|
Argument:
|
||||||
raw_string (string) - raw command input
|
raw_string (string) - raw command input
|
||||||
|
sessid (int) - id of session executing the command. This sets the sessid property on the command
|
||||||
|
|
||||||
Returns Deferred - this is an asynchronous Twisted object that will
|
Returns Deferred - this is an asynchronous Twisted object that will
|
||||||
not fire until the command has actually finished executing. To overload
|
not fire until the command has actually finished executing. To overload
|
||||||
|
|
@ -133,7 +134,7 @@ class Player(TypeClass):
|
||||||
This return is not used at all by Evennia by default, but might be useful
|
This return is not used at all by Evennia by default, but might be useful
|
||||||
for coders intending to implement some sort of nested command structure.
|
for coders intending to implement some sort of nested command structure.
|
||||||
"""
|
"""
|
||||||
return self.dbobj.execute_cmd(raw_string)
|
return self.dbobj.execute_cmd(raw_string, sessid=sessid)
|
||||||
|
|
||||||
def search(self, ostring, return_character=False):
|
def search(self, ostring, return_character=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,9 @@ class Evennia(object):
|
||||||
from src.objects.models import ObjectDB
|
from src.objects.models import ObjectDB
|
||||||
#from src.players.models import PlayerDB
|
#from src.players.models import PlayerDB
|
||||||
|
|
||||||
|
# clear eventual lingering session storages
|
||||||
|
ObjectDB.objects.clear_all_sessids()
|
||||||
|
|
||||||
#update eventual changed defaults
|
#update eventual changed defaults
|
||||||
self.update_defaults()
|
self.update_defaults()
|
||||||
|
|
||||||
|
|
@ -288,7 +291,7 @@ class Evennia(object):
|
||||||
|
|
||||||
yield [(p.typeclass, p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()]
|
yield [(p.typeclass, p.at_server_shutdown()) for p in PlayerDB.get_all_cached_instances()]
|
||||||
yield [(s.typeclass, s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
|
yield [(s.typeclass, s.at_server_shutdown()) for s in ScriptDB.get_all_cached_instances()]
|
||||||
|
yield ObjectDB.objects.clear_all_sessids()
|
||||||
ServerConfig.objects.conf("server_restart_mode", "reset")
|
ServerConfig.objects.conf("server_restart_mode", "reset")
|
||||||
|
|
||||||
if SERVER_STARTSTOP_MODULE:
|
if SERVER_STARTSTOP_MODULE:
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ class ServerSession(Session):
|
||||||
else:
|
else:
|
||||||
# we are not logged in. Use the session directly
|
# we are not logged in. Use the session directly
|
||||||
# (it uses the settings.UNLOGGEDIN cmdset)
|
# (it uses the settings.UNLOGGEDIN cmdset)
|
||||||
cmdhandler.cmdhandler(self, command_string)
|
cmdhandler.cmdhandler(self, command_string, sessid=self.sessid)
|
||||||
|
|
||||||
def data_out(self, msg, data=None):
|
def data_out(self, msg, data=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1311,7 +1311,7 @@ class TypedObject(SharedMemoryModel):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_attribute(self, attribute_name, new_value=None):
|
def set_attribute(self, attribute_name, new_value=None, lockstring=""):
|
||||||
"""
|
"""
|
||||||
Sets an attribute on an object. Creates the attribute if need
|
Sets an attribute on an object. Creates the attribute if need
|
||||||
be.
|
be.
|
||||||
|
|
@ -1319,6 +1319,10 @@ class TypedObject(SharedMemoryModel):
|
||||||
attribute_name: (str) The attribute's name.
|
attribute_name: (str) The attribute's name.
|
||||||
new_value: (python obj) The value to set the attribute to. If this is not
|
new_value: (python obj) The value to set the attribute to. If this is not
|
||||||
a str, the object will be stored as a pickle.
|
a str, the object will be stored as a pickle.
|
||||||
|
lockstring - this sets an access restriction on the attribute object. Note that
|
||||||
|
this is normally NOT checked - use the secureattr() access method
|
||||||
|
below to perform access-checked modification of attributes. Lock
|
||||||
|
types checked by secureattr are 'attrread','attredit','attrcreate'.
|
||||||
"""
|
"""
|
||||||
attrib_obj = get_attr_cache(self, attribute_name)
|
attrib_obj = get_attr_cache(self, attribute_name)
|
||||||
if not attrib_obj:
|
if not attrib_obj:
|
||||||
|
|
@ -1332,6 +1336,8 @@ class TypedObject(SharedMemoryModel):
|
||||||
else:
|
else:
|
||||||
# no match; create new attribute
|
# no match; create new attribute
|
||||||
attrib_obj = attrclass(db_key=attribute_name, db_obj=self)
|
attrib_obj = attrclass(db_key=attribute_name, db_obj=self)
|
||||||
|
if lockstring:
|
||||||
|
attrib_obj.locks.add(lockstring)
|
||||||
# re-set an old attribute value
|
# re-set an old attribute value
|
||||||
try:
|
try:
|
||||||
attrib_obj.value = new_value
|
attrib_obj.value = new_value
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue