mirror of
				https://github.com/solero/houdini.git
				synced 2025-10-31 04:32:07 +00:00 
			
		
		
		
	Igloo handlers
This commit is contained in:
		| @@ -0,0 +1,491 @@ | ||||
| import itertools | ||||
| import ujson | ||||
| import time | ||||
| from datetime import datetime, timedelta | ||||
|  | ||||
| from houdini import handlers | ||||
| from houdini.handlers import XTPacket | ||||
| from houdini.converters import SeparatorConverter | ||||
| from houdini.constants import ClientType | ||||
| from houdini.handlers.play.navigation import handle_join_server | ||||
|  | ||||
| from houdini.data import db | ||||
| from houdini.data.penguin import Penguin | ||||
| from houdini.data.room import PenguinIglooRoom | ||||
| from houdini.data.igloo import IglooFurniture, IglooLike, Igloo, Furniture, Flooring, Location | ||||
|  | ||||
| from sqlalchemy.dialects.postgresql import insert | ||||
|  | ||||
| from aiocache import cached | ||||
|  | ||||
|  | ||||
| def get_layout_furniture_key(_, p, igloo_id): | ||||
|     return f'layout_furniture.{igloo_id}' | ||||
|  | ||||
|  | ||||
| def get_active_igloo_string_key(_, p, penguin_id): | ||||
|     return f'active_igloo.{penguin_id}' | ||||
|  | ||||
|  | ||||
| def get_legacy_igloo_string_key(_, p, penguin_id): | ||||
|     return f'legacy_igloo.{penguin_id}' | ||||
|  | ||||
|  | ||||
| def get_igloo_layouts_key(_, p): | ||||
|     return f'igloo_layouts.{p.data.id}' | ||||
|  | ||||
|  | ||||
| def get_layout_like_count_key(_, igloo_id): | ||||
|     return f'layout_like_count.{igloo_id}' | ||||
|  | ||||
|  | ||||
| @cached(alias='default', key_builder=get_layout_furniture_key) | ||||
| async def get_layout_furniture(p, igloo_id): | ||||
|     igloo_furniture = IglooFurniture.query.where(IglooFurniture.igloo_id == igloo_id).gino | ||||
|     async with p.server.db.transaction(): | ||||
|         furniture_string = ','.join([f'{furniture.furniture_id}|{furniture.x}|{furniture.y}|' | ||||
|                                     f'{furniture.rotation}|{furniture.frame}' | ||||
|                                      async for furniture in igloo_furniture.iterate()]) | ||||
|     return furniture_string | ||||
|  | ||||
|  | ||||
| @cached(alias='default', key_builder=get_active_igloo_string_key) | ||||
| async def get_active_igloo_string(p, penguin_id): | ||||
|     igloo = await PenguinIglooRoom.load(parent=Penguin.on(Penguin.igloo == PenguinIglooRoom.id))\ | ||||
|          .where(PenguinIglooRoom.penguin_id == penguin_id).gino.first() | ||||
|  | ||||
|     furniture_string = await get_layout_furniture(p, igloo.id) | ||||
|     like_count = await get_layout_like_count(igloo.id) | ||||
|     return f'{igloo.id}:1:0:{int(igloo.locked)}:{igloo.music}:{igloo.flooring}:' \ | ||||
|            f'{igloo.location}:{igloo.type}:{like_count}:{furniture_string}' | ||||
|  | ||||
|  | ||||
| @cached(alias='default', key_builder=get_legacy_igloo_string_key) | ||||
| async def get_legacy_igloo_string(p, penguin_id): | ||||
|     igloo = await PenguinIglooRoom.load(parent=Penguin.on(Penguin.igloo == PenguinIglooRoom.id))\ | ||||
|          .where(PenguinIglooRoom.penguin_id == penguin_id).gino.first() | ||||
|  | ||||
|     furniture_string = await get_layout_furniture(p, igloo.id) | ||||
|     return f'{igloo.type}%{igloo.music}%{igloo.flooring}%{furniture_string}' | ||||
|  | ||||
|  | ||||
| @cached(alias='default', key_builder=get_igloo_layouts_key) | ||||
| async def get_all_igloo_layouts(p): | ||||
|     layout_details = [] | ||||
|     slot = 0 | ||||
|     for igloo in p.data.igloo_rooms.values(): | ||||
|         slot += 1 | ||||
|         furniture_string = await get_layout_furniture(p, igloo.id) | ||||
|         like_count = await get_layout_like_count(igloo.id) | ||||
|         igloo_details = f'{igloo.id}:{slot}:0:{int(igloo.locked)}:{igloo.music}:{igloo.flooring}' \ | ||||
|                         f':{igloo.location}:{igloo.type}:{like_count}:{furniture_string}' | ||||
|         layout_details.append(igloo_details) | ||||
|     return '%'.join(layout_details) | ||||
|  | ||||
|  | ||||
| @cached(alias='default', key_builder=get_layout_like_count_key) | ||||
| async def get_layout_like_count(igloo_id): | ||||
|     layout_like_count = await db.select([db.func.sum(IglooLike.count)])\ | ||||
|         .where(IglooLike.igloo_id == igloo_id).gino.scalar() | ||||
|     return layout_like_count or 0 | ||||
|  | ||||
|  | ||||
| async def create_first_igloo(p, penguin_id): | ||||
|     igloo = await PenguinIglooRoom.query.where(PenguinIglooRoom.penguin_id == penguin_id).gino.scalar() | ||||
|     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.set(PenguinIglooRoom.id, penguin_id=penguin_id, type=1, | ||||
|                                                        flooring=0, location=1) | ||||
|             await penguin.data.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)\ | ||||
|                 .where(Penguin.id == penguin_id).gino.status() | ||||
|  | ||||
|  | ||||
| async def save_igloo_furniture(p, furniture_list=None): | ||||
|     await IglooFurniture.delete.where(IglooFurniture.igloo_id == p.data.igloo).gino.status() | ||||
|  | ||||
|     if furniture_list: | ||||
|         furniture_tracker = {} | ||||
|         furniture = [] | ||||
|         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: | ||||
|                 return | ||||
|  | ||||
|             if furniture_id not in furniture_tracker: | ||||
|                 furniture_tracker[furniture_id] = 0 | ||||
|             else: | ||||
|                 furniture_tracker[furniture_id] += 1 | ||||
|  | ||||
|             if furniture_tracker[furniture_id] > p.data.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, | ||||
|                 'furniture_id': furniture_id, | ||||
|                 'x': x, 'y': y, | ||||
|                 'frame': frame, | ||||
|                 'rotation': rotation | ||||
|             }) | ||||
|  | ||||
|         await IglooFurniture.insert().values(furniture).gino.status() | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'gm')) | ||||
| @handlers.cooldown(1) | ||||
| async def handle_get_igloo_details(p, penguin_id: int): | ||||
|     await create_first_igloo(p, penguin_id) | ||||
|     igloo_string_method = get_active_igloo_string if p.is_vanilla_client else get_legacy_igloo_string | ||||
|     await p.send_xt('gm', penguin_id, await igloo_string_method(p, penguin_id)) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'gail'), client=ClientType.Vanilla) | ||||
| async def handle_get_all_igloo_layouts(p): | ||||
|     await p.send_xt('gail', p.data.id, 0, await get_all_igloo_layouts(p)) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'ag')) | ||||
| async def handle_buy_flooring(p, flooring: Flooring): | ||||
|     if flooring is None: | ||||
|         return await p.send_error(402) | ||||
|  | ||||
|     if p.is_vanilla_client: | ||||
|         if flooring.id in p.data.flooring: | ||||
|             return await p.send_error(400) | ||||
|  | ||||
|         if p.data.coins < flooring.cost: | ||||
|             return await p.send_error(401) | ||||
|  | ||||
|         await p.add_flooring(flooring) | ||||
|     else: | ||||
|         igloo = p.data.igloo_rooms[p.data.igloo] | ||||
|  | ||||
|         await igloo.update(flooring=flooring.id).apply() | ||||
|         await p.data.update(coins=p.data.coins - flooring.cost).apply() | ||||
|  | ||||
|         await p.send_xt('ag', flooring.id, p.data.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}') | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'aloc'), client=ClientType.Vanilla) | ||||
| 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: | ||||
|         return await p.send_error(400) | ||||
|  | ||||
|     if p.data.coins < location.cost: | ||||
|         return await p.send_error(401) | ||||
|  | ||||
|     await p.add_location(location) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'au')) | ||||
| 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: | ||||
|         return await p.send_error(400) | ||||
|  | ||||
|     if p.data.coins < igloo.cost: | ||||
|         return await p.send_error(401) | ||||
|  | ||||
|     await p.add_igloo(igloo) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'af')) | ||||
| 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: | ||||
|         return await p.send_error(400) | ||||
|  | ||||
|     if p.data.coins < furniture.cost: | ||||
|         return await p.send_error(401) | ||||
|  | ||||
|     await p.add_furniture(furniture) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'uic'), client=ClientType.Vanilla) | ||||
| @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] | ||||
|  | ||||
|         await p.data.update(igloo=igloo_id).apply() | ||||
|         p.server.igloos_by_penguin_id[p.data.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: | ||||
|             await igloo.update( | ||||
|                 type=igloo_type_id, | ||||
|                 flooring=flooring_id, | ||||
|                 location=location_id, | ||||
|                 music=music_id | ||||
|             ).apply() | ||||
|  | ||||
|         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.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}') | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'ur'), client=ClientType.Legacy) | ||||
| @handlers.cooldown(1) | ||||
| 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}') | ||||
|  | ||||
|  | ||||
| _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] | ||||
|  | ||||
|         await p.data.update(igloo=igloo_id).apply() | ||||
|         p.server.igloos_by_penguin_id[p.data.id] = igloo | ||||
|  | ||||
|         if p.data.id in p.server.open_igloos_by_penguin_id: | ||||
|             del p.server.open_igloos_by_penguin_id[p.data.id] | ||||
|  | ||||
|         for slot in slot_summary: | ||||
|             igloo_id, locked = map(int, slot.split('|')) | ||||
|             igloo = p.data.igloo_rooms[igloo_id] | ||||
|  | ||||
|             if igloo_id == p.data.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}') | ||||
|  | ||||
|         active_igloo_string = await get_active_igloo_string(p, p.data.id) | ||||
|         await p.room.send_xt('uvi', p.data.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 not igloo.locked: | ||||
|             p.server.open_igloos_by_penguin_id[p.data.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] | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'pio'), client=ClientType.Vanilla) | ||||
| async def handle_is_player_igloo_open(p, penguin_id: int): | ||||
|     await p.send_xt('pio', int(penguin_id in p.server.open_igloos_by_penguin_id)) | ||||
|  | ||||
|  | ||||
| @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.set(PenguinIglooRoom.id, penguin_id=p.data.id, type=1, flooring=0, location=1) | ||||
|         slot_id = len(p.data.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:') | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'gili'), client=ClientType.Vanilla) | ||||
| @handlers.cooldown(1) | ||||
| async def handle_get_igloo_like_by(p, pagination_start: int, pagination_end: int): | ||||
|     if p.room.igloo: | ||||
|         like_count = await get_layout_like_count(p.room.id) | ||||
|  | ||||
|         liked_by = IglooLike.query.where(IglooLike.igloo_id == p.room.id). \ | ||||
|             limit(pagination_end - pagination_start).offset(pagination_start).gino | ||||
|  | ||||
|         async with p.server.db.transaction(): | ||||
|             like_collection = { | ||||
|                 'likedby': { | ||||
|                     'counts': { | ||||
|                         'count': like_count, | ||||
|                         'maxCount': like_count, | ||||
|                         'accumCount': like_count | ||||
|                     }, | ||||
|                     'IDs': [ | ||||
|                         { | ||||
|                             'id': like.player_id, | ||||
|                             'time': int(time.mktime(like.date.timetuple())), | ||||
|                             'count': like.count, | ||||
|                             'isFriend': like.player_id in p.data.buddies | ||||
|                         } async for like in liked_by.iterate() | ||||
|                     ] | ||||
|                 }, | ||||
|             } | ||||
|  | ||||
|         await p.send_xt('gili', p.room.id, 200, ujson.dumps(like_collection)) | ||||
|  | ||||
|  | ||||
| @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() | ||||
|  | ||||
|     time_elapsed = datetime.now() | ||||
|     if last_like is not None: | ||||
|         time_elapsed = datetime.now() - last_like | ||||
|  | ||||
|     can_like = ujson.dumps({'canLike': True, 'periodicity': 'ScheduleDaily', 'nextLike_msecs': 0}) | ||||
|  | ||||
|     if last_like is None or time_elapsed > timedelta(1): | ||||
|         await p.send_xt('cli', p.room.id, 200, can_like) | ||||
|     else: | ||||
|         next_like = int((timedelta(1) - time_elapsed).total_seconds() * 1000) | ||||
|         await p.send_xt('cli', p.room.id, 200, ujson.dumps({'canLike': False, 'periodicity': 'ScheduleDaily', | ||||
|                                                             'nextLike_msecs': next_like})) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'gr'), client=ClientType.Vanilla) | ||||
| async def handle_get_open_igloo_list(p): | ||||
|     async def get_igloo_string(igloo): | ||||
|         owner_name = p.server.penguins_by_id[igloo.penguin_id].data.nickname | ||||
|         like_count = await get_layout_like_count(igloo.id) | ||||
|         igloo_population = len(igloo.penguins_by_id) | ||||
|         return f'{igloo.penguin_id}|{owner_name}|{like_count}|{igloo_population}|{int(igloo.locked)}' | ||||
|  | ||||
|     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) | ||||
|     await p.send_xt('gr', own_layout_like_count, local_room_population, *open_igloos) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'gr'), client=ClientType.Legacy) | ||||
| async def handle_get_open_igloo_list_legacy(p): | ||||
|     if not p.server.open_igloos_by_penguin_id: | ||||
|         return await p.send_line('%xt%gr%-1%') | ||||
|  | ||||
|     async def get_igloo_string(igloo): | ||||
|         owner_name = p.server.penguins_by_id[igloo.penguin_id].data.nickname | ||||
|         return f'{igloo.penguin_id}|{owner_name}' | ||||
|  | ||||
|     open_igloos = [await get_igloo_string(igloo) for igloo in p.server.open_igloos_by_penguin_id.values()] | ||||
|     await p.send_xt('gr', *open_igloos) | ||||
|  | ||||
|  | ||||
| @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 | ||||
|  | ||||
|  | ||||
| @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] | ||||
|  | ||||
|  | ||||
| @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())) | ||||
|  | ||||
|  | ||||
| @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()) | ||||
|     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: | ||||
|         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}') | ||||
|  | ||||
|  | ||||
| @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: | ||||
|         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}') | ||||
|  | ||||
|  | ||||
| @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}' | ||||
|  | ||||
|     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] | ||||
|  | ||||
|     await p.send_xt('grf', *friend_igloos) | ||||
|  | ||||
|  | ||||
| @handlers.handler(XTPacket('g', 'li'), client=ClientType.Vanilla) | ||||
| @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 = like_insert.on_conflict_do_update( | ||||
|             constraint='igloo_like_pkey', | ||||
|             set_=dict(count=IglooLike.count + 1, date=datetime.now()), | ||||
|             where=(IglooLike.date < datetime.today()) | ||||
|         ) | ||||
|         await like_insert.gino.status() | ||||
|  | ||||
|         await p.server.cache.delete(f'layout_like_count.{p.room.id}') | ||||
|  | ||||
|         if len(p.room.penguins_by_id) > 1: | ||||
|             like_count = await get_layout_like_count(p.room.id) | ||||
|             for penguin in p.room.penguins_by_id.values(): | ||||
|                 if penguin.data.id != p.data.id: | ||||
|                     await p.send_xt('lue', p.data.id, like_count) | ||||
|  | ||||
|  | ||||
| @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()) | ||||
|  | ||||
|     await p.send_xt('gii', furniture, flooring, igloos, locations) | ||||
|   | ||||
| @@ -73,6 +73,9 @@ class Houdini: | ||||
|         self.penguins_by_username = {} | ||||
|         self.penguins_by_character_id = {} | ||||
|  | ||||
|         self.igloos_by_penguin_id = {} | ||||
|         self.open_igloos_by_penguin_id = {} | ||||
|  | ||||
|         self.xt_listeners = XTListenerManager(self) | ||||
|         self.xml_listeners = XMLListenerManager(self) | ||||
|         self.dummy_event_listeners = DummyEventListenerManager(self) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ben
					Ben