Make houdini.penguin.Penguin inherit houdini.data.penguin.Penguin

This allows for much clearer syntax
This commit is contained in:
Ben 2019-12-02 23:04:59 +00:00
parent 15e8035d26
commit 3e7943c6db
21 changed files with 438 additions and 481 deletions

View File

@ -65,27 +65,21 @@ class PenguinStringCompiler(OrderedDict):
return getattr(p, attribute_name) or 0
return attribute_method
@classmethod
def data_attribute_by_name(cls, attribute_name):
async def attribute_method(p):
return getattr(p.data, attribute_name) or 0
return attribute_method
@classmethod
def setup_default_builder(cls, string_builder):
string_builder.update({
'ID': PenguinStringCompiler.data_attribute_by_name('id'),
'Nickname': PenguinStringCompiler.data_attribute_by_name('nickname'),
'Approval': PenguinStringCompiler.data_attribute_by_name('approval'),
'Color': PenguinStringCompiler.data_attribute_by_name('color'),
'Head': PenguinStringCompiler.data_attribute_by_name('head'),
'Face': PenguinStringCompiler.data_attribute_by_name('face'),
'Neck': PenguinStringCompiler.data_attribute_by_name('neck'),
'Body': PenguinStringCompiler.data_attribute_by_name('body'),
'Hand': PenguinStringCompiler.data_attribute_by_name('hand'),
'Feet': PenguinStringCompiler.data_attribute_by_name('feet'),
'Flag': PenguinStringCompiler.data_attribute_by_name('flag'),
'Photo': PenguinStringCompiler.data_attribute_by_name('photo'),
'ID': PenguinStringCompiler.attribute_by_name('id'),
'Nickname': PenguinStringCompiler.attribute_by_name('nickname'),
'Approval': PenguinStringCompiler.attribute_by_name('approval'),
'Color': PenguinStringCompiler.attribute_by_name('color'),
'Head': PenguinStringCompiler.attribute_by_name('head'),
'Face': PenguinStringCompiler.attribute_by_name('face'),
'Neck': PenguinStringCompiler.attribute_by_name('neck'),
'Body': PenguinStringCompiler.attribute_by_name('body'),
'Hand': PenguinStringCompiler.attribute_by_name('hand'),
'Feet': PenguinStringCompiler.attribute_by_name('feet'),
'Flag': PenguinStringCompiler.attribute_by_name('flag'),
'Photo': PenguinStringCompiler.attribute_by_name('photo'),
'X': PenguinStringCompiler.attribute_by_name('x'),
'Y': PenguinStringCompiler.attribute_by_name('y'),
'Frame': PenguinStringCompiler.attribute_by_name('frame'),

View File

@ -2,16 +2,7 @@ from datetime import datetime, date
from houdini.data import db
from houdini.data.permission import PenguinPermissionCollection
from houdini.data.item import PenguinItemCollection
from houdini.data.igloo import PenguinIglooCollection, PenguinFurnitureCollection, \
PenguinFlooringCollection, PenguinLocationCollection
from houdini.data.stamp import PenguinStampCollection
from houdini.data.ninja import PenguinCardCollection
from houdini.data.pet import PenguinPuffleCollection, PenguinPuffleItemCollection
from houdini.data.buddy import BuddyListCollection, BuddyRequestCollection, \
CharacterBuddyCollection, IgnoreListCollection
from houdini.data.room import PenguinIglooRoomCollection
from functools import lru_cache
class Penguin(db.Model):
@ -107,23 +98,7 @@ class Penguin(db.Model):
super().__init__(*args, **kwargs)
async def load_inventories(self):
self.inventory = await PenguinItemCollection.get_collection(self.id)
self.permissions = await PenguinPermissionCollection.get_collection(self.id)
self.igloos = await PenguinIglooCollection.get_collection(self.id)
self.igloo_rooms = await PenguinIglooRoomCollection.get_collection(self.id)
self.furniture = await PenguinFurnitureCollection.get_collection(self.id)
self.flooring = await PenguinFlooringCollection.get_collection(self.id)
self.locations = await PenguinLocationCollection.get_collection(self.id)
self.stamps = await PenguinStampCollection.get_collection(self.id)
self.cards = await PenguinCardCollection.get_collection(self.id)
self.puffles = await PenguinPuffleCollection.get_collection(self.id)
self.puffle_items = await PenguinPuffleItemCollection.get_collection(self.id)
self.buddies = await BuddyListCollection.get_collection(self.id)
self.buddy_requests = await BuddyRequestCollection.get_collection(self.id)
self.character_buddies = await CharacterBuddyCollection.get_collection(self.id)
self.ignore = await IgnoreListCollection.get_collection(self.id)
@lru_cache()
def safe_nickname(self, language_bitmask):
return self.nickname if self.approval & language_bitmask else "P" + str(self.id)

View File

@ -17,23 +17,23 @@ class RoomMixin:
async def add_penguin(self, p):
if p.room:
await p.room.remove_penguin(p)
self.penguins_by_id[p.data.id] = p
self.penguins_by_username[p.data.username] = p
self.penguins_by_id[p.id] = p
self.penguins_by_username[p.username] = p
if p.data.character:
self.penguins_by_character_id[p.data.character] = p
if p.character:
self.penguins_by_character_id[p.character] = p
p.room = self
async def remove_penguin(self, p):
if not (p.is_vanilla_client and p.data.stealth_moderator):
await self.send_xt('rp', p.data.id)
if not (p.is_vanilla_client and p.stealth_moderator):
await self.send_xt('rp', p.id, f=lambda penguin: penguin.id != p.id)
del self.penguins_by_id[p.data.id]
del self.penguins_by_username[p.data.username]
del self.penguins_by_id[p.id]
del self.penguins_by_username[p.username]
if p.data.character:
del self.penguins_by_character_id[p.data.character]
if p.character:
del self.penguins_by_character_id[p.character]
p.room = None
p.frame = 1

View File

@ -232,15 +232,6 @@ def player_attribute(**attrs):
return check(check_for_attributes)
def player_data_attribute(**attrs):
def check_for_attributes(_, p):
for attr, value in attrs.items():
if not getattr(p.data, attr) == value:
return False
return True
return check(check_for_attributes)
def player_in_room(*room_ids):
def check_room_id(_, p):
return p.room.id in room_ids

View File

@ -35,8 +35,7 @@ async def world_login(p, data):
await p.server.penguins_by_id[data.id].close()
p.logger.info(f'{data.username} logged in successfully')
p.data = data
p.update(**data.to_dict())
await p.send_xt('l')

View File

@ -8,21 +8,21 @@ from houdini.constants import ClientType
async def update_player_presence(p):
for buddy_id in p.data.buddies.keys():
for buddy_id in p.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)
await p.send_xt('bon', buddy.id, p.server.config.id, buddy.room.id)
await buddy.send_xt('bon', p.id, p.server.config.id, p.room.id)
for character_id in p.data.character_buddies.keys():
for character_id in p.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)
await p.send_xt('caon', character_id, p.server.config.id, character.room.id)
if p.data.character is not None:
if p.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)
if p.character in penguin.character_buddies:
await penguin.send_xt('caon', p.character, p.server.config.id, p.room.id)
@handlers.handler(XTPacket('j', 'jr'), after=handle_join_room, client=ClientType.Vanilla)
@ -34,9 +34,9 @@ async def handle_send_room_presence(p):
@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)
BuddyList.penguin_id == p.id)
request_query = BuddyRequest.load(parent=Penguin.on(Penguin.id == BuddyRequest.requester_id)).where(
BuddyRequest.penguin_id == p.data.id)
BuddyRequest.penguin_id == p.id)
buddies = []
best_buddies = []
@ -54,7 +54,7 @@ async def handle_get_buddies(p):
if buddy.best_buddy:
best_buddies.append(str(buddy.buddy_id))
for character in p.data.character_buddies.values():
for character in p.character_buddies.values():
character_presence = int(character.character_id in p.server.penguins_by_character_id)
characters.append(f'{character.character_id}|{character_presence}')
@ -66,7 +66,7 @@ async def handle_get_buddies(p):
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('gs', best_friend_count, notification_aware, int(p.active), best_friends_enabled)
await p.send_xt('gb', *buddies)
await p.send_xt('pr', *requests)
@ -83,7 +83,7 @@ async def handle_get_buddies(p):
@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)
BuddyList.penguin_id == p.id)
buddies = []
@ -100,7 +100,7 @@ async def handle_get_buddies_legacy(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:
if buddy_id in p.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.external_id if buddy.room.igloo else buddy.room.id)
@ -108,101 +108,100 @@ async def handle_find_buddy(p, buddy_id: int):
@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 not in p.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.insert(buddy_id=p.data.id)
elif p.data.id not in buddy.buddy_requests:
buddy.buddy_requests.add(p.data.id)
if buddy.client_type == ClientType.Vanilla and p.id not in buddy.buddy_requests:
await buddy.buddy_requests.insert(buddy_id=p.id)
elif p.id not in buddy.buddy_requests:
buddy.buddy_requests.add(p.id)
else:
return
await buddy.send_xt('br', p.data.id, p.data.nickname)
await buddy.send_xt('br', p.id, p.safe_name)
else:
await BuddyRequest.create(penguin_id=buddy_id, requester_id=p.data.id)
await BuddyRequest.create(penguin_id=buddy_id, requester_id=p.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)
if buddy_id in p.buddy_requests:
await p.buddy_requests.delete(buddy_id)
elif buddy_id in p.buddy_requests:
p.buddy_requests.remove(buddy_id)
else:
return
await p.data.buddies.insert(buddy_id=buddy_id)
await p.buddies.insert(buddy_id=buddy_id)
if buddy_id in p.server.penguins_by_id:
buddy = p.server.penguins_by_id[buddy_id]
await buddy.data.buddies.insert(buddy_id=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)
await buddy.buddies.insert(buddy_id=p.id)
await buddy.send_xt('ba', p.id, p.safe_name, 1)
await p.send_xt('ba', buddy.id, buddy.safe_name, 1)
if p.client_type == ClientType.Vanilla:
await p.send_xt('bon', buddy.data.id, p.server.server_config['Id'], buddy.room.id)
await p.send_xt('bon', buddy.id, p.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)
await buddy.send_xt('bon', p.id, p.server.config.id, p.room.id)
else:
await BuddyList.create(penguin_id=buddy_id, buddy_id=p.data.id)
await BuddyList.create(penguin_id=buddy_id, buddy_id=p.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)
if buddy_id in p.buddies:
await p.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)
await buddy.send_xt('rb', p.id)
await buddy.buddies.delete(p.id)
else:
await BuddyList.delete.where((BuddyList.penguin_id == buddy_id) &
(BuddyList.buddy_id == p.data.id)).gino.status()
(BuddyList.buddy_id == p.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.insert(character_id=character_id)
if character_id in p.server.characters and character_id not in p.character_buddies:
await p.character_buddies.insert(character_id=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)
await p.send_xt('caon', character_id, p.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)
await p.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]
if buddy_id in p.buddies:
buddy_record = p.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]
if character_id in p.character_buddies:
character_buddy_record = p.character_buddies[character_id]
await character_buddy_record.update(best_buddy=not character_buddy_record.best_buddy).apply()
@handlers.disconnected
@handlers.player_attribute(joined_world=True)
async def handle_disconnect_buddy(p):
if p.data.character is not None:
del p.server.penguins_by_character_id[p.data.character]
if p.character is not None:
del p.server.penguins_by_character_id[p.character]
for penguin in p.server.penguins_by_id.values():
if p.data.character in penguin.data.character_buddies:
await penguin.send_xt('caof', p.data.character)
if p.character in penguin.character_buddies:
await penguin.send_xt('caof', p.character)
for buddy_id in p.data.buddies:
for buddy_id in p.buddies:
if buddy_id in p.server.penguins_by_id:
await p.server.penguins_by_id[buddy_id].send_xt('bof', p.data.id)
await p.server.penguins_by_id[buddy_id].send_xt('bof', p.id)

View File

@ -12,40 +12,40 @@ import random
@handlers.handler(XTPacket('l', 'mst'), before=handle_start_mail_engine)
async def handle_send_job_mail(p):
postcards = []
if not p.data.agent_status and random.random() < 0.4:
if not p.agent_status and random.random() < 0.4:
epf_invited = await PenguinPostcard.query.where(
(PenguinPostcard.penguin_id == p.data.id) & ((PenguinPostcard.postcard_id == 112)
| (PenguinPostcard.postcard_id == 47))).gino.scalar()
(PenguinPostcard.penguin_id == p.id) & ((PenguinPostcard.postcard_id == 112)
| (PenguinPostcard.postcard_id == 47))).gino.scalar()
if not epf_invited:
postcards.append({
'penguin_id': p.data.id,
'penguin_id': p.id,
'postcard_id': 112
})
last_paycheck = p.data.last_paycheck.date()
last_paycheck = p.last_paycheck.date()
today = datetime.date.today()
first_day_of_month = today.replace(day=1)
last_paycheck = last_paycheck.replace(day=1)
player_data = p.data
player_data = p.update()
while last_paycheck < first_day_of_month:
last_paycheck = last_paycheck + datetime.timedelta(days=32)
last_paycheck = last_paycheck.replace(day=1)
send_date = last_paycheck + datetime.timedelta(days=1)
if 428 in p.data.inventory:
if 428 in p.inventory:
postcards.append({
'penguin_id': p.data.id,
'penguin_id': p.id,
'postcard_id': 172,
'send_date': send_date
})
player_data.update(coins=p.data.coins + 250)
if p.data.agent_status:
player_data.update(coins=p.coins + 250)
if p.agent_status:
postcards.append({
'penguin_id': p.data.id,
'penguin_id': p.id,
'postcard_id': 184,
'send_date': send_date
})
player_data.update(coins=p.data.coins + 350)
player_data.update(coins=p.coins + 350)
await player_data.update(last_paycheck=last_paycheck).apply()
if postcards:
@ -54,51 +54,51 @@ async def handle_send_job_mail(p):
@handlers.handler(XTPacket('f', 'epfga'))
async def handle_get_agent_status(p):
await p.send_xt('epfga', int(p.data.agent_status))
await p.send_xt('epfga', int(p.agent_status))
@handlers.handler(XTPacket('f', 'epfsa'))
@handlers.player_data_attribute(agent_status=False)
@handlers.player_attribute(agent_status=False)
async def handle_set_agent_status(p):
await p.data.update(agent_status=True).apply()
await p.send_xt('epfsa', int(p.data.agent_status))
await p.update(agent_status=True).apply()
await p.send_xt('epfsa', int(p.agent_status))
@handlers.handler(XTPacket('f', 'epfgf'))
async def handle_get_field_op_status(p):
today = datetime.date.today()
monday = today - datetime.timedelta(days=today.weekday())
if p.data.last_field_op.date() < monday:
await p.data.update(field_op_status=0).apply()
await p.send_xt('epfgf', p.data.field_op_status)
if p.last_field_op.date() < monday:
await p.update(field_op_status=0).apply()
await p.send_xt('epfgf', p.field_op_status)
@handlers.handler(XTPacket('f', 'epfsf'))
@handlers.player_data_attribute(agent_status=True)
@handlers.player_attribute(agent_status=True)
async def handle_set_field_op_status(p, field_op_status: int):
if 2 >= field_op_status == p.data.field_op_status + 1:
player_data = p.data.update(field_op_status=p.data.field_op_status + 1)
if p.data.field_op_status == 2:
player_data.update(career_medals=p.data.career_medals + 2)
player_data.update(agent_medals=p.data.agent_medals + 2)
if 2 >= field_op_status == p.field_op_status + 1:
player_data = p.update(field_op_status=p.field_op_status + 1)
if p.field_op_status == 2:
player_data.update(career_medals=p.career_medals + 2)
player_data.update(agent_medals=p.agent_medals + 2)
await p.send_xt('epfsf', p.data.field_op_status)
await p.send_xt('epfsf', p.field_op_status)
await player_data.update(last_field_op=datetime.datetime.now()).apply()
@handlers.handler(XTPacket('f', 'epfgr'))
async def handle_get_epf_points(p):
await p.send_xt('epfgr', p.data.career_medals, p.data.agent_medals)
await p.send_xt('epfgr', p.career_medals, p.agent_medals)
@handlers.handler(XTPacket('f', 'epfai'))
@handlers.player_data_attribute(agent_status=True)
@handlers.player_attribute(agent_status=True)
async def handle_buy_epf_item(p, item: Item):
if item.epf:
if item.id in p.data.inventory:
if item.id in p.inventory:
return await p.send_error(400)
if p.data.agent_medals < item.cost:
if p.agent_medals < item.cost:
return await p.send_error(401)
await p.add_epf_inventory(item)

View File

@ -11,7 +11,7 @@ from aiocache import cached
def get_status_key(_, p):
return f'quest.status.{p.data.id}'
return f'quest.status.{p.id}'
def get_settings_key(_, p):
@ -24,18 +24,18 @@ async def get_player_quest_status(p):
items=QuestAwardItem,
furniture=QuestAwardFurniture,
pet=QuestAwardPuffleItem,
complete=PenguinQuestTask.on((PenguinQuestTask.penguin_id == p.data.id) &
complete=PenguinQuestTask.on((PenguinQuestTask.penguin_id == p.id) &
(QuestTask.id == PenguinQuestTask.task_id))).gino
def has_award(quest):
for award in quest.items:
if award.item_id not in p.data.inventory:
if award.item_id not in p.inventory:
return False
for award in quest.furniture:
if award.furniture_id not in p.data.furniture:
if award.furniture_id not in p.furniture:
return False
for award in quest.pet:
if award.puffle_item_id not in p.data.puffle_items:
if award.puffle_item_id not in p.puffle_items:
return False
return True
@ -103,14 +103,14 @@ async def get_quest_settings(p):
async def init_all_quests(p):
query = Quest.load(tasks=QuestTask,
complete=PenguinQuestTask.on((PenguinQuestTask.penguin_id == p.data.id) &
complete=PenguinQuestTask.on((PenguinQuestTask.penguin_id == p.id) &
(QuestTask.id == PenguinQuestTask.task_id))).gino
async with db.transaction():
async for quest in query.iterate():
for task in quest.tasks:
if task.id not in quest.in_progress.union(quest.complete):
await PenguinQuestTask.create(task_id=task.id, penguin_id=p.data.id)
await PenguinQuestTask.create(task_id=task.id, penguin_id=p.id)
await load_active_quests(p)
@ -120,7 +120,7 @@ async def load_active_quests(p):
items=QuestAwardItem,
furniture=QuestAwardFurniture,
pet=QuestAwardPuffleItem,
complete=PenguinQuestTask.on((PenguinQuestTask.penguin_id == p.data.id) &
complete=PenguinQuestTask.on((PenguinQuestTask.penguin_id == p.id) &
(PenguinQuestTask.task_id == QuestTask.id) &
(PenguinQuestTask.complete == False))).gino.all()
@ -128,7 +128,7 @@ async def load_active_quests(p):
@handlers.handler(XTPacket('j', 'js'), after=handle_join_server)
@handlers.allow_once
async def handle_quest_join_server(p):
await p.server.cache.delete(f'quest.status.{p.data.id}')
await p.server.cache.delete(f'quest.status.{p.id}')
await load_active_quests(p)
await p.send_xt('nxquestsettings', await get_quest_settings(p))
@ -136,11 +136,11 @@ async def handle_quest_join_server(p):
async def set_task_cleared(p, task_id):
await p.server.cache.delete(f'quest.status.{p.data.id}')
await p.server.cache.delete(f'quest.status.{p.id}')
await PenguinQuestTask.update.values(complete=True) \
.where((PenguinQuestTask.task_id == task_id) &
(PenguinQuestTask.penguin_id == p.data.id)).gino.status()
(PenguinQuestTask.penguin_id == p.id)).gino.status()
return await p.send_xt('nxquestdata', await get_player_quest_status(p))
@ -159,7 +159,7 @@ async def handle_quest_join_room(p):
if p.active_quests is not None:
for quest in p.active_quests:
for task in quest.tasks:
igloo_quest_completed = task.id == 3 and p.room.igloo and p.room.penguin_id == p.data.id
igloo_quest_completed = task.id == 3 and p.room.igloo and p.room.penguin_id == p.id
if task.id in quest.in_progress and igloo_quest_completed:
await set_task_cleared(p, task.id)
p.active_quests.remove(quest)
@ -167,7 +167,7 @@ async def handle_quest_join_room(p):
@handlers.handler(XTPacket('nx', 'nxquestaward'))
async def handle_quest_award(p, quest_id: int):
await p.server.cache.delete(f'quest.status.{p.data.id}')
await p.server.cache.delete(f'quest.status.{p.id}')
quest = await Quest.load(items=QuestAwardItem,
furniture=QuestAwardFurniture,
@ -184,7 +184,7 @@ async def handle_quest_award(p, quest_id: int):
@handlers.handler(XTPacket('nx', 'nxquestactivate'))
@handlers.allow_once
async def handle_quest_activate(p):
await p.server.cache.delete(f'quest.status.{p.data.id}')
await p.server.cache.delete(f'quest.status.{p.id}')
await init_all_quests(p)
await p.send_xt('nxquestdata', await get_player_quest_status(p))
@ -193,39 +193,39 @@ async def handle_quest_activate(p):
@handlers.handler(XTPacket('nx', 'gas'))
@handlers.allow_once
async def handle_get_action_status(p):
await p.send_xt('gas', int(p.data.special_dance), int(p.data.special_wave),
int(p.data.special_snowball))
await p.send_xt('gas', int(p.special_dance), int(p.special_wave),
int(p.special_snowball))
@handlers.handler(XTPacket('nx', 'mcs'))
async def handle_map_category_setting(p, map_category: int):
if 0 <= map_category <= 4:
await p.data.update(map_category=map_category).apply()
await p.update(map_category=map_category).apply()
@handlers.handler(XTPacket('nx', 'pcos'))
@handlers.allow_once
@handlers.player_data_attribute(opened_playercard=False)
@handlers.player_attribute(opened_playercard=False)
async def handle_playercard_opened_setting(p):
await p.data.update(opened_playercard=True).apply()
await p.update(opened_playercard=True).apply()
@handlers.handler(XTPacket('nx', 'swave'))
@handlers.allow_once
@handlers.player_data_attribute(special_wave=False)
@handlers.player_attribute(special_wave=False)
async def handle_special_wave(p):
await p.data.update(special_wave=True).apply()
await p.update(special_wave=True).apply()
@handlers.handler(XTPacket('nx', 'sdance'))
@handlers.allow_once
@handlers.player_data_attribute(special_dance=False)
@handlers.player_attribute(special_dance=False)
async def handle_special_dance(p):
await p.data.update(special_dance=True).apply()
await p.update(special_dance=True).apply()
@handlers.handler(XTPacket('nx', 'ssnowball'))
@handlers.allow_once
@handlers.player_data_attribute(special_snowball=False)
@handlers.player_attribute(special_snowball=False)
async def handle_special_snowball(p):
await p.data.update(special_snowball=True).apply()
await p.update(special_snowball=True).apply()

View File

@ -32,7 +32,7 @@ def get_legacy_igloo_string_key(_, p, penguin_id):
def get_igloo_layouts_key(_, p):
return f'igloo_layouts.{p.data.id}'
return f'igloo_layouts.{p.id}'
def get_layout_like_count_key(_, igloo_id):
@ -73,7 +73,7 @@ async def get_legacy_igloo_string(p, penguin_id):
async def get_all_igloo_layouts(p):
layout_details = []
slot = 0
for igloo in p.data.igloo_rooms.values():
for igloo in p.igloo_rooms.values():
slot += 1
furniture_string = await get_layout_furniture(p, igloo.id)
like_count = await get_layout_like_count(igloo.id)
@ -95,8 +95,8 @@ async def create_first_igloo(p, penguin_id):
if igloo is None:
if penguin_id in p.server.penguins_by_id:
penguin = p.server.penguins_by_id[penguin_id]
igloo = await penguin.data.igloo_rooms.insert(penguin_id=penguin_id, type=1, flooring=0, location=1)
await penguin.data.update(igloo=igloo.id).apply()
igloo = await penguin.igloo_rooms.insert(penguin_id=penguin_id, type=1, flooring=0, location=1)
await penguin.update(igloo=igloo.id).apply()
else:
igloo = await PenguinIglooRoom.create(penguin_id=penguin_id, type=1, flooring=0, location=1)
await Penguin.update.values(igloo=igloo.id)\
@ -104,7 +104,7 @@ async def create_first_igloo(p, penguin_id):
async def save_igloo_furniture(p, furniture_list=None):
await IglooFurniture.delete.where(IglooFurniture.igloo_id == p.data.igloo).gino.status()
await IglooFurniture.delete.where(IglooFurniture.igloo_id == p.igloo).gino.status()
if furniture_list:
furniture_tracker = {}
@ -112,7 +112,7 @@ async def save_igloo_furniture(p, furniture_list=None):
for furniture_string in itertools.islice(furniture_list, 0, 100):
furniture_id, x, y, rotation, frame = map(int, furniture_string.split('|'))
if furniture_id not in p.data.furniture:
if furniture_id not in p.furniture:
return
if furniture_id not in furniture_tracker:
@ -120,14 +120,14 @@ async def save_igloo_furniture(p, furniture_list=None):
else:
furniture_tracker[furniture_id] += 1
if furniture_tracker[furniture_id] > p.data.furniture[furniture_id].quantity:
if furniture_tracker[furniture_id] > p.furniture[furniture_id].quantity:
return
if not (0 <= x <= 700 and 0 <= y <= 700 and 1 <= rotation <= 8 and 1 <= frame <= 10):
return
furniture.append({
'igloo_id': p.data.igloo,
'igloo_id': p.igloo,
'furniture_id': furniture_id,
'x': x, 'y': y,
'frame': frame,
@ -156,24 +156,24 @@ async def handle_buy_flooring(p, flooring: Flooring):
return await p.send_error(402)
if p.is_vanilla_client:
if flooring.id in p.data.flooring:
if flooring.id in p.flooring:
return await p.send_error(400)
if p.data.coins < flooring.cost:
if p.coins < flooring.cost:
return await p.send_error(401)
await p.add_flooring(flooring)
else:
igloo = p.data.igloo_rooms[p.data.igloo]
igloo = p.igloo_rooms[p.igloo]
await igloo.update(flooring=flooring.id).apply()
await p.data.update(coins=p.data.coins - flooring.cost).apply()
await p.update(coins=p.coins - flooring.cost).apply()
await p.send_xt('ag', flooring.id, p.data.coins)
await p.send_xt('ag', flooring.id, p.coins)
await p.server.cache.delete(f'active_igloo.{p.data.id}')
await p.server.cache.delete(f'legacy_igloo.{p.data.id}')
await p.server.cache.delete(f'igloo_layouts.{p.data.id}')
await p.server.cache.delete(f'active_igloo.{p.id}')
await p.server.cache.delete(f'legacy_igloo.{p.id}')
await p.server.cache.delete(f'igloo_layouts.{p.id}')
@handlers.handler(XTPacket('g', 'aloc'), client=ClientType.Vanilla)
@ -181,10 +181,10 @@ async def handle_buy_igloo_location(p, location: Location):
if location is None:
return await p.send_error(402)
if location.id in p.data.locations:
if location.id in p.locations:
return await p.send_error(400)
if p.data.coins < location.cost:
if p.coins < location.cost:
return await p.send_error(401)
await p.add_location(location)
@ -195,10 +195,10 @@ async def handle_buy_igloo_type(p, igloo: Igloo):
if igloo is None:
return await p.send_error(402)
if igloo.id in p.data.igloos:
if igloo.id in p.igloos:
return await p.send_error(400)
if p.data.coins < igloo.cost:
if p.coins < igloo.cost:
return await p.send_error(401)
await p.add_igloo(igloo)
@ -209,10 +209,10 @@ async def handle_buy_furniture(p, furniture: Furniture):
if furniture is None:
return await p.send_error(402)
if furniture.id in p.data.igloos:
if furniture.id in p.igloos:
return await p.send_error(400)
if p.data.coins < furniture.cost:
if p.coins < furniture.cost:
return await p.send_error(401)
await p.add_furniture(furniture)
@ -222,18 +222,18 @@ async def handle_buy_furniture(p, furniture: Furniture):
@handlers.cooldown(1)
async def handle_update_igloo_configuration(p, igloo_id: int, igloo_type_id: int, flooring_id: int, location_id: int,
music_id: int, furniture_data):
if p.room.igloo and p.room.penguin_id == p.data.id and igloo_id in p.data.igloo_rooms:
igloo = p.data.igloo_rooms[igloo_id]
if p.room.igloo and p.room.penguin_id == p.id and igloo_id in p.igloo_rooms:
igloo = p.igloo_rooms[igloo_id]
await p.data.update(igloo=igloo_id).apply()
p.server.igloos_by_penguin_id[p.data.id] = igloo
await p.update(igloo=igloo_id).apply()
p.server.igloos_by_penguin_id[p.id] = igloo
furniture_list = furniture_data.split(',') if furniture_data else None
await save_igloo_furniture(p, furniture_list)
if not igloo_type_id or igloo_type_id in p.data.igloos\
and not flooring_id or flooring_id in p.data.flooring\
and not location_id or location_id in p.data.locations:
if not igloo_type_id or igloo_type_id in p.igloos\
and not flooring_id or flooring_id in p.flooring\
and not location_id or location_id in p.locations:
await igloo.update(
type=igloo_type_id,
flooring=flooring_id,
@ -244,12 +244,12 @@ async def handle_update_igloo_configuration(p, igloo_id: int, igloo_type_id: int
like_count = await get_layout_like_count(igloo.id)
active_igloo_string = f'{igloo.id}:1:0:{int(igloo.locked)}:{igloo.music}:{igloo.flooring}:' \
f'{igloo.location}:{igloo.type}:{like_count}:{furniture_data}'
await p.room.send_xt('uvi', p.data.id, active_igloo_string)
await p.room.send_xt('uvi', p.id, active_igloo_string)
await p.server.cache.set(f'layout_furniture.{igloo.id}', furniture_data)
await p.server.cache.set(f'active_igloo.{p.data.id}', active_igloo_string)
await p.server.cache.delete(f'legacy_igloo.{p.data.id}')
await p.server.cache.delete(f'igloo_layouts.{p.data.id}')
await p.server.cache.set(f'active_igloo.{p.id}', active_igloo_string)
await p.server.cache.delete(f'legacy_igloo.{p.id}')
await p.server.cache.delete(f'igloo_layouts.{p.id}')
@handlers.handler(XTPacket('g', 'ur'), client=ClientType.Legacy)
@ -257,8 +257,8 @@ async def handle_update_igloo_configuration(p, igloo_id: int, igloo_type_id: int
async def handle_save_igloo_furniture(p, *furniture_data):
await save_igloo_furniture(p, furniture_data)
await p.server.cache.set(f'layout_furniture.{p.data.igloo}', ','.join(furniture_data))
await p.server.cache.delete(f'legacy_igloo.{p.data.id}')
await p.server.cache.set(f'layout_furniture.{p.igloo}', ','.join(furniture_data))
await p.server.cache.delete(f'legacy_igloo.{p.id}')
_slot_converter = SeparatorConverter(separator=',', mapper=str)
@ -267,47 +267,47 @@ _slot_converter = SeparatorConverter(separator=',', mapper=str)
@handlers.handler(XTPacket('g', 'uiss'), client=ClientType.Vanilla)
@handlers.cooldown(1)
async def handle_update_igloo_slot_summary(p, igloo_id: int, slot_summary: _slot_converter):
if p.room.igloo and p.room.penguin_id == p.data.id and igloo_id in p.data.igloo_rooms:
igloo = p.data.igloo_rooms[igloo_id]
if p.room.igloo and p.room.penguin_id == p.id and igloo_id in p.igloo_rooms:
igloo = p.igloo_rooms[igloo_id]
await p.data.update(igloo=igloo_id).apply()
p.server.igloos_by_penguin_id[p.data.id] = igloo
if p.id in p.server.open_igloos_by_penguin_id:
del p.server.open_igloos_by_penguin_id[p.id]
if p.data.id in p.server.open_igloos_by_penguin_id:
del p.server.open_igloos_by_penguin_id[p.data.id]
if igloo_id != p.room.id:
await p.update(igloo=igloo_id).apply()
for slot in slot_summary:
igloo_id, locked = map(int, slot.split('|'))
igloo = p.data.igloo_rooms[igloo_id]
igloo = p.igloo_rooms[igloo_id]
if igloo_id == p.data.igloo:
if igloo_id == p.igloo:
if not locked:
p.server.open_igloos_by_penguin_id[p.data.id] = igloo
if igloo.locked != bool(locked):
await igloo.update(locked=bool(locked)).apply()
await p.server.cache.delete(f'active_igloo.{p.data.id}')
await p.server.cache.delete(f'legacy_igloo.{p.data.id}')
await p.server.cache.delete(f'igloo_layouts.{p.data.id}')
await p.server.cache.delete(f'active_igloo.{p.id}')
await p.server.cache.delete(f'legacy_igloo.{p.id}')
await p.server.cache.delete(f'igloo_layouts.{p.id}')
active_igloo_string = await get_active_igloo_string(p, p.data.id)
await p.room.send_xt('uvi', p.data.id, active_igloo_string)
active_igloo_string = await get_active_igloo_string(p, p.id)
await p.room.send_xt('uvi', p.id, active_igloo_string)
@handlers.handler(XTPacket('j', 'js'), after=handle_join_server, client=ClientType.Vanilla)
async def handle_add_igloo_map(p):
if p.data.igloo is not None:
igloo = p.data.igloo_rooms[p.data.igloo]
if p.igloo is not None:
igloo = p.igloo_rooms[p.igloo]
if not igloo.locked:
p.server.open_igloos_by_penguin_id[p.data.id] = igloo
p.server.open_igloos_by_penguin_id[p.id] = igloo
@handlers.disconnected
async def handle_remove_igloo_map(p):
if p.data.id in p.server.open_igloos_by_penguin_id:
del p.server.open_igloos_by_penguin_id[p.data.id]
if p.id in p.server.open_igloos_by_penguin_id:
del p.server.open_igloos_by_penguin_id[p.id]
@handlers.handler(XTPacket('g', 'pio'), client=ClientType.Vanilla)
@ -317,12 +317,12 @@ async def handle_is_player_igloo_open(p, penguin_id: int):
@handlers.handler(XTPacket('g', 'al'), client=ClientType.Vanilla)
async def handle_add_igloo_layout(p):
if len(p.data.igloo_rooms) < 4:
igloo = await p.data.igloo_rooms.insert(penguin_id=p.data.id, type=1, flooring=0, location=1)
slot_id = len(p.data.igloo_rooms)
if len(p.igloo_rooms) < 4:
igloo = await p.igloo_rooms.insert(penguin_id=p.id, type=1, flooring=0, location=1)
slot_id = len(p.igloo_rooms)
await p.send_xt('al', p.data.id, f'{igloo.id}:{slot_id}:0:{int(igloo.locked)}:{igloo.music}:{igloo.flooring}:'
f'{igloo.location}:{igloo.type}:0:')
await p.send_xt('al', p.id, f'{igloo.id}:{slot_id}:0:{int(igloo.locked)}:{igloo.music}:{igloo.flooring}:'
f'{igloo.location}:{igloo.type}:0:')
@handlers.handler(XTPacket('g', 'gili'), client=ClientType.Vanilla)
@ -347,7 +347,7 @@ async def handle_get_igloo_like_by(p, pagination_start: int, pagination_end: int
'id': like.player_id,
'time': int(time.mktime(like.date.timetuple())),
'count': like.count,
'isFriend': like.player_id in p.data.buddies
'isFriend': like.player_id in p.buddies
} async for like in liked_by.iterate()
]
},
@ -359,7 +359,7 @@ async def handle_get_igloo_like_by(p, pagination_start: int, pagination_end: int
@handlers.handler(XTPacket('g', 'cli'), client=ClientType.Vanilla)
async def handle_can_like_igloo(p):
last_like = await db.select([IglooLike.date]).where((IglooLike.igloo_id == p.room.id)
& (IglooLike.player_id == p.data.id)).gino.scalar()
& (IglooLike.player_id == p.id)).gino.scalar()
time_elapsed = datetime.now()
if last_like is not None:
@ -385,7 +385,7 @@ async def handle_get_open_igloo_list(p):
open_igloos = [await get_igloo_string(igloo) for igloo in p.server.open_igloos_by_penguin_id.values()]
local_room_population = 0
own_layout_like_count = 0 if p.data.igloo is None else await get_layout_like_count(p.data.igloo)
own_layout_like_count = 0 if p.igloo is None else await get_layout_like_count(p.igloo)
await p.send_xt('gr', own_layout_like_count, local_room_population, *open_igloos)
@ -404,56 +404,56 @@ async def handle_get_open_igloo_list_legacy(p):
@handlers.handler(XTPacket('g', 'or'), client=ClientType.Legacy)
async def handle_unlock_igloo(p):
igloo = p.data.igloo_rooms[p.data.igloo]
p.server.open_igloos_by_penguin_id[p.data.id] = igloo
igloo = p.igloo_rooms[p.igloo]
p.server.open_igloos_by_penguin_id[p.id] = igloo
@handlers.handler(XTPacket('g', 'cr'), client=ClientType.Legacy)
async def handle_lock_igloo(p):
del p.server.open_igloos_by_penguin_id[p.data.id]
del p.server.open_igloos_by_penguin_id[p.id]
@handlers.handler(XTPacket('g', 'go'), client=ClientType.Legacy)
async def handle_get_owned_igloos(p):
await p.send_xt('go', '|'.join(str(igloo_id) for igloo_id in p.data.igloos.keys()))
await p.send_xt('go', '|'.join(str(igloo_id) for igloo_id in p.igloos.keys()))
@handlers.handler(XTPacket('g', 'gf'), client=ClientType.Legacy)
async def handle_get_furniture(p):
furniture_string = '%'.join(f'{furniture.furniture_id}|{furniture.quantity}'
for furniture in p.data.furniture.values())
for furniture in p.furniture.values())
await p.send_xt('gf', furniture_string)
@handlers.handler(XTPacket('g', 'um'), client=ClientType.Legacy)
async def handle_update_igloo_music(p, music_id: int):
if p.room.igloo and p.room.penguin_id == p.data.id and p.room.music != music_id:
if p.room.igloo and p.room.penguin_id == p.id and p.room.music != music_id:
await p.room.update(music=music_id).apply()
await p.server.cache.delete(f'active_igloo.{p.data.id}')
await p.server.cache.delete(f'legacy_igloo.{p.data.id}')
await p.server.cache.delete(f'igloo_layouts.{p.data.id}')
await p.server.cache.delete(f'active_igloo.{p.id}')
await p.server.cache.delete(f'legacy_igloo.{p.id}')
await p.server.cache.delete(f'igloo_layouts.{p.id}')
@handlers.handler(XTPacket('g', 'ao'), client=ClientType.Legacy)
async def handle_activate_igloo_type(p, igloo_type_id: int):
if p.room.igloo and p.room.penguin_id == p.data.id and p.room.type != igloo_type_id \
and igloo_type_id in p.data.igloos:
if p.room.igloo and p.room.penguin_id == p.id and p.room.type != igloo_type_id \
and igloo_type_id in p.igloos:
await p.room.update(type=igloo_type_id, flooring=0).apply()
await p.server.cache.delete(f'active_igloo.{p.data.id}')
await p.server.cache.delete(f'legacy_igloo.{p.data.id}')
await p.server.cache.delete(f'igloo_layouts.{p.data.id}')
await p.server.cache.delete(f'active_igloo.{p.id}')
await p.server.cache.delete(f'legacy_igloo.{p.id}')
await p.server.cache.delete(f'igloo_layouts.{p.id}')
@handlers.handler(XTPacket('g', 'grf'), client=ClientType.Vanilla)
async def handle_get_friends_igloo_list(p):
async def get_friend_igloo_string(penguin):
like_count = 0 if penguin.data.igloo is None else await get_layout_like_count(penguin.data.igloo)
return f'{penguin.data.id}|{like_count}'
like_count = 0 if penguin.igloo is None else await get_layout_like_count(penguin.igloo)
return f'{penguin.id}|{like_count}'
friend_igloos = [await get_friend_igloo_string(penguin) for penguin in p.server.penguins_by_id.values()
if penguin.data.id in p.data.buddies]
if penguin.id in p.buddies]
await p.send_xt('grf', *friend_igloos)
@ -462,7 +462,7 @@ async def handle_get_friends_igloo_list(p):
@handlers.cooldown(1)
async def handle_like_igloo(p):
if p.room.igloo:
like_insert = insert(IglooLike).values(igloo_id=p.room.id, player_id=p.data.id)
like_insert = insert(IglooLike).returning(IglooLike.count).values(igloo_id=p.room.id, player_id=p.id)
like_insert = like_insert.on_conflict_do_update(
constraint='igloo_like_pkey',
set_=dict(count=IglooLike.count + 1, date=datetime.now()),
@ -482,9 +482,9 @@ async def handle_like_igloo(p):
@handlers.handler(XTPacket('g', 'gii'), client=ClientType.Vanilla)
async def handle_get_furniture_inventory(p):
furniture = ','.join(f'{furniture_id}|0000000000|{furniture_item.quantity}'
for furniture_id, furniture_item in p.data.furniture.items())
flooring = ','.join(f'{flooring_id}|0000000000' for flooring_id in p.data.flooring.keys())
igloos = ','.join(f'{igloo_id}|0000000000' for igloo_id in p.data.igloos.keys())
locations = ','.join(f'{location_id}|0000000000' for location_id in p.data.locations.keys())
for furniture_id, furniture_item in p.furniture.items())
flooring = ','.join(f'{flooring_id}|0000000000' for flooring_id in p.flooring.keys())
igloos = ','.join(f'{igloo_id}|0000000000' for igloo_id in p.igloos.keys())
locations = ','.join(f'{location_id}|0000000000' for location_id in p.locations.keys())
await p.send_xt('gii', furniture, flooring, igloos, locations)

View File

@ -9,7 +9,7 @@ from houdini.data.buddy import IgnoreList
@handlers.allow_once
async def handle_get_ignore_list(p):
ignore_query = IgnoreList.load(parent=Penguin.on(Penguin.id == IgnoreList.ignore_id)).where(
IgnoreList.penguin_id == p.data.id)
IgnoreList.penguin_id == p.id)
async with p.server.db.transaction():
ignore_list = ignore_query.gino.iterate()
@ -20,17 +20,17 @@ async def handle_get_ignore_list(p):
@handlers.handler(XTPacket('n', 'rn'))
async def handle_ignore_remove(p, ignored_id: int):
if ignored_id in p.data.ignore:
await p.data.ignore.delete(ignored_id)
if ignored_id in p.ignore:
await p.ignore.delete(ignored_id)
await p.send_xt('rn', ignored_id)
@handlers.handler(XTPacket('n', 'an'))
async def handle_ignore_add(p, ignored_id: int):
if ignored_id not in p.data.ignore:
if ignored_id not in p.ignore:
if ignored_id in p.server.penguins_by_id:
nickname = p.server.penguins_by_id[ignored_id].data.nickname
nickname = p.server.penguins_by_id[ignored_id].safe_name
else:
nickname = await Penguin.select('nickname').where(Penguin.id == ignored_id).gino.scalar()
await p.data.ignore.insert(ignore_id=ignored_id)
await p.ignore.insert(ignore_id=ignored_id)
await p.send_xt('an', ignored_id, nickname)

View File

@ -18,7 +18,7 @@ def get_awards_string_key(_, p, player_id):
@cached(alias='default', key_builder=get_pin_string_key)
async def get_pin_string(p, player_id):
if player_id in p.server.penguins_by_id:
inventory = p.server.penguins_by_id[player_id].data.inventory
inventory = p.server.penguins_by_id[player_id].inventory
else:
inventory = await PenguinItemCollection.get_collection(player_id)
@ -35,7 +35,7 @@ async def get_pin_string(p, player_id):
@cached(alias='default', key_builder=get_awards_string_key)
async def get_awards_string(p, player_id):
if player_id in p.server.penguins_by_id:
inventory = p.server.penguins_by_id[player_id].data.inventory
inventory = p.server.penguins_by_id[player_id].inventory
else:
inventory = await PenguinItemCollection.get_collection(player_id)
@ -46,7 +46,7 @@ async def get_awards_string(p, player_id):
@handlers.handler(XTPacket('i', 'gi'))
@handlers.allow_once
async def handle_get_inventory(p):
await p.send_xt('gi', *p.data.inventory.keys())
await p.send_xt('gi', *p.inventory.keys())
@handlers.handler(XTPacket('i', 'ai'))
@ -55,13 +55,13 @@ async def handle_buy_inventory(p, item: Item):
if item is None:
return await p.send_error(402)
if item.id in p.data.inventory:
if item.id in p.inventory:
return await p.send_error(400)
if item.tour:
return await p.add_inbox(p.server.postcards[126])
if p.data.coins < item.cost:
if p.coins < item.cost:
return await p.send_error(401)
await p.add_inventory(item)

View File

@ -13,9 +13,9 @@ import time
@handlers.allow_once
async def handle_start_mail_engine(p):
mail_count = await db.select([db.func.count(PenguinPostcard.id)]).where(
PenguinPostcard.penguin_id == p.data.id).gino.scalar()
PenguinPostcard.penguin_id == p.id).gino.scalar()
unread_mail_count = await db.select([db.func.count(PenguinPostcard.id)]).where(
(PenguinPostcard.penguin_id == p.data.id)
(PenguinPostcard.penguin_id == p.id)
& (PenguinPostcard.has_read == False)).gino.scalar()
await p.send_xt('mst', unread_mail_count, mail_count)
@ -24,7 +24,7 @@ async def handle_start_mail_engine(p):
@handlers.allow_once
async def handle_get_mail(p):
mail_query = PenguinPostcard.load(parent=Penguin.on(Penguin.id == PenguinPostcard.sender_id)).where(
PenguinPostcard.penguin_id == p.data.id).order_by(
PenguinPostcard.penguin_id == p.id).order_by(
PenguinPostcard.send_date.desc())
postcards = []
@ -41,49 +41,49 @@ async def handle_get_mail(p):
@handlers.handler(XTPacket('l', 'ms'))
@handlers.cooldown(2)
async def handle_send_mail(p, recipient_id: int, postcard_id: int):
if p.data.coins < 10:
return await p.send_xt('ms', p.data.coins, 0)
if p.coins < 10:
return await p.send_xt('ms', p.coins, 0)
mail_count = await db.select([db.func.count(PenguinPostcard.id)]).where(
PenguinPostcard.penguin_id == recipient_id).gino.scalar()
if recipient_id in p.server.penguins_by_id:
recipient = p.server.penguins_by_id[recipient_id]
if p.data.id in recipient.data.ignore:
return await p.send_xt('ms', p.data.coins, 1)
if len(recipient.data.postcards) >= 100:
return await p.send_xt('ms', p.data.coins, 0)
postcard = await PenguinPostcard.create(penguin_id=recipient_id, sender_id=p.data.id,
if p.id in recipient.ignore:
return await p.send_xt('ms', p.coins, 1)
if mail_count >= 100:
return await p.send_xt('ms', p.coins, 0)
postcard = await PenguinPostcard.create(penguin_id=recipient_id, sender_id=p.id,
postcard_id=postcard_id)
sent_timestamp = int(time.mktime(postcard.send_date.timetuple()))
await recipient.send_xt('mr', p.data.nickname, p.data.id, postcard_id, '', sent_timestamp, postcard.id)
else:
ignored = await IgnoreList.query.where((IgnoreList.penguin_id == recipient_id)
& (IgnoreList.ignore_id == p.data.id)).gino.scalar()
& (IgnoreList.ignore_id == p.id)).gino.scalar()
if ignored is not None:
return await p.send_xt('ms', p.data.coins, 1)
mail_count = await db.select([db.func.count(PenguinPostcard.id)]).where(
PenguinPostcard.penguin_id == recipient_id).gino.scalar()
return await p.send_xt('ms', p.coins, 1)
if mail_count >= 100:
return await p.send_xt('ms', p.data.coins, 0)
await PenguinPostcard.create(penguin_id=recipient_id, sender_id=p.data.id, postcard_id=postcard_id)
await p.data.update(coins=p.data.coins - 10).apply()
return await p.send_xt('ms', p.data.coins, 1)
return await p.send_xt('ms', p.coins, 0)
await PenguinPostcard.create(penguin_id=recipient_id, sender_id=p.id, postcard_id=postcard_id)
await p.update(coins=p.coins - 10).apply()
return await p.send_xt('ms', p.coins, 1)
@handlers.handler(XTPacket('l', 'mc'))
async def handle_mail_checked(p):
await PenguinPostcard.update.values(has_read=True).where(
PenguinPostcard.penguin_id == p.data.id).gino.status()
PenguinPostcard.penguin_id == p.id).gino.status()
@handlers.handler(XTPacket('l', 'md'))
async def handle_delete_mail(p, postcard_id: int):
await PenguinPostcard.delete.where((PenguinPostcard.penguin_id == p.data.id)
await PenguinPostcard.delete.where((PenguinPostcard.penguin_id == p.id)
& (PenguinPostcard.id == postcard_id)).gino.status()
@handlers.handler(XTPacket('l', 'mdp'))
async def handle_delete_mail_from_user(p, sender_id: int):
sender_id = None if sender_id == 0 else sender_id
await PenguinPostcard.delete.where((PenguinPostcard.penguin_id == p.data.id)
await PenguinPostcard.delete.where((PenguinPostcard.penguin_id == p.id)
& (PenguinPostcard.sender_id == sender_id)).gino.status()
mail_count = await db.select([db.func.count(PenguinPostcard.id)]).where(
PenguinPostcard.penguin_id == p.data.id).gino.scalar()
PenguinPostcard.penguin_id == p.id).gino.scalar()
await p.send_xt('mdp', mail_count)

View File

@ -6,16 +6,16 @@ from houdini.commands import invoke_command_string, has_command_prefix
@handlers.handler(XTPacket('m', 'sm'))
@handlers.cooldown(.5)
async def handle_send_message(p, penguin_id: int, message: str):
if penguin_id != p.data.id:
if penguin_id != p.id:
return await p.close()
if p.muted:
for penguin in p.room.penguins_by_id.values():
if penguin.data.moderator:
if penguin.moderator:
await penguin.send_xt("mm", message, penguin_id)
return
if has_command_prefix(message):
await invoke_command_string(p.server.commands, p, message)
else:
await p.room.send_xt('sm', p.data.id, message)
await p.room.send_xt('sm', p.id, message)

View File

@ -95,7 +95,7 @@ async def get_player_tracks(p):
likes = db.func.count(TrackLike.track_id)
tracks_query = db.select([PenguinTrack, likes])\
.select_from(PenguinTrack.outerjoin(TrackLike))\
.where(PenguinTrack.owner_id == p.data.id)\
.where(PenguinTrack.owner_id == p.id)\
.group_by(PenguinTrack.id).gino.load(PenguinTrack.load(likes=ColumnLoader(likes)))
async with db.transaction():
async for track in tracks_query.iterate():
@ -131,7 +131,7 @@ async def can_like_track(p, owner_id: int, track_id: int):
like = await db.select(TrackLike) \
.select_from(TrackLike.outerjoin(PenguinTrack)) \
.where((PenguinTrack.owner_id == owner_id)
& (TrackLike.penguin_id == p.data.id)
& (TrackLike.penguin_id == p.id)
& (TrackLike.track_id == track_id)
& (TrackLike.date > yesterday)).gino.first()
return like is None
@ -139,7 +139,7 @@ async def can_like_track(p, owner_id: int, track_id: int):
def get_playlist_position(p):
for position, track in enumerate(p.server.music.playlist):
if track.owner_id == p.data.id:
if track.owner_id == p.id:
return position + 1
return -1
@ -206,10 +206,10 @@ async def handle_save_my_music_track(p, track_name, track_pattern, track_hash):
return
track_count = await db.select([db.func.count(PenguinTrack.id)])\
.where(PenguinTrack.owner_id == p.data.id).gino.scalar()
.where(PenguinTrack.owner_id == p.id).gino.scalar()
if track_count >= 12:
return
track = await PenguinTrack.create(owner_id=p.data.id, name=track_name, pattern=track_pattern)
track = await PenguinTrack.create(owner_id=p.id, name=track_name, pattern=track_pattern)
await p.send_xt('savemymusictrack', track.id)
@ -219,11 +219,11 @@ async def handle_refresh_my_track_likes(p):
likes = db.func.count(TrackLike.track_id)
track_likes_query = db.select([PenguinTrack.id, likes])\
.select_from(PenguinTrack.outerjoin(TrackLike))\
.where(PenguinTrack.owner_id == p.data.id)\
.where(PenguinTrack.owner_id == p.id)\
.group_by(PenguinTrack.id).gino.load(PenguinTrack.load(likes=ColumnLoader(likes)))
async with db.transaction():
async for track in track_likes_query.iterate():
await p.send_xt('getlikecountfortrack', p.data.id, track.id, track.likes)
await p.send_xt('getlikecountfortrack', p.id, track.id, track.likes)
@handlers.handler(XTPacket('musictrack', 'sharemymusictrack'), client=ClientType.Vanilla)
@ -232,10 +232,10 @@ async def handle_refresh_my_track_likes(p):
async def handle_share_my_music_track(p, track_id: int, sharing: int):
if sharing:
await PenguinTrack.update.values(sharing=False)\
.where(PenguinTrack.owner_id == p.data.id).gino.status()
.where(PenguinTrack.owner_id == p.id).gino.status()
await PenguinTrack.update.values(sharing=bool(sharing))\
.where((PenguinTrack.id == track_id)
& (PenguinTrack.owner_id == p.data.id)).gino.status()
& (PenguinTrack.owner_id == p.id)).gino.status()
await p.send_xt('sharemymusictrack', 1)
@ -243,7 +243,7 @@ async def handle_share_my_music_track(p, track_id: int, sharing: int):
@handlers.player_in_room(SoundStudio.StudioRoomId, SoundStudio.DeckRoomId)
async def handle_delete_track(p, track_id: int):
await PenguinTrack.delete.where((PenguinTrack.id == track_id)
& (PenguinTrack.owner_id == p.data.id)).gino.status()
& (PenguinTrack.owner_id == p.id)).gino.status()
await p.send_xt('deletetrack', 1)
@ -260,7 +260,7 @@ async def handle_can_like_track(p, owner_id: int, track_id: int):
async def handle_like_track(p, owner_id: int, track_id: int):
can_like = await can_like_track(p, owner_id, track_id)
if can_like:
await TrackLike.create(penguin_id=p.data.id, track_id=track_id)
await TrackLike.create(penguin_id=p.id, track_id=track_id)
like_count = await db.select([db.func.count(TrackLike.track_id)])\
.where(TrackLike.track_id == track_id).gino.scalar()
await p.room.send_xt('liketrack', owner_id, track_id, like_count)

View File

@ -14,7 +14,7 @@ from datetime import datetime
@handlers.handler(XTPacket('j', 'js'), pre_login=True)
@handlers.allow_once
async def handle_join_server(p, penguin_id: int, login_key: str):
if penguin_id != p.data.id:
if penguin_id != p.id:
return await p.close()
if login_key != p.login_key:
@ -22,40 +22,38 @@ async def handle_join_server(p, penguin_id: int, login_key: str):
await p.send_xt('activefeatures')
moderator_status = 3 if p.data.character else 2 if p.data.stealth_moderator else 1 if p.data.moderator else 0
moderator_status = 3 if p.character else 2 if p.stealth_moderator else 1 if p.moderator else 0
await p.send_xt('js', int(p.data.agent_status), int(0),
moderator_status, int(p.data.book_modified))
await p.send_xt('js', int(p.agent_status), int(0),
moderator_status, int(p.book_modified))
current_time = int(time.time())
penguin_standard_time = current_time * 1000
server_time_offset = 7
if p.data.timer_active:
minutes_until_timer_end = datetime.combine(datetime.today(), p.data.timer_end) - datetime.now()
if p.timer_active:
minutes_until_timer_end = datetime.combine(datetime.today(), p.timer_end) - datetime.now()
minutes_until_timer_end = minutes_until_timer_end.total_seconds() // 60
minutes_played_today = await p.data.minutes_played_today
minutes_left_today = (p.data.timer_total.total_seconds() // 60) - minutes_played_today
minutes_played_today = await p.minutes_played_today
minutes_left_today = (p.timer_total.total_seconds() // 60) - minutes_played_today
p.egg_timer_minutes = int(min(minutes_until_timer_end, minutes_left_today))
else:
p.egg_timer_minutes = 24 * 60
await p.send_xt('lp', await p.string, p.data.coins, int(p.data.safe_chat), p.egg_timer_minutes,
penguin_standard_time, p.data.age, 0, p.data.minutes_played,
"membership_days", server_time_offset, int(p.data.opened_playercard),
p.data.map_category, p.data.status_field)
await p.send_xt('lp', await p.string, p.coins, int(p.safe_chat), p.egg_timer_minutes,
penguin_standard_time, p.age, 0, p.minutes_played,
"membership_days", server_time_offset, int(p.opened_playercard),
p.map_category, p.status_field)
spawn = random.choice(p.server.spawn_rooms)
await p.join_room(spawn)
await p.data.load_inventories()
p.server.penguins_by_id[p.id] = p
p.server.penguins_by_username[p.username] = p
p.server.penguins_by_id[p.data.id] = p
p.server.penguins_by_username[p.data.username] = p
if p.data.character is not None:
p.server.penguins_by_character_id[p.data.character] = p
if p.character is not None:
p.server.penguins_by_character_id[p.character] = p
p.login_timestamp = datetime.now()
p.joined_world = True
@ -76,7 +74,7 @@ async def create_temporary_room(p, penguin_id):
igloo = None
if penguin_id in p.server.penguins_by_id:
igloo_owner = p.server.penguins_by_id[penguin_id]
igloo = igloo_owner.data.igloo_rooms[igloo_owner.data.igloo]
igloo = igloo_owner.igloo_rooms[igloo_owner.igloo]
p.server.igloos_by_penguin_id[penguin_id] = igloo
elif penguin_id not in p.server.igloos_by_penguin_id:
igloo = await PenguinIglooRoom.load(parent=Penguin.on(Penguin.igloo == PenguinIglooRoom.id)) \
@ -89,7 +87,7 @@ async def create_temporary_room(p, penguin_id):
@handlers.handler(XTPacket('j', 'jp'), client=ClientType.Vanilla)
@handlers.cooldown(1)
async def handle_join_player_room(p, penguin_id: int, room_type: str):
if room_type == 'backyard' and p.room.igloo and p.room.penguin_id == p.data.id:
if room_type == 'backyard' and p.room.igloo and p.room.penguin_id == p.id:
backyard = PenguinBackyardRoom()
await p.send_xt('jp', backyard.id, backyard.id, room_type)
await p.join_room(backyard)
@ -119,15 +117,15 @@ async def handle_disconnect_room(p):
await p.room.remove_penguin(p)
minutes_played = (datetime.now() - p.login_timestamp).total_seconds() / 60.0
await Login.create(penguin_id=p.data.id,
await Login.create(penguin_id=p.id,
date=p.login_timestamp,
ip_address=p.peer_name[0],
minutes_played=minutes_played)
await p.data.update(minutes_played=p.data.minutes_played + minutes_played).apply()
await p.update(minutes_played=p.minutes_played + minutes_played).apply()
del p.server.penguins_by_id[p.data.id]
del p.server.penguins_by_username[p.data.username]
del p.server.penguins_by_id[p.id]
del p.server.penguins_by_username[p.username]
server_key = f'houdini.players.{p.server.server_config["Id"]}'
await p.server.redis.srem(server_key, p.data.id)

View File

@ -15,10 +15,10 @@ DefaultPartyCookie = {
@handlers.handler(XTPacket('party', 'partycookie'))
@handlers.allow_once
async def handle_party_cookie(p):
cookie = await p.server.redis.hget('partycookie', p.data.id)
cookie = await p.server.redis.hget('partycookie', p.id)
if cookie is None:
cookie = ujson.dumps(DefaultPartyCookie)
await p.server.redis.hset('partycookie', p.data.id, cookie)
await p.server.redis.hset('partycookie', p.id, cookie)
else:
cookie = cookie.decode('utf-8')
await p.send_xt('partycookie', cookie)
@ -27,34 +27,34 @@ async def handle_party_cookie(p):
@handlers.handler(XTPacket('party', 'msgviewed'))
@handlers.depends_on_packet(XTPacket('party', 'partycookie'))
async def handle_party_message_viewed(p, message_index: int):
cookie = await p.server.redis.hget('partycookie', p.data.id)
cookie = await p.server.redis.hget('partycookie', p.id)
cookie = ujson.loads(cookie)
cookie['msgViewedArray'][message_index] = 1
await p.server.redis.hset('partycookie', p.data.id, ujson.dumps(cookie))
await p.server.redis.hset('partycookie', p.id, ujson.dumps(cookie))
@handlers.handler(XTPacket('party', 'qcmsgviewed'))
@handlers.depends_on_packet(XTPacket('party', 'partycookie'))
async def handle_party_communicator_message_viewed(p, message_index: int):
cookie = await p.server.redis.hget('partycookie', p.data.id)
cookie = await p.server.redis.hget('partycookie', p.id)
cookie = ujson.loads(cookie)
cookie['communicatorMsgArray'][message_index] = 1
await p.server.redis.hset('partycookie', p.data.id, ujson.dumps(cookie))
await p.server.redis.hset('partycookie', p.id, ujson.dumps(cookie))
@handlers.handler(XTPacket('party', 'qtaskcomplete'))
@handlers.depends_on_packet(XTPacket('party', 'partycookie'))
async def handle_party_task_complete(p, task_index: int):
cookie = await p.server.redis.hget('partycookie', p.data.id)
cookie = await p.server.redis.hget('partycookie', p.id)
cookie = ujson.loads(cookie)
cookie['questTaskStatus'][task_index] = 1
await p.server.redis.hset('partycookie', p.data.id, ujson.dumps(cookie))
await p.server.redis.hset('partycookie', p.id, ujson.dumps(cookie))
@handlers.handler(XTPacket('party', 'qtupdate'))
@ -62,5 +62,5 @@ async def handle_party_task_complete(p, task_index: int):
@handlers.cooldown(5)
async def handle_party_task_update(p, coins: int):
coins = min(coins, 10)
await p.data.update(coins=p.data.coins + coins).apply()
await p.send_xt('qtupdate', p.data.coins)
await p.update(coins=p.coins + coins).apply()
await p.send_xt('qtupdate', p.coins)

View File

@ -51,28 +51,28 @@ async def server_egg_timer(server):
while True:
await asyncio.sleep(60)
for p in server.penguins_by_id.values():
if p.data.timer_active:
if p.timer_active:
p.egg_timer_minutes -= 1
if p.client_type == ClientType.Vanilla:
minutes_until_timer_end = datetime.combine(datetime.today(), p.data.timer_end) - datetime.now()
if p.is_vanilla_client:
minutes_until_timer_end = datetime.combine(datetime.today(), p.timer_end) - datetime.now()
minutes_until_timer_end = minutes_until_timer_end.total_seconds() // 60
if minutes_until_timer_end <= p.egg_timer_minutes + 1:
if p.egg_timer_minutes == 7:
await p.send_error(915, p.egg_timer_minutes, p.data.timer_start, p.data.timer_end)
await p.send_error(915, p.egg_timer_minutes, p.timer_start, p.timer_end)
elif p.egg_timer_minutes == 5:
await p.send_error(915, p.egg_timer_minutes, p.data.timer_start, p.data.timer_end)
await p.send_error(915, p.egg_timer_minutes, p.timer_start, p.timer_end)
else:
if p.egg_timer_minutes == 7:
await p.send_error(914, p.egg_timer_minutes, p.data.timer_total)
await p.send_error(914, p.egg_timer_minutes, p.timer_total)
elif p.egg_timer_minutes == 5:
await p.send_error(914, p.egg_timer_minutes, p.data.timer_total)
await p.send_error(914, p.egg_timer_minutes, p.timer_total)
await p.send_xt('uet', p.egg_timer_minutes)
if p.egg_timer_minutes <= 0:
await p.send_error_and_disconnect(916, p.data.timer_start, p.data.timer_end)
await p.send_xt('uet', max(0, p.egg_timer_minutes))
if p.egg_timer_minutes < 0:
await p.send_error_and_disconnect(916, p.timer_start, p.timer_end)
else:
if p.egg_timer_minutes <= 0:
if p.egg_timer_minutes < 0:
await p.send_error_and_disconnect(910)
@ -117,7 +117,7 @@ async def handle_get_player_by_name(p, player_name: str):
player_name = player_name.lower()
if player_name in p.server.penguins_by_username:
player = p.server.penguins_by_username[player_name]
await p.send_xt('pbn', player.data.id, player.data.id, player.data.nickname)
await p.send_xt('pbn', player.id, player.id, player.safe_name)
else:
result = await Penguin.select('id', 'nickname').where(
Penguin.username == player_name).gino.first()
@ -131,9 +131,9 @@ async def handle_get_player_by_name(p, player_name: str):
@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()))
if character_id in p.server.characters and p.character is not None:
players = random.sample(list(p.server.penguins_by_id.values()), min(num_invites, len(p.server.penguins_by_id)))
for player in players:
await player.send_xt('smi', character_id)
@ -151,7 +151,7 @@ async def handle_find_player(p, player_id: int):
@handlers.handler(XTPacket('u', 'gbffl'))
async def handle_get_best_friends(p):
await p.send_xt('gbffl', ','.join((str(buddy.buddy_id) for buddy in p.data.buddies.values() if buddy.best_buddy)))
await p.send_xt('gbffl', ','.join((str(buddy.buddy_id) for buddy in p.buddies.values() if buddy.best_buddy)))
@handlers.handler(XTPacket('u', 'pbsms'), client=ClientType.Vanilla)
@ -174,49 +174,49 @@ async def handle_set_player_position(p, x: int, y: int):
p.x, p.y = x, y
p.frame = 1
p.toy = None
await p.room.send_xt('sp', p.data.id, x, y)
await p.room.send_xt('sp', p.id, x, y)
@handlers.handler(XTPacket('u', 'sf'))
@handlers.cooldown(.5)
async def handle_set_player_frame(p, frame: int):
p.frame = frame
await p.room.send_xt('sf', p.data.id, frame)
await p.room.send_xt('sf', p.id, frame)
@handlers.handler(XTPacket('u', 'sb'))
@handlers.cooldown(1)
async def handle_send_throw_ball(p, x: int, y: int):
await p.room.send_xt('sb', p.data.id, x, y)
await p.room.send_xt('sb', p.id, x, y)
@handlers.handler(XTPacket('u', 'se'))
@handlers.cooldown(1)
async def handle_send_emote(p, emote: int):
await p.room.send_xt('se', p.data.id, emote)
await p.room.send_xt('se', p.id, emote)
@handlers.handler(XTPacket('u', 'sa'))
@handlers.cooldown(1)
async def handle_send_action(p, action: int):
await p.room.send_xt('sa', p.data.id, action)
await p.room.send_xt('sa', p.id, action)
@handlers.handler(XTPacket('u', 'followpath'))
@handlers.cooldown(1)
async def handle_follow_path(p, path: int):
await p.room.send_xt('followpath', p.data.id, path)
await p.room.send_xt('followpath', p.id, path)
@handlers.handler(XTPacket('u', 'ss'))
async def handle_send_safe_message(p, message_id: int):
await p.room.send_xt('ss', p.data.id, message_id)
await p.room.send_xt('ss', p.id, message_id)
@handlers.handler(XTPacket('u', 'sma'))
async def handle_send_mascot_message(p, message_id: int):
if p.data.character:
await p.room.send_xt('sma', p.data.id, message_id)
if p.character:
await p.room.send_xt('sma', p.id, message_id)
@handlers.handler(XTPacket('u', 'glr'))

View File

@ -7,61 +7,61 @@ from houdini.data.item import Item
@handlers.handler(XTPacket('s', 'upc'))
@handlers.cooldown(1)
async def handle_send_update_player_colour(p, item: Item):
if item.id in p.data.inventory and item.is_color():
if item.id in p.inventory and item.is_color():
await p.set_color(item)
@handlers.handler(XTPacket('s', 'uph'))
@handlers.cooldown(1)
async def handle_send_update_player_head(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_head()):
if item is None or (item.id in p.inventory and item.is_head()):
await p.set_head(item)
@handlers.handler(XTPacket('s', 'upf'))
@handlers.cooldown(1)
async def handle_send_update_player_face(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_face()):
if item is None or (item.id in p.inventory and item.is_face()):
await p.set_face(item)
@handlers.handler(XTPacket('s', 'upn'))
@handlers.cooldown(1)
async def handle_send_update_player_neck(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_neck()):
if item is None or (item.id in p.inventory and item.is_neck()):
await p.set_neck(item)
@handlers.handler(XTPacket('s', 'upb'))
@handlers.cooldown(1)
async def handle_send_update_player_body(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_body()):
if item is None or (item.id in p.inventory and item.is_body()):
await p.set_body(item)
@handlers.handler(XTPacket('s', 'upa'))
@handlers.cooldown(1)
async def handle_send_update_player_hand(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_hand()):
if item is None or (item.id in p.inventory and item.is_hand()):
await p.set_hand(item)
@handlers.handler(XTPacket('s', 'upe'))
@handlers.cooldown(1)
async def handle_send_update_player_feet(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_feet()):
if item is None or (item.id in p.inventory and item.is_feet()):
await p.set_feet(item)
@handlers.handler(XTPacket('s', 'upl'))
@handlers.cooldown(1)
async def handle_send_update_player_flag(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_flag()):
if item is None or (item.id in p.inventory and item.is_flag()):
await p.set_flag(item)
@handlers.handler(XTPacket('s', 'upp'))
@handlers.cooldown(1)
async def handle_send_update_player_photo(p, item: Item):
if item is None or (item.id in p.data.inventory and item.is_photo()):
if item is None or (item.id in p.inventory and item.is_photo()):
await p.set_photo(item)

View File

@ -19,8 +19,8 @@ def get_player_stamps_key(_, p, player_id):
async def get_book_cover_string(p, player_id):
if player_id in p.server.penguins_by_id:
player = p.server.penguins_by_id[player_id]
cover_details = [player.data.book_color, player.data.book_highlight, player.data.book_pattern,
player.data.book_icon]
cover_details = [player.book_color, player.book_highlight, player.book_pattern,
player.book_icon]
else:
cover_details = list(await Penguin.select('book_color', 'book_highlight', 'book_pattern', 'book_icon')
.where(Penguin.id == player_id).gino.first())
@ -41,7 +41,7 @@ async def get_book_cover_string(p, player_id):
@cached(alias='default', key_builder=get_player_stamps_key)
async def get_player_stamps_string(p, player_id):
if player_id in p.server.penguins_by_id:
stamp_inventory = p.server.penguins_by_id[player_id].data.stamps
stamp_inventory = p.server.penguins_by_id[player_id].stamps
else:
stamp_inventory = await PenguinStampCollection.get_collection(player_id)
return '|'.join(map(str, stamp_inventory.keys()))
@ -50,20 +50,20 @@ async def get_player_stamps_string(p, player_id):
@handlers.handler(XTPacket('j', 'js'), after=handle_join_server)
@handlers.allow_once
async def handle_get_stamps(p):
await p.send_xt('gps', p.data.id, await get_player_stamps_string(p, p.data.id))
await p.send_xt('gps', p.id, await get_player_stamps_string(p, p.id))
@handlers.handler(XTPacket('st', 'gps'))
@handlers.cooldown(1)
async def handle_get_player_stamps(p, player_id: int):
await p.send_xt('gps', p.data.id, await get_player_stamps_string(p, player_id))
await p.send_xt('gps', p.id, await get_player_stamps_string(p, player_id))
@handlers.handler(XTPacket('st', 'gmres'))
@handlers.cooldown(1)
async def handle_get_recent_stamps(p):
recent_stamps = []
for stamp in p.data.stamps.values():
for stamp in p.stamps.values():
if stamp.recent:
recent_stamps.append(stamp.stamp_id)
await stamp.update(recent=False).apply()
@ -88,8 +88,8 @@ async def handle_update_book_cover(p, color: int, highlight: int, pattern: int,
and len(cover) <= 10):
return
await CoverItem.delete.where(CoverItem.penguin_id == p.data.id).gino.status()
await CoverStamp.delete.where(CoverStamp.penguin_id == p.data.id).gino.status()
await CoverItem.delete.where(CoverItem.penguin_id == p.id).gino.status()
await CoverStamp.delete.where(CoverStamp.penguin_id == p.id).gino.status()
stamp_tracker = set()
inventory_tracker = set()
@ -106,19 +106,19 @@ async def handle_update_book_cover(p, color: int, highlight: int, pattern: int,
return
if stamp_type == 0:
if stamp_id in stamp_tracker or stamp_id not in p.data.stamps:
if stamp_id in stamp_tracker or stamp_id not in p.stamps:
return
stamp_tracker.add(stamp_id)
cover_stamps.append({'penguin_id': p.data.id, 'stamp_id': stamp_id, 'x': pos_x, 'y': pos_y,
cover_stamps.append({'penguin_id': p.id, 'stamp_id': stamp_id, 'x': pos_x, 'y': pos_y,
'rotation': rotation, 'depth': depth})
elif stamp_type == 1 or stamp_type == 2:
cover_item = p.server.items[stamp_id]
if stamp_id in inventory_tracker or stamp_id not in p.data.inventory or \
if stamp_id in inventory_tracker or stamp_id not in p.inventory or \
(stamp_type == 1 and not cover_item.is_flag()) or \
(stamp_type == 2 and not cover_item.is_award()):
return
inventory_tracker.add(stamp_id)
cover_items.append({'penguin_id': p.data.id, 'item_id': stamp_id, 'x': pos_x, 'y': pos_y,
cover_items.append({'penguin_id': p.id, 'item_id': stamp_id, 'x': pos_x, 'y': pos_y,
'rotation': rotation, 'depth': depth})
if cover_items:
@ -126,11 +126,11 @@ async def handle_update_book_cover(p, color: int, highlight: int, pattern: int,
if cover_stamps:
await CoverStamp.insert().values(cover_stamps).gino.status()
await p.data.update(book_color=color,
book_highlight=highlight,
book_pattern=pattern,
book_icon=icon,
book_modified=1).apply()
await p.update(book_color=color,
book_highlight=highlight,
book_pattern=pattern,
book_icon=icon,
book_modified=1).apply()
stringified_cover = '%'.join(cover)
await p.server.cache.set(f'book.{p.data.id}', f'{color}%{highlight}%{pattern}%{icon}%{stringified_cover}')
await p.server.cache.set(f'book.{p.id}', f'{color}%{highlight}%{pattern}%{icon}%{stringified_cover}')

View File

@ -6,20 +6,20 @@ from houdini.constants import ClientType
@handlers.handler(XTPacket('t', 'at'))
async def handle_open_book(p, toy_id: int):
p.toy = toy_id
await p.room.send_xt('at', p.data.id, toy_id)
await p.room.send_xt('at', p.id, toy_id)
@handlers.handler(XTPacket('t', 'rt'))
async def handle_close_book(p):
p.toy = None
await p.room.send_xt('rt', p.data.id)
await p.room.send_xt('rt', p.id)
@handlers.handler(XTPacket('j', 'jr'), client=ClientType.Legacy)
async def handle_join_room_toy(p):
for penguin in p.room.penguins_by_id.values():
if penguin.toy is not None:
await p.send_xt('at', penguin.data.id, penguin.toy)
await p.send_xt('at', penguin.id, penguin.toy)
@handlers.handler(XTPacket('j', 'crl'), client=ClientType.Vanilla)
@ -27,4 +27,4 @@ async def handle_join_room_toy(p):
async def handle_client_room_loaded_toy(p):
for penguin in p.room.penguins_by_id.values():
if penguin.toy is not None:
await p.send_xt('at', penguin.data.id, penguin.toy)
await p.send_xt('at', penguin.id, penguin.toy)

View File

@ -1,9 +1,10 @@
import time
from houdini.spheniscidae import Spheniscidae
from houdini.data import penguin
class Penguin(Spheniscidae):
class Penguin(Spheniscidae, penguin.Penguin):
__slots__ = ['x', 'y', 'frame', 'toy', 'room', 'waddle', 'table',
'data', 'muted', 'login_key', 'member', 'membership_days',
@ -22,7 +23,6 @@ class Penguin(Spheniscidae):
self.table = None
self.muted = False
self.data = None
self.login_key = None
self.member = 1
@ -61,22 +61,22 @@ class Penguin(Spheniscidae):
async def join_room(self, room):
await room.add_penguin(self)
self.logger.info(f'{self.data.username} joined room \'{room.name}\'')
self.logger.info(f'{self.username} joined room \'{room.name}\'')
async def add_inventory(self, item, notify=True):
if item.id in self.data.inventory:
if item.id in self.inventory:
return False
await self.data.inventory.insert(item_id=item.id)
await self.data.update(coins=self.data.coins - item.cost).apply()
await self.inventory.insert(item_id=item.id)
await self.update(coins=self.coins - item.cost).apply()
if notify:
await self.send_xt('ai', item.id, self.data.coins)
await self.send_xt('ai', item.id, self.coins)
self.logger.info(f'{self.data.username} added \'{item.name}\' to their clothing inventory')
self.logger.info(f'{self.username} added \'{item.name}\' to their clothing inventory')
await self.server.cache.delete(f'pins.{self.data.id}')
await self.server.cache.delete(f'awards.{self.data.id}')
await self.server.cache.delete(f'pins.{self.id}')
await self.server.cache.delete(f'awards.{self.id}')
return True
@ -84,209 +84,210 @@ class Penguin(Spheniscidae):
if not item.epf:
return False
if item.id in self.data.inventory:
if item.id in self.inventory:
return False
await self.data.inventory.insert(item_id=item.id)
await self.data.update(agent_medals=self.data.agent_medals - item.cost).apply()
await self.inventory.insert(item_id=item.id)
await self.update(agent_medals=self.agent_medals - item.cost).apply()
if notify:
await self.send_xt('epfai', self.data.agent_medals)
await self.send_xt('epfai', self.agent_medals)
return True
async def add_igloo(self, igloo, notify=True):
if igloo.id in self.data.igloos:
if igloo.id in self.igloos:
return False
await self.data.igloos.insert(igloo_id=igloo.id)
await self.data.update(coins=self.data.coins - igloo.cost).apply()
await self.igloos.insert(igloo_id=igloo.id)
await self.update(coins=self.coins - igloo.cost).apply()
if notify:
await self.send_xt('au', igloo.id, self.data.coins)
await self.send_xt('au', igloo.id, self.coins)
self.logger.info(f'{self.data.username} added \'{igloo.name}\' to their igloos inventory')
self.logger.info(f'{self.username} added \'{igloo.name}\' to their igloos inventory')
return True
async def add_puffle_item(self, care_item, quantity=1, notify=True):
if care_item.id in self.data.puffle_items:
penguin_care_item = self.data.puffle_items[care_item.id]
if care_item.id in self.puffle_items:
penguin_care_item = self.puffle_items[care_item.id]
if penguin_care_item.quantity >= 100:
return False
await penguin_care_item.update(
quantity=penguin_care_item.quantity + quantity).apply()
else:
await self.data.puffle_items.insert(item_id=care_item.id)
await self.puffle_items.insert(item_id=care_item.id)
await self.data.update(coins=self.data.coins - care_item.cost).apply()
await self.update(coins=self.coins - care_item.cost).apply()
if notify:
await self.send_xt('papi', self.data.coins, care_item.id, quantity)
await self.send_xt('papi', self.coins, care_item.id, quantity)
self.logger.info(f'{self.data.username} added \'{care_item.name}\' to their puffle care inventory')
self.logger.info(f'{self.username} added \'{care_item.name}\' to their puffle care inventory')
return True
async def add_furniture(self, furniture, quantity=1, notify=True):
if furniture.id in self.data.furniture:
penguin_furniture = self.data.furniture[furniture.id]
if furniture.id in self.furniture:
penguin_furniture = self.furniture[furniture.id]
if penguin_furniture.quantity >= furniture.max_quantity:
return False
await penguin_furniture.update(
quantity=penguin_furniture.quantity + quantity).apply()
else:
await self.data.furniture.insert(furniture_id=furniture.id)
await self.furniture.insert(furniture_id=furniture.id)
await self.data.update(coins=self.data.coins - furniture.cost).apply()
await self.update(coins=self.coins - furniture.cost).apply()
if notify:
await self.send_xt('af', furniture.id, self.data.coins)
await self.send_xt('af', furniture.id, self.coins)
self.logger.info(f'{self.data.username} added \'{furniture.name}\' to their furniture inventory')
self.logger.info(f'{self.username} added \'{furniture.name}\' to their furniture inventory')
return True
async def add_card(self, card, quantity=1):
if card.id in self.data.cards:
penguin_card = self.data.cards[card.id]
if card.id in self.cards:
penguin_card = self.cards[card.id]
await penguin_card.update(
quantity=penguin_card.quantity + quantity).apply()
else:
await self.data.cards.insert(card_id=card.id)
await self.cards.insert(card_id=card.id)
self.logger.info(f'{self.data.username} added \'{card.name}\' to their ninja deck')
self.logger.info(f'{self.username} added \'{card.name}\' to their ninja deck')
return True
async def add_flooring(self, flooring, notify=True):
if flooring.id in self.data.flooring:
if flooring.id in self.flooring:
return False
await self.data.flooring.insert(flooring_id=flooring.id)
await self.data.update(coins=self.data.coins - flooring.cost).apply()
await self.flooring.insert(flooring_id=flooring.id)
await self.update(coins=self.coins - flooring.cost).apply()
if notify:
await self.send_xt('ag', flooring.id, self.data.coins)
await self.send_xt('ag', flooring.id, self.coins)
self.logger.info(f'{self.data.username} added \'{flooring.name}\' to their flooring inventory')
self.logger.info(f'{self.username} added \'{flooring.name}\' to their flooring inventory')
return True
async def add_location(self, location, notify=True):
if location.id in self.data.locations:
if location.id in self.locations:
return False
await self.data.locations.insert(location_id=location.id)
await self.data.update(coins=self.data.coins - location.cost).apply()
await self.locations.insert(location_id=location.id)
await self.update(coins=self.coins - location.cost).apply()
if notify:
await self.send_xt('aloc', location.id, self.data.coins)
await self.send_xt('aloc', location.id, self.coins)
self.logger.info(f'{self.data.username} added \'{location.name}\' to their location inventory')
self.logger.info(f'{self.username} added \'{location.name}\' to their location inventory')
return True
async def add_stamp(self, stamp, notify=True):
if stamp.id in self.data.stamps:
if stamp.id in self.stamps:
return False
await self.data.stamps.insert(stamp_id=stamp.id)
await self.stamps.insert(stamp_id=stamp.id)
if notify:
await self.send_xt('aabs', stamp.id)
self.logger.info(f'{self.data.username} earned stamp \'{stamp.name}\'')
await self.server.cache.delete(f'stamps.{self.data.id}')
self.logger.info(f'{self.username} earned stamp \'{stamp.name}\'')
await self.server.cache.delete(f'stamps.{self.id}')
return True
async def add_inbox(self, postcard, sender_name="sys", sender_id=None, details=""):
penguin_postcard = await self.data.postcards.insert(penguin_id=self.data.id, sender_id=sender_id, postcard_id=postcard.id, details=details)
penguin_postcard = await self.postcards.insert(penguin_id=self.id, sender_id=sender_id,
postcard_id=postcard.id, details=details)
await self.send_xt('mr', sender_name, 0, postcard.id, details, int(time.time()), penguin_postcard.id)
async def add_permission(self, permission):
if permission not in self.data.permissions:
await self.data.permissions.insert(name=permission)
if permission not in self.permissions:
await self.permissions.insert(name=permission)
self.logger.info(f'{self.data.username} was assigned permission \'{permission}\'')
self.logger.info(f'{self.username} was assigned permission \'{permission}\'')
return True
async def set_color(self, item):
await self.data.update(color=item.id).apply()
await self.room.send_xt('upc', self.data.id, item.id)
self.logger.info(f'{self.data.username} updated their color to \'{item.name}\' ')
await self.update(color=item.id).apply()
await self.room.send_xt('upc', self.id, item.id)
self.logger.info(f'{self.username} updated their color to \'{item.name}\' ')
async def set_head(self, item):
item_id = None if item is None else item.id
await self.data.update(head=item_id).apply()
await self.room.send_xt('uph', self.data.id, item_id or 0)
await self.update(head=item_id).apply()
await self.room.send_xt('uph', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their head item to \'{item.name}\' ' if item else
f'{self.data.username} removed their head item')
self.logger.info(f'{self.username} updated their head item to \'{item.name}\' ' if item else
f'{self.username} removed their head item')
async def set_face(self, item):
item_id = None if item is None else item.id
await self.data.update(face=item_id).apply()
await self.room.send_xt('upf', self.data.id, item_id or 0)
await self.update(face=item_id).apply()
await self.room.send_xt('upf', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their face item to \'{item.name}\' ' if item else
f'{self.data.username} removed their face item')
self.logger.info(f'{self.username} updated their face item to \'{item.name}\' ' if item else
f'{self.username} removed their face item')
async def set_neck(self, item):
item_id = None if item is None else item.id
await self.data.update(neck=item_id).apply()
await self.room.send_xt('upn', self.data.id, item_id or 0)
await self.update(neck=item_id).apply()
await self.room.send_xt('upn', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their neck item to \'{item.name}\' ' if item else
f'{self.data.username} removed their neck item')
self.logger.info(f'{self.username} updated their neck item to \'{item.name}\' ' if item else
f'{self.username} removed their neck item')
async def set_body(self, item):
item_id = None if item is None else item.id
await self.data.update(body=item_id).apply()
await self.room.send_xt('upb', self.data.id, item_id or 0)
await self.update(body=item_id).apply()
await self.room.send_xt('upb', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their body item to \'{item.name}\' ' if item else
f'{self.data.username} removed their body item')
self.logger.info(f'{self.username} updated their body item to \'{item.name}\' ' if item else
f'{self.username} removed their body item')
async def set_hand(self, item):
item_id = None if item is None else item.id
await self.data.update(hand=item_id).apply()
await self.room.send_xt('upa', self.data.id, item_id or 0)
await self.update(hand=item_id).apply()
await self.room.send_xt('upa', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their hand item to \'{item.name}\' ' if item else
f'{self.data.username} removed their hand item')
self.logger.info(f'{self.username} updated their hand item to \'{item.name}\' ' if item else
f'{self.username} removed their hand item')
async def set_feet(self, item):
item_id = None if item is None else item.id
await self.data.update(feet=item_id).apply()
await self.room.send_xt('upe', self.data.id, item_id or 0)
await self.update(feet=item_id).apply()
await self.room.send_xt('upe', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their feet item to \'{item.name}\' ' if item else
f'{self.data.username} removed their feet item')
self.logger.info(f'{self.username} updated their feet item to \'{item.name}\' ' if item else
f'{self.username} removed their feet item')
async def set_flag(self, item):
item_id = None if item is None else item.id
await self.data.update(flag=item_id).apply()
await self.room.send_xt('upl', self.data.id, item_id or 0)
await self.update(flag=item_id).apply()
await self.room.send_xt('upl', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their flag item to \'{item.name}\' ' if item else
f'{self.data.username} removed their flag item')
self.logger.info(f'{self.username} updated their flag item to \'{item.name}\' ' if item else
f'{self.username} removed their flag item')
async def set_photo(self, item):
item_id = None if item is None else item.id
await self.data.update(photo=item_id).apply()
await self.room.send_xt('upp', self.data.id, item_id or 0)
await self.update(photo=item_id).apply()
await self.room.send_xt('upp', self.id, item_id or 0)
self.logger.info(f'{self.data.username} updated their background to \'{item.name}\' ' if item else
f'{self.data.username} removed their background item')
self.logger.info(f'{self.username} updated their background to \'{item.name}\' ' if item else
f'{self.username} removed their background item')
def __repr__(self):
if self.data is not None:
return f'<Penguin ID=\'{self.data.id}\' Username=\'{self.data.username}\'>'
if self.id is not None:
return f'<Penguin ID=\'{self.id}\' Username=\'{self.username}\'>'
return super().__repr__()