summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbaitv-daemon.py144
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))