Changed player.search to only search for players explicitly.
Added a MuxCommandOOC class to handle the OOC commands in a more uniform way. Fixed the @ic/@ooc and page commands. Resolves issue 233. Resolves issue 234.
This commit is contained in:
parent
96e95ca525
commit
8ad4f4a9fc
12 changed files with 253 additions and 168 deletions
|
|
@ -12,7 +12,7 @@ from src.comms.models import Channel, Msg, PlayerChannelConnection, ExternalChan
|
|||
from src.comms import irc, imc2, rss
|
||||
from src.comms.channelhandler import CHANNELHANDLER
|
||||
from src.utils import create, utils
|
||||
from src.commands.default.muxcommand import MuxCommand
|
||||
from src.commands.default.muxcommand import MuxCommand, MuxCommandOOC
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CommCommand", "CmdAddCom", "CmdDelCom", "CmdAllCom",
|
||||
|
|
@ -624,7 +624,7 @@ class CmdCdesc(MuxCommand):
|
|||
channel.save()
|
||||
caller.msg("Description of channel '%s' set to '%s'." % (channel.key, self.rhs))
|
||||
|
||||
class CmdPage(MuxCommand):
|
||||
class CmdPage(MuxCommandOOC):
|
||||
"""
|
||||
page - send private message
|
||||
|
||||
|
|
@ -647,18 +647,17 @@ class CmdPage(MuxCommand):
|
|||
help_category = "Comms"
|
||||
|
||||
def func(self):
|
||||
|
||||
"Implement function using the Msg methods"
|
||||
|
||||
# this is a MuxCommandOOC, which means caller will be a Player.
|
||||
caller = self.caller
|
||||
player = caller
|
||||
character = self.character
|
||||
|
||||
# get the messages we've sent
|
||||
messages_we_sent = list(Msg.objects.get_messages_by_sender(player))
|
||||
pages_we_sent = [msg for msg in messages_we_sent
|
||||
if msg.receivers]
|
||||
messages_we_sent = list(Msg.objects.get_messages_by_sender(caller))
|
||||
pages_we_sent = [msg for msg in messages_we_sent if msg.receivers]
|
||||
# get last messages we've got
|
||||
pages_we_got = list(Msg.objects.get_messages_by_receiver(player))
|
||||
pages_we_got = list(Msg.objects.get_messages_by_receiver(caller))
|
||||
|
||||
if 'last' in self.switches:
|
||||
if pages_we_sent:
|
||||
|
|
@ -718,9 +717,7 @@ class CmdPage(MuxCommand):
|
|||
recobjs = []
|
||||
for receiver in set(receivers):
|
||||
if isinstance(receiver, basestring):
|
||||
pobj = caller.search("*%s" % (receiver.lstrip('*')), global_search=True)
|
||||
if not pobj:
|
||||
return
|
||||
pobj = caller.search(receiver)
|
||||
elif hasattr(receiver, 'character'):
|
||||
pobj = receiver.character
|
||||
else:
|
||||
|
|
@ -739,7 +736,7 @@ class CmdPage(MuxCommand):
|
|||
message = "%s %s" % (caller.key, message.strip(':').strip())
|
||||
|
||||
# create the persistent message object
|
||||
msg = create.create_message(player, message,
|
||||
msg = create.create_message(caller, message,
|
||||
receivers=recobjs)
|
||||
|
||||
# tell the players they got a message.
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ now.
|
|||
import time
|
||||
from django.conf import settings
|
||||
from src.server.sessionhandler import SESSIONS
|
||||
from src.utils import utils
|
||||
from src.utils import utils, search
|
||||
from src.objects.models import ObjectNick as Nick
|
||||
from src.commands.default.muxcommand import MuxCommand
|
||||
from src.commands.default.muxcommand import MuxCommand, MuxCommandOOC
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdHome", "CmdLook", "CmdPassword", "CmdNick",
|
||||
|
|
@ -611,7 +611,7 @@ class CmdAccess(MuxCommand):
|
|||
|
||||
# OOC commands
|
||||
|
||||
class CmdOOCLook(CmdLook):
|
||||
class CmdOOCLook(MuxCommandOOC, CmdLook):
|
||||
"""
|
||||
ooc look
|
||||
|
||||
|
|
@ -633,14 +633,6 @@ class CmdOOCLook(CmdLook):
|
|||
def func(self):
|
||||
"implement the ooc look command"
|
||||
|
||||
self.character = None
|
||||
if utils.inherits_from(self.caller, "src.objects.objects.Object"):
|
||||
# An object of some type is calling. Convert to player.
|
||||
#print self.caller, self.caller.__class__
|
||||
self.character = self.caller
|
||||
if hasattr(self.caller, "player"):
|
||||
self.caller = self.caller.player
|
||||
|
||||
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."
|
||||
|
|
@ -649,7 +641,7 @@ class CmdOOCLook(CmdLook):
|
|||
self.caller = self.character # we have to put this back for normal look to work.
|
||||
super(CmdOOCLook, self).func()
|
||||
|
||||
class CmdIC(MuxCommand):
|
||||
class CmdIC(MuxCommandOOC):
|
||||
"""
|
||||
Switch control to an object
|
||||
|
||||
|
|
@ -674,8 +666,7 @@ class CmdIC(MuxCommand):
|
|||
Simple puppet method
|
||||
"""
|
||||
caller = self.caller
|
||||
if utils.inherits_from(caller, "src.objects.objects.Object"):
|
||||
caller = caller.player
|
||||
old_character = self.character
|
||||
|
||||
new_character = None
|
||||
if not self.args:
|
||||
|
|
@ -685,10 +676,12 @@ class CmdIC(MuxCommand):
|
|||
return
|
||||
if not new_character:
|
||||
# search for a matching character
|
||||
new_character = caller.search(self.args, global_search=True)
|
||||
if not new_character:
|
||||
# the search method handles error messages etc.
|
||||
return
|
||||
new_character = search.objects(self.args, caller, global_search=True, single_result=True)
|
||||
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)
|
||||
|
|
@ -698,13 +691,9 @@ class CmdIC(MuxCommand):
|
|||
if not new_character.access(caller, "puppet"):
|
||||
caller.msg("{rYou may not become %s.{n" % new_character.name)
|
||||
return
|
||||
old_char = None
|
||||
if caller.character:
|
||||
# save the old character. We only assign this to last_puppet if swap is successful.
|
||||
old_char = caller.character
|
||||
if caller.swap_character(new_character):
|
||||
new_character.msg("\n{gYou become {c%s{n.\n" % new_character.name)
|
||||
caller.db.last_puppet = old_char
|
||||
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
|
||||
|
|
@ -718,7 +707,7 @@ class CmdIC(MuxCommand):
|
|||
else:
|
||||
caller.msg("{rYou cannot become {C%s{n." % new_character.name)
|
||||
|
||||
class CmdOOC(MuxCommand):
|
||||
class CmdOOC(MuxCommandOOC):
|
||||
"""
|
||||
@ooc - go ooc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""
|
||||
The command template for the default MUX-style command set
|
||||
The command template for the default MUX-style command set. There
|
||||
is also an OOC version that makes sure caller is a Player object.
|
||||
"""
|
||||
|
||||
from src.utils import utils
|
||||
|
|
@ -11,7 +12,7 @@ __all__ = ("MuxCommand",)
|
|||
class MuxCommand(Command):
|
||||
"""
|
||||
This sets up the basis for a MUX command. The idea
|
||||
is that most other Mux-related commands should just
|
||||
is tkhat most other Mux-related commands should just
|
||||
inherit from this and don't have to implement much
|
||||
parsing of their own unless they do something particularly
|
||||
advanced.
|
||||
|
|
@ -161,3 +162,33 @@ class MuxCommand(Command):
|
|||
string += "rhs, comma separated (self.rhslist): {w%s{n\n" % self.rhslist
|
||||
string += "-" * 50
|
||||
self.caller.msg(string)
|
||||
|
||||
class MuxCommandOOC(MuxCommand):
|
||||
"""
|
||||
This is an OOC version of the MuxCommand. Since OOC commands sit
|
||||
on Players rather than on Characters/Objects, we need to check
|
||||
this in the parser.
|
||||
|
||||
OOC commands are strictly speaking also available when IC, it's
|
||||
just that they are applied with a lower priority and are always
|
||||
available, also when disconnected from a character (i.e. "ooc").
|
||||
|
||||
This class makes sure that caller is always a Player object, while
|
||||
creating a new property "character" that is set only if a
|
||||
character is actually attached to the Player.
|
||||
"""
|
||||
def parse(self):
|
||||
"""
|
||||
We run the parent parser as usual, then fix the result
|
||||
"""
|
||||
super(MuxCommandOOC, self).parse()
|
||||
|
||||
if utils.inherits_from(self.caller, "src.objects.objects.Object"):
|
||||
# caller is an Object/Character
|
||||
self.character = self.caller
|
||||
self.caller = self.caller.player
|
||||
elif hasattr(self.caller, "character"):
|
||||
# caller was already a Player
|
||||
self.character = self.caller.character
|
||||
else:
|
||||
self.character = None
|
||||
|
|
|
|||
|
|
@ -33,10 +33,11 @@ from src.objects.models import ObjectDB
|
|||
# ------------------------------------------------------------
|
||||
|
||||
# print all feedback from test commands (can become very verbose!)
|
||||
VERBOSE = False
|
||||
|
||||
VERBOSE = True
|
||||
NOMANGLE = True # mangle command input for extra testing
|
||||
|
||||
def cleanup():
|
||||
print "cleaning test database ..."
|
||||
User.objects.all().delete()
|
||||
PlayerDB.objects.all().delete()
|
||||
ObjectDB.objects.all().delete()
|
||||
|
|
@ -45,6 +46,7 @@ def cleanup():
|
|||
PlayerChannelConnection.objects.all().delete()
|
||||
ExternalChannelConnection.objects.all().delete()
|
||||
ServerConfig.objects.all().delete()
|
||||
cleanup()
|
||||
|
||||
class FakeSessionHandler(sessionhandler.ServerSessionHandler):
|
||||
"""
|
||||
|
|
@ -82,6 +84,7 @@ class FakeSession(serversession.ServerSession):
|
|||
def lineReceived(self, raw_string):
|
||||
pass
|
||||
def msg(self, message, data=None):
|
||||
global VERBOSE
|
||||
if message.startswith("Traceback (most recent call last):"):
|
||||
#retval = "Traceback last line: %s" % message.split('\n')[-4:]
|
||||
raise AssertionError(message)
|
||||
|
|
@ -103,6 +106,7 @@ class FakeSession(serversession.ServerSession):
|
|||
raise AssertionError(retval)
|
||||
if VERBOSE:
|
||||
print message
|
||||
# setting up objects
|
||||
|
||||
class CommandTest(TestCase):
|
||||
"""
|
||||
|
|
@ -111,53 +115,77 @@ class CommandTest(TestCase):
|
|||
|
||||
Inherit new tests from this.
|
||||
"""
|
||||
|
||||
NOMANGLE = True # mangle command input for extra testing
|
||||
print "creating command testing objects ..."
|
||||
ROOM1 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room1")
|
||||
ROOM2 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room2")
|
||||
# create a faux player/character for testing.
|
||||
CHAR1 = create.create_player("TestChar", "testplayer@test.com", "testpassword", character_location=ROOM1)
|
||||
CHAR1.player.user.is_superuser = True
|
||||
CHAR1.lock_storage = ""
|
||||
CHAR1.locks = LockHandler(CHAR1)
|
||||
CHAR1.ndb.return_string = None
|
||||
sess = FakeSession()
|
||||
sess.connectionMade()
|
||||
sess.session_login(CHAR1.player)
|
||||
# create second player
|
||||
CHAR2 = create.create_player("TestChar2", "testplayer2@test.com", "testpassword2", character_location=ROOM1)
|
||||
CHAR2.player.user.is_superuser = False
|
||||
CHAR2.lock_storage = ""
|
||||
CHAR2.locks = LockHandler(CHAR2)
|
||||
CHAR2.ndb.return_string = None
|
||||
sess2 = FakeSession()
|
||||
sess2.connectionMade()
|
||||
sess2.session_login(CHAR2.player)
|
||||
# A non-player-controlled character
|
||||
CHAR3 = create.create_object(settings.BASE_CHARACTER_TYPECLASS, key="TestChar3", location=ROOM1)
|
||||
# create some objects
|
||||
OBJ1 = create.create_object(settings.BASE_OBJECT_TYPECLASS, key="obj1", location=ROOM1)
|
||||
OBJ2 = create.create_object(settings.BASE_OBJECT_TYPECLASS, key="obj2", location=ROOM1)
|
||||
EXIT1 = create.create_object(settings.BASE_EXIT_TYPECLASS, key="exit1", location=ROOM1)
|
||||
EXIT2 = create.create_object(settings.BASE_EXIT_TYPECLASS, key="exit2", location=ROOM2)
|
||||
|
||||
def setUp(self):
|
||||
"sets up the testing environment"
|
||||
#ServerConfig.objects.conf("default_home", 2)
|
||||
|
||||
self.addCleanup(cleanup)
|
||||
self.room1 = self.ROOM1
|
||||
self.room2 = self.ROOM2
|
||||
self.char1 = self.CHAR1
|
||||
self.char2 = self.CHAR2
|
||||
self.char3 = self.CHAR3
|
||||
self.obj1 = self.OBJ1
|
||||
self.obj2 = self.OBJ2
|
||||
self.exit1 = self.EXIT1
|
||||
self.exit2 = self.EXIT2
|
||||
|
||||
self.room1 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room1")
|
||||
self.room2 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room2")
|
||||
# create a faux player/character for testing.
|
||||
self.char1 = create.create_player("TestChar", "testplayer@test.com", "testpassword", character_location=self.room1)
|
||||
self.char1.player.user.is_superuser = True
|
||||
self.char1.lock_storage = ""
|
||||
self.char1.locks = LockHandler(self.char1)
|
||||
self.char1.ndb.return_string = None
|
||||
sess = FakeSession()
|
||||
sess.connectionMade()
|
||||
sess.session_login(self.char1.player)
|
||||
# create second player
|
||||
self.char2 = create.create_player("TestChar2", "testplayer2@test.com", "testpassword2", character_location=self.room1)
|
||||
self.char2.player.user.is_superuser = False
|
||||
self.char2.lock_storage = ""
|
||||
self.char2.locks = LockHandler(self.char2)
|
||||
self.char2.ndb.return_string = None
|
||||
sess2 = FakeSession()
|
||||
sess2.connectionMade()
|
||||
sess2.session_login(self.char2.player)
|
||||
# A non-player-controlled character
|
||||
self.char3 = create.create_object(settings.BASE_CHARACTER_TYPECLASS, key="TestChar3", location=self.room1)
|
||||
# create some objects
|
||||
self.obj1 = create.create_object(settings.BASE_OBJECT_TYPECLASS, key="obj1", location=self.room1)
|
||||
self.obj2 = create.create_object(settings.BASE_OBJECT_TYPECLASS, key="obj2", location=self.room1)
|
||||
self.exit1 = create.create_object(settings.BASE_EXIT_TYPECLASS, key="exit1", location=self.room1)
|
||||
self.exit2 = create.create_object(settings.BASE_EXIT_TYPECLASS, key="exit2", location=self.room2)
|
||||
|
||||
def tearDown(self):
|
||||
"Cleans up testing environment after test has run."
|
||||
User.objects.all().delete()
|
||||
PlayerDB.objects.all().delete()
|
||||
ObjectDB.objects.all().delete()
|
||||
Channel.objects.all().delete()
|
||||
Msg.objects.all().delete()
|
||||
PlayerChannelConnection.objects.all().delete()
|
||||
ExternalChannelConnection.objects.all().delete()
|
||||
ServerConfig.objects.all().delete()
|
||||
#self.addCleanup(cleanup)
|
||||
#self.room1 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room1")
|
||||
#self.room2 = create.create_object(settings.BASE_ROOM_TYPECLASS, key="room2")
|
||||
## create a faux player/character for testing.
|
||||
#self.char1 = create.create_player("TestChar", "testplayer@test.com", "testpassword", character_location=self.room1)
|
||||
#self.char1.player.user.is_superuser = True
|
||||
#self.char1.lock_storage = ""
|
||||
#self.char1.locks = LockHandler(self.char1)
|
||||
#self.char1.ndb.return_string = None
|
||||
#sess = FakeSession()
|
||||
#sess.connectionMade()
|
||||
#sess.session_login(self.char1.player)
|
||||
## create second player
|
||||
#self.char2 = create.create_player("TestChar2", "testplayer2@test.com", "testpassword2", character_location=self.room1)
|
||||
#self.char2.player.user.is_superuser = False
|
||||
#self.char2.lock_storage = ""
|
||||
#self.char2.locks = LockHandler(self.char2)
|
||||
#self.char2.ndb.return_string = None
|
||||
#sess2 = FakeSession()
|
||||
#sess2.connectionMade()
|
||||
#sess2.session_login(self.char2.player)
|
||||
## A non-player-controlled character
|
||||
#self.char3 = create.create_object(settings.BASE_CHARACTER_TYPECLASS, key="TestChar3", location=self.room1)
|
||||
## create some objects
|
||||
#self.obj1 = create.create_object(settings.BASE_OBJECT_TYPECLASS, key="obj1", location=self.room1)
|
||||
#self.obj2 = create.create_object(settings.BASE_OBJECT_TYPECLASS, key="obj2", location=self.room1)
|
||||
#self.exit1 = create.create_object(settings.BASE_EXIT_TYPECLASS, key="exit1", location=self.room1)
|
||||
#self.exit2 = create.create_object(settings.BASE_EXIT_TYPECLASS, key="exit2", location=self.room2)
|
||||
|
||||
def get_cmd(self, cmd_class, argument_string=""):
|
||||
"""
|
||||
|
|
@ -178,7 +206,7 @@ class CommandTest(TestCase):
|
|||
This also mangles the input in various ways to test if the command
|
||||
will be fooled.
|
||||
"""
|
||||
if not nomangle and not VERBOSE and not self.NOMANGLE:
|
||||
if not nomangle and not VERBOSE and not NOMANGLE:
|
||||
# only mangle if not VERBOSE, to make fewer return lines
|
||||
test1 = re.sub(r'\s', '', raw_string) # remove all whitespace inside it
|
||||
test2 = "%s/åäö öäö;-:$£@*~^' 'test" % raw_string # inserting weird characters in call
|
||||
|
|
@ -202,7 +230,6 @@ class BuildTest(CommandTest):
|
|||
NOMANGLE = True
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Default set Command testing
|
||||
#------------------------------------------------------------
|
||||
|
|
@ -352,7 +379,7 @@ class TestSet(BuildTest):
|
|||
class TestCpAttr(BuildTest):
|
||||
def test_call(self):
|
||||
self.execute_cmd("@set obj1/test = value")
|
||||
self.execute_cmd("@set me/test2 = value2")
|
||||
self.execute_cmd("@set obj2/test2 = value2")
|
||||
self.execute_cmd("@cpattr obj1/test = obj2/test")
|
||||
self.execute_cmd("@cpattr test2 = obj2")
|
||||
self.assertEqual(self.obj2.db.test, u"value")
|
||||
|
|
@ -408,7 +435,7 @@ class TestCmdSets(BuildTest):
|
|||
def test_call(self):
|
||||
self.execute_cmd("@cmdsets")
|
||||
self.execute_cmd("@cmdsets obj1")
|
||||
class TestDesc(BuildTest):
|
||||
class TestName(BuildTest):
|
||||
def test_call(self):
|
||||
self.execute_cmd("@name obj1 = Test object", "Object's name changed to 'Test object'.")
|
||||
self.assertEqual(self.obj1.key, u"Test object")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue