mirror of
				https://github.com/solero/houdini.git
				synced 2025-10-31 04:32:07 +00:00 
			
		
		
		
	Make houdini.penguin.Penguin inherit houdini.data.penguin.Penguin
This allows for much clearer syntax
This commit is contained in:
		| @@ -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'), | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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') | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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')) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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}') | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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__() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ben
					Ben