mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Run migrations! Made Channel model also accept ObjectDB subscriptions.
This commit is contained in:
parent
d63db77eb4
commit
94778f1c44
4 changed files with 193 additions and 27 deletions
|
|
@ -58,44 +58,78 @@ class DefaultChannel(ChannelDB):
|
|||
|
||||
# helper methods, for easy overloading
|
||||
|
||||
def has_connection(self, player):
|
||||
def has_connection(self, subscriber):
|
||||
"""
|
||||
Checks so this player is actually listening
|
||||
to this channel.
|
||||
"""
|
||||
if hasattr(player, "player"):
|
||||
player = player.player
|
||||
return player in self.db_subscriptions.all()
|
||||
|
||||
def connect(self, player):
|
||||
"Connect the user to this channel. This checks access."
|
||||
if hasattr(player, "player"):
|
||||
player = player.player
|
||||
Args:
|
||||
subscriber (Player or Object): Entity to check.
|
||||
|
||||
Returns:
|
||||
has_sub (bool): Whether the subscriber is subscribing to
|
||||
this channel or not.
|
||||
|
||||
Notes:
|
||||
This will first try Player subscribers and only try Object
|
||||
if the Player fails.
|
||||
|
||||
"""
|
||||
has_sub = self.subscriptions.has(subscriber)
|
||||
if not has_sub and hasattr(subscriber, "player"):
|
||||
# it's common to send an Object when we
|
||||
# by default only allow Players to subscribe.
|
||||
has_sub = self.subscriptions.has(subscriber.player)
|
||||
return has_sub
|
||||
|
||||
|
||||
def connect(self, subscriber):
|
||||
"""
|
||||
Connect the user to this channel. This checks access.
|
||||
|
||||
Args:
|
||||
subscriber (Player or Object): the entity to subscribe
|
||||
to this channel.
|
||||
|
||||
Returns:
|
||||
success (bool): Whether or not the addition was
|
||||
successful.
|
||||
|
||||
"""
|
||||
# check access
|
||||
if not self.access(player, 'listen'):
|
||||
if not self.access(subscriber, 'listen'):
|
||||
return False
|
||||
# pre-join hook
|
||||
connect = self.pre_join_channel(player)
|
||||
connect = self.pre_join_channel(subscriber)
|
||||
if not connect:
|
||||
return False
|
||||
# subscribe
|
||||
self.db_subscriptions.add(player)
|
||||
self.subscriptions.add(subscriber)
|
||||
# post-join hook
|
||||
self.post_join_channel(player)
|
||||
self.post_join_channel(subscriber)
|
||||
return True
|
||||
|
||||
def disconnect(self, player):
|
||||
"Disconnect user from this channel."
|
||||
if hasattr(player, "player"):
|
||||
player = player.player
|
||||
def disconnect(self, subscriber):
|
||||
"""
|
||||
Disconnect entity from this channel.
|
||||
|
||||
Args:
|
||||
subscriber (Player of Object): the
|
||||
entity to disconnect.
|
||||
|
||||
Returns:
|
||||
success (bool): Whether or not the removal was
|
||||
successful.
|
||||
|
||||
"""
|
||||
# pre-disconnect hook
|
||||
disconnect = self.pre_leave_channel(player)
|
||||
disconnect = self.pre_leave_channel(subscriber)
|
||||
if not disconnect:
|
||||
return False
|
||||
# disconnect
|
||||
self.db_subscriptions.remove(player)
|
||||
self.subscriptions.remove(subscriber)
|
||||
# post-disconnect hook
|
||||
self.post_leave_channel(player)
|
||||
self.post_leave_channel(subscriber)
|
||||
return True
|
||||
|
||||
def access(self, accessing_obj, access_type='listen', default=False):
|
||||
|
|
@ -133,17 +167,17 @@ class DefaultChannel(ChannelDB):
|
|||
|
||||
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.
|
||||
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 player in self.db_subscriptions.all():
|
||||
for entity in self.subscriptions.all():
|
||||
try:
|
||||
# note our addition of the from_channel keyword here. This could be checked
|
||||
# by a custom player.msg() to treat channel-receives differently.
|
||||
player.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
|
||||
entity.msg(msg.message, from_obj=msg.senders, from_channel=self.id)
|
||||
except AttributeError, e:
|
||||
logger.log_trace("%s\nCannot send msg to player '%s'." % (e, player))
|
||||
logger.log_trace("%s\nCannot send msg to '%s'." % (e, entity))
|
||||
|
||||
def msg(self, msgobj, header=None, senders=None, sender_strings=None,
|
||||
persistent=False, online=False, emit=False, external=False):
|
||||
|
|
|
|||
|
|
@ -283,11 +283,16 @@ class ChannelDBManager(TypedObjectManager):
|
|||
return None
|
||||
|
||||
@returns_typeclass_list
|
||||
def get_subscriptions(self, player):
|
||||
def get_subscriptions(self, entity):
|
||||
"""
|
||||
Return all channels a given player is subscribed to
|
||||
"""
|
||||
return player.subscription_set.all()
|
||||
clsname = entity.__dbclass__.__name__
|
||||
if clsname == "PlayerDB":
|
||||
return entity.subscription_set.all()
|
||||
if clsname == "ObjectDB":
|
||||
return entity.object_subscription_set.all()
|
||||
return []
|
||||
|
||||
@returns_typeclass_list
|
||||
def channel_search(self, ostring, exact=True):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('objects', '0004_auto_20150118_1622'),
|
||||
('comms', '0005_auto_20150223_1517'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='channeldb',
|
||||
name='db_object_subscriptions',
|
||||
field=models.ManyToManyField(related_name='object_subscription_set', null=True, verbose_name=b'subscriptions', to='objects.ObjectDB', db_index=True),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
|
|
@ -349,6 +349,105 @@ class TempMsg(object):
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
class SubscriptionHandler(object):
|
||||
"""
|
||||
This handler manages subscriptions to the
|
||||
channel and hides away which type of entity is
|
||||
subscribing (Player or Object)
|
||||
"""
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Initialize the handler
|
||||
|
||||
Attr:
|
||||
obj (ChannelDB): The channel the handler sits on.
|
||||
|
||||
"""
|
||||
self.obj = obj
|
||||
|
||||
def has(self, entity):
|
||||
"""
|
||||
Check if the given entity subscribe to this channel
|
||||
|
||||
Args:
|
||||
entity (str, Player or Object): The entity to return. If
|
||||
a string, it assumed to be the key or the #dbref
|
||||
of the entity.
|
||||
|
||||
Returns:
|
||||
subscriber (Player, Object or None): The given
|
||||
subscriber.
|
||||
|
||||
"""
|
||||
clsname = entity.__dbclass__.__name__
|
||||
if clsname == "PlayerDB":
|
||||
return entity in self.obj.db_subscriptions.all()
|
||||
elif clsname == "ObjectDB":
|
||||
return entity in self.obj.db_object_subscriptions.all()
|
||||
|
||||
|
||||
def add(self, entity):
|
||||
"""
|
||||
Subscribe an entity to this channel.
|
||||
|
||||
Args:
|
||||
entity (Player, Object or list): The entity or
|
||||
list of entities to subscribe to this channel.
|
||||
|
||||
Note:
|
||||
No access-checking is done here, this must have
|
||||
been done before calling this method. Also
|
||||
no hooks will be called.
|
||||
|
||||
"""
|
||||
for subscriber in make_iter(entity):
|
||||
if subscriber:
|
||||
clsname = subscriber.__dbclass__.__name__
|
||||
# chooses the right type
|
||||
if clsname == "ObjectDB":
|
||||
self.obj.db_object_subscriptions.add(subscriber)
|
||||
elif clsname == "PlayerDB":
|
||||
self.obj.db_subscriptions.add(subscriber)
|
||||
|
||||
def remove(self, entity):
|
||||
"""
|
||||
Remove a subecriber from the channel.
|
||||
|
||||
Args:
|
||||
entity (Player, Object or list): The entity or
|
||||
entities to un-subscribe from the channel.
|
||||
|
||||
"""
|
||||
for subscriber in make_iter(entity):
|
||||
if subscriber:
|
||||
clsname = subscriber.__dbclass__.__name__
|
||||
# chooses the right type
|
||||
if clsname == "PlayerDB":
|
||||
self.obj.db_subscriptions.remove(entity)
|
||||
elif clsname == "ObjectDB":
|
||||
self.obj.db_object_subscriptions.remove(entity)
|
||||
|
||||
def all(self):
|
||||
"""
|
||||
Get all subscriptions to this channel.
|
||||
|
||||
Returns:
|
||||
subscribers (list): The subscribers. This
|
||||
may be a mix of Players and Objects!
|
||||
|
||||
"""
|
||||
return list(self.obj.db_subscriptions.all()) + \
|
||||
list(self.obj.db_object_subscriptions.all())
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Remove all subscribers from channel.
|
||||
|
||||
"""
|
||||
self.obj.db_subscriptions.clear()
|
||||
self.obj.db_object_subscriptions.clear()
|
||||
|
||||
|
||||
class ChannelDB(TypedObject):
|
||||
"""
|
||||
This is the basis of a comm channel, only implementing
|
||||
|
|
@ -364,6 +463,9 @@ class ChannelDB(TypedObject):
|
|||
db_subscriptions = models.ManyToManyField("players.PlayerDB",
|
||||
related_name="subscription_set", null=True, verbose_name='subscriptions', db_index=True)
|
||||
|
||||
db_object_subscriptions = models.ManyToManyField("objects.ObjectDB",
|
||||
related_name="object_subscription_set", null=True, verbose_name='subscriptions', db_index=True)
|
||||
|
||||
# Database manager
|
||||
objects = managers.ChannelDBManager()
|
||||
|
||||
|
|
@ -377,3 +479,7 @@ class ChannelDB(TypedObject):
|
|||
|
||||
def __str__(self):
|
||||
return "Channel '%s' (%s)" % (self.key, self.db.desc)
|
||||
|
||||
@lazy_property
|
||||
def subscriptions(self):
|
||||
return SubscriptionHandler(self)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue