diff options
-rwxr-xr-x | baitv-daemon.py | 144 |
1 files changed, 73 insertions, 71 deletions
diff --git a/baitv-daemon.py b/baitv-daemon.py index c4caffe..1983f95 100755 --- a/baitv-daemon.py +++ b/baitv-daemon.py @@ -9,8 +9,9 @@ import sys import settings import utils -VERSION = "baitv-daemon v0.2.4" +VERSION = "baitv-daemon v0.2.5" USERS = set() +HISTORY = [] current_time = lambda: int(round(time.time() * 1000)) timestamp = lambda: int(round(time.time())) @@ -34,6 +35,7 @@ class Client: self.cmds = { "msg": (self.on_msg, 2, False), "notice": (self.on_notice, 2, True), + "history":(self.on_history, 1, False), "login": (self.on_login, 1, False), "logout": (self.on_logout, 0, True), "kick": (self.on_kick, 1, True), @@ -48,40 +50,50 @@ class Client: self.ip_hash = hashlib.md5(self.ip.encode('ascii')).hexdigest()[:5] print("IP: {} ({})".format(self.ip, self.ip_hash)) - @asyncio.coroutine - def broadcast(self, msg, exclude=[]): + async def broadcast(self, msg, exclude=[]): users_to_send = [user for user in USERS if user not in exclude] if users_to_send: - yield from asyncio.wait([user.ws.send(msg) for user in users_to_send]) + _ = [await user.ws.send(msg) for user in users_to_send] - @asyncio.coroutine - def on_msg(self, args): - if current_time() - self.last_chat > settings.flood_time: + async def on_msg(self, args): + t = current_time() + + if t - self.last_chat > settings.flood_time: color, msg = args for user in USERS: if user != self: if user.mod: - yield from user.ws.send("FMSG:{}:{}:{}".format(self.ip_hash, color, msg)) + await user.ws.send("FMSG:{}:{}:{}".format(self.ip_hash, color, msg)) else: - yield from user.ws.send("MSG:{}:{}".format(color, msg)) + await user.ws.send("MSG:{}:{}".format(color, msg)) - self.last_chat = current_time() + self.last_chat = t + + HISTORY.append((t, color, msg)) + if len(HISTORY) > settings.history_length: + HISTORY.pop(0) else: - yield from self.ws.send("FLOOD") + await self.ws.send("FLOOD") - @asyncio.coroutine - def on_notice(self, args): + async def on_notice(self, args): (showname, msg) = args if showname == "1": - yield from self.broadcast("NOTICE:{}:{}".format(self.mod, msg), [self]) + await self.broadcast("NOTICE:{}:{}".format(self.mod, msg), [self]) else: - yield from self.broadcast("NOTICE::{}".format(msg), [self]) + await self.broadcast("NOTICE::{}".format(msg), [self]) - @asyncio.coroutine - def on_login(self, args): + async def on_history(self, args): + if HISTORY: + msgs = min(len(HISTORY), int(args[0])) * -1 + for msg in HISTORY[msgs:]: + await self.ws.send("HMSG:{}:{}:{}".format(*msg)) + + await self.ws.send("HISTORY_OK") + + async def on_login(self, args): valid_psks = utils.parse_streamers_file(settings.streamers_file) psk = args[0] @@ -89,62 +101,56 @@ class Client: print("User logged in") self.mod = valid_psks[psk] - yield from self.ws.send("LOGIN_OK:{}".format(self.mod)) + await self.ws.send("LOGIN_OK:{}".format(self.mod)) else: - yield from self.ws.send("BADPASS") + await self.ws.send("BADPASS") - @asyncio.coroutine - def on_logout(self, args): + async def on_logout(self, args): self.mod = None - yield from self.ws.send("LOGOUT_OK") + await self.ws.send("LOGOUT_OK") - @asyncio.coroutine - def on_kick(self, args): + async def on_kick(self, args): users_to_kick = [user for user in USERS if args[0] == user.ip_hash] if users_to_kick: - yield from self.broadcast("KICKED", users_to_kick) + await self.broadcast("KICKED", users_to_kick) for user in users_to_kick: - yield from user.ws.send("YOU_KICKED") - yield from user.ws.close(4000, "Has sido expulsado.") + await user.ws.send("YOU_KICKED") + await user.ws.close(4000, "Has sido expulsado.") - yield from self.ws.send("KICK_OK") + await self.ws.send("KICK_OK") print("Kicked " + args[0]) - @asyncio.coroutine - def on_ban(self, args): + async def on_ban(self, args): users_to_ban = [user for user in USERS if args[0] == user.ip_hash] if users_to_ban: - yield from self.broadcast("BANNED", users_to_ban) + await self.broadcast("BANNED", users_to_ban) utils.add_ban(users_to_ban[0].ip, settings.bans_file) for user in users_to_ban: - yield from user.ws.send("YOU_BANNED") - yield from user.ws.close(4001, "Has sido baneado.") + await user.ws.send("YOU_BANNED") + await user.ws.close(4001, "Has sido baneado.") - yield from self.ws.send("BAN_OK") + await self.ws.send("BAN_OK") print("Banned " + ip_to_ban) - @asyncio.coroutine - def on_settitle(self, args): + async def on_settitle(self, args): update_state('title', args[0]) - yield from self.broadcast("TITLE:{}".format(args[0]), [self]) + await self.broadcast("TITLE:{}".format(args[0]), [self]) - @asyncio.coroutine - def on_setsource(self, args): + async def on_setsource(self, args): t = timestamp() update_state('source', args[0]) update_state('source_time', t) - yield from self.broadcast("SOURCE:{}:{}".format(args[0], t), [self]) + await self.broadcast("SOURCE:{}:{}".format(args[0], t), [self]) - @asyncio.coroutine - def handle_message(self, msg_in): + async def handle_message(self, msg_in): if len(msg_in) > settings.max_cmd_length: - yield from self.ws.send("FUCKOFF") + await self.ws.send("FUCKOFF") return args = msg_in.split(":") @@ -154,71 +160,67 @@ class Client: if len(args) - 1 == required_args: if need_mod: if self.mod: - yield from cmd_to_run(args[1:]) + await cmd_to_run(args[1:]) else: - yield from self.ws.send("FORBIDDEN") + await self.ws.send("FORBIDDEN") else: - yield from cmd_to_run(args[1:]) + await cmd_to_run(args[1:]) else: - yield from self.ws.send("INVALID") + await self.ws.send("INVALID") else: - yield from self.ws.send("WHAT") + await self.ws.send("WHAT") -@asyncio.coroutine -def broadcast(msg): +async def broadcast(msg): print("broadcasting " + msg) if USERS: - yield from asyncio.wait([user.ws.send(msg) for user in USERS]) + _ = [await user.ws.send(msg) for user in USERS] -@asyncio.coroutine -def notify_count(): +async def notify_count(): total_users = len(USERS) - yield from broadcast("COUNT:{}".format(total_users)) + await broadcast("COUNT:{}".format(total_users)) -@asyncio.coroutine -def register(websocket): +async def register(websocket): USERS.add(websocket) - yield from notify_count() + await notify_count() -@asyncio.coroutine -def unregister(websocket): +async def unregister(websocket): USERS.remove(websocket) - yield from notify_count() + await notify_count() -@asyncio.coroutine -def baitv_daemon(websocket, path): +async def baitv_daemon(websocket, path): print("New client ({})".format(websocket.remote_address)) - real_ip = websocket.request_headers['X-Real-IP'] - if not real_ip: + try: + real_ip = websocket.request_headers['X-Real-IP'] + except: real_ip = websocket.remote_address[0] this_client = Client(websocket, real_ip) - yield from websocket.send("WELCOME:{}".format(VERSION)) + await websocket.send("WELCOME:{}".format(VERSION)) #print(list(websocket.request_headers.raw_items())) if utils.is_banned(real_ip, settings.bans_file): - yield from websocket.send("YOU_BANNED") - yield from websocket.close(4002, "Estás baneado.") + await websocket.send("YOU_BANNED") + await websocket.close(4002, "Estás baneado.") return if real_ip != "127.0.0.1": - yield from register(this_client) + await register(this_client) try: while True: - msg_in = yield from websocket.recv() + msg_in = await websocket.recv() print("< {}".format(msg_in)) - yield from this_client.handle_message(msg_in) + await this_client.handle_message(msg_in) except websockets.ConnectionClosed as e: print("Connection was closed. ({}|{})".format(e.code, e.reason)) finally: print("Client disconnected ({})".format(websocket.remote_address)) if real_ip != "127.0.0.1": - yield from unregister(this_client) + await unregister(this_client) print("baitv-daemon {}".format(VERSION)) |