Implement egg-timer for legacy and vanilla clients

This commit is contained in:
Ben 2019-09-09 22:26:11 +01:00
parent 2ecd9f1850
commit 1c03374bd8
7 changed files with 68 additions and 5 deletions

View File

@ -500,6 +500,8 @@ CREATE TABLE penguin (
timer_active BOOLEAN NOT NULL DEFAULT FALSE,
timer_start TIME NOT NULL DEFAULT '00:00:00',
timer_end TIME NOT NULL DEFAULT '23:59:59',
timer_total INTERVAL NOT NULL DEFAULT '01:00:00',
grounded BOOLEAN NOT NULL DEFAULT FALSE,
approval_en BOOLEAN NOT NULL DEFAULT FALSE,
approval_pt BOOLEAN NOT NULL DEFAULT FALSE,
approval_fr BOOLEAN NOT NULL DEFAULT FALSE,
@ -587,6 +589,8 @@ COMMENT ON COLUMN penguin.status_field IS 'New player status field';
COMMENT ON COLUMN penguin.timer_active IS 'Is egg-timer active?';
COMMENT ON COLUMN penguin.timer_start IS 'Egg-timer start time';
COMMENT ON COLUMN penguin.timer_end IS 'Egg-timer end time';
COMMENT ON COLUMN penguin.timer_total IS 'Egg-timer total play time';
COMMENT ON COLUMN penguin.grounded IS 'Is player grounded?';
COMMENT ON COLUMN penguin.approval_en IS 'English username approval';
COMMENT ON COLUMN penguin.approval_pt IS 'Portuguese username approval';
COMMENT ON COLUMN penguin.approval_fr IS 'French username approval';

View File

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, date
from houdini.data import db
@ -72,6 +72,7 @@ class Penguin(db.Model):
timer_active = db.Column(db.Boolean, nullable=False, server_default=db.text("false"))
timer_start = db.Column(db.Time, nullable=False, server_default=db.text("'00:00:00'::time without time zone"))
timer_end = db.Column(db.Time, nullable=False, server_default=db.text("'23:59:59'::time without time zone"))
timer_total = db.Column(db.Interval, nullable=False, server_default=db.text("'01:00:00'::interval"))
grounded = db.Column(db.Boolean, nullable=False, server_default=db.text("false"))
approval_en = db.Column(db.Boolean, nullable=False, server_default=db.text("false"))
approval_pt = db.Column(db.Boolean, nullable=False, server_default=db.text("false"))

View File

@ -11,7 +11,7 @@ import asyncio
import bcrypt
import os
from datetime import datetime
from datetime import datetime, timedelta
@handlers.handler(XMLPacket('login'))
@ -73,6 +73,14 @@ async def handle_login(p, credentials: Credentials):
if data.grounded:
return await p.send_error_and_disconnect(913)
if data.timer_active:
if not data.timer_start < datetime.now().time() < data.timer_end:
return await p.send_error_and_disconnect(911, data.timer_start, data.timer_end)
if await data.minutes_played_today >= data.timer_total.total_seconds() // 60:
return await p.send_error_and_disconnect(910, data.timer_total)
active_ban = await Ban.query.where(Ban.penguin_id == data.id and Ban.expires >= datetime.now()).gino.first()
if active_ban is not None:

View File

@ -1,9 +1,11 @@
from houdini import handlers
from houdini.handlers import XTPacket
from houdini.data.room import Room
from houdini.data.penguin import Login
import random
import time
from datetime import datetime
@handlers.handler(XTPacket('j', 'js'), pre_login=True)
@ -26,7 +28,17 @@ async def handle_join_server(p, penguin_id: int, login_key: str):
penguin_standard_time = current_time * 1000
server_time_offset = 7
await p.send_xt('lp', await p.string, p.data.coins, int(p.data.safe_chat), 1440,
if p.data.timer_active:
minutes_until_timer_end = datetime.combine(datetime.today(), p.data.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
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)

View File

@ -45,6 +45,37 @@ async def server_heartbeat(server):
for penguin in server.penguins_by_id.values():
if penguin.heartbeat < timer:
await penguin.close()
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:
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()
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)
elif p.egg_timer_minutes == 5:
await p.send_error(915, p.egg_timer_minutes, p.data.timer_start, p.data.timer_end)
else:
if p.egg_timer_minutes == 7:
await p.send_error(914, p.egg_timer_minutes, p.data.timer_total)
elif p.egg_timer_minutes == 5:
await p.send_error(914, p.egg_timer_minutes, p.data.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)
else:
if p.egg_timer_minutes <= 0:
await p.send_error_and_disconnect(910)
@handlers.handler(XTPacket('u', 'h'))
@handlers.cooldown(59)
async def handle_heartbeat(p):

View File

@ -40,6 +40,7 @@ from houdini.plugins import PluginManager
from houdini.commands import CommandManager
from houdini.handlers.play.player import server_heartbeat
from houdini.handlers.play.player import server_egg_timer
class Houdini:
@ -93,6 +94,7 @@ class Houdini:
self.spawn_rooms = None
self.heartbeat = None
self.egg_timer = None
async def start(self):
self.config = config
@ -228,6 +230,8 @@ class Houdini:
await self.plugins.setup(houdini.plugins)
self.heartbeat = asyncio.create_task(server_heartbeat(self))
self.egg_timer = asyncio.create_task(server_egg_timer(self))
async with self.server:
await self.server.serve_forever()

View File

@ -9,6 +9,7 @@ class Penguin(Spheniscidae):
'data', 'muted', 'login_key', 'member', 'membership_days',
'avatar', 'walking_puffle', 'permissions', 'active_quests',
'buddy_requests', 'heartbeat', 'login_timestamp',
'egg_timer_minutes']
def __init__(self, *args):
super().__init__(*args)
@ -28,12 +29,14 @@ class Penguin(Spheniscidae):
self.membership_days = 1
self.avatar = None
self.walking_puffle = None
self.active_quests = None
self.buddy_requests = set()
self.heartbeat = time.time()
self.login_timestamp = None
self.egg_timer_minutes = None
@property
def party_state(self):