Useful default typeclass for channels added. Handles poses and provides interfaces for external messages and internal alike.
This commit is contained in:
parent
851e6d00cc
commit
48bcb9d0ba
7 changed files with 267 additions and 107 deletions
|
|
@ -151,8 +151,9 @@ class CmdDelCom(MuxPlayerCommand):
|
||||||
for nick in [nick for nick in caller.nicks.get(category="channel")
|
for nick in [nick for nick in caller.nicks.get(category="channel")
|
||||||
if nick.db_data.lower() == chkey]:
|
if nick.db_data.lower() == chkey]:
|
||||||
nick.delete()
|
nick.delete()
|
||||||
channel.disconnect_from(player)
|
disconnect = channel.disconnect_from(player)
|
||||||
self.msg("You stop listening to channel '%s'. Eventual aliases were removed." % channel.key)
|
if disconnect:
|
||||||
|
self.msg("You stop listening to channel '%s'. Eventual aliases were removed." % channel.key)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# we are removing a channel nick
|
# we are removing a channel nick
|
||||||
|
|
|
||||||
|
|
@ -77,20 +77,8 @@ class ChannelCommand(command.Command):
|
||||||
string = "You are not permitted to send to channel '%s'."
|
string = "You are not permitted to send to channel '%s'."
|
||||||
self.msg(string % channelkey)
|
self.msg(string % channelkey)
|
||||||
return
|
return
|
||||||
msg = "[%s] %s: %s" % (channel.key, caller.name, msg)
|
channel.msg(msg, senders=self.caller, online=True)
|
||||||
# we can't use the utils.create function to make the Msg,
|
|
||||||
# since that creates an import recursive loop.
|
|
||||||
try:
|
|
||||||
sender = caller.player
|
|
||||||
except AttributeError:
|
|
||||||
# this could happen if a player is calling directly.
|
|
||||||
sender = caller.dbobj
|
|
||||||
msgobj = Msg(db_message=msg)
|
|
||||||
msgobj.save()
|
|
||||||
msgobj.senders = sender
|
|
||||||
msgobj.channels = channel
|
|
||||||
# send new message object to channel
|
|
||||||
channel.msg(msgobj, senders=sender, online=True)
|
|
||||||
|
|
||||||
class ChannelHandler(object):
|
class ChannelHandler(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ Default Typeclass for Comms.
|
||||||
|
|
||||||
See objects.objects for more information on Typeclassing.
|
See objects.objects for more information on Typeclassing.
|
||||||
"""
|
"""
|
||||||
|
from src.comms import Msg, TempMsg, ChannelDB
|
||||||
from src.typeclasses.typeclass import TypeClass
|
from src.typeclasses.typeclass import TypeClass
|
||||||
|
from src.utils import logger
|
||||||
|
from src.utils.utils import make_iter
|
||||||
|
|
||||||
|
|
||||||
class Comm(TypeClass):
|
class Comm(TypeClass):
|
||||||
|
|
@ -14,8 +17,214 @@ class Comm(TypeClass):
|
||||||
def __init__(self, dbobj):
|
def __init__(self, dbobj):
|
||||||
super(Comm, self).__init__(dbobj)
|
super(Comm, self).__init__(dbobj)
|
||||||
|
|
||||||
def format_message(self, msg):
|
def channel_prefix(self, msg=None, emit=False):
|
||||||
"""
|
"""
|
||||||
Takes a Msg (see models.Msg), and derives the output display for it on
|
How the channel should prefix itself for users. Return a string.
|
||||||
the channel.
|
|
||||||
"""
|
"""
|
||||||
|
return '[%s] ' % self.key
|
||||||
|
|
||||||
|
def format_senders(self, senders=None):
|
||||||
|
"""
|
||||||
|
Function used to format a list of sender names.
|
||||||
|
|
||||||
|
This function exists separately so that external sources can use
|
||||||
|
it to format source names in the same manner as normal object/player
|
||||||
|
names.
|
||||||
|
"""
|
||||||
|
if not senders:
|
||||||
|
return ''
|
||||||
|
return ', '.join(senders)
|
||||||
|
|
||||||
|
def pose_transform(self, msg, sender_string):
|
||||||
|
"""
|
||||||
|
Detects if the sender is posing, and modifies the message accordingly.
|
||||||
|
"""
|
||||||
|
pose = False
|
||||||
|
message = msg.message
|
||||||
|
message_start = message.lstrip()
|
||||||
|
if message_start.startswith((':', ';')):
|
||||||
|
pose = True
|
||||||
|
message = message[1:]
|
||||||
|
if not message.startswith((':', "'", ',')):
|
||||||
|
if not message.startswith(' '):
|
||||||
|
message = ' ' + message
|
||||||
|
if pose:
|
||||||
|
return '%s%s' % (sender_string, message)
|
||||||
|
else:
|
||||||
|
return '%s: %s' % (sender_string, message)
|
||||||
|
|
||||||
|
|
||||||
|
def format_external(self, msg, senders, emit=False):
|
||||||
|
"""
|
||||||
|
Used for formatting external messages. This is needed as a separate
|
||||||
|
operation because the senders of external messages may not be in-game
|
||||||
|
objects/players, and so cannot have things like custom user
|
||||||
|
preferences.
|
||||||
|
|
||||||
|
senders should be a list of strings, each containing a sender.
|
||||||
|
msg should contain the body of the message to be sent.
|
||||||
|
"""
|
||||||
|
if not senders:
|
||||||
|
emit = True
|
||||||
|
if emit:
|
||||||
|
return msg.message
|
||||||
|
senders = ', '.join(senders)
|
||||||
|
return self.pose_transform(msg, senders)
|
||||||
|
|
||||||
|
|
||||||
|
def format_message(self, msg, emit=False):
|
||||||
|
"""
|
||||||
|
Formats a message body for display.
|
||||||
|
|
||||||
|
If emit is True, it means the message is intended to be posted detached
|
||||||
|
from an identity.
|
||||||
|
"""
|
||||||
|
# We don't want to count things like external sources as senders for
|
||||||
|
# the purpose of constructing the message string.
|
||||||
|
senders = [sender for sender in msg.senders if hasattr(sender, 'key')]
|
||||||
|
if not senders:
|
||||||
|
emit = True
|
||||||
|
if emit:
|
||||||
|
return msg.message
|
||||||
|
else:
|
||||||
|
senders = [sender.key for sender in msg.senders]
|
||||||
|
senders = ', '.join(senders)
|
||||||
|
return self.pose_transform(msg, senders)
|
||||||
|
|
||||||
|
def message_transform(self, msg, emit=False, prefix=True,
|
||||||
|
sender_strings=None, external=False):
|
||||||
|
"""
|
||||||
|
Generates the formatted string sent to listeners on a channel.
|
||||||
|
"""
|
||||||
|
if sender_strings or external:
|
||||||
|
body = self.format_external(msg, sender_strings, emit=emit)
|
||||||
|
else:
|
||||||
|
body = self.format_message(msg, emit=emit)
|
||||||
|
if prefix:
|
||||||
|
body = "%s%s" % (self.channel_prefix(msg, emit=emit), body)
|
||||||
|
msg.message = body
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def at_channel_create(self):
|
||||||
|
"""
|
||||||
|
Run at channel creation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def pre_join_channel(self, joiner):
|
||||||
|
"""
|
||||||
|
Run right before a channel is joined. If this returns a false value,
|
||||||
|
channel joining is aborted.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def post_join_channel(self, joiner):
|
||||||
|
"""
|
||||||
|
Run right after an object or player joins a channel.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def pre_leave_channel(self, leaver):
|
||||||
|
"""
|
||||||
|
Run right before a user leaves a channel. If this returns a false
|
||||||
|
value, leaving the channel will be aborted.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def post_leave_channel(self, leaver):
|
||||||
|
"""
|
||||||
|
Run right after an object or player leaves a channel.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def pre_send_message(self, msg):
|
||||||
|
"""
|
||||||
|
Run before a message is sent to the channel.
|
||||||
|
|
||||||
|
This should return the message object, after any transformations.
|
||||||
|
If the message is to be discarded, return a false value.
|
||||||
|
"""
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def post_send_message(self, msg):
|
||||||
|
"""
|
||||||
|
Run after a message is sent to the channel.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def at_init(self):
|
||||||
|
"""
|
||||||
|
This is always called whenever this channel is initiated --
|
||||||
|
that is, whenever it its typeclass is cached from memory. This
|
||||||
|
happens on-demand first time the channel is used or activated
|
||||||
|
in some way after being created but also after each server
|
||||||
|
restart or reload.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def distribute_message(self, msg, online=False):
|
||||||
|
"""
|
||||||
|
Method for grabbing all listeners that a message should be sent to on
|
||||||
|
this channel, and sending them a message.
|
||||||
|
"""
|
||||||
|
# get all players connected to this channel and send to them
|
||||||
|
for conn in ChannelDB.objects.get_all_connections(self, online=online):
|
||||||
|
try:
|
||||||
|
conn.player.msg(msg.message, from_obj=msg.senders)
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
conn.to_external(msg.message, senders=msg.senders, from_channel=self)
|
||||||
|
except Exception:
|
||||||
|
logger.log_trace("Cannot send msg to connection '%s'" % conn)
|
||||||
|
|
||||||
|
|
||||||
|
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
|
||||||
|
persistent=True, online=False, emit=False, external=False):
|
||||||
|
"""
|
||||||
|
Send the given message to all players connected to channel. Note that
|
||||||
|
no permission-checking is done here; it is assumed to have been
|
||||||
|
done before calling this method. The optional keywords are not used if persistent is False.
|
||||||
|
|
||||||
|
msgobj - a Msg/TempMsg instance or a message string. If one of the former, the remaining
|
||||||
|
keywords will be ignored. If a string, this will either be sent as-is (if persistent=False) or
|
||||||
|
it will be used together with header and senders keywords to create a Msg instance on the fly.
|
||||||
|
senders - an object, player or a list of objects or players. Optional if persistent=False.
|
||||||
|
sender_strings - Name strings of senders. Used for external connections where the sender
|
||||||
|
is not a player or object. When this is defined, external will be assumed.
|
||||||
|
external - Treat this message agnostic of its sender.
|
||||||
|
persistent (bool) - ignored if msgobj is a Msg or TempMsg. If True, a Msg will be created, using
|
||||||
|
header and senders keywords. If False, other keywords will be ignored.
|
||||||
|
online (bool) - If this is set true, only messages people who are online. Otherwise, messages all players
|
||||||
|
connected. This can make things faster, but may not trigger listeners on players that are offline.
|
||||||
|
emit (bool) - Signals to the message formatter that this message is not to be directly associated with a name.
|
||||||
|
"""
|
||||||
|
if senders:
|
||||||
|
senders = make_iter(senders)
|
||||||
|
else:
|
||||||
|
senders = []
|
||||||
|
if isinstance(msgobj, basestring):
|
||||||
|
# given msgobj is a string
|
||||||
|
msg = msgobj
|
||||||
|
if persistent and self.db.keep_log:
|
||||||
|
msgobj = Msg()
|
||||||
|
msgobj.save()
|
||||||
|
else:
|
||||||
|
# Use TempMsg, so this message is not stored.
|
||||||
|
msgobj = TempMsg()
|
||||||
|
msgobj.header = header
|
||||||
|
msgobj.message = msg
|
||||||
|
msgobj.channels = [self.dbobj] # add this channel
|
||||||
|
|
||||||
|
if not msgobj.senders:
|
||||||
|
msgobj.senders = senders
|
||||||
|
msgobj = self.pre_send_message(msgobj)
|
||||||
|
if not msgobj:
|
||||||
|
return False
|
||||||
|
msgobj = self.message_transform(msgobj, emit=emit,
|
||||||
|
sender_strings=sender_strings,
|
||||||
|
external=external)
|
||||||
|
self.distribute_message(msgobj, online=online)
|
||||||
|
self.post_send_message(msgobj)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def tempmsg(self, message, header=None, senders=None):
|
||||||
|
"""
|
||||||
|
A wrapper for sending non-persistent messages.
|
||||||
|
"""
|
||||||
|
self.msg(message, senders=senders, header=header, persistent=False)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,10 @@ class IRC_Bot(irc.IRCClient):
|
||||||
msg_info(msg)
|
msg_info(msg)
|
||||||
logger.log_infomsg(msg)
|
logger.log_infomsg(msg)
|
||||||
|
|
||||||
|
def get_mesg_info(self, user, irc_channel, msg):
|
||||||
def privmsg(self, user, irc_channel, msg):
|
"""
|
||||||
"Someone has written something in irc channel. Echo it to the evennia channel"
|
Get basic information about a message posted in IRC.
|
||||||
|
"""
|
||||||
#find irc->evennia channel mappings
|
#find irc->evennia channel mappings
|
||||||
conns = ExternalChannelConnection.objects.filter(db_external_key=self.factory.key)
|
conns = ExternalChannelConnection.objects.filter(db_external_key=self.factory.key)
|
||||||
if not conns:
|
if not conns:
|
||||||
|
|
@ -65,28 +66,31 @@ class IRC_Bot(irc.IRCClient):
|
||||||
user.strip()
|
user.strip()
|
||||||
else:
|
else:
|
||||||
user = _("Unknown")
|
user = _("Unknown")
|
||||||
msg = "[%s] %s@%s: %s" % (self.factory.evennia_channel, user, irc_channel, msg.strip())
|
msg = msg.strip()
|
||||||
|
sender_strings = ["%s@%s" % (user, irc_channel)]
|
||||||
|
return conns, msg, sender_strings
|
||||||
|
|
||||||
|
def privmsg(self, user, irc_channel, msg):
|
||||||
|
"Someone has written something in irc channel. Echo it to the evennia channel"
|
||||||
|
conns, msg, sender_strings = self.get_mesg_info(user, irc_channel, msg)
|
||||||
#logger.log_infomsg("<IRC: " + msg)
|
#logger.log_infomsg("<IRC: " + msg)
|
||||||
for conn in conns:
|
for conn in conns:
|
||||||
if conn.channel:
|
if conn.channel:
|
||||||
conn.to_channel(msg)
|
conn.to_channel(msg, sender_strings=sender_strings)
|
||||||
|
|
||||||
def action(self, user, irc_channel, msg):
|
def action(self, user, irc_channel, msg):
|
||||||
"Someone has performed an action, e.g. using /me <pose>"
|
"Someone has performed an action, e.g. using /me <pose>"
|
||||||
#find irc->evennia channel mappings
|
#find irc->evennia channel mappings
|
||||||
conns = ExternalChannelConnection.objects.filter(db_external_key=self.factory.key)
|
conns = ExternalChannelConnection.objects.filter(db_external_key=self.factory.key)
|
||||||
if not conns:
|
if not conns:
|
||||||
return
|
return
|
||||||
#format message:
|
conns, msg, sender_strings = self.get_mesg_info(user, irc_channel, msg)
|
||||||
user = user.split("!")[0]
|
# Transform this into a pose.
|
||||||
if user:
|
msg = ':' + msg
|
||||||
user.strip()
|
|
||||||
else:
|
|
||||||
user = _("Unknown")
|
|
||||||
msg = "[%s] *%s@%s %s*" % (self.factory.evennia_channel, user, irc_channel, msg.strip())
|
|
||||||
#logger.log_infomsg("<IRC: " + msg)
|
#logger.log_infomsg("<IRC: " + msg)
|
||||||
for conn in conns:
|
for conn in conns:
|
||||||
if conn.channel:
|
if conn.channel:
|
||||||
conn.to_channel(msg)
|
conn.to_channel(msg, sender_strings=sender_strings)
|
||||||
|
|
||||||
def msg_irc(self, msg, senders=None):
|
def msg_irc(self, msg, senders=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,8 @@ class ChannelManager(models.Manager):
|
||||||
unique_online_users = set(sess.uid for sess in session_list if sess.logged_in)
|
unique_online_users = set(sess.uid for sess in session_list if sess.logged_in)
|
||||||
online_players = (sess.get_player() for sess in session_list if sess.uid in unique_online_users)
|
online_players = (sess.get_player() for sess in session_list if sess.uid in unique_online_users)
|
||||||
for player in online_players:
|
for player in online_players:
|
||||||
players.extend(PlayerChannelConnection.objects.filter(db_player=player.dbobj, db_channel=channel))
|
players.extend(PlayerChannelConnection.objects.filter(
|
||||||
|
db_player=player.dbobj, db_channel=channel.dbobj))
|
||||||
else:
|
else:
|
||||||
players.extend(PlayerChannelConnection.objects.get_all_connections(channel))
|
players.extend(PlayerChannelConnection.objects.get_all_connections(channel))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ class Msg(SharedMemoryModel):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
SharedMemoryModel.__init__(self, *args, **kwargs)
|
SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||||
self.locks = LockHandler(self)
|
self.locks = LockHandler(self)
|
||||||
|
self.extra_senders = []
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
|
|
@ -120,7 +121,9 @@ class Msg(SharedMemoryModel):
|
||||||
def __senders_get(self):
|
def __senders_get(self):
|
||||||
"Getter. Allows for value = self.sender"
|
"Getter. Allows for value = self.sender"
|
||||||
return [hasattr(o, "typeclass") and o.typeclass or o for o in
|
return [hasattr(o, "typeclass") and o.typeclass or o for o in
|
||||||
list(self.db_sender_players.all()) + list(self.db_sender_objects.all())]
|
list(self.db_sender_players.all()) +
|
||||||
|
list(self.db_sender_objects.all()) +
|
||||||
|
self.extra_senders]
|
||||||
#@sender.setter
|
#@sender.setter
|
||||||
def __senders_set(self, value):
|
def __senders_set(self, value):
|
||||||
"Setter. Allows for self.sender = value"
|
"Setter. Allows for self.sender = value"
|
||||||
|
|
@ -130,6 +133,10 @@ class Msg(SharedMemoryModel):
|
||||||
self.db_sender_players.add(obj)
|
self.db_sender_players.add(obj)
|
||||||
elif typ == 'object':
|
elif typ == 'object':
|
||||||
self.db_sender_objects.add(obj)
|
self.db_sender_objects.add(obj)
|
||||||
|
elif typ == 'external':
|
||||||
|
self.db_sender_external = "1"
|
||||||
|
self.extra_senders.append(obj)
|
||||||
|
print "I ran!"
|
||||||
elif isinstance(typ, basestring):
|
elif isinstance(typ, basestring):
|
||||||
self.db_sender_external = obj
|
self.db_sender_external = obj
|
||||||
elif not obj:
|
elif not obj:
|
||||||
|
|
@ -143,6 +150,7 @@ class Msg(SharedMemoryModel):
|
||||||
self.db_sender_players.clear()
|
self.db_sender_players.clear()
|
||||||
self.db_sender_objects.clear()
|
self.db_sender_objects.clear()
|
||||||
self.db_sender_external = ""
|
self.db_sender_external = ""
|
||||||
|
self.extra_senders = []
|
||||||
self.save()
|
self.save()
|
||||||
senders = property(__senders_get, __senders_set, __senders_del)
|
senders = property(__senders_get, __senders_set, __senders_del)
|
||||||
|
|
||||||
|
|
@ -154,8 +162,11 @@ class Msg(SharedMemoryModel):
|
||||||
self.db_sender_players.remove(obj)
|
self.db_sender_players.remove(obj)
|
||||||
elif typ == 'object':
|
elif typ == 'object':
|
||||||
self.db_sender_objects.remove(obj)
|
self.db_sender_objects.remove(obj)
|
||||||
elif isinstance(obj, basestring) and self.db_sender_external == obj:
|
elif typ == 'external':
|
||||||
self.db_sender_external = ""
|
self.extra_senders = [receiver for receiver in
|
||||||
|
self.extra_senders if receiver != obj]
|
||||||
|
elif isinstance(obj, basestring):
|
||||||
|
self.db_sender_external = obj
|
||||||
else:
|
else:
|
||||||
raise ValueError(obj)
|
raise ValueError(obj)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
@ -185,6 +196,7 @@ class Msg(SharedMemoryModel):
|
||||||
"Deleter. Clears all receivers"
|
"Deleter. Clears all receivers"
|
||||||
self.db_receivers_players.clear()
|
self.db_receivers_players.clear()
|
||||||
self.db_receivers_objects.clear()
|
self.db_receivers_objects.clear()
|
||||||
|
self.extra_senders = []
|
||||||
self.save()
|
self.save()
|
||||||
receivers = property(__receivers_get, __receivers_set, __receivers_del)
|
receivers = property(__receivers_get, __receivers_set, __receivers_del)
|
||||||
|
|
||||||
|
|
@ -241,22 +253,6 @@ class Msg(SharedMemoryModel):
|
||||||
self.save()
|
self.save()
|
||||||
hide_from = property(__hide_from_get, __hide_from_set, __hide_from_del)
|
hide_from = property(__hide_from_get, __hide_from_set, __hide_from_del)
|
||||||
|
|
||||||
# lock_storage property (wraps db_lock_storage)
|
|
||||||
#@property
|
|
||||||
#def __lock_storage_get(self):
|
|
||||||
# "Getter. Allows for value = self.lock_storage"
|
|
||||||
# return self.db_lock_storage
|
|
||||||
##@nick.setter
|
|
||||||
#def __lock_storage_set(self, value):
|
|
||||||
# """Saves the lock_storagetodate. This is usually not called directly, but through self.lock()"""
|
|
||||||
# self.db_lock_storage = value
|
|
||||||
# self.save()
|
|
||||||
##@nick.deleter
|
|
||||||
#def __lock_storage_del(self):
|
|
||||||
# "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
|
||||||
# logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
|
|
||||||
#lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Msg class methods
|
# Msg class methods
|
||||||
#
|
#
|
||||||
|
|
@ -385,77 +381,36 @@ class ChannelDB(TypedObject):
|
||||||
# do the check
|
# do the check
|
||||||
return PlayerChannelConnection.objects.has_player_connection(player, self)
|
return PlayerChannelConnection.objects.has_player_connection(player, self)
|
||||||
|
|
||||||
def msg(self, msgobj, header=None, senders=None, persistent=True, online=False):
|
|
||||||
"""
|
|
||||||
Send the given message to all players connected to channel. Note that
|
|
||||||
no permission-checking is done here; it is assumed to have been
|
|
||||||
done before calling this method. The optional keywords are not used if persistent is False.
|
|
||||||
|
|
||||||
msgobj - a Msg/TempMsg instance or a message string. If one of the former, the remaining
|
|
||||||
keywords will be ignored. If a string, this will either be sent as-is (if persistent=False) or
|
|
||||||
it will be used together with header and senders keywords to create a Msg instance on the fly.
|
|
||||||
senders (object, player or a list of objects or players) - ignored if msgobj is a Msg or TempMsg, or if
|
|
||||||
persistent=False.
|
|
||||||
persistent (bool) - ignored if msgobj is a Msg or TempMsg. If True, a Msg will be created, using
|
|
||||||
header and senders keywords. If False, other keywords will be ignored.
|
|
||||||
online (bool) - If this is set true, only messages people who are online. Otherwise, messages all players
|
|
||||||
connected. This can make things faster, but may not trigger listeners on players that are offline.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if isinstance(msgobj, basestring):
|
|
||||||
# given msgobj is a string
|
|
||||||
if persistent:
|
|
||||||
msg = msgobj
|
|
||||||
msgobj = Msg()
|
|
||||||
msgobj.save()
|
|
||||||
if senders:
|
|
||||||
msgobj.senders = make_iter(senders)
|
|
||||||
msgobj.header = header
|
|
||||||
msgobj.message = msg
|
|
||||||
msgobj.channels = [self] # add this channel
|
|
||||||
else:
|
|
||||||
# just use the msg as-is
|
|
||||||
msg = msgobj
|
|
||||||
else:
|
|
||||||
# already in a Msg/TempMsg
|
|
||||||
msg = msgobj.message
|
|
||||||
|
|
||||||
# get all players connected to this channel and send to them
|
|
||||||
for conn in ChannelDB.objects.get_all_connections(self, online=online):
|
|
||||||
try:
|
|
||||||
conn.player.msg(msg, from_obj=senders)
|
|
||||||
except AttributeError:
|
|
||||||
try:
|
|
||||||
conn.to_external(msg, senders=senders, from_channel=self)
|
|
||||||
except Exception:
|
|
||||||
logger.log_trace("Cannot send msg to connection '%s'" % conn)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def tempmsg(self, message, header=None, senders=None):
|
|
||||||
"""
|
|
||||||
A wrapper for sending non-persistent messages.
|
|
||||||
"""
|
|
||||||
self.msg(message, senders=senders, header=header, persistent=False)
|
|
||||||
|
|
||||||
def connect_to(self, player):
|
def connect_to(self, player):
|
||||||
"Connect the user to this channel"
|
"Connect the user to this channel"
|
||||||
|
self.typeclass.pre_join_channel(player)
|
||||||
if not self.access(player, 'listen'):
|
if not self.access(player, 'listen'):
|
||||||
return False
|
return False
|
||||||
|
connect = self.typeclass.pre_join_channel(player)
|
||||||
|
if not connect:
|
||||||
|
return False
|
||||||
player = player.dbobj
|
player = player.dbobj
|
||||||
conn = PlayerChannelConnection.objects.create_connection(player, self)
|
conn = PlayerChannelConnection.objects.create_connection(player, self)
|
||||||
if conn:
|
if conn:
|
||||||
|
self.typeclass.post_join_channel(player)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def disconnect_from(self, player):
|
def disconnect_from(self, player):
|
||||||
"Disconnect user from this channel."
|
"Disconnect user from this channel."
|
||||||
|
disconnect = self.typeclass.pre_leave_channel(self, player)
|
||||||
|
if not disconnect:
|
||||||
|
return False
|
||||||
PlayerChannelConnection.objects.break_connection(player, self)
|
PlayerChannelConnection.objects.break_connection(player, self)
|
||||||
|
self.typeclass.post_leave_channel(self, player)
|
||||||
|
return True
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
"Clean out all connections to this channel and delete it."
|
"Clean out all connections to this channel and delete it."
|
||||||
for connection in ChannelDB.objects.get_all_connections(self):
|
for connection in ChannelDB.objects.get_all_connections(self):
|
||||||
connection.delete()
|
connection.delete()
|
||||||
super(ChannelDB, self).delete()
|
super(ChannelDB, self).delete()
|
||||||
|
|
||||||
def access(self, accessing_obj, access_type='listen', default=False):
|
def access(self, accessing_obj, access_type='listen', default=False):
|
||||||
"""
|
"""
|
||||||
Determines if another object has permission to access.
|
Determines if another object has permission to access.
|
||||||
|
|
@ -637,17 +592,18 @@ class ExternalChannelConnection(SharedMemoryModel):
|
||||||
# methods
|
# methods
|
||||||
#
|
#
|
||||||
|
|
||||||
def to_channel(self, message, from_obj=None):
|
def to_channel(self, message, *args, **kwargs):
|
||||||
"Send external -> channel"
|
"Send external -> channel"
|
||||||
if not from_obj:
|
if 'from_obj' in kwargs and kwargs.pop('from_obj'):
|
||||||
from_obj = self.external_key
|
from_obj = self.external_key
|
||||||
self.channel.msg(message, senders=[self])
|
self.channel.msg(message, senders=[self], *args, **kwargs)
|
||||||
|
|
||||||
def to_external(self, message, senders=None, from_channel=None):
|
def to_external(self, message, senders=None, from_channel=None):
|
||||||
"Send channel -> external"
|
"Send channel -> external"
|
||||||
|
|
||||||
# make sure we are not echoing back our own message to ourselves
|
# make sure we are not echoing back our own message to ourselves
|
||||||
# (this would result in a nasty infinite loop)
|
# (this would result in a nasty infinite loop)
|
||||||
|
print senders
|
||||||
if self in make_iter(senders):#.external_key:
|
if self in make_iter(senders):#.external_key:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -384,6 +384,7 @@ def create_channel(key, aliases=None, desc=None,
|
||||||
new_channel.locks.add(locks)
|
new_channel.locks.add(locks)
|
||||||
new_channel.save()
|
new_channel.save()
|
||||||
_channelhandler.CHANNELHANDLER.add_channel(new_channel)
|
_channelhandler.CHANNELHANDLER.add_channel(new_channel)
|
||||||
|
new_channel.at_channel_create()
|
||||||
return new_channel
|
return new_channel
|
||||||
|
|
||||||
channel = create_channel
|
channel = create_channel
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue