mirror of
https://github.com/solero/houdini.git
synced 2024-11-13 22:28:21 +00:00
Implement egg-timer for legacy and vanilla clients
This commit is contained in:
parent
2ecd9f1850
commit
1c03374bd8
@ -500,6 +500,8 @@ CREATE TABLE penguin (
|
|||||||
timer_active BOOLEAN NOT NULL DEFAULT FALSE,
|
timer_active BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
timer_start TIME NOT NULL DEFAULT '00:00:00',
|
timer_start TIME NOT NULL DEFAULT '00:00:00',
|
||||||
timer_end TIME NOT NULL DEFAULT '23:59:59',
|
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_en BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
approval_pt BOOLEAN NOT NULL DEFAULT FALSE,
|
approval_pt BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
approval_fr 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_active IS 'Is egg-timer active?';
|
||||||
COMMENT ON COLUMN penguin.timer_start IS 'Egg-timer start time';
|
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_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_en IS 'English username approval';
|
||||||
COMMENT ON COLUMN penguin.approval_pt IS 'Portuguese username approval';
|
COMMENT ON COLUMN penguin.approval_pt IS 'Portuguese username approval';
|
||||||
COMMENT ON COLUMN penguin.approval_fr IS 'French username approval';
|
COMMENT ON COLUMN penguin.approval_fr IS 'French username approval';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime, date
|
||||||
|
|
||||||
from houdini.data import db
|
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_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_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_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"))
|
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_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"))
|
approval_pt = db.Column(db.Boolean, nullable=False, server_default=db.text("false"))
|
||||||
|
@ -11,7 +11,7 @@ import asyncio
|
|||||||
import bcrypt
|
import bcrypt
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
|
||||||
@handlers.handler(XMLPacket('login'))
|
@handlers.handler(XMLPacket('login'))
|
||||||
@ -73,6 +73,14 @@ async def handle_login(p, credentials: Credentials):
|
|||||||
|
|
||||||
if data.grounded:
|
if data.grounded:
|
||||||
return await p.send_error_and_disconnect(913)
|
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()
|
active_ban = await Ban.query.where(Ban.penguin_id == data.id and Ban.expires >= datetime.now()).gino.first()
|
||||||
|
|
||||||
if active_ban is not None:
|
if active_ban is not None:
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
from houdini import handlers
|
from houdini import handlers
|
||||||
from houdini.handlers import XTPacket
|
from houdini.handlers import XTPacket
|
||||||
from houdini.data.room import Room
|
from houdini.data.room import Room
|
||||||
|
from houdini.data.penguin import Login
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
@handlers.handler(XTPacket('j', 'js'), pre_login=True)
|
@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
|
penguin_standard_time = current_time * 1000
|
||||||
server_time_offset = 7
|
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,
|
penguin_standard_time, p.data.age, 0, p.data.minutes_played,
|
||||||
"membership_days", server_time_offset, int(p.data.opened_playercard),
|
"membership_days", server_time_offset, int(p.data.opened_playercard),
|
||||||
p.data.map_category, p.data.status_field)
|
p.data.map_category, p.data.status_field)
|
||||||
|
@ -45,6 +45,37 @@ async def server_heartbeat(server):
|
|||||||
for penguin in server.penguins_by_id.values():
|
for penguin in server.penguins_by_id.values():
|
||||||
if penguin.heartbeat < timer:
|
if penguin.heartbeat < timer:
|
||||||
await penguin.close()
|
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.handler(XTPacket('u', 'h'))
|
||||||
@handlers.cooldown(59)
|
@handlers.cooldown(59)
|
||||||
async def handle_heartbeat(p):
|
async def handle_heartbeat(p):
|
||||||
|
@ -40,6 +40,7 @@ from houdini.plugins import PluginManager
|
|||||||
from houdini.commands import CommandManager
|
from houdini.commands import CommandManager
|
||||||
|
|
||||||
from houdini.handlers.play.player import server_heartbeat
|
from houdini.handlers.play.player import server_heartbeat
|
||||||
|
from houdini.handlers.play.player import server_egg_timer
|
||||||
|
|
||||||
class Houdini:
|
class Houdini:
|
||||||
|
|
||||||
@ -93,6 +94,7 @@ class Houdini:
|
|||||||
self.spawn_rooms = None
|
self.spawn_rooms = None
|
||||||
|
|
||||||
self.heartbeat = None
|
self.heartbeat = None
|
||||||
|
self.egg_timer = None
|
||||||
async def start(self):
|
async def start(self):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
@ -228,6 +230,8 @@ class Houdini:
|
|||||||
await self.plugins.setup(houdini.plugins)
|
await self.plugins.setup(houdini.plugins)
|
||||||
|
|
||||||
self.heartbeat = asyncio.create_task(server_heartbeat(self))
|
self.heartbeat = asyncio.create_task(server_heartbeat(self))
|
||||||
|
self.egg_timer = asyncio.create_task(server_egg_timer(self))
|
||||||
|
|
||||||
async with self.server:
|
async with self.server:
|
||||||
await self.server.serve_forever()
|
await self.server.serve_forever()
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ class Penguin(Spheniscidae):
|
|||||||
'data', 'muted', 'login_key', 'member', 'membership_days',
|
'data', 'muted', 'login_key', 'member', 'membership_days',
|
||||||
'avatar', 'walking_puffle', 'permissions', 'active_quests',
|
'avatar', 'walking_puffle', 'permissions', 'active_quests',
|
||||||
'buddy_requests', 'heartbeat', 'login_timestamp',
|
'buddy_requests', 'heartbeat', 'login_timestamp',
|
||||||
|
'egg_timer_minutes']
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
@ -28,12 +29,14 @@ class Penguin(Spheniscidae):
|
|||||||
self.membership_days = 1
|
self.membership_days = 1
|
||||||
|
|
||||||
self.avatar = None
|
self.avatar = None
|
||||||
|
|
||||||
self.walking_puffle = None
|
self.walking_puffle = None
|
||||||
|
|
||||||
self.active_quests = None
|
self.active_quests = None
|
||||||
|
self.buddy_requests = set()
|
||||||
|
|
||||||
|
self.heartbeat = time.time()
|
||||||
|
|
||||||
self.login_timestamp = None
|
self.login_timestamp = None
|
||||||
|
self.egg_timer_minutes = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def party_state(self):
|
def party_state(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user