mirror of
https://github.com/solero/houdini.git
synced 2025-05-16 11:31:12 +00:00
108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
import config
|
|
|
|
from houdini import handlers
|
|
from houdini.handlers import XMLPacket, login
|
|
from houdini.converters import WorldCredentials, Credentials
|
|
from houdini.data.penguin import Penguin
|
|
from houdini.data.moderator import Ban
|
|
from houdini.crypto import Crypto
|
|
from houdini.constants import ClientType
|
|
|
|
from datetime import datetime
|
|
|
|
handle_version_check = login.handle_version_check
|
|
handle_random_key = login.handle_random_key
|
|
|
|
|
|
@handlers.handler(XMLPacket('login'), client=ClientType.Vanilla)
|
|
@handlers.allow_once
|
|
@handlers.depends_on_packet(XMLPacket('verChk'), XMLPacket('rndK'))
|
|
async def handle_login(p, credentials: WorldCredentials):
|
|
if len(p.server.penguins_by_id) >= p.server.server_config['Capacity']:
|
|
return await p.send_error_and_disconnect(103)
|
|
|
|
tr = p.server.redis.multi_exec()
|
|
tr.get('{}.lkey'.format(credentials.username))
|
|
tr.get('{}.ckey'.format(credentials.username))
|
|
tr.delete('{}.lkey'.format(credentials.username), '{}.ckey'.format(credentials.username))
|
|
login_key, confirmation_hash, _ = await tr.execute()
|
|
|
|
if login_key is None or confirmation_hash is None:
|
|
return await p.close()
|
|
|
|
login_key = login_key.decode()
|
|
login_hash = Crypto.encrypt_password(login_key + config.client['AuthStaticKey']) + login_key
|
|
|
|
if credentials.client_key != login_hash:
|
|
return await p.close()
|
|
|
|
if login_key != credentials.login_key or confirmation_hash.decode() != credentials.confirmation_hash:
|
|
return await p.close()
|
|
|
|
data = await Penguin.get(credentials.id)
|
|
|
|
if data is None:
|
|
return await p.send_error_and_disconnect(100)
|
|
|
|
if not data.active:
|
|
return await p.close()
|
|
|
|
if data.permaban:
|
|
return await p.close()
|
|
|
|
active_ban = await Ban.query.where((Ban.penguin_id == data.id) & (Ban.expires >= datetime.now())).gino.scalar()
|
|
if active_ban is not None:
|
|
return await p.close()
|
|
|
|
if data.id in p.server.penguins_by_id:
|
|
await p.server.penguins_by_id[data.id].close()
|
|
|
|
p.logger.info('{} logged in successfully'.format(data.username))
|
|
|
|
p.data = data
|
|
p.login_key = login_key
|
|
await p.send_xt('l')
|
|
|
|
|
|
@handlers.handler(XMLPacket('login'), client=ClientType.Legacy)
|
|
@handlers.allow_once
|
|
@handlers.depends_on_packet(XMLPacket('verChk'), XMLPacket('rndK'))
|
|
async def handle_legacy_login(p, credentials: Credentials):
|
|
if len(p.server.penguins_by_id) >= p.server.server_config['Capacity']:
|
|
return await p.send_error_and_disconnect(103)
|
|
|
|
tr = p.server.redis.multi_exec()
|
|
tr.get('{}.lkey'.format(credentials.username))
|
|
tr.delete('{}.lkey'.format(credentials.username), '{}.ckey'.format(credentials.username))
|
|
login_key, _ = await tr.execute()
|
|
|
|
login_key = login_key.decode()
|
|
login_hash = Crypto.encrypt_password(login_key + config.client['AuthStaticKey']) + login_key
|
|
|
|
if login_key is None or login_hash != credentials.password:
|
|
return await p.close()
|
|
|
|
data = await Penguin.query.where(Penguin.username == credentials.username).gino.first()
|
|
|
|
if data is None:
|
|
return await p.send_error_and_disconnect(100)
|
|
|
|
if not data.active:
|
|
return await p.close()
|
|
|
|
if data.permaban:
|
|
return await p.close()
|
|
|
|
active_ban = await Ban.query.where((Ban.penguin_id == data.id) & (Ban.expires >= datetime.now())).gino.scalar()
|
|
if active_ban is not None:
|
|
return await p.close()
|
|
|
|
if data.id in p.server.penguins_by_id:
|
|
await p.server.penguins_by_id[data.id].close()
|
|
|
|
p.logger.info('{} logged in successfully'.format(data.username))
|
|
|
|
p.data = data
|
|
p.login_key = login_key
|
|
await p.send_xt('l')
|