Setup for future IRC work, add centeralized message parser
This commit is contained in:
parent
e71b256a3e
commit
6376818b85
1 changed files with 41 additions and 20 deletions
61
server.py
61
server.py
|
@ -37,6 +37,8 @@ G.outboundLinks = []
|
||||||
G.S2SLogs = []
|
G.S2SLogs = []
|
||||||
G.cwlgd = False
|
G.cwlgd = False
|
||||||
G.NUL = "\x1e"
|
G.NUL = "\x1e"
|
||||||
|
G.IRCStats = {"users": {"localMax": 0, "localCurrent": 0, "globalMax": 0, "globalCurrent": 0}, "servers": 0}
|
||||||
|
G.queue = []
|
||||||
saveLogs = True
|
saveLogs = True
|
||||||
address = "::"
|
address = "::"
|
||||||
# Try to load a message log, if one exists
|
# Try to load a message log, if one exists
|
||||||
|
@ -113,6 +115,31 @@ if len(G.remoteID) > 16:
|
||||||
G.remoteID = G.remoteID[:15]
|
G.remoteID = G.remoteID[:15]
|
||||||
|
|
||||||
|
|
||||||
|
async def getMessage(reader, localQueue: list, size: int = 0, timeout: float = 0, sanitize: bool = False, _raise: bool = False) -> str:
|
||||||
|
if not localQueue:
|
||||||
|
data = ""
|
||||||
|
if timeout > 0:
|
||||||
|
if _raise:
|
||||||
|
data = await asyncio.wait_for(reader.read(size), timeout)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
data = await asyncio.wait_for(reader.read(size), timeout)
|
||||||
|
except TimeoutErrors:
|
||||||
|
return "" # We should never return nothing, except in this one case.
|
||||||
|
else:
|
||||||
|
data = await reader.read(size)
|
||||||
|
localQueue = data.decode("utf8").strip().split("\r\n")
|
||||||
|
tmp = localQueue.pop(0)
|
||||||
|
if sanitize:
|
||||||
|
tmp = raw(tmp)
|
||||||
|
if size:
|
||||||
|
other = tmp[size:]
|
||||||
|
tmp = tmp[:size]
|
||||||
|
if other:
|
||||||
|
localQueue.insert(0, other)
|
||||||
|
return tmp, localQueue
|
||||||
|
|
||||||
|
|
||||||
def raw(string: str) -> str:
|
def raw(string: str) -> str:
|
||||||
s = string.strip()
|
s = string.strip()
|
||||||
s = f"{s!r}"[1:-1].replace("\\\\", "\\")
|
s = f"{s!r}"[1:-1].replace("\\\\", "\\")
|
||||||
|
@ -135,17 +162,12 @@ async def handleClient(reader, writer):
|
||||||
global G
|
global G
|
||||||
writer.write(b"Please identify yourself. Nick limit is 20 chars.\r\n")
|
writer.write(b"Please identify yourself. Nick limit is 20 chars.\r\n")
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
name = raw((await reader.read(20)).decode("utf8"))
|
name, localQueue = await getMessage(reader, [], 20, 0, True)
|
||||||
|
localQueue = []
|
||||||
if len(name) > 20:
|
if len(name) > 20:
|
||||||
name = name[
|
name = name[
|
||||||
:19
|
:19
|
||||||
] # Really this is only possible if someone passes raw unicode as a nick, but let's clean it up anyways.
|
] # Really this is only possible if someone passes raw unicode as a nick, but let's clean it up anyways.
|
||||||
try:
|
|
||||||
await asyncio.wait_for(
|
|
||||||
reader.read(), 0.01
|
|
||||||
) # Silently consume the excess username data
|
|
||||||
except TimeoutErrors:
|
|
||||||
pass
|
|
||||||
if not name:
|
if not name:
|
||||||
writer.write(b"Nice try. Actually set a nick.\r\n")
|
writer.write(b"Nice try. Actually set a nick.\r\n")
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
|
@ -158,7 +180,9 @@ async def handleClient(reader, writer):
|
||||||
writer.close()
|
writer.close()
|
||||||
await writer.wait_closed()
|
await writer.wait_closed()
|
||||||
return
|
return
|
||||||
if not name.startswith("S2S-"):
|
if name == "CAP LS 302":
|
||||||
|
pass # TODO: IRC Logic
|
||||||
|
elif not name.startswith("S2S-"):
|
||||||
G.clientsConnected[name.lower()] = G.remoteID
|
G.clientsConnected[name.lower()] = G.remoteID
|
||||||
msgIndex = 0
|
msgIndex = 0
|
||||||
G.uniqueClients += 1
|
G.uniqueClients += 1
|
||||||
|
@ -166,8 +190,7 @@ async def handleClient(reader, writer):
|
||||||
G.S2SLogs.append(("+", name, G.remoteID))
|
G.S2SLogs.append(("+", name, G.remoteID))
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
buffer = await asyncio.wait_for(reader.read(967), 0.1)
|
request, localQueue = await getMessage(reader, localQueue, 967, 0.1, True, True)
|
||||||
request = raw(buffer.decode("utf8"))
|
|
||||||
response = None
|
response = None
|
||||||
if request.startswith("/mes "):
|
if request.startswith("/mes "):
|
||||||
response = log(f"* {name}'s {request[5:]}")
|
response = log(f"* {name}'s {request[5:]}")
|
||||||
|
@ -253,7 +276,7 @@ Please note that this is not network level statistics.\r\n""".encode(
|
||||||
msgIndex = 0
|
msgIndex = 0
|
||||||
writer.write(b"I am awaiting your client listing.\r\n")
|
writer.write(b"I am awaiting your client listing.\r\n")
|
||||||
while 1:
|
while 1:
|
||||||
client = raw((await reader.read(1024)).decode("utf8"))
|
client, localQueue = await getMessage(reader, localQueue, 20, 0, True)
|
||||||
if client == f"END OF CLIENT LISTING FROM {sName}":
|
if client == f"END OF CLIENT LISTING FROM {sName}":
|
||||||
break
|
break
|
||||||
if (
|
if (
|
||||||
|
@ -274,7 +297,7 @@ Please note that this is not network level statistics.\r\n""".encode(
|
||||||
for client in G.clientsConnected:
|
for client in G.clientsConnected:
|
||||||
writer.write(f"{client}\r\n".encode("utf8"))
|
writer.write(f"{client}\r\n".encode("utf8"))
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
resp = raw((await reader.read(1024)).decode("utf8"))
|
resp, localQueue = await getMessage(reader, localQueue, 1024, 0, True)
|
||||||
if resp.startswith("K"):
|
if resp.startswith("K"):
|
||||||
if G.clientsConnected[client] == G.remoteID:
|
if G.clientsConnected[client] == G.remoteID:
|
||||||
G.killList[client] = True
|
G.killList[client] = True
|
||||||
|
@ -287,8 +310,7 @@ Please note that this is not network level statistics.\r\n""".encode(
|
||||||
msgInd = len(G.S2SLogs)
|
msgInd = len(G.S2SLogs)
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
rawMsg = await asyncio.wait_for(reader.read(967), 0.1)
|
buffer, localQueue = await getMessage(reader, localQueue, 967, 0.1, False, True)
|
||||||
buffer = rawMsg.decode("utf8").strip()
|
|
||||||
match buffer[0]:
|
match buffer[0]:
|
||||||
case "S": # Server notice
|
case "S": # Server notice
|
||||||
G.msgs.extend([log(buffer[2:])])
|
G.msgs.extend([log(buffer[2:])])
|
||||||
|
@ -425,14 +447,14 @@ async def connectServer(hostname: str, port: int):
|
||||||
global G
|
global G
|
||||||
try:
|
try:
|
||||||
reader, writer = await asyncio.open_connection(hostname, port)
|
reader, writer = await asyncio.open_connection(hostname, port)
|
||||||
await reader.read(1024)
|
ext, localQueue = await getMessage(reader, [], 1024)
|
||||||
writer.write(f"S2S-{G.remoteID}\r\n".encode("utf8"))
|
writer.write(f"S2S-{G.remoteID}\r\n".encode("utf8"))
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
await reader.read(1024)
|
ext, localQueue = await getMessage(reader, [], 1024)
|
||||||
for client in G.clientsConnected:
|
for client in G.clientsConnected:
|
||||||
writer.write(f"{client}\r\n".encode("utf8"))
|
writer.write(f"{client}\r\n".encode("utf8"))
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
resp = raw((await reader.read(1024)).decode("utf8"))
|
resp, localQueue = await getMessage(reader, [localQueue], 1024)
|
||||||
if resp.startswith("K"):
|
if resp.startswith("K"):
|
||||||
if G.clientsConnected[client] == G.remoteID:
|
if G.clientsConnected[client] == G.remoteID:
|
||||||
G.killList[client] = True
|
G.killList[client] = True
|
||||||
|
@ -459,7 +481,7 @@ async def connectServer(hostname: str, port: int):
|
||||||
await writer.drain()
|
await writer.drain()
|
||||||
# recieve client list from the other server
|
# recieve client list from the other server
|
||||||
while 1:
|
while 1:
|
||||||
client = raw((await reader.read(1024)).decode("utf8"))
|
client, localQueue = await getMessage(reader, localQueue, 1024, 0, True)
|
||||||
if client == f"END OF CLIENT LISTING FROM {rID}":
|
if client == f"END OF CLIENT LISTING FROM {rID}":
|
||||||
break
|
break
|
||||||
if client.lower() in G.servers[rID] or client.lower() in G.clientsConnected:
|
if client.lower() in G.servers[rID] or client.lower() in G.clientsConnected:
|
||||||
|
@ -476,8 +498,7 @@ async def connectServer(hostname: str, port: int):
|
||||||
try:
|
try:
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
rawMsg = await asyncio.wait_for(reader.read(1024), 0.1)
|
buffer, localQueue = await getMessage(reader, localQueue, 1024, 0.1, False, True)
|
||||||
buffer = rawMsg.decode("utf8").strip()
|
|
||||||
match buffer[0]:
|
match buffer[0]:
|
||||||
case "S":
|
case "S":
|
||||||
G.msgs.extend([log(buffer[2:])])
|
G.msgs.extend([log(buffer[2:])])
|
||||||
|
|
Loading…
Reference in a new issue