class Filters(IPlugin): author = "Snipe" description = "Word Filter" version = "1" def __init__(self, server): super().__init__(server) async def ready(self): self.server.logger.info('Word Filters Loaded!') @handlers.handler(XTPacket('m', 'sm')) async def handle_send_message(self, p, penguin_id: int, message: str): # Use regular expressions to look for patterns in the words and make it case insensitive. if re.findall(r"(?!(" + '|'.join(allowedwords) + r"))" r"(\b(?=(" + '|'.join(bannedwords) + r"))\b)", message, flags=re.IGNORECASE): print(f"Successfully filtered bad word! Message: {message}") await p.room.send_xt('mm', message, p.id, f=lambda px: px.moderator) await moderator_kick(p, p.id) else: return
class SwearFilter(IPlugin): author = "Allinol" description = "Perspective API Plugin" version = "1" def __init__(self, server): super().__init__(server) async def ready(self): self.server.logger.info('PerspectiveAPI Filter Ready!') async def get_toxicity(self, message): if not API_ACTIVE: self.server.logger.info("Perspective API not active. Message not filtered.") return 0 try: analyze_request = { 'comment': { 'text': message }, 'requestedAttributes': { TOXIC_FILTER: {} }, 'languages': 'en' #english is the default language you can change this to french(fr), spanish(es), german(de) , portuguese(pt) and italy(it) } async with aiohttp.ClientSession() as session: async with session.post(f'https://commentanalyzer.googleapis.com/v1alpha1/comments:analyze?key={PERSPECTIVE_API_KEY}', json = analyze_request) as resp: response = await resp.json() toxicity = round(100 * float(response['attributeScores'][TOXIC_FILTER]['summaryScore']['value'])) self.server.logger.info(f'Toxicity {toxicity}. Message {message}') return toxicity except Exception as e: self.server.logger.info(f'Error, {e}') self.server.logger.info("Unable to filter message via Perspective API. Message not filtered.") return 0 @handlers.handler(XTPacket('m', 'sm')) async def handle_send_message(self, p, penguin_id: int, message: str): toxic = await self.get_toxicity(message) if toxic > TOXICITY_FILTER: await p.room.send_xt('mm', message, p.id, f=lambda px: px.moderator) await moderator_ban(p, p.id, comment='Inappropriate language', message=message) await p.close() else: return
async def __handle_xt_data(self, data): self.logger.debug('Received XT data: %s', data) parsed_data = data.split('%')[1:-1] packet_id = parsed_data[2] packet = XTPacket(packet_id) 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 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)
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)
class Example(IPlugin): author = "Allinol" description = "Commands Plugin" version = "1.0.0" def __init__(self, server): super().__init__(server) async def ready(self): self.server.logger.info('Commands.ready()') print(f'hello') async def message_cooling(self, p): print(f'{p}, Message was sent during cooldown') @handlers.handler(XTPacket('m', 'sm')) @handlers.cooldown(1, callback=message_cooling) async def handle_send_message(self, p, penguin_id: int, message: str): print(f'Do stuff with {message}') @commands.command('ping') async def ping(self, p): await p.send_xt('cprompt', 'Pong') @commands.command('ac') async def add_coins(self, p, amount: int = 100): await p.add_coins(amount, stay=True) @commands.command('ai') async def add_inventory(self, p, item: int): await p.add_inventory(p.server.items[item], notify=True, cost=0) @commands.command('af') async def add_furniture(self, p, furniture: int): await p.add_furniture(p.server.furniture[furniture], notify=True, cost=0) @commands.command('jr') async def join_room(self, p, room_id: int): await p.join_room(p.server.rooms[room_id])
class Example(IPlugin): author = "Ben" description = "Example plugin for developers" version = "1.0.0" def __init__(self, server): super().__init__(server) async def ready(self): self.server.logger.info('Example.ready()') await self.server.permissions.register('houdini.ping') async def message_cooling(self, p): print("{}, Message was sent during cooldown".format(p)) @handlers.handler(XTPacket('m', 'sm')) @handlers.cooldown(1, callback=message_cooling) async def handle_send_message(self, p, penguin_id: int, message: str): print('Do stuff with {}'.format(message)) @commands.command('ping') @permissions.has('houdini.ping') async def ping(self, p): await p.send_xt('cprompt', 'Pong')
from houdini.handlers import XTPacket from houdini.handlers.play.mail import handle_start_mail_engine async def get_com_messages(p): async with p.server.db.transaction(): messages = [] async for message in EpfComMessage.query.order_by( EpfComMessage.date.desc()).gino.iterate(): messages.append( f'{message.message}|{int(time.mktime(message.date.timetuple()))}|{message.character_id}' ) return '%'.join(messages) @handlers.handler(XTPacket('l', 'mst'), before=handle_start_mail_engine) async def handle_send_job_mail(p): postcards = [] if p.is_legacy_client and not p.agent_status and random.random() < 0.1: epf_invited = await PenguinPostcard.query.where( (PenguinPostcard.penguin_id == p.id) & ((PenguinPostcard.postcard_id == 112) | (PenguinPostcard.postcard_id == 47))).gino.scalar() if not epf_invited: postcards.append({'penguin_id': p.id, 'postcard_id': 112}) 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)
from houdini import handlers from houdini.data import db from houdini.data.buddy import IgnoreList from houdini.data.mail import PenguinPostcard, PostcardCollection from houdini.data.penguin import Penguin from houdini.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):
from houdini import handlers from houdini.constants import ClientType from houdini.data.redemption import PenguinRedemptionBook from houdini.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), 'houdini', int(p.is_member))
from houdini.data.igloo import Furniture, Igloo from houdini.data.item import Item from houdini.data.redemption import PenguinRedemptionCode, RedemptionAwardCard, \ RedemptionAwardFlooring, RedemptionAwardFurniture, RedemptionAwardIgloo, RedemptionAwardItem, \ RedemptionAwardLocation, RedemptionAwardPuffle, RedemptionAwardPuffleItem, RedemptionCode from houdini.handlers import XTPacket from houdini.handlers.games.ninja.card import ninja_rank_up TreasureUnlockCount = 3 NinjaRankUpChoice = 1 FireNinjaRankUpChoice = 3 WaterNinjaRankUpChoice = 4 SnowNinjaRankUpChoice = 5 @handlers.handler(XTPacket('rsc', ext='red'), pre_login=True, client=ClientType.Legacy) @handlers.depends_on_packet(XTPacket('rjs', ext='red')) async def handle_code_legacy(p, redemption_code: str): query = RedemptionCode.distinct(RedemptionCode.id)\ .load(cards=RedemptionAwardCard.distinct(RedemptionAwardCard.card_id), items=RedemptionAwardItem.distinct(RedemptionAwardItem.item_id))\ .query.where(RedemptionCode.code == redemption_code) codes = await query.gino.all() if not codes: return await p.send_error(720) code = codes[0] awards = []
from houdini import handlers from houdini.handlers import XTPacket 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(): 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()): 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()): 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()):
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)
from houdini.data.redemption import PenguinRedemptionCode, RedemptionAwardCard, \ RedemptionAwardFlooring, RedemptionAwardFurniture, RedemptionAwardIgloo, RedemptionAwardItem, \ RedemptionAwardLocation, RedemptionAwardPuffle, RedemptionAwardPuffleItem, RedemptionCode from houdini.handlers import XTPacket from houdini.handlers.games.ninja.card import ninja_rank_up from houdini.handlers.games.ninja.fire import fire_ninja_rank_up TreasureUnlockCount = 3 NinjaRankUpChoice = 1 FireNinjaRankUpChoice = 3 WaterNinjaRankUpChoice = 4 SnowNinjaRankUpChoice = 5 @handlers.handler(XTPacket('rsc', ext='red'), pre_login=True, client=ClientType.Legacy) @handlers.depends_on_packet(XTPacket('rjs', ext='red')) async def handle_code_legacy(p, redemption_code: str): query = RedemptionCode.distinct(RedemptionCode.id)\ .load(cards=RedemptionAwardCard.distinct(RedemptionAwardCard.card_id), items=RedemptionAwardItem.distinct(RedemptionAwardItem.item_id))\ .query.where(RedemptionCode.code == redemption_code) codes = await query.gino.all() if not codes: return await p.send_error(720) code = codes[0] awards = [] if code.uses is not None: redeemed_count = await db.select([db.func.count(PenguinRedemptionCode.code_id)]).where(
waddle.room = room_collection[waddle.room_id] waddle.logic = WaddleLogicMapping[waddle.game] waddle.penguins = [None] * waddle.seats @handlers.boot async def rooms_load(server): server.rooms = await RoomCollection.get_collection() await setup_tables(server.rooms) await setup_waddles(server.rooms) server.logger.info( f'Loaded {len(server.rooms)} rooms ({len(server.rooms.spawn_rooms)} spawn)' ) @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.id: return await p.close() if login_key != p.login_key: return await p.close() await p.send_xt('activefeatures') 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.agent_status), int(0), moderator_status, int(p.book_modified))
from houdini import handlers from houdini.handlers import XTPacket from houdini.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):
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 houdini import handlers from houdini.data import db from houdini.data.redemption import PenguinRedemptionBook, RedemptionBook, RedemptionBookWord from houdini.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()
import datetime from houdini import handlers from houdini.constants import ClientType from houdini.data import db from houdini.data.moderator import Ban, Report, Warning from houdini.data.penguin import Penguin from houdini.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
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',
buddy = p.server.penguins_by_id[buddy_id] await p.send_xt('bon', buddy.data.id, p.server.server_config['Id'], buddy.room.id) await buddy.send_xt('bon', p.data.id, p.server.server_config['Id'], p.room.id) for character_id in p.data.character_buddies.keys(): if character_id in p.server.penguins_by_character_id: character = p.server.penguins_by_character_id[character_id] await p.send_xt('caon', character_id, p.server.server_config['Id'], character.room.id) if p.data.character is not None: for penguin in p.server.penguins_by_id.values(): if p.data.character in penguin.data.character_buddies: await penguin.send_xt('caon', p.data.character, p.server.server_config['Id'], p.room.id) @handlers.handler(XTPacket('j', 'jr'), after=handle_join_room, client=ClientType.Vanilla) async def handle_send_room_presence(p): await update_player_presence(p) @handlers.handler(XTPacket('b', 'gb'), client=ClientType.Vanilla) @handlers.allow_once async def handle_get_buddies(p): buddies_query = BuddyList.load(parent=Penguin.on(Penguin.id == BuddyList.buddy_id)).where( BuddyList.penguin_id == p.data.id) request_query = BuddyRequest.load(parent=Penguin.on(Penguin.id == BuddyRequest.requester_id)).where( BuddyRequest.penguin_id == p.data.id) buddies = [] best_buddies = [] characters = []
from houdini import handlers from houdini.handlers import XTPacket from houdini.constants import ClientType @handlers.handler(XTPacket('p', 'getdigcooldown'), pre_login=True) async def handle_get_dig_cooldown(p): await p.send_xt('getdigcooldown', 1) @handlers.handler(XTPacket('p', 'checkpufflename')) async def handle_check_puffle_name_with_response(p, puffle_name): name_ok = puffle_name.isalnum() await p.send_xt('checkpufflename', puffle_name, int(name_ok)) @handlers.handler(XTPacket('p', 'pg'), client=ClientType.Vanilla) async def handle_get_player_puffles(p, penguin_id: int, room_type: str): await p.send_xt('pg') @handlers.handler(XTPacket('p', 'pg'), client=ClientType.Legacy) async def handle_get_player_puffles_legacy(p, penguin_id: int): await p.send_xt('pg')
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)
import ujson from houdini import handlers from houdini.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
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')
treasure_row, treasure_col = self.get_gem_by_piece(row, column) treasure, digs = self.treasure_map[treasure_row][treasure_col] if self.is_gem_uncovered(treasure_row, treasure_col): if treasure == 2: self.gems_found += 1 elif treasure == 4: self.emerald_found = 1 def determine_winnings(self): total = self.coins_found * self.coin_value total += self.gems_found * self.gem_value total += self.emerald_found * self.emerald_value return total @handlers.handler(XTPacket('gz', ext='z')) @handlers.table(TreasureHuntLogic) async def handle_get_game(p): if len(p.table.penguins) == 2: player_one = p.table.penguins[0] await p.send_xt('gz', player_one.safe_name, str()) else: await p.send_xt('gz', p.table.get_string()) @handlers.handler(XTPacket('jz', ext='z')) @handlers.table(TreasureHuntLogic) async def handle_join_game(p): game_full = len(p.table.penguins) > 2 if not game_full: seat_id = p.table.get_seat_id(p)
) return '%'.join(map(str, cover_details)) @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 else: stamp_inventory = await PenguinStampCollection.get_collection(player_id ) return '|'.join(map(str, stamp_inventory.keys())) @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)) @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)) @handlers.handler(XTPacket('st', 'gmres')) @handlers.cooldown(1)
from houdini import handlers from houdini.commands import has_command_prefix, invoke_command_string from houdini.data.moderator import ChatFilterRuleCollection from houdini.handlers import XTPacket from houdini.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) if consequence is not None:
from houdini import handlers from houdini.data.room import Room from houdini.handlers import XTPacket from houdini.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] await waddle.add_penguin(p) except KeyError: p.logger.warn(f'{p.username} tried to join a waddle that doesn\'t exist') @handlers.handler(XTPacket('lw', ext='z')) async def handle_leave_waddle(p): if p.waddle: await p.waddle.remove_penguin(p) @handlers.handler(XTPacket('w', 'jx')) async def handle_start_waddle(p, room: Room, waddle: int): await room.waddles[waddle].add_penguin(p)
from houdini import handlers from houdini.handlers import XTPacket from houdini.data import db from houdini.data.penguin import Penguin from houdini.data.buddy import IgnoreList from houdini.data.mail import PenguinPostcard import time @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.data.id).gino.scalar() unread_mail_count = await db.select([db.func.count(PenguinPostcard.id)]).where( (PenguinPostcard.penguin_id == p.data.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): mail_query = PenguinPostcard.load(parent=Penguin.on(Penguin.id == PenguinPostcard.sender_id)).where( PenguinPostcard.penguin_id == p.data.id).order_by( PenguinPostcard.send_date.desc()) postcards = [] async with p.server.db.transaction():
import random from houdini import handlers from houdini.data.penguin import Penguin from houdini.handlers import XTPacket @handlers.handler(XTPacket('r', 'cdu')) @handlers.cooldown(1) async def handle_get_coin_reward(p): if random.random() < 0.3: coins = random.choice([1, 2, 5, 10, 20, 50, 100]) await p.update(coins=Penguin.coins + coins).apply() await p.send_xt('cdu', coins, p.coins)