mirror of
https://github.com/solero/houdini.git
synced 2024-11-10 05:08:19 +00:00
Cross-client buddy handlers
This commit is contained in:
parent
c84bf9114a
commit
9098ae50a1
@ -20,6 +20,8 @@ class Room(db.Model):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.penguins = []
|
||||
|
||||
self.igloo = False
|
||||
|
||||
self.tables = {}
|
||||
self.waddles = {}
|
||||
|
||||
|
@ -0,0 +1,193 @@
|
||||
from houdini import handlers
|
||||
from houdini.handlers import XTPacket
|
||||
from houdini.handlers.play.navigation import handle_join_room
|
||||
|
||||
from houdini.data.penguin import Penguin
|
||||
from houdini.data.buddy import BuddyList, BuddyRequest
|
||||
from houdini import ClientType
|
||||
|
||||
|
||||
async def update_player_presence(p):
|
||||
for buddy_id in p.data.buddies.keys():
|
||||
if buddy_id in p.server.penguins_by_id:
|
||||
buddy = p.server.penguins_by_id[buddy_id]
|
||||
await p.send_xt('bon', buddy.data.id, p.server.server_config['Id'], buddy.room.id)
|
||||
await buddy.send_xt('bon', p.data.id, p.server.server_config['Id'], p.room.id)
|
||||
|
||||
for character_id in p.data.character_buddies.keys():
|
||||
if character_id in p.server.penguins_by_character_id:
|
||||
character = p.server.penguins_by_character_id[character_id]
|
||||
await p.send_xt('caon', character_id, p.server.server_config['Id'], character.room.id)
|
||||
|
||||
if p.data.character is not None:
|
||||
for penguin in p.server.penguins_by_id.values():
|
||||
if p.data.character in penguin.data.character_buddies:
|
||||
await penguin.send_xt('caon', p.data.character, p.server.server_config['Id'], p.room.id)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('j', 'jr'), after=handle_join_room, client=ClientType.Vanilla)
|
||||
async def handle_send_room_presence(p):
|
||||
await update_player_presence(p)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'gb'), client=ClientType.Vanilla)
|
||||
@handlers.allow_once
|
||||
async def handle_get_buddies(p):
|
||||
buddies_query = BuddyList.load(parent=Penguin.on(Penguin.id == BuddyList.buddy_id)).where(
|
||||
BuddyList.penguin_id == p.data.id)
|
||||
request_query = BuddyRequest.load(parent=Penguin.on(Penguin.id == BuddyRequest.requester_id)).where(
|
||||
BuddyRequest.penguin_id == p.data.id)
|
||||
|
||||
buddies = []
|
||||
best_buddies = []
|
||||
characters = []
|
||||
best_characters = []
|
||||
|
||||
async with p.server.db.transaction():
|
||||
buddy_list = buddies_query.gino.iterate()
|
||||
buddy_requests = request_query.gino.iterate()
|
||||
|
||||
async for buddy in buddy_list:
|
||||
buddy_presence = int(buddy.buddy_id in p.server.penguins_by_id)
|
||||
buddies.append(f'{buddy.buddy_id}|{buddy.parent.nickname}|{buddy_presence}')
|
||||
|
||||
if buddy.best_buddy:
|
||||
best_buddies.append(str(buddy.buddy_id))
|
||||
|
||||
for character in p.data.character_buddies.values():
|
||||
character_presence = int(character.character_id in p.server.penguins_by_character_id)
|
||||
characters.append(f'{character.character_id}|{character_presence}')
|
||||
|
||||
if character.best_buddy:
|
||||
best_characters.append(str(character.character_id))
|
||||
|
||||
requests = [f'{request.requester_id}|{request.parent.nickname}' async for request in buddy_requests]
|
||||
|
||||
best_friend_count = len(best_buddies) + len(best_characters)
|
||||
notification_aware = int(best_friend_count >= 1)
|
||||
best_friends_enabled = int((len(buddies) + len(characters)) >= 6)
|
||||
await p.send_xt('gs', best_friend_count, notification_aware, int(p.data.active), best_friends_enabled)
|
||||
|
||||
await p.send_xt('gb', *buddies)
|
||||
await p.send_xt('pr', *requests)
|
||||
await p.send_xt('gc', *characters)
|
||||
|
||||
if best_friends_enabled:
|
||||
await p.send_xt('gbf', *best_buddies)
|
||||
await p.send_xt('gbc', *best_characters)
|
||||
|
||||
await update_player_presence(p)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'gb'), client=ClientType.Legacy)
|
||||
@handlers.allow_once
|
||||
async def handle_get_buddies_legacy(p):
|
||||
buddies_query = BuddyList.load(parent=Penguin.on(Penguin.id == BuddyList.buddy_id)).where(
|
||||
BuddyList.penguin_id == p.data.id)
|
||||
|
||||
buddies = []
|
||||
|
||||
async with p.server.db.transaction():
|
||||
buddy_list = buddies_query.gino.iterate()
|
||||
|
||||
async for buddy in buddy_list:
|
||||
buddy_presence = int(buddy.buddy_id in p.server.penguins_by_id)
|
||||
buddies.append(f'{buddy.buddy_id}|{buddy.parent.nickname}|{buddy_presence}')
|
||||
|
||||
await p.send_xt('gb', *buddies)
|
||||
await update_player_presence(p)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'bf'), client=ClientType.Legacy)
|
||||
async def handle_find_buddy(p, buddy_id: int):
|
||||
if buddy_id in p.data.buddies and buddy_id in p.server.penguins_by_id:
|
||||
buddy = p.server.penguins_by_id[buddy_id]
|
||||
await p.send_xt('bf', buddy.room.id)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'br'))
|
||||
@handlers.cooldown(.5)
|
||||
async def handle_buddy_request(p, buddy_id: int):
|
||||
if buddy_id not in p.data.buddies:
|
||||
if buddy_id in p.server.penguins_by_id:
|
||||
buddy = p.server.penguins_by_id[buddy_id]
|
||||
|
||||
if buddy.client_type == ClientType.Vanilla and p.data.id not in buddy.data.buddy_requests:
|
||||
await buddy.data.buddy_requests.set(p.data.id)
|
||||
elif p.data.id not in buddy.buddy_requests:
|
||||
buddy.buddy_requests.add(p.data.id)
|
||||
else:
|
||||
return
|
||||
|
||||
await buddy.send_xt('br', p.data.id, p.data.nickname)
|
||||
else:
|
||||
await BuddyRequest.create(penguin_id=buddy_id, requester_id=p.data.id)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'ba'))
|
||||
async def handle_buddy_accept(p, buddy_id: int):
|
||||
if buddy_id in p.data.buddy_requests:
|
||||
await p.data.buddy_requests.delete(buddy_id)
|
||||
elif buddy_id in p.buddy_requests:
|
||||
p.buddy_requests.remove(buddy_id)
|
||||
else:
|
||||
return
|
||||
|
||||
await p.data.buddies.set(buddy_id)
|
||||
|
||||
if buddy_id in p.server.penguins_by_id:
|
||||
buddy = p.server.penguins_by_id[buddy_id]
|
||||
await buddy.data.buddies.set(p.data.id)
|
||||
await buddy.send_xt('ba', p.data.id, p.data.nickname, 1)
|
||||
await p.send_xt('ba', buddy.data.id, buddy.data.nickname, 1)
|
||||
|
||||
if p.client_type == ClientType.Vanilla:
|
||||
await p.send_xt('bon', buddy.data.id, p.server.server_config['Id'], buddy.room.id)
|
||||
if buddy.client_type == ClientType.Vanilla:
|
||||
await buddy.send_xt('bon', p.data.id, p.server.server_config['Id'], p.room.id)
|
||||
else:
|
||||
await BuddyList.create(penguin_id=buddy_id, buddy_id=p.data.id)
|
||||
nickname = await Penguin.select('nickname').where(Penguin.id == buddy_id).gino.scalar()
|
||||
await p.send_xt('ba', buddy_id, nickname, 0)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'rb'))
|
||||
async def handle_buddy_remove(p, buddy_id: int):
|
||||
if buddy_id in p.data.buddies:
|
||||
await p.data.buddies.delete(buddy_id)
|
||||
await p.send_xt('rb', buddy_id)
|
||||
if buddy_id in p.server.penguins_by_id:
|
||||
buddy = p.server.penguins_by_id[buddy_id]
|
||||
await buddy.send_xt('rb', p.data.id)
|
||||
await buddy.data.buddies.delete(p.data.id)
|
||||
else:
|
||||
await BuddyList.delete.where((BuddyList.penguin_id == buddy_id) &
|
||||
(BuddyList.buddy_id == p.data.id)).gino.status()
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'cr'), client=ClientType.Vanilla)
|
||||
async def handle_character_request(p, character_id: int):
|
||||
if character_id in p.server.characters and character_id not in p.data.character_buddies:
|
||||
character = p.server.characters[character_id]
|
||||
await p.data.character_buddies.set(character_id)
|
||||
await p.send_xt('cr', character_id, 0)
|
||||
await p.send_xt('caon', character_id, p.server.server_config['Id'], p.room.id)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'rr'), client=ClientType.Vanilla)
|
||||
async def handle_buddy_reject(p, buddy_id: int):
|
||||
await p.data.buddy_requests.delete(buddy_id)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'tbf'), client=ClientType.Vanilla)
|
||||
async def handle_toggle_best_friend(p, buddy_id: int):
|
||||
if buddy_id in p.data.buddies:
|
||||
buddy_record = p.data.buddies[buddy_id]
|
||||
await buddy_record.update(best_buddy=not buddy_record.best_buddy).apply()
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('b', 'tbc'), client=ClientType.Vanilla)
|
||||
async def handle_toggle_best_character(p, character_id: int):
|
||||
if character_id in p.data.character_buddies:
|
||||
character_buddy_record = p.data.character_buddies[character_id]
|
||||
await character_buddy_record.update(best_buddy=not character_buddy_record.best_buddy).apply()
|
@ -3,6 +3,7 @@ from houdini.handlers import XTPacket
|
||||
from houdini.data.penguin import Penguin
|
||||
|
||||
from aiocache import cached
|
||||
import random
|
||||
|
||||
|
||||
def get_player_string_key(_, p, player_id):
|
||||
@ -83,6 +84,27 @@ async def handle_get_player_by_name(p, player_name: str):
|
||||
await p.send_xt('pbn')
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('u', 'smi'), client=ClientType.Vanilla)
|
||||
@handlers.cooldown(10)
|
||||
async def handle_send_mascot_invite(p, num_invites: int, character_id: int):
|
||||
if character_id in p.server.characters and p.data.character is not None:
|
||||
for _ in range(min(num_invites, len(p.server.penguins_by_id))):
|
||||
player = random.choice(list(p.server.penguins_by_id.values()))
|
||||
await player.send_xt('smi', character_id)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('u', 'bf'), client=ClientType.Vanilla)
|
||||
async def handle_find_player(p, player_id: int):
|
||||
if player_id in p.server.penguins_by_id:
|
||||
player = p.server.penguins_by_id[player_id]
|
||||
room_id = player.room.id
|
||||
room_type = 'igloo' if player.room.igloo else 'invalid'
|
||||
room_owner = player.room.penguin_id if player.room.igloo else -1
|
||||
else:
|
||||
room_id, room_type, room_owner = -1, 'invalid', -1
|
||||
await p.send_xt('bf', room_id, room_type, room_owner)
|
||||
|
||||
|
||||
@handlers.handler(XTPacket('u', 'pbsms'), client=ClientType.Vanilla)
|
||||
async def handle_pbsm_start(p):
|
||||
await p.send_xt('pbsms')
|
||||
|
@ -6,8 +6,9 @@ from houdini.spheniscidae import Spheniscidae
|
||||
class Penguin(Spheniscidae):
|
||||
|
||||
__slots__ = ['x', 'y', 'frame', 'toy', 'room', 'waddle', 'table',
|
||||
'login_key', 'member', 'membership_days', 'avatar',
|
||||
'walking_puffle', 'permissions', 'active_quests']
|
||||
'data', 'muted', 'login_key', 'member', 'membership_days',
|
||||
'avatar', 'walking_puffle', 'permissions', 'active_quests',
|
||||
'buddy_requests']
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
@ -32,6 +33,8 @@ class Penguin(Spheniscidae):
|
||||
|
||||
self.active_quests = None
|
||||
|
||||
self.buddy_requests = set()
|
||||
|
||||
@property
|
||||
def party_state(self):
|
||||
return str()
|
||||
@ -301,6 +304,17 @@ class Penguin(Spheniscidae):
|
||||
del self.server.penguins_by_id[self.data.id]
|
||||
del self.server.penguins_by_username[self.data.username]
|
||||
|
||||
if self.data.character is not None:
|
||||
del self.server.penguins_by_character_id[self.data.character]
|
||||
|
||||
for penguin in self.server.penguins_by_id.values():
|
||||
if self.data.character in penguin.data.character_buddies:
|
||||
await penguin.send_xt('caof', self.data.character)
|
||||
|
||||
for buddy_id in self.data.buddies:
|
||||
if buddy_id in self.server.penguins_by_id:
|
||||
await self.server.penguins_by_id[buddy_id].send_xt('bof', self.data.id)
|
||||
|
||||
await self.server.redis.hincrby('population', self.server.server_config['Id'], -1)
|
||||
|
||||
await super()._client_disconnected()
|
||||
|
Loading…
Reference in New Issue
Block a user