Merge.
This commit is contained in:
commit
70b8f074f1
20 changed files with 905 additions and 253 deletions
|
|
@ -41,7 +41,6 @@ from twisted.internet.defer import inlineCallbacks, returnValue
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from src.comms.channelhandler import CHANNELHANDLER
|
from src.comms.channelhandler import CHANNELHANDLER
|
||||||
from src.utils import logger, utils
|
from src.utils import logger, utils
|
||||||
from src.commands.cmdset import CmdSet
|
|
||||||
from src.commands.cmdparser import at_multimatch_cmd
|
from src.commands.cmdparser import at_multimatch_cmd
|
||||||
from src.utils.utils import string_suggestions
|
from src.utils.utils import string_suggestions
|
||||||
|
|
||||||
|
|
@ -165,7 +164,7 @@ def get_and_merge_cmdsets(caller):
|
||||||
# Main command-handler function
|
# Main command-handler function
|
||||||
|
|
||||||
@inlineCallbacks
|
@inlineCallbacks
|
||||||
def cmdhandler(caller, raw_string, testing=False):
|
def cmdhandler(caller, raw_string, testing=False, sessid=None):
|
||||||
"""
|
"""
|
||||||
This is the main function to handle any string sent to the engine.
|
This is the main function to handle any string sent to the engine.
|
||||||
|
|
||||||
|
|
@ -251,6 +250,7 @@ def cmdhandler(caller, raw_string, testing=False):
|
||||||
cmd.cmdstring = cmdname
|
cmd.cmdstring = cmdname
|
||||||
cmd.args = args
|
cmd.args = args
|
||||||
cmd.cmdset = cmdset
|
cmd.cmdset = cmdset
|
||||||
|
cmd.sessid = sessid
|
||||||
cmd.raw_string = unformatted_raw_string
|
cmd.raw_string = unformatted_raw_string
|
||||||
|
|
||||||
if hasattr(cmd, 'obj') and hasattr(cmd.obj, 'scripts'):
|
if hasattr(cmd, 'obj') and hasattr(cmd.obj, 'scripts'):
|
||||||
|
|
|
||||||
|
|
@ -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,151 +649,6 @@ 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)
|
||||||
|
|
||||||
# OOC commands
|
|
||||||
|
|
||||||
class CmdOOCLook(MuxCommandOOC, CmdLook):
|
|
||||||
"""
|
|
||||||
ooc look
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
look
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
def func(self):
|
|
||||||
"implement the ooc look command"
|
|
||||||
|
|
||||||
if not self.character:
|
|
||||||
string = "You are out-of-character (OOC). "
|
|
||||||
string += "Use {w@ic{n to get back to the game, {whelp{n for more info."
|
|
||||||
self.caller.msg(string)
|
|
||||||
else:
|
|
||||||
self.caller = self.character # we have to put this back for normal look to work.
|
|
||||||
super(CmdOOCLook, self).func()
|
|
||||||
|
|
||||||
class CmdIC(MuxCommandOOC):
|
|
||||||
"""
|
|
||||||
Switch control to an object
|
|
||||||
|
|
||||||
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"
|
|
||||||
locks = "cmd:all()" # must be all() or different puppeted objects won't be able to access it.
|
|
||||||
aliases = "@puppet"
|
|
||||||
help_category = "General"
|
|
||||||
|
|
||||||
def func(self):
|
|
||||||
"""
|
|
||||||
Simple puppet method
|
|
||||||
"""
|
|
||||||
caller = self.caller
|
|
||||||
old_character = self.character
|
|
||||||
|
|
||||||
new_character = None
|
|
||||||
if not self.args:
|
|
||||||
new_character = caller.db.last_puppet
|
|
||||||
if not new_character:
|
|
||||||
caller.msg("Usage: @ic <character>")
|
|
||||||
return
|
|
||||||
if not new_character:
|
|
||||||
# search for a matching character
|
|
||||||
new_character = search.objects(self.args, caller)
|
|
||||||
if new_character:
|
|
||||||
new_character = new_character[0]
|
|
||||||
else:
|
|
||||||
# the search method handles error messages etc.
|
|
||||||
return
|
|
||||||
if new_character.player:
|
|
||||||
if new_character.player == caller:
|
|
||||||
caller.msg("{RYou already are {c%s{n." % new_character.name)
|
|
||||||
else:
|
|
||||||
caller.msg("{c%s{r is already acted by another player.{n" % new_character.name)
|
|
||||||
return
|
|
||||||
if not new_character.access(caller, "puppet"):
|
|
||||||
caller.msg("{rYou may not become %s.{n" % new_character.name)
|
|
||||||
return
|
|
||||||
if caller.swap_character(new_character):
|
|
||||||
new_character.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
|
||||||
caller.db.last_puppet = old_character
|
|
||||||
if not new_character.location:
|
|
||||||
# this might be due to being hidden away at logout; check
|
|
||||||
loc = new_character.db.prelogout_location
|
|
||||||
if not loc: # still no location; use home
|
|
||||||
loc = new_character.home
|
|
||||||
new_character.location = loc
|
|
||||||
if new_character.location:
|
|
||||||
new_character.location.msg_contents("%s has entered the game." % new_character.key, exclude=[new_character])
|
|
||||||
new_character.location.at_object_receive(new_character, new_character.location)
|
|
||||||
new_character.execute_cmd("look")
|
|
||||||
else:
|
|
||||||
caller.msg("{rYou cannot become {C%s{n." % new_character.name)
|
|
||||||
|
|
||||||
class CmdOOC(MuxCommandOOC):
|
|
||||||
"""
|
|
||||||
@ooc - 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:all()" # this must be all(), or different puppeted objects won't be able to access it.
|
|
||||||
aliases = "@unpuppet"
|
|
||||||
help_category = "General"
|
|
||||||
|
|
||||||
def func(self):
|
|
||||||
"Implement function"
|
|
||||||
|
|
||||||
caller = self.caller
|
|
||||||
|
|
||||||
if utils.inherits_from(caller, "src.objects.objects.Object"):
|
|
||||||
caller = self.caller.player
|
|
||||||
|
|
||||||
if not caller.character:
|
|
||||||
string = "You are already OOC."
|
|
||||||
caller.msg(string)
|
|
||||||
return
|
|
||||||
|
|
||||||
caller.db.last_puppet = caller.character
|
|
||||||
# save location as if we were disconnecting from the game entirely.
|
|
||||||
if caller.character.location:
|
|
||||||
caller.character.location.msg_contents("%s has left the game." % caller.character.key, exclude=[caller.character])
|
|
||||||
caller.character.db.prelogout_location = caller.character.location
|
|
||||||
caller.character.location = None
|
|
||||||
|
|
||||||
# disconnect
|
|
||||||
caller.character.player = None
|
|
||||||
caller.character = None
|
|
||||||
|
|
||||||
caller.msg("\n{GYou go OOC.{n\n")
|
|
||||||
caller.execute_cmd("look")
|
|
||||||
|
|
||||||
class CmdColorTest(MuxCommand):
|
class CmdColorTest(MuxCommand):
|
||||||
"""
|
"""
|
||||||
testing colors
|
testing colors
|
||||||
|
|
@ -851,3 +706,239 @@ class CmdColorTest(MuxCommand):
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
self.caller.msg("(e.g. %%c123 and %%cb123 also work)")
|
self.caller.msg("(e.g. %%c123 and %%cb123 also work)")
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------------------
|
||||||
|
# OOC commands
|
||||||
|
#------------------------------------------------------------
|
||||||
|
|
||||||
|
class CmdOOCLook(MuxCommandOOC, CmdLook):
|
||||||
|
"""
|
||||||
|
ooc look
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
def look_target(self):
|
||||||
|
"Hook method for when an argument is given."
|
||||||
|
# caller is assumed to be a player object here.
|
||||||
|
caller = self.caller
|
||||||
|
looktarget = caller.get_character(key=self.args)
|
||||||
|
if looktarget:
|
||||||
|
caller.msg(looktarget.return_appearance())
|
||||||
|
else:
|
||||||
|
caller.msg("No such character.")
|
||||||
|
return
|
||||||
|
|
||||||
|
def no_look_target(self):
|
||||||
|
"Hook method for default look without a specified target"
|
||||||
|
# caller is always a player at this point.
|
||||||
|
player = self.caller
|
||||||
|
sessid = self.sessid
|
||||||
|
# get all our characters
|
||||||
|
characters = player.get_all_characters() # get all characters
|
||||||
|
string = "You are logged in as {g%s{n." % player.key
|
||||||
|
string += " Use {w@ic <character>{n to enter the game."
|
||||||
|
string += "\n\nAvailable character%s:" % (len(characters) > 1 and "s" or "")
|
||||||
|
for char in characters:
|
||||||
|
csessid = char.sessid
|
||||||
|
if csessid:
|
||||||
|
# character is already puppeted
|
||||||
|
if csessid == sessid:
|
||||||
|
# this should not happen.
|
||||||
|
string += "\n - {r%s{n (sessid not properly cleared! Contact an admin!)" % char.key
|
||||||
|
elif player.get_session(csessid):
|
||||||
|
string += "\n - {G%s{n (played by you in another session)"
|
||||||
|
else:
|
||||||
|
string += "\n - {R%s{n (played by someone else)" % char.key
|
||||||
|
else:
|
||||||
|
# character is "free to puppet"
|
||||||
|
string += "\n - %s" % char.key
|
||||||
|
player.msg(string)
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"implement the ooc look command"
|
||||||
|
|
||||||
|
if utils.inherits_from(self.caller, "src.objects.objects.Object"):
|
||||||
|
# An object of some type is calling. Use default look instead.
|
||||||
|
super(CmdOOCLook, self).func()
|
||||||
|
elif self.args:
|
||||||
|
self.look_target()
|
||||||
|
else:
|
||||||
|
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):
|
||||||
|
"""
|
||||||
|
Switch control to an object
|
||||||
|
|
||||||
|
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"
|
||||||
|
locks = "cmd:all()" # must be all() or different puppeted objects won't be able to access it.
|
||||||
|
aliases = "@puppet"
|
||||||
|
help_category = "General"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"""
|
||||||
|
Simple puppet method
|
||||||
|
"""
|
||||||
|
caller = self.caller
|
||||||
|
sessid = self.sessid
|
||||||
|
old_character = self.character
|
||||||
|
|
||||||
|
new_character = None
|
||||||
|
if not self.args:
|
||||||
|
new_character = caller.db.last_puppet
|
||||||
|
if not new_character:
|
||||||
|
caller.msg("Usage: @ic <character>")
|
||||||
|
return
|
||||||
|
if not new_character:
|
||||||
|
# search for a matching character
|
||||||
|
new_character = search.objects(self.args, caller)
|
||||||
|
if new_character:
|
||||||
|
new_character = new_character[0]
|
||||||
|
else:
|
||||||
|
# the search method handles error messages etc.
|
||||||
|
return
|
||||||
|
# permission checks
|
||||||
|
if caller.get_character(sessid=sessid, character=new_character):
|
||||||
|
caller.msg("{RYou already act as {c%s{n." % new_character.name)
|
||||||
|
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"):
|
||||||
|
caller.msg("{rYou may not become %s.{n" % new_character.name)
|
||||||
|
return
|
||||||
|
if caller.connect_character(new_character, sessid=sessid):
|
||||||
|
new_character.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
||||||
|
caller.db.last_puppet = old_character
|
||||||
|
if not new_character.location:
|
||||||
|
# this might be due to being hidden away at logout; check
|
||||||
|
loc = new_character.db.prelogout_location
|
||||||
|
if not loc: # still no location; use home
|
||||||
|
loc = new_character.home
|
||||||
|
new_character.location = loc
|
||||||
|
if new_character.location:
|
||||||
|
new_character.location.msg_contents("%s has entered the game." % new_character.key, exclude=[new_character])
|
||||||
|
new_character.location.at_object_receive(new_character, new_character.location)
|
||||||
|
new_character.execute_cmd("look")
|
||||||
|
else:
|
||||||
|
caller.msg("{rYou cannot become {C%s{n." % new_character.name)
|
||||||
|
|
||||||
|
class CmdOOC(MuxCommandOOC):
|
||||||
|
"""
|
||||||
|
@ooc - 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:all()" # this must be all(), or different puppeted objects won't be able to access it.
|
||||||
|
aliases = "@unpuppet"
|
||||||
|
help_category = "General"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"Implement function"
|
||||||
|
|
||||||
|
caller = self.caller
|
||||||
|
|
||||||
|
if utils.inherits_from(caller, "src.objects.objects.Object"):
|
||||||
|
caller = self.caller.player
|
||||||
|
|
||||||
|
old_char = caller.get_character(sessid=self.sessid)
|
||||||
|
if not old_char:
|
||||||
|
string = "You are already OOC."
|
||||||
|
caller.msg(string)
|
||||||
|
return
|
||||||
|
|
||||||
|
caller.db.last_puppet = old_char
|
||||||
|
# save location as if we were disconnecting from the game entirely.
|
||||||
|
if old_char.location:
|
||||||
|
old_char.location.msg_contents("%s has left the game." % old_char.key, exclude=[old_char])
|
||||||
|
old_char.db.prelogout_location = old_char.location
|
||||||
|
old_char.location = None
|
||||||
|
|
||||||
|
# disconnect
|
||||||
|
caller.disconnect_character(caller)
|
||||||
|
|
||||||
|
caller.msg("\n{GYou go OOC.{n\n")
|
||||||
|
caller.execute_cmd("look")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
113
src/objects/migrations/0016_adding_sessid.py
Normal file
113
src/objects/migrations/0016_adding_sessid.py
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Adding field 'ObjectDB.db_sessid'
|
||||||
|
db.add_column('objects_objectdb', 'db_sessid',
|
||||||
|
self.gf('django.db.models.fields.IntegerField')(null=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Deleting field 'ObjectDB.db_sessid'
|
||||||
|
db.delete_column('objects_objectdb', 'db_sessid')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
},
|
||||||
|
'objects.alias': {
|
||||||
|
'Meta': {'object_name': 'Alias'},
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'objects.objattribute': {
|
||||||
|
'Meta': {'object_name': 'ObjAttribute'},
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'objects.objectdb': {
|
||||||
|
'Meta': {'object_name': 'ObjectDB'},
|
||||||
|
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||||
|
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||||
|
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'objects.objectnick': {
|
||||||
|
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'ObjectNick'},
|
||||||
|
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_real': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'players.playerdb': {
|
||||||
|
'Meta': {'object_name': 'PlayerDB'},
|
||||||
|
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'obj_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_objs': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'objs_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||||
|
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['objects']
|
||||||
|
|
@ -21,7 +21,7 @@ from django.conf import settings
|
||||||
from src.utils.idmapper.models import SharedMemoryModel
|
from src.utils.idmapper.models import SharedMemoryModel
|
||||||
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
|
||||||
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
from src.server.caches import get_field_cache, set_field_cache, del_field_cache
|
||||||
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache, hashid
|
from src.server.caches import get_prop_cache, set_prop_cache, del_prop_cache
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
from src.players.models import PlayerNick
|
from src.players.models import PlayerNick
|
||||||
from src.objects.manager import ObjectManager
|
from src.objects.manager import ObjectManager
|
||||||
|
|
@ -176,6 +176,9 @@ class ObjectDB(TypedObject):
|
||||||
# If this is a character object, the player is connected here.
|
# If this is a character object, the player is connected here.
|
||||||
db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True, verbose_name='player',
|
db_player = models.ForeignKey("players.PlayerDB", blank=True, null=True, verbose_name='player',
|
||||||
help_text='a Player connected to this object, if any.')
|
help_text='a Player connected to this object, if any.')
|
||||||
|
# the session id associated with this player, if any
|
||||||
|
db_sessid = models.IntegerField(null=True, verbose_name="session id",
|
||||||
|
help_text="unique session id of connected Player, if any.")
|
||||||
# The location in the game world. Since this one is likely
|
# The location in the game world. Since this one is likely
|
||||||
# to change often, we set this with the 'location' property
|
# to change often, we set this with the 'location' property
|
||||||
# to transparently handle Typeclassing.
|
# to transparently handle Typeclassing.
|
||||||
|
|
@ -191,7 +194,6 @@ class ObjectDB(TypedObject):
|
||||||
# database storage of persistant cmdsets.
|
# database storage of persistant cmdsets.
|
||||||
db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, blank=True,
|
db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True, blank=True,
|
||||||
help_text="optional python path to a cmdset class.")
|
help_text="optional python path to a cmdset class.")
|
||||||
|
|
||||||
# Database manager
|
# Database manager
|
||||||
objects = ObjectManager()
|
objects = ObjectManager()
|
||||||
|
|
||||||
|
|
@ -260,6 +262,28 @@ class ObjectDB(TypedObject):
|
||||||
del_field_cache(self, "player")
|
del_field_cache(self, "player")
|
||||||
player = property(__player_get, __player_set, __player_del)
|
player = property(__player_get, __player_set, __player_del)
|
||||||
|
|
||||||
|
# sessid property (wraps db_sessid)
|
||||||
|
#@property
|
||||||
|
def __sessid_get(self):
|
||||||
|
"""
|
||||||
|
Getter. Allows for value = self.sessid. Since sessid
|
||||||
|
is directly related to self.player, we cannot have
|
||||||
|
a sessid without a player being connected (but the
|
||||||
|
opposite could be true).
|
||||||
|
"""
|
||||||
|
if not get_field_cache(self, "sessid"):
|
||||||
|
del_field_cache(self, "sessid")
|
||||||
|
return get_field_cache(self, "sessid")
|
||||||
|
#@sessid.setter
|
||||||
|
def __sessid_set(self, sessid):
|
||||||
|
"Setter. Allows for self.player = value"
|
||||||
|
set_field_cache(self, "sessid", sessid)
|
||||||
|
#@sessid.deleter
|
||||||
|
def __sessid_del(self):
|
||||||
|
"Deleter. Allows for del self.player"
|
||||||
|
del_field_cache(self, "sessid")
|
||||||
|
sessid = property(__sessid_get, __sessid_set, __sessid_del)
|
||||||
|
|
||||||
# location property (wraps db_location)
|
# location property (wraps db_location)
|
||||||
#@property
|
#@property
|
||||||
def __location_get(self):
|
def __location_get(self):
|
||||||
|
|
@ -612,7 +636,7 @@ class ObjectDB(TypedObject):
|
||||||
# Execution/action methods
|
# Execution/action methods
|
||||||
#
|
#
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -644,11 +668,11 @@ class ObjectDB(TypedObject):
|
||||||
if nick.db_nick in raw_list:
|
if nick.db_nick in raw_list:
|
||||||
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
|
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
|
||||||
break
|
break
|
||||||
return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string)
|
return cmdhandler.cmdhandler(_GA(self, "typeclass"), raw_string, sessid=sessid)
|
||||||
|
|
||||||
def msg(self, message, from_obj=None, data=None):
|
def msg(self, message, from_obj=None, data=None):
|
||||||
"""
|
"""
|
||||||
Emits something to any sessions attached to the object.
|
Emits something to a session attached to the object.
|
||||||
|
|
||||||
message (str): The message to send
|
message (str): The message to send
|
||||||
from_obj (obj): object that is sending.
|
from_obj (obj): object that is sending.
|
||||||
|
|
@ -656,8 +680,8 @@ class ObjectDB(TypedObject):
|
||||||
be used by the protocol.
|
be used by the protocol.
|
||||||
"""
|
"""
|
||||||
if _GA(self, 'player'):
|
if _GA(self, 'player'):
|
||||||
# note that we check the typeclass' msg, otherwise one couldn't overload it.
|
# note that we must call the player *typeclass'* msg(), otherwise one couldn't overload it.
|
||||||
_GA(_GA(self, 'player'), "typeclass").msg(message, from_obj=from_obj, data=data)
|
_GA(_GA(self, 'player'), "typeclass").msg(message, from_obj=from_obj, data=data, sessid=_GA(self, "sessid"))
|
||||||
|
|
||||||
def emit_to(self, message, from_obj=None, data=None):
|
def emit_to(self, message, from_obj=None, data=None):
|
||||||
"Deprecated. Alias for msg"
|
"Deprecated. Alias for msg"
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
116
src/players/migrations/0014_adding_objs_m2m.py
Normal file
116
src/players/migrations/0014_adding_objs_m2m.py
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Adding M2M table for field db_objs on 'PlayerDB'
|
||||||
|
db.create_table('players_playerdb_db_objs', (
|
||||||
|
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||||
|
('playerdb', models.ForeignKey(orm['players.playerdb'], null=False)),
|
||||||
|
('objectdb', models.ForeignKey(orm['objects.objectdb'], null=False))
|
||||||
|
))
|
||||||
|
db.create_unique('players_playerdb_db_objs', ['playerdb_id', 'objectdb_id'])
|
||||||
|
|
||||||
|
if not db.dry_run:
|
||||||
|
for player in orm.PlayerDB.objects.all():
|
||||||
|
# move data from old field to new
|
||||||
|
if player.db_obj:
|
||||||
|
player.db_objs.add(player.db_obj)
|
||||||
|
player.save()
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Removing M2M table for field db_objs on 'PlayerDB'
|
||||||
|
db.delete_table('players_playerdb_db_objs')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
},
|
||||||
|
'objects.objectdb': {
|
||||||
|
'Meta': {'object_name': 'ObjectDB'},
|
||||||
|
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||||
|
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||||
|
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'players.playerattribute': {
|
||||||
|
'Meta': {'object_name': 'PlayerAttribute'},
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||||
|
'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'players.playerdb': {
|
||||||
|
'Meta': {'object_name': 'PlayerDB'},
|
||||||
|
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'obj_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_objs': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'objs_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||||
|
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
},
|
||||||
|
'players.playernick': {
|
||||||
|
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
|
||||||
|
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||||
|
'db_real': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['players']
|
||||||
106
src/players/migrations/0015_removing_obj.py
Normal file
106
src/players/migrations/0015_removing_obj.py
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Deleting field 'PlayerDB.db_obj'
|
||||||
|
db.delete_column('players_playerdb', 'db_obj_id')
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Adding field 'PlayerDB.db_obj'
|
||||||
|
db.add_column('players_playerdb', 'db_obj',
|
||||||
|
self.gf('django.db.models.fields.related.ForeignKey')(related_name='obj_set', null=True, to=orm['objects.ObjectDB'], blank=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
},
|
||||||
|
'objects.objectdb': {
|
||||||
|
'Meta': {'object_name': 'ObjectDB'},
|
||||||
|
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||||
|
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
|
||||||
|
'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||||
|
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'players.playerattribute': {
|
||||||
|
'Meta': {'object_name': 'PlayerAttribute'},
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||||
|
'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'players.playerdb': {
|
||||||
|
'Meta': {'object_name': 'PlayerDB'},
|
||||||
|
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||||
|
'db_objs': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'objs_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||||
|
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||||
|
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
},
|
||||||
|
'players.playernick': {
|
||||||
|
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
|
||||||
|
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||||
|
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||||
|
'db_real': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['players']
|
||||||
|
|
@ -161,8 +161,9 @@ class PlayerDB(TypedObject):
|
||||||
help_text="The <I>User</I> object holds django-specific authentication for each Player. A unique User should be created and tied to each Player, the two should never be switched or changed around. The User will be deleted automatically when the Player is.")
|
help_text="The <I>User</I> object holds django-specific authentication for each Player. A unique User should be created and tied to each Player, the two should never be switched or changed around. The User will be deleted automatically when the Player is.")
|
||||||
# the in-game object connected to this player (if any).
|
# the in-game object connected to this player (if any).
|
||||||
# Use the property 'obj' to access.
|
# Use the property 'obj' to access.
|
||||||
db_obj = models.ForeignKey("objects.ObjectDB", null=True, blank=True,
|
db_objs = models.ManyToManyField("objects.ObjectDB", null=True,
|
||||||
verbose_name="character", help_text='In-game object.')
|
verbose_name="characters", related_name="objs_set",
|
||||||
|
help_text="In-game objects.")
|
||||||
# store a connected flag here too, not just in sessionhandler.
|
# store a connected flag here too, not just in sessionhandler.
|
||||||
# This makes it easier to track from various out-of-process locations
|
# This makes it easier to track from various out-of-process locations
|
||||||
db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not")
|
db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not")
|
||||||
|
|
@ -195,11 +196,12 @@ class PlayerDB(TypedObject):
|
||||||
|
|
||||||
# obj property (wraps db_obj)
|
# obj property (wraps db_obj)
|
||||||
#@property
|
#@property
|
||||||
def obj_get(self):
|
def objs_get(self):
|
||||||
"Getter. Allows for value = self.obj"
|
"Getter. Allows for value = self.obj"
|
||||||
return get_field_cache(self, "obj")
|
return self.db_objs.all()
|
||||||
|
#return get_field_cache(self, "objs").all()
|
||||||
#@obj.setter
|
#@obj.setter
|
||||||
def obj_set(self, value):
|
def objs_set(self, value):
|
||||||
"Setter. Allows for self.obj = value"
|
"Setter. Allows for self.obj = value"
|
||||||
global _TYPECLASS
|
global _TYPECLASS
|
||||||
if not _TYPECLASS:
|
if not _TYPECLASS:
|
||||||
|
|
@ -208,15 +210,19 @@ class PlayerDB(TypedObject):
|
||||||
if isinstance(value, _TYPECLASS):
|
if isinstance(value, _TYPECLASS):
|
||||||
value = value.dbobj
|
value = value.dbobj
|
||||||
try:
|
try:
|
||||||
set_field_cache(self, "obj", value)
|
self.db_objs.add(value)
|
||||||
|
self.save()
|
||||||
|
#set_field_cache(self, "obj", value)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
raise Exception("Cannot assign %s as a player object!" % value)
|
raise Exception("Cannot assign %s as a player object!" % value)
|
||||||
#@obj.deleter
|
#@obj.deleter
|
||||||
def obj_del(self):
|
def objs_del(self):
|
||||||
"Deleter. Allows for del self.obj"
|
"Deleter. Allows for del self.obj"
|
||||||
del_field_cache(self, "obj")
|
self.db_objs.clear()
|
||||||
obj = property(obj_get, obj_set, obj_del)
|
self.save()
|
||||||
|
#del_field_cache(self, "obj")
|
||||||
|
objs = property(objs_get, objs_set, objs_del)
|
||||||
|
|
||||||
# whereas the name 'obj' is consistent with the rest of the code,
|
# whereas the name 'obj' is consistent with the rest of the code,
|
||||||
# 'character' is a more intuitive property name, so we
|
# 'character' is a more intuitive property name, so we
|
||||||
|
|
@ -236,6 +242,7 @@ class PlayerDB(TypedObject):
|
||||||
"Deleter. Allows for del self.character"
|
"Deleter. Allows for del self.character"
|
||||||
del_field_cache(self, "obj")
|
del_field_cache(self, "obj")
|
||||||
character = property(character_get, character_set, character_del)
|
character = property(character_get, character_set, character_del)
|
||||||
|
|
||||||
# cmdset_storage property
|
# cmdset_storage property
|
||||||
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
||||||
#@property
|
#@property
|
||||||
|
|
@ -358,32 +365,220 @@ class PlayerDB(TypedObject):
|
||||||
# PlayerDB class access methods
|
# PlayerDB class access methods
|
||||||
#
|
#
|
||||||
|
|
||||||
def msg(self, outgoing_string, from_obj=None, data=None):
|
def msg(self, outgoing_string, from_obj=None, data=None, sessid=None):
|
||||||
"""
|
"""
|
||||||
Evennia -> User
|
Evennia -> User
|
||||||
This is the main route for sending data back to the user from the server.
|
This is the main route for sending data back to the user from the server.
|
||||||
|
|
||||||
|
outgoing_string (string) - text data to send
|
||||||
|
from_obj (Object/Player) - source object of message to send
|
||||||
|
data (dict) - arbitrary data object containing eventual protocol-specific options
|
||||||
|
sessid - the session id of the session to send to. If not given, return to
|
||||||
|
all sessions connected to this player. This is usually only
|
||||||
|
relevant when using msg() directly from a player-command (from
|
||||||
|
a command on a Character, the character automatically stores and
|
||||||
|
handles the sessid).
|
||||||
"""
|
"""
|
||||||
if from_obj:
|
if from_obj:
|
||||||
|
# call hook
|
||||||
try:
|
try:
|
||||||
_GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data)
|
_GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if (_GA(self, "character") and not
|
|
||||||
_GA(self, "character").at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
|
|
||||||
# the at_msg_receive() hook may block receiving of certain messages
|
|
||||||
return
|
|
||||||
|
|
||||||
outgoing_string = utils.to_str(outgoing_string, force_string=True)
|
outgoing_string = utils.to_str(outgoing_string, force_string=True)
|
||||||
|
|
||||||
for session in _GA(self, 'sessions'):
|
session = None
|
||||||
|
if sessid:
|
||||||
|
session = _GA(self, "get_session")(sessid)
|
||||||
|
if session:
|
||||||
|
char = _GA(self, "get_character")(sessid=sessid)
|
||||||
|
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data):
|
||||||
|
# if hook returns false, cancel send
|
||||||
|
return
|
||||||
session.msg(outgoing_string, data)
|
session.msg(outgoing_string, data)
|
||||||
|
else:
|
||||||
|
# if no session was specified, send to them all
|
||||||
|
for sess in _GA(self, 'get_all_sessions')():
|
||||||
|
sess.msg(outgoing_string, data)
|
||||||
|
|
||||||
|
def inmsg(self, ingoing_string, sessid):
|
||||||
|
"""
|
||||||
|
User -> Evennia
|
||||||
|
This is the reverse of msg - used by sessions to relay
|
||||||
|
messages/data back into the game. It is normally not called
|
||||||
|
from inside game code but only by the serversessions directly.
|
||||||
|
|
||||||
|
ingoing_string - text string (i.e. command string)
|
||||||
|
data - dictionary of optional data
|
||||||
|
session - session sending this data
|
||||||
|
"""
|
||||||
|
character = _GA(self, "get_character")(sessid=sessid)
|
||||||
|
if character:
|
||||||
|
# execute command on character
|
||||||
|
_GA(character, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||||
|
else:
|
||||||
|
# a non-character session; this goes to player directly
|
||||||
|
_GA(self, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||||
|
|
||||||
|
def connect_session_to_character(self, sessid, character, force=False):
|
||||||
|
"""
|
||||||
|
Connect the given session to a character through this player.
|
||||||
|
Note that this assumes the character has previously been
|
||||||
|
linked to the player using self.connect_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
|
||||||
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
|
if char:
|
||||||
|
if force and char != character:
|
||||||
|
_GA(self, "disconnect_session_from_character")(sessid)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
# do the connection
|
||||||
|
character.sessid = sessid
|
||||||
|
# update cache
|
||||||
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
|
cache[sessid] = character
|
||||||
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
# call hooks
|
||||||
|
character.at_init()
|
||||||
|
if character:
|
||||||
|
# start (persistent) scripts on this object
|
||||||
|
#ScriptDB.objects.validate(obj=character)
|
||||||
|
pass
|
||||||
|
if character.db.FIRST_LOGIN:
|
||||||
|
character.at_first_login()
|
||||||
|
del character.db.FIRST_LOGIN
|
||||||
|
character.at_pre_login()
|
||||||
|
character.at_post_login()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def disconnect_session_from_character(self, sessid):
|
||||||
|
"""
|
||||||
|
Disconnect a session from the characterm (still keeping the
|
||||||
|
connection to the Player)
|
||||||
|
returns the newly disconnected character, if it existed
|
||||||
|
"""
|
||||||
|
if not sessid:
|
||||||
|
return
|
||||||
|
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||||
|
if char:
|
||||||
|
# call hook before disconnecting
|
||||||
|
_GA(char.typeclass, "at_disconnect")()
|
||||||
|
del char.sessid
|
||||||
|
# update cache
|
||||||
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
|
if sessid in cache:
|
||||||
|
del cache[sessid]
|
||||||
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
return char
|
||||||
|
|
||||||
|
def get_session(self, sessid):
|
||||||
|
"""
|
||||||
|
Return session with given sessid connected to this player.
|
||||||
|
"""
|
||||||
|
return SESSIONS.sessions_from_player(self, sessid=sessid)
|
||||||
|
|
||||||
|
def get_all_sessions(self):
|
||||||
|
"Return all sessions connected to this player"
|
||||||
|
return SESSIONS.sessions_from_player(self)
|
||||||
|
|
||||||
|
def get_character(self, sessid=None, character=None, return_dbobj=False):
|
||||||
|
"""
|
||||||
|
Get the character connected to this player and sessid
|
||||||
|
|
||||||
|
sessid - return character connected to this sessid,
|
||||||
|
character - return character if connected to this player, else None.
|
||||||
|
|
||||||
|
Combining both keywords will check the entire connection - if the
|
||||||
|
given session is currently connected to the given char. If no
|
||||||
|
keywords are given, returns all connected characters.
|
||||||
|
"""
|
||||||
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
|
if sessid:
|
||||||
|
# try to return a character with a given sessid
|
||||||
|
char = cache.get(sessid)
|
||||||
|
if not char:
|
||||||
|
char = _GA(self, "db_objs").filter(db_player=self, db_sessid=sessid) or None
|
||||||
|
if char:
|
||||||
|
char = char[0]
|
||||||
|
cache[sessid] = char
|
||||||
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
if character:
|
||||||
|
return char and (char == character.dbobj and (return_dbobj and char or char.typeclass)) or None
|
||||||
|
return char and (return_dbobj and char or char.typeclass) or None
|
||||||
|
elif character:
|
||||||
|
char = _GA(self, "db_objs").filter(id=_GA(character.dbobj, "id"))
|
||||||
|
return char and (return_dbobj and char[0] or char[0].typeclass) or None
|
||||||
|
else:
|
||||||
|
# no sessid given - return all available characters
|
||||||
|
return list(return_dbobj and o or o.typeclass for o in self.db_objs.all())
|
||||||
|
|
||||||
|
def get_all_characters(self):
|
||||||
|
"""
|
||||||
|
Readability-wrapper for getting all characters
|
||||||
|
"""
|
||||||
|
return _GA(self, "get_character")(sessid=None, character=None)
|
||||||
|
|
||||||
|
def connect_character(self, character, sessid=None):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
game was fully restarted (including the Portal), this must be
|
||||||
|
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
|
||||||
|
char = character.dbobj
|
||||||
|
_GA(self, "disconnect_character")(char)
|
||||||
|
char.player = self
|
||||||
|
_GA(self, "db_objs").add(char)
|
||||||
|
_GA(self, "save")()
|
||||||
|
if sessid:
|
||||||
|
return _GA(self, "connect_session_to_character")(sessid=sessid, character=char)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def disconnect_character(self, character):
|
||||||
|
"""
|
||||||
|
Disconnect a character from this player, either based
|
||||||
|
on sessid or by giving the character object directly
|
||||||
|
|
||||||
|
Returns newly disconnected character.
|
||||||
|
"""
|
||||||
|
if not character:
|
||||||
|
return
|
||||||
|
char = _GA(self, "get_character")(character=character, return_dbobj=True)
|
||||||
|
if char:
|
||||||
|
_GA(self, "disconnect_session_from_character")(char.sessid)
|
||||||
|
_GA(self, "db_objs").remove(char)
|
||||||
|
del char.player
|
||||||
|
del char.sessid
|
||||||
|
self.save()
|
||||||
|
# clear cache
|
||||||
|
cache = get_prop_cache(self, "_characters") or {}
|
||||||
|
[cache.pop(sessid) for sessid,stored_char in cache.items() if stored_char==char]
|
||||||
|
set_prop_cache(self, "_characters", cache)
|
||||||
|
return char
|
||||||
|
|
||||||
|
|
||||||
def swap_character(self, new_character, delete_old_character=False):
|
def disconnect_all_characters(self):
|
||||||
|
for char in self.db_objs.all():
|
||||||
|
_GA(self, "disconnect_character")(char)
|
||||||
|
|
||||||
|
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."
|
||||||
|
|
@ -401,7 +596,7 @@ class PlayerDB(TypedObject):
|
||||||
# Execution/action methods
|
# Execution/action methods
|
||||||
#
|
#
|
||||||
|
|
||||||
def execute_cmd(self, raw_string):
|
def execute_cmd(self, raw_string, sessid=None):
|
||||||
"""
|
"""
|
||||||
Do something as this player. This command transparently
|
Do something as this player. This command transparently
|
||||||
lets its typeclass execute the command.
|
lets its typeclass execute the command.
|
||||||
|
|
@ -417,7 +612,7 @@ class PlayerDB(TypedObject):
|
||||||
if nick.db_nick in raw_list:
|
if nick.db_nick in raw_list:
|
||||||
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
|
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
|
||||||
break
|
break
|
||||||
return cmdhandler.cmdhandler(self.typeclass, raw_string)
|
return cmdhandler.cmdhandler(self.typeclass, raw_string, sessid=sessid)
|
||||||
|
|
||||||
def search(self, ostring, return_character=False):
|
def search(self, ostring, return_character=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -88,17 +88,21 @@ class Player(TypeClass):
|
||||||
|
|
||||||
## methods inherited from database model
|
## methods inherited from database model
|
||||||
|
|
||||||
def msg(self, outgoing_string, from_obj=None, data=None):
|
def msg(self, outgoing_string, from_obj=None, data=None, sessid=None):
|
||||||
"""
|
"""
|
||||||
Evennia -> User
|
Evennia -> User
|
||||||
This is the main route for sending data back to the user from the server.
|
This is the main route for sending data back to the user from the server.
|
||||||
|
|
||||||
outgoing_string (string) - text data to send
|
outgoing_string (string) - text data to send
|
||||||
from_obj (Object/Player) - source object of message to send
|
from_obj (Object/Player) - source object of message to send
|
||||||
data (?) - arbitrary data object containing eventual protocol-specific options
|
data (dict) - arbitrary data object containing eventual protocol-specific options
|
||||||
|
sessid - the session id of the session to send to. If not given, return to
|
||||||
"""
|
all sessions connected to this player. This is usually only
|
||||||
self.dbobj.msg(outgoing_string, from_obj=from_obj, data=data)
|
relevant when using msg() directly from a player-command (from
|
||||||
|
a command on a Character, the character automatically stores and
|
||||||
|
handles the sessid).
|
||||||
|
"""
|
||||||
|
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):
|
||||||
"""
|
"""
|
||||||
|
|
@ -111,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
|
||||||
|
|
@ -119,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
|
||||||
|
|
@ -129,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):
|
||||||
"""
|
"""
|
||||||
|
|
@ -293,8 +298,7 @@ class Player(TypeClass):
|
||||||
"""
|
"""
|
||||||
# Character.at_post_login also looks around. Only use
|
# Character.at_post_login also looks around. Only use
|
||||||
# this as a backup when logging in without a character
|
# this as a backup when logging in without a character
|
||||||
if not self.character:
|
self.execute_cmd("look")
|
||||||
self.execute_cmd("look")
|
|
||||||
|
|
||||||
def at_disconnect(self, reason=None):
|
def at_disconnect(self, reason=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,6 @@ class ServerSession(Session):
|
||||||
self.cmdset.update(init_mode=True)
|
self.cmdset.update(init_mode=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
character = self.get_character()
|
|
||||||
if character:
|
|
||||||
# start (persistent) scripts on this object
|
|
||||||
ScriptDB.objects.validate(obj=character)
|
|
||||||
|
|
||||||
def session_login(self, player):
|
def session_login(self, player):
|
||||||
"""
|
"""
|
||||||
|
|
@ -91,38 +87,24 @@ class ServerSession(Session):
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
# player init
|
# player init
|
||||||
#print "at_init() - player"
|
|
||||||
player.at_init()
|
player.at_init()
|
||||||
|
|
||||||
# Check if this is the first time the *player* logs in
|
# Check if this is the first time the *player* logs in
|
||||||
if player.db.FIRST_LOGIN:
|
if player.db.FIRST_LOGIN:
|
||||||
player.at_first_login()
|
player.at_first_login()
|
||||||
del player.db.FIRST_LOGIN
|
del player.db.FIRST_LOGIN
|
||||||
player.at_pre_login()
|
|
||||||
|
|
||||||
character = player.character
|
player.at_pre_login()
|
||||||
if character:
|
|
||||||
# this player has a character. Check if it's the
|
|
||||||
# first time *this character* logs in
|
|
||||||
character.at_init()
|
|
||||||
if character.db.FIRST_LOGIN:
|
|
||||||
character.at_first_login()
|
|
||||||
del character.db.FIRST_LOGIN
|
|
||||||
# run character login hook
|
|
||||||
character.at_pre_login()
|
|
||||||
|
|
||||||
self.log(_('Logged in: %(self)s') % {'self': self})
|
self.log(_('Logged in: %(self)s') % {'self': self})
|
||||||
|
|
||||||
# start (persistent) scripts on this object
|
# start (persistent) scripts on this object
|
||||||
ScriptDB.objects.validate(obj=self.player.character)
|
#ScriptDB.objects.validate(obj=self.player.character)
|
||||||
|
|
||||||
#add session to connected list
|
#add session to connected list
|
||||||
self.sessionhandler.login(self)
|
self.sessionhandler.login(self)
|
||||||
|
|
||||||
# post-login hooks
|
|
||||||
player.at_post_login()
|
player.at_post_login()
|
||||||
if character:
|
|
||||||
character.at_post_login()
|
|
||||||
|
|
||||||
def session_disconnect(self):
|
def session_disconnect(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -131,10 +113,10 @@ class ServerSession(Session):
|
||||||
accounts.
|
accounts.
|
||||||
"""
|
"""
|
||||||
if self.logged_in:
|
if self.logged_in:
|
||||||
player = self.get_player()
|
sessid = self.sessid
|
||||||
character = self.get_character()
|
player = self.player
|
||||||
if character:
|
if player.get_character(sessid):
|
||||||
character.at_disconnect()
|
player.disconnect_session_from_character(sessid)
|
||||||
uaccount = player.user
|
uaccount = player.user
|
||||||
uaccount.last_login = datetime.now()
|
uaccount.last_login = datetime.now()
|
||||||
uaccount.save()
|
uaccount.save()
|
||||||
|
|
@ -154,10 +136,7 @@ class ServerSession(Session):
|
||||||
Returns the in-game character associated with this session.
|
Returns the in-game character associated with this session.
|
||||||
This returns the typeclass of the object.
|
This returns the typeclass of the object.
|
||||||
"""
|
"""
|
||||||
player = self.get_player()
|
return self.logged_in and self.player.get_character(self.sessid) or None
|
||||||
if player:
|
|
||||||
return player.character
|
|
||||||
return None
|
|
||||||
|
|
||||||
def log(self, message, channel=True):
|
def log(self, message, channel=True):
|
||||||
"""
|
"""
|
||||||
|
|
@ -193,20 +172,13 @@ class ServerSession(Session):
|
||||||
if str(command_string).strip() == IDLE_COMMAND:
|
if str(command_string).strip() == IDLE_COMMAND:
|
||||||
self.update_session_counters(idle=True)
|
self.update_session_counters(idle=True)
|
||||||
return
|
return
|
||||||
|
if self.logged_in:
|
||||||
# all other inputs, including empty inputs
|
# the inmsg handler will relay to the right place
|
||||||
character = self.get_character()
|
self.player.inmsg(command_string, self.sessid)
|
||||||
if character:
|
|
||||||
character.execute_cmd(command_string)
|
|
||||||
else:
|
else:
|
||||||
if self.logged_in:
|
# we are not logged in. Use the session directly
|
||||||
# there is no character, but we are logged in. Use player instead.
|
# (it uses the settings.UNLOGGEDIN cmdset)
|
||||||
self.get_player().execute_cmd(command_string)
|
cmdhandler.cmdhandler(self, command_string, sessid=self.sessid)
|
||||||
else:
|
|
||||||
# we are not logged in. Use the session directly
|
|
||||||
# (it uses the settings.UNLOGGEDIN cmdset)
|
|
||||||
cmdhandler.cmdhandler(self, command_string)
|
|
||||||
self.update_session_counters()
|
|
||||||
|
|
||||||
def data_out(self, msg, data=None):
|
def data_out(self, msg, data=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -243,11 +215,11 @@ class ServerSession(Session):
|
||||||
func = OOB_FUNC_MODULE.__dict__.get(functuple[0])
|
func = OOB_FUNC_MODULE.__dict__.get(functuple[0])
|
||||||
if func:
|
if func:
|
||||||
try:
|
try:
|
||||||
outdata[funcname] = func(oobkey, self, *functuple[1], **functuple[2])
|
outdata[functuple[0]] = func(oobkey, self, *functuple[1], **functuple[2])
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
else:
|
else:
|
||||||
logger.log_errmsg("oob_data_in error: funcname '%s' not found in OOB_FUNC_MODULE." % funcname)
|
logger.log_errmsg("oob_data_in error: funcname '%s' not found in OOB_FUNC_MODULE." % functuple[0])
|
||||||
if outdata:
|
if outdata:
|
||||||
# we have a direct result - send it back right away
|
# we have a direct result - send it back right away
|
||||||
self.oob_data_out(outdata)
|
self.oob_data_out(outdata)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ SSYNC = chr(8) # server session sync
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
SERVERNAME = settings.SERVERNAME
|
SERVERNAME = settings.SERVERNAME
|
||||||
ALLOW_MULTISESSION = settings.ALLOW_MULTISESSION
|
#ALLOW_MULTISESSION = settings.ALLOW_MULTISESSION
|
||||||
|
MULTISESSION_MODE = settings.MULTISESSION_MODE
|
||||||
IDLE_TIMEOUT = settings.IDLE_TIMEOUT
|
IDLE_TIMEOUT = settings.IDLE_TIMEOUT
|
||||||
|
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
|
|
@ -163,8 +164,8 @@ class ServerSessionHandler(SessionHandler):
|
||||||
"""
|
"""
|
||||||
# prep the session with player/user info
|
# prep the session with player/user info
|
||||||
|
|
||||||
if not ALLOW_MULTISESSION:
|
if MULTISESSION_MODE == 0:
|
||||||
# disconnect previous sessions.
|
# disconnect all previous sessions.
|
||||||
self.disconnect_duplicate_sessions(session)
|
self.disconnect_duplicate_sessions(session)
|
||||||
session.logged_in = True
|
session.logged_in = True
|
||||||
# sync the portal to this session
|
# sync the portal to this session
|
||||||
|
|
@ -222,26 +223,30 @@ class ServerSessionHandler(SessionHandler):
|
||||||
|
|
||||||
def player_count(self):
|
def player_count(self):
|
||||||
"""
|
"""
|
||||||
Get the number of connected players (not sessions since a player
|
Get the number of connected players (not sessions since a
|
||||||
may have more than one session connected if ALLOW_MULTISESSION is True)
|
player may have more than one session depending on settings).
|
||||||
Only logged-in players are counted here.
|
Only logged-in players are counted here.
|
||||||
"""
|
"""
|
||||||
return len(set(session.uid for session in self.sessions.values() if session.logged_in))
|
return len(set(session.uid for session in self.sessions.values() if session.logged_in))
|
||||||
|
|
||||||
def sessions_from_player(self, player):
|
def sessions_from_player(self, player, sessid=None):
|
||||||
"""
|
"""
|
||||||
Given a player, return any matching sessions.
|
Given a player, return any matching sessions.
|
||||||
"""
|
"""
|
||||||
uid = player.uid
|
uid = player.uid
|
||||||
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
|
if sessid:
|
||||||
|
session = self.sessions.get(sessid)
|
||||||
|
return session and session.logged_in and session.uid == uid and session or None
|
||||||
|
else:
|
||||||
|
return [session for session in self.sessions.values() if session.logged_in and session.uid == uid]
|
||||||
|
|
||||||
def sessions_from_character(self, character):
|
def sessions_from_character(self, character):
|
||||||
"""
|
"""
|
||||||
Given a game character, return any matching sessions.
|
Given a game character, return any matching sessions.
|
||||||
"""
|
"""
|
||||||
player = character.player
|
sessid = character.sessid
|
||||||
if player:
|
if sessid:
|
||||||
return self.sessions_from_player(player)
|
return self.sessions.get(sessid)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def announce_all(self, message):
|
def announce_all(self, message):
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,12 @@ SSL_ENABLED = False
|
||||||
SSL_PORTS = [4001]
|
SSL_PORTS = [4001]
|
||||||
# Interface addresses to listen to. If 0.0.0.0, listen to all.
|
# Interface addresses to listen to. If 0.0.0.0, listen to all.
|
||||||
SSL_INTERFACES = ['0.0.0.0']
|
SSL_INTERFACES = ['0.0.0.0']
|
||||||
# If multisessions are allowed, a user can log into the game
|
# Multisession modes allow a player (=account) to connect to the game simultaneously
|
||||||
# from several different computers/clients at the same time.
|
# with multiple clients in various ways according to the set mode:
|
||||||
# All feedback from the game will be echoed to all sessions.
|
# 0 - no multisession - when a new session is connected, the old one is disconnected
|
||||||
# If false, only one session is allowed, all other are logged off
|
# 1 - multiple sessions, one player, one character, each session getting the same data
|
||||||
# when a new connects.
|
# 2 - multiple sessions, one player, each session controlling different characters
|
||||||
ALLOW_MULTISESSION = False
|
MULTISESSION_MODE = 0
|
||||||
# The path that contains this settings.py file (no trailing slash).
|
# The path that contains this settings.py file (no trailing slash).
|
||||||
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
# Path to the src directory containing the bulk of the codebase's code.
|
# Path to the src directory containing the bulk of the codebase's code.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,8 @@ class TypeClass(object):
|
||||||
"""
|
"""
|
||||||
if propname == 'dbobj':
|
if propname == 'dbobj':
|
||||||
return _GA(self, 'dbobj')
|
return _GA(self, 'dbobj')
|
||||||
|
if propname == 'typeclass':
|
||||||
|
return self
|
||||||
if propname.startswith('__') and propname.endswith('__'):
|
if propname.startswith('__') and propname.endswith('__'):
|
||||||
# python specials are parsed as-is (otherwise things like
|
# python specials are parsed as-is (otherwise things like
|
||||||
# isinstance() fail to identify the typeclass)
|
# isinstance() fail to identify the typeclass)
|
||||||
|
|
|
||||||
|
|
@ -500,6 +500,7 @@ def create_player(name, email, password,
|
||||||
# call hook method (may override default permissions)
|
# call hook method (may override default permissions)
|
||||||
new_player.at_player_creation()
|
new_player.at_player_creation()
|
||||||
|
|
||||||
|
print
|
||||||
# custom given arguments potentially overrides the hook
|
# custom given arguments potentially overrides the hook
|
||||||
if permissions:
|
if permissions:
|
||||||
new_player.permissions = permissions
|
new_player.permissions = permissions
|
||||||
|
|
@ -521,7 +522,7 @@ def create_player(name, email, password,
|
||||||
player=new_player, report_to=report_to)
|
player=new_player, report_to=report_to)
|
||||||
return new_character
|
return new_character
|
||||||
return new_player
|
return new_player
|
||||||
except Exception, e:
|
except Exception:
|
||||||
# a failure in creating the character
|
# a failure in creating the character
|
||||||
if not user:
|
if not user:
|
||||||
# in there was a failure we clean up everything we can
|
# in there was a failure we clean up everything we can
|
||||||
|
|
@ -538,7 +539,7 @@ def create_player(name, email, password,
|
||||||
del new_character
|
del new_character
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
raise e
|
raise
|
||||||
|
|
||||||
# alias
|
# alias
|
||||||
player = create_player
|
player = create_player
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue