mirror of
https://github.com/solero/houdini.git
synced 2025-04-24 23:56:25 +00:00
147 lines
5.5 KiB
Python
147 lines
5.5 KiB
Python
import random
|
|
import time
|
|
|
|
from sqlalchemy.dialects.postgresql import insert
|
|
|
|
from houdini import handlers
|
|
from houdini.constants import ClientType
|
|
from houdini.converters import OptionalConverter
|
|
from houdini.data.game import PenguinGameData
|
|
from houdini.data.room import Room
|
|
from houdini.handlers import XTPacket
|
|
from houdini.handlers.play.moderation import cheat_ban
|
|
from houdini.handlers.play.navigation import handle_join_room
|
|
|
|
default_score_games = {904, 905, 906, 912, 916, 917, 918, 919, 950, 952}
|
|
|
|
|
|
def determine_coins_earned(p, score):
|
|
return score if p.room.id in default_score_games else score // 10
|
|
|
|
|
|
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)
|
|
|
|
|
|
async def game_over_cooling(p):
|
|
await p.send_xt('zo', p.coins, '', 0, 0, 0)
|
|
|
|
|
|
@handlers.handler(XTPacket('m', ext='z'))
|
|
@handlers.player_in_room(802)
|
|
async def handle_send_move_puck(p, _, x: int, y: int, speed_x: int, speed_y: int):
|
|
p.server.puck = (x, y)
|
|
await p.room.send_xt('zm', p.id, x, y, speed_x, speed_y)
|
|
|
|
|
|
@handlers.handler(XTPacket('gz', ext='z'))
|
|
@handlers.player_in_room(802)
|
|
async def handle_get_puck(p):
|
|
await p.send_xt('gz', *p.server.puck)
|
|
|
|
|
|
@handlers.handler(XTPacket('zo', ext='z'))
|
|
@handlers.cooldown(10, callback=game_over_cooling)
|
|
async def handle_get_game_over(p, score: int):
|
|
# If the room is Card Jitsu Snow, it this should do nothing
|
|
if p.room.id == 996:
|
|
return
|
|
|
|
if p.room.game and not p.waddle and not p.table:
|
|
coins_earned = determine_coins_earned(p, score)
|
|
if await determine_coins_overdose(p, coins_earned):
|
|
return await cheat_ban(p, p.id, comment='Coins overdose')
|
|
|
|
collected_stamps_string, total_collected_stamps, total_game_stamps, total_stamps = '', 0, 0, 0
|
|
if p.room.stamp_group:
|
|
game_stamps = [stamp for stamp in p.server.stamps.values() if stamp.group_id == p.room.stamp_group]
|
|
collected_stamps = [stamp for stamp in game_stamps if stamp.id in p.stamps]
|
|
|
|
total_stamps = len([stamp for stamp in p.stamps.values() if p.server.stamps[stamp.stamp_id].group_id])
|
|
total_collected_stamps = len(collected_stamps)
|
|
total_game_stamps = len(game_stamps)
|
|
collected_stamps_string = '|'.join(str(stamp.id) for stamp in collected_stamps)
|
|
|
|
if total_collected_stamps == total_game_stamps:
|
|
coins_earned *= 2
|
|
|
|
await p.update(coins=min(p.coins + coins_earned, p.server.config.max_coins)).apply()
|
|
await p.send_xt('zo', p.coins,
|
|
collected_stamps_string,
|
|
total_collected_stamps,
|
|
total_game_stamps,
|
|
total_stamps)
|
|
|
|
|
|
@handlers.handler(XTPacket('ggd', ext='z'), client=ClientType.Vanilla)
|
|
async def handle_get_game_data(p, index: int = 0):
|
|
game_data = await PenguinGameData.select('data').where((PenguinGameData.penguin_id == p.id) &
|
|
(PenguinGameData.room_id == p.room.id) &
|
|
(PenguinGameData.index == index)).gino.scalar()
|
|
await p.send_xt('ggd', game_data or '')
|
|
|
|
|
|
@handlers.handler(XTPacket('sgd', ext='z'), client=ClientType.Vanilla)
|
|
@handlers.cooldown(5)
|
|
async def handle_set_game_data(p, index: OptionalConverter(int) = 0, *, game_data: str):
|
|
if p.room.game:
|
|
data_insert = insert(PenguinGameData).values(penguin_id=p.id, room_id=p.room.id, index=index, data=game_data)
|
|
data_insert = data_insert.on_conflict_do_update(
|
|
constraint='penguin_game_data_pkey',
|
|
set_=dict(data=game_data),
|
|
where=((PenguinGameData.penguin_id == p.id)
|
|
& (PenguinGameData.room_id == p.room.id)
|
|
& (PenguinGameData.index == index))
|
|
)
|
|
|
|
await data_insert.gino.scalar()
|
|
|
|
|
|
@handlers.handler(XTPacket('zr', ext='z'), client=ClientType.Vanilla)
|
|
@handlers.player_attribute(agent_status=True)
|
|
async def handle_get_game_again(p):
|
|
games = list(range(1, 11))
|
|
|
|
games_string = f'{games.pop(random.randrange(len(games)))},' \
|
|
f'{games.pop(random.randrange(len(games)))},' \
|
|
f'{games.pop(random.randrange(len(games)))}'
|
|
await p.send_xt('zr', games_string, random.randint(1, 6))
|
|
|
|
|
|
@handlers.handler(XTPacket('zc', ext='z'), client=ClientType.Vanilla)
|
|
@handlers.player_attribute(agent_status=True)
|
|
@handlers.cooldown(5)
|
|
async def handle_game_complete(p, medals: int):
|
|
medals = min(6, medals)
|
|
await p.update(career_medals=p.career_medals + medals,
|
|
agent_medals=p.agent_medals + medals).apply()
|