async def __handle_xt_data(self, data): self.logger.debug(f'Received XT data: {data}') parsed_data = data.split('%')[1:-1] packet_id = parsed_data[2] packet = XTPacket(packet_id, ext=parsed_data[1]) if packet in self.server.xt_listeners: xt_listeners = self.server.xt_listeners[packet] packet_data = parsed_data[4:] for listener in xt_listeners: if not self.__writer.is_closing() and listener.client_type is None \ or listener.client_type == self.client_type: await listener(self, packet_data) self.received_packets.add(packet) else: self.logger.warn('Handler for %s doesn\'t exist!', packet_id)
) server.puffle_clothing_treasure = await PuffleTreasureItem.query.gino.all() server.puffle_killer = asyncio.create_task(decrease_stats(server)) @handlers.handler(XMLPacket('login'), priority=Priority.Low) @handlers.allow_once async def load_pet_inventory(p): p.puffles = await PenguinPuffleCollection.get_collection(p.id) p.puffle_items = await PenguinPuffleItemCollection.get_collection(p.id) await p.send_xt('pgu', *get_my_player_puffles(p)) @handlers.handler(XTPacket('p', 'getdigcooldown'), pre_login=True) async def handle_get_dig_cooldown(p): last_dig = await p.server.redis.get(f'mystic.last_dig.{p.id}') if last_dig is not None: cooldown_remaining = max(0, 120 - (int(time.time()) - int(last_dig))) return await p.send_xt('getdigcooldown', cooldown_remaining) await p.send_xt('getdigcooldown', 0) @handlers.handler(XTPacket('p', 'checkpufflename')) async def handle_check_puffle_name_with_response(p, puffle_name): name_ok = check_name(p, puffle_name) await p.send_xt('checkpufflename', puffle_name, int(name_ok))
from mystic import handlers from mystic.data.buddy import IgnoreList, IgnoreListCollection from mystic.data.penguin import Penguin from mystic.handlers import Priority, XMLPacket, XTPacket @handlers.handler(XMLPacket('login'), priority=Priority.Low) @handlers.allow_once async def load_ignore_inventory(p): p.ignore = await IgnoreListCollection.get_collection(p.id) @handlers.handler(XTPacket('n', 'gn')) @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.id) async with p.server.db.transaction(): ignore_list = ignore_query.gino.iterate() ignores = [ f'{ignore.ignore_id}|{ignore.parent.safe_nickname(p.server.config.lang)}' async for ignore in ignore_list ] await p.send_xt('gn', *ignores) @handlers.handler(XTPacket('n', 'rn')) async def handle_ignore_remove(p, ignored_id: int):
async def determine_coins_overdose(p, coins): overdose_key = f'{p.id}.overdose' last_overdose = await p.server.redis.get(overdose_key) if last_overdose is None: return True minutes_since_last_dose = ((time.time() - float(last_overdose)) // 60) + 1 max_game_coins = p.server.config.max_coins_per_min * minutes_since_last_dose if coins > max_game_coins: return True return False @handlers.handler(XTPacket('j', 'jr'), before=handle_join_room) async def handle_overdose_key(p, room: Room): if p.room.game and not room.game: overdose_key = f'{p.id}.overdose' await p.server.redis.delete(overdose_key) elif room.game: overdose_key = f'{p.id}.overdose' await p.server.redis.set(overdose_key, time.time()) @handlers.disconnected @handlers.player_attribute(joined_world=True) async def disconnect_overdose_key(p): if p.room is not None and p.room.game: overdose_key = f'{p.id}.overdose' await p.server.redis.delete(overdose_key)
if ninja.penguin.fire_matches_won >= 10: await ninja.penguin.add_stamp(ninja.penguin.server.stamps[252]) if ninja.penguin.fire_matches_won >= 50: await ninja.penguin.add_stamp(ninja.penguin.server.stamps[268]) if ninja.energy >= 6: await ninja.penguin.add_stamp(ninja.penguin.server.stamps[260]) if type(ninja.penguin.waddle) == FireSenseiLogic: await ninja.penguin.add_stamp(ninja.penguin.server.stamps[264]) if ninja.energy_won >= 1: await ninja.penguin.add_stamp(ninja.penguin.server.stamps[254]) if ninja.energy_won >= 3: await ninja.penguin.add_stamp(ninja.penguin.server.stamps[266]) @handlers.handler(XTPacket('gz', ext='z')) @handlers.waddle(CardJitsuFireLogic, FireMatLogic) async def handle_get_game(p): seat_id = p.waddle.get_seat_id(p) await p.send_xt('gz', p.waddle.seats, len(p.waddle.penguins)) await p.send_xt('jz', seat_id) nicknames = ','.join(penguin.safe_name for penguin in p.waddle.penguins) colors = ','.join(str(penguin.color) for penguin in p.waddle.penguins) energy = ','.join(str(ninja.energy) for ninja in p.waddle.ninjas) tile_ids = ','.join(map(str, p.waddle.tile_ids)) deck = ','.join(str(card.id) for card in p.waddle.ninjas[seat_id].deck) spin = f'{p.waddle.spin_amount},{p.waddle.move_clockwise},{p.waddle.move_anticlockwise}' ninja_ranks = ','.join( str(penguin.fire_ninja_rank) for penguin in p.waddle.penguins)
from mystic import handlers from mystic.data import db from mystic.data.redemption import PenguinRedemptionBook, RedemptionBook, RedemptionBookWord from mystic.handlers import XTPacket @handlers.handler(XTPacket('rgbq', ext='red'), pre_login=True) @handlers.depends_on_packet(XTPacket('rjs', ext='red')) async def handle_get_book_question(p, book: int): book_exist = await RedemptionBook.query.where(RedemptionBook.id == book).gino.scalar() book_redeemed = await PenguinRedemptionBook.query.\ where((PenguinRedemptionBook.book_id == book) & (PenguinRedemptionBook.penguin_id == p.id)).gino.scalar() if not book_exist: return await p.close() if book_redeemed: return await p.close() question = await RedemptionBookWord.query.where(RedemptionBookWord.book_id == book)\ .order_by(db.func.random()).gino.first() await p.send_xt('rgbq', question.question_id, question.book_id, question.page, question.line, question.word_number) @handlers.handler(XTPacket('rsba', ext='red'), pre_login=True) @handlers.depends_on_packet(XTPacket('rgbq', ext='red')) async def handle_send_book_answer(p, book: int, question_id: int, answer: str): book_exist = await RedemptionBook.query.where(RedemptionBook.id == book).gino.scalar() book_redeemed = await PenguinRedemptionBook.query.where((PenguinRedemptionBook.book_id == book) & (PenguinRedemptionBook.penguin_id == p.id)).gino.scalar() if not book_exist:
await load_active_quests(p) async def load_active_quests(p): p.active_quests = await Quest.load( tasks=QuestTask, items=QuestAwardItem, furniture=QuestAwardFurniture, pet=QuestAwardPuffleItem, complete=PenguinQuestTask.on( (PenguinQuestTask.penguin_id == p.id) & (PenguinQuestTask.task_id == QuestTask.id) & (PenguinQuestTask.complete == False))).gino.all() @handlers.handler(XTPacket('j', 'js'), after=handle_join_server) @handlers.allow_once async def handle_quest_join_server(p): p.server.cache.delete(f'quest.status.{p.id}') await load_active_quests(p) quest_settings = p.server.cache.get(f'quest.settings.{p.room.id}') quest_status = p.server.cache.get(f'quest.status.{p.id}') quest_settings = await get_quest_settings( p) if quest_settings is None else quest_settings quest_status = await get_player_quest_status( p) if quest_status is None else quest_status p.server.cache.set(f'quest.settings.{p.room.id}', quest_settings) p.server.cache.set(f'quest.status.{p.id}', quest_status) await p.send_xt('nxquestsettings', quest_settings)
from mystic import handlers from mystic.constants import ClientType from mystic.handlers import XTPacket @handlers.handler(XTPacket('pt', 'spts'), client=ClientType.Vanilla) @handlers.cooldown(1) async def handle_player_transformation(p, transform_id: int): p.avatar = transform_id await p.room.send_xt('spts', p.id, transform_id)
async def load_inventory(p): p.inventory = await PenguinItemCollection.get_collection(p.id) p.permissions = await PenguinPermissionCollection.get_collection(p.id) p.attributes = await PenguinAttributeCollection.get_collection(p.id) if p.color is not None and p.color not in p.inventory: await p.inventory.insert(item_id=p.color) default_items = p.server.items.legacy_inventory if p.is_legacy_client else \ p.server.items.vanilla_inventory for default_item in default_items: if default_item.id not in p.inventory: await p.inventory.insert(item_id=default_item.id) @handlers.handler(XTPacket('i', 'gi')) @handlers.allow_once async def handle_get_inventory(p): await p.send_xt('gi', *p.inventory.keys()) @handlers.handler(XTPacket('i', 'ai')) @handlers.depends_on_packet(XTPacket('i', 'gi')) async def handle_buy_inventory(p, item: Item): if item is None: return await p.send_error(402) if item.id in p.inventory: return await p.send_error(400) if p.coins < item.cost:
from mystic import handlers from mystic.commands import UnknownCommandException, has_command_prefix, invoke_command_string from mystic.data.moderator import ChatFilterRuleCollection from mystic.handlers import XTPacket from mystic.handlers.play.moderation import moderator_ban @handlers.boot async def filter_load(server): server.chat_filter_words = await ChatFilterRuleCollection.get_collection() server.logger.info(f'Loaded {len(server.chat_filter_words)} filter words') @handlers.handler(XTPacket('m', 'sm')) @handlers.cooldown(.5) async def handle_send_message(p, penguin_id: int, message: str): if penguin_id != p.id: return await p.close() if p.muted: for penguin in p.room.penguins_by_id.values(): if penguin.moderator: await penguin.send_xt("mm", message, penguin_id) return if p.server.chat_filter_words: tokens = message.lower().split() consequence = next( (c for w, c in p.server.chat_filter_words.items() if w in tokens), None)
await p.locations.insert(location_id=default_item.id) default_flooring = p.server.flooring.legacy_inventory if p.is_legacy_client else \ p.server.flooring.vanilla_inventory for default_item in default_flooring: if default_item.id not in p.flooring: await p.flooring.insert(flooring_id=default_item.id) default_furniture = p.server.furniture.legacy_inventory if p.is_legacy_client else \ p.server.furniture.vanilla_inventory for default_item in default_furniture: if default_item.id not in p.furniture: await p.furniture.insert(furniture_id=default_item.id) @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) cache_key = f'active_igloo.{penguin_id}' if p.is_vanilla_client else f'legacy_igloo.{penguin_id}' igloo_string_method = get_active_igloo_string if p.is_vanilla_client else get_legacy_igloo_string igloo_string = p.server.cache.get(cache_key) igloo_string = await igloo_string_method( p, penguin_id) if igloo_string is None else igloo_string p.server.cache.set(cache_key, igloo_string) await p.send_xt('gm', penguin_id, igloo_string) @handlers.handler(XTPacket('g', 'gail'), client=ClientType.Vanilla) async def handle_get_all_igloo_layouts(p): await p.status_field_set(StatusField.OpenedIglooViewer)
@handlers.boot async def characters_load(server): server.characters = await CharacterCollection.get_collection() server.logger.info(f'Loaded {len(server.characters)} characters') @handlers.handler(XMLPacket('login'), priority=Priority.Low) @handlers.allow_once async def load_buddy_inventory(p): p.buddies = await BuddyListCollection.get_collection(p.id) p.buddy_requests = await BuddyRequestCollection.get_collection(p.id) p.character_buddies = await CharacterBuddyCollection.get_collection(p.id) @handlers.handler(XTPacket('j', 'jr'), after=handle_join_room, client=ClientType.Vanilla) async def handle_send_room_presence(p): await update_player_presence(p) @handlers.handler(XTPacket('b', 'gb'), client=ClientType.Vanilla) @handlers.allow_once async def handle_get_buddies(p): buddies_query = BuddyList.load(parent=Penguin.on( Penguin.id == BuddyList.buddy_id)).where(BuddyList.penguin_id == p.id) request_query = BuddyRequest.load(parent=Penguin.on( Penguin.id == BuddyRequest.requester_id)).where( BuddyRequest.penguin_id == p.id)
import datetime from mystic import handlers from mystic.constants import ClientType from mystic.data import db from mystic.data.moderator import Ban, Report, Warning from mystic.data.penguin import Penguin from mystic.handlers import XTPacket @handlers.handler(XTPacket('o', 'k')) async def handle_kick_player(p, penguin_id: int): if p.moderator: await moderator_kick(p, penguin_id) @handlers.handler(XTPacket('o', 'b'), client=ClientType.Legacy) async def handle_ban_player(p, penguin_id: int, message: str): if p.moderator: await moderator_ban(p, penguin_id, comment=message) @handlers.handler(XTPacket('o', 'm')) async def handle_mute_player(p, penguin_id: int): if p.moderator: if penguin_id in p.server.penguins_by_id: player = p.server.penguins_by_id[penguin_id] if not player.moderator: player.muted = True
from mystic import handlers from mystic.data import db from mystic.data.buddy import IgnoreList from mystic.data.mail import PenguinPostcard, PostcardCollection from mystic.data.penguin import Penguin from mystic.handlers import XTPacket @handlers.boot async def postcards_load(server): server.postcards = await PostcardCollection.get_collection() server.logger.info(f'Loaded {len(server.postcards)} postcards') @handlers.handler(XTPacket('l', 'mst')) @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.id ).gino.scalar() unread_mail_count = await db.select([ db.func.count(PenguinPostcard.id) ]).where((PenguinPostcard.penguin_id == p.id) & (PenguinPostcard.has_read == False)).gino.scalar() await p.send_xt('mst', unread_mail_count, mail_count) @handlers.handler(XTPacket('l', 'mg')) @handlers.allow_once async def handle_get_mail(p):
total_collected_stamps = len(collected_stamps) total_game_stamps = len(game_stamps) collected_stamps_string = '|'.join(str(stamp.id) for stamp in collected_stamps) await p.send_xt('cjsi', collected_stamps_string, total_collected_stamps, total_game_stamps) async def ninja_win(winner, loser): await ninja_progress(winner.penguin, won=True) await ninja_progress(loser.penguin, won=False) await ninja_stamps_earned(winner.penguin) await ninja_stamps_earned(loser.penguin) await winner.penguin.waddle.remove_penguin(winner.penguin) await loser.penguin.waddle.remove_penguin(loser.penguin) @handlers.handler(XTPacket('gz', ext='z')) @handlers.waddle(CardJitsuLogic, CardJitsuMatLogic) async def handle_get_game(p): seat_id = p.waddle.get_seat_id(p) await p.send_xt('gz', p.waddle.seats, len(p.waddle.penguins)) await p.send_xt('jz', seat_id, p.safe_name, p.color, p.ninja_rank) @handlers.handler(XTPacket('uz', ext='z')) @handlers.waddle(CardJitsuLogic, CardJitsuMatLogic) async def handle_update_game(p): players = [f'{seat_id}|{player.safe_name}|{player.color}|{player.ninja_rank}' for seat_id, player in enumerate(p.waddle.penguins)] await p.send_xt('uz', *players) await p.send_xt('sz')
from mystic import handlers from mystic.constants import ClientType from mystic.data.redemption import PenguinRedemptionBook from mystic.handlers import XTPacket @handlers.handler(XTPacket('rjs', ext='red'), pre_login=True, client=ClientType.Vanilla) @handlers.allow_once async def handle_join_redemption_server_vanilla(p, credentials: str, confirmation_hash: str): pid, _, username, login_key, rdnk, approved, rejected = credentials.split( '|') if login_key != p.login_key: return await p.close() tr = p.server.redis.multi_exec() tr.setex(f'{username}.lkey', p.server.config.auth_ttl, login_key) tr.setex(f'{username}.ckey', p.server.config.auth_ttl, confirmation_hash) await tr.execute() redeemed_books = await PenguinRedemptionBook.query.where( PenguinRedemptionBook.penguin_id == p.id).gino.all() await p.send_xt( 'rjs', ','.join( str(redeemed_book.book_id) for redeemed_book in redeemed_books), 'mystic', int(p.is_member))
if not membership_record.start_aware: postcards.append(dict( penguin_id=p.id, postcard_id=start_postcard, send_date=membership_record.start )) await membership_record.update(start_aware=True).apply() membership_end_date = current_timestamp if membership_active else membership_record.expires p.membership_days_total += (membership_end_date - membership_record.start).days if postcards: await PenguinPostcard.insert().values(postcards).gino.status() @handlers.handler(XTPacket('u', 'h')) @handlers.cooldown(59) async def handle_heartbeat(p): p.heartbeat = time.time() await p.send_xt('h') @handlers.handler(XTPacket('u', 'gp')) @handlers.cooldown(1) async def handle_get_player(p, penguin_id: int): player_string = p.server.cache.get(f'player.{penguin_id}') player_string = await get_player_string(p, penguin_id) if player_string is None else player_string await p.send_xt('gp', player_string) @handlers.handler(XTPacket('u', 'gmo'), client=ClientType.Vanilla)
from mystic import handlers from mystic.handlers import XTPacket @handlers.handler(XTPacket('bh', 'lnbhg')) async def handle_leave_non_blackhole_game(p): if p.room.blackhole: await p.room.leave_blackhole(p)
from mystic import handlers from mystic.constants import ClientType from mystic.handlers import XTPacket @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.id, toy_id) @handlers.handler(XTPacket('t', 'rt')) async def handle_close_book(p): p.toy = None 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.id, penguin.toy) @handlers.handler(XTPacket('j', 'crl'), client=ClientType.Vanilla) @handlers.depends_on_packet(XTPacket('j', 'jr')) 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.id, penguin.toy)
if random.randrange(4) == 0: add_note(song_time + 0.5, 0) return note_types, note_times, note_lengths @handlers.boot async def songs_load(server): server.dance_songs = await DanceSongCollection.get_collection() server.logger.info(f'Loaded {len(server.dance_songs)} dance tracks') server.dance_floor = DanceFloor(server) asyncio.create_task(server.dance_floor.start()) @handlers.handler(XTPacket('gz', ext='z')) @handlers.player_in_room(DanceFloor.DanceRoomId) async def handle_get_game(p): await p.server.dance_floor.add_penguin(p) @handlers.handler(XTPacket('zr', ext='z')) @handlers.player_in_room(DanceFloor.DanceRoomId) async def handle_get_game_again(p): await p.server.dance_floor.add_penguin(p) @handlers.handler(XTPacket('zd', ext='z')) @handlers.player_in_room(DanceFloor.DanceRoomId) async def handle_change_difficulty(p, difficulty: int): p.server.dance_floor.set_difficulty(p, difficulty)
from mystic import handlers from mystic.data.room import Room from mystic.handlers import XTPacket from mystic.handlers.play.navigation import handle_join_player_room, handle_join_room @handlers.handler(XTPacket('gw', ext='z')) async def handle_get_waddle_population(p): await p.send_xt( 'gw', '%'.join( f'{waddle.id}|{",".join(penguin.safe_name if penguin else str() for penguin in waddle.penguins)}' for waddle in p.room.waddles.values())) @handlers.handler(XTPacket('jw', ext='z')) async def handle_join_waddle(p, waddle_id: int): try: waddle = p.room.waddles[waddle_id] if waddle.game in ['card', 'water', 'fire' ] and waddle.penguins.count(None) < waddle.seats: await p.send_xt( 'gwcj', *(penguin.id for penguin in waddle.penguins if penguin is not None)) await waddle.add_penguin(p) except KeyError: p.logger.warn( f'{p.username} tried to join a waddle that doesn\'t exist')
import time from datetime import datetime, timedelta import ujson from mystic import handlers from mystic.constants import ClientType from mystic.handlers import XTPacket RainbowQuestRewards = [6158, 4809, 1560, 3159] RainbowBonusReward = 5220 RainbowQuestWait = timedelta(minutes=60) RainbowQuestWaitMember = timedelta(minutes=20) @handlers.handler(XTPacket('rpq', 'rpqtc'), client=ClientType.Vanilla) async def handle_rainbow_puffle_task_complete(p, task_id: int): current_datetime = datetime.now() current_task = await p.server.redis.get(f'mystic.rainbow_task.{p.id}') or 0 if int(current_task) < len(RainbowQuestRewards) and int( current_task) == task_id: task_completion = await p.server.redis.get( f'mystic.rainbow_completion.{p.id}') or time.time() quest_wait = RainbowQuestWaitMember if p.is_member else RainbowQuestWait if int(current_task) == 0 or current_datetime - datetime.fromtimestamp( int(task_completion)) > quest_wait: if int(task_id) == len(RainbowQuestRewards) - 1: await p.update(rainbow_adoptability=True).apply()
self.payouts = [20, 10, 5, 5] async def remove_penguin(self, p): await super().remove_penguin(p) await self.send_xt( 'uz', self.seats, *(f'{penguin.safe_name}|{penguin.color}|' f'{penguin.hand}|{penguin.safe_name}' for penguin in self.penguins)) def get_payout(self): return self.payouts.pop(0) @handlers.handler(XTPacket('jz', ext='z')) @handlers.waddle(SledRacingLogic) async def handle_join_game(p): await p.send_xt( 'uz', p.waddle.seats, *(f'{penguin.safe_name}|{penguin.color}|' f'{penguin.hand or 0}|{penguin.nickname}' for penguin in p.waddle.penguins)) @handlers.handler(XTPacket('zm', ext='z')) @handlers.waddle(SledRacingLogic) async def handle_send_move(p, player_id: int, x: float, y: float, time: float): await p.waddle.send_xt('zm', player_id, x, y, time)
import ujson from mystic import handlers from mystic.handlers import XTPacket DefaultPartyCookie = { 'msgViewedArray': [0] * 10, 'communicatorMsgArray': [0] * 5, 'questTaskStatus': [0] * 10 } @handlers.handler(XTPacket('party', 'partycookie')) async def handle_party_cookie(p): cookie = await p.server.redis.hget('partycookie', p.id) if cookie is None: cookie = ujson.dumps(DefaultPartyCookie) await p.server.redis.hset('partycookie', p.id, cookie) else: cookie = cookie.decode('utf-8') await p.send_xt('partycookie', cookie) @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.id) cookie = ujson.loads(cookie) cookie['msgViewedArray'][message_index] = 1
from mystic import handlers from mystic.handlers import XTPacket from mystic.data.penguin import Penguin @handlers.handler(XTPacket('ni', 'gnr')) async def handle_get_ninja_ranks(p, penguin_id: int): if penguin_id in p.server.penguins_by_id: penguin = p.server.penguins_by_id[penguin_id] ninja_rank, fire_ninja_rank, water_ninja_rank = \ penguin.ninja_rank, penguin.fire_ninja_rank, penguin.water_ninja_rank else: ninja_rank, fire_ninja_rank, water_ninja_rank = await Penguin.select( 'ninja_rank', 'fire_ninja_rank', 'water_ninja_rank').where(Penguin.id == penguin_id).gino.first() await p.send_xt('gnr', p.id, ninja_rank, fire_ninja_rank, water_ninja_rank, 0) @handlers.handler(XTPacket('ni', 'gnl')) async def handle_get_ninja_level(p): await p.send_xt('gnl', p.ninja_rank, p.ninja_progress, 10) @handlers.handler(XTPacket('ni', 'gfl')) async def handle_get_fire_level(p): await p.send_xt('gfl', p.fire_ninja_rank, p.fire_ninja_progress, 5) @handlers.handler(XTPacket('ni', 'gwl')) async def handle_get_water_level(p):
card_color_tick, card_fire_matched, match_by='fire_ninja_rank', max_players=4) server.water_match_making = MatchMaking(server, card_color_tick, card_water_matched, match_by='water_ninja_rank', max_players=4) asyncio.create_task(server.match_making.start()) asyncio.create_task(server.fire_match_making.start()) asyncio.create_task(server.water_match_making.start()) @handlers.handler(XTPacket('jmm', ext='z')) @handlers.player_in_room(MatchMaking.SenseiRoom) async def handle_join_match_making(p): p.server.match_making.add_penguin(p) await p.send_xt('jmm', p.safe_name) @handlers.handler(XTPacket('jmm', ext='z')) @handlers.player_in_room(MatchMaking.SenseiFireRoom) async def handle_join_fire_match_making(p): p.server.fire_match_making.add_penguin(p) await p.send_xt('jmm', p.safe_name) @handlers.handler(XTPacket('jmm', ext='z')) @handlers.player_in_room(MatchMaking.SenseiWaterRoom)
def determine_song_length(track_pattern): if track_pattern == '0': return 0 track_length = track_pattern.split(',')[-1] track_length = track_length.split('|')[1] return int(track_length, 16) // 1000 @handlers.boot async def music_service_start(server): server.music = SoundStudio(server) @handlers.handler(XTPacket('musictrack', 'broadcastingmusictracks'), client=ClientType.Vanilla) @handlers.player_in_room(SoundStudio.StudioRoomId) async def handle_broadcasting_tracks(p): if not p.server.music.broadcasting: await p.server.music.start_broadcasting() elif not p.server.music.playlist: await p.send_xt('broadcastingmusictracks', 0, -1, '') else: playlist_position = get_playlist_position(p) broadcasted_tracks = await p.server.music.get_broadcasted_tracks() await p.send_xt('broadcastingmusictracks', len(p.server.music.playlist), playlist_position, broadcasted_tracks) @handlers.handler(XTPacket('musictrack', 'getmymusictracks'), client=ClientType.Vanilla) async def handle_get_my_music_tracks(p):
server.cards = await CardCollection.get_collection() server.logger.info(f'Loaded {len(server.cards)} ninja cards') starter_deck_cards = await CardStarterDeck.query.gino.all() server.cards.set_starter_decks(starter_deck_cards) server.logger.info( f'Loaded {len(server.cards.starter_decks)} starter decks') @handlers.handler(XMLPacket('login'), priority=Priority.Low) @handlers.allow_once async def load_card_inventory(p): p.cards = await PenguinCardCollection.get_collection(p.id) @handlers.handler(XTPacket('i', 'ai')) async def handle_buy_starter_deck(p, deck_id: int): if deck_id in p.server.cards.starter_decks: starter_deck = p.server.cards.starter_decks[deck_id] power_cards = [card for card, qty in starter_deck if card.power_id > 0] for card, qty in starter_deck: if card.power_id == 0: await p.add_card(card, quantity=qty) power_card = random.choice(power_cards) await p.add_card(power_card, quantity=1) @handlers.handler(XTPacket('cd', 'gcd')) async def handle_get_card_data(p): await p.send_xt( 'gcd',
if self.timer < 1: self.timer_task.cancel() self.started = True await self.player_initiate() self.velocity_loop = asyncio.create_task( self.set_velocity()) self.sensei_loop = asyncio.create_task(self.sensei_ai()) elif self.timer < 0: await self.send_zm("ge") await self.game_over() await asyncio.sleep(1) except asyncio.CancelledError: pass @handlers.handler(XTPacket('gz', ext='z')) @handlers.waddle(CardJitsuWaterLogic, WaterMatLogic) async def handle_get_game(p): seat_id = p.waddle.get_seat_id(p) ninja = p.waddle.get_ninja_by_penguin(p) await p.send_xt('gz') await p.send_xt('jz') await p.waddle.send_zm_client(ninja, "po", seat_id) ninja.joined = True if all(map(lambda ninja: ninja.joined, p.waddle.ninjas)): await p.waddle.initiate_vector() await p.waddle.initiate_player_cards() @handlers.handler(XTPacket('gz', ext='z')) @handlers.waddle(WaterSenseiLogic)
from mystic import handlers from mystic.handlers import XTPacket from mystic.handlers.play.navigation import handle_join_player_room, handle_join_room @handlers.handler(XTPacket('a', 'gt')) async def handle_get_waddle_population(p): await p.send_xt( 'gt', '%'.join( f'{table.id}|{",".join(penguin.safe_name for penguin in table.penguins)}' for table in p.room.tables.values())) @handlers.handler(XTPacket('a', 'jt')) async def handle_join_table(p, table_id: int): try: table = p.room.tables[table_id] await table.add_penguin(p) except KeyError: p.logger.warn( f'{p.username} tried to join a table that doesn\'t exist') @handlers.handler(XTPacket('a', 'lt')) async def handle_leave_table(p): if p.table: await p.table.remove_penguin(p) @handlers.handler(XTPacket('j', 'jr'), after=handle_join_room) async def handle_join_room_table(p):