Upload files to "/"
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
venv
|
||||
@@ -1,3 +1,2 @@
|
||||
# old-webchat-server
|
||||
|
||||
gfrtgf
|
||||
# Building
|
||||
Create a new venv by going clicking on `Python <version>` in the bottom right corner of PyCharm, then in the dropdown `Add New Interpreter` and then `Add Local Interpreter`. The default options are correct so just click `Ok`. When you go into `main.py` you should see `Package requirements <package names> are not satisfied`. Just click `Install requirements` and `Install`.
|
||||
141
main.py
Normal file
141
main.py
Normal file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3
|
||||
import asyncio
|
||||
|
||||
import websockets
|
||||
import json
|
||||
from better_profanity import profanity
|
||||
from html_sanitizer import Sanitizer
|
||||
with open("config/xss-config.py","r") as f:
|
||||
configs = {}
|
||||
exec(f.read(),configs) # run configuration script
|
||||
sanitizer = Sanitizer(configs["config"]) # default configuration
|
||||
# Store connected clients
|
||||
ignore_profanity = True
|
||||
connected = []
|
||||
profanity.load_censor_words()
|
||||
extraswears = ["hitler"]
|
||||
profanity.add_censor_words(extraswears)
|
||||
|
||||
|
||||
class Kick(Exception):
|
||||
pass
|
||||
|
||||
async def sendwithappropriate(ws, clientdata, msg):
|
||||
msg = sanitizer.sanitize(msg)
|
||||
if clientdata["legacy"]:
|
||||
await ws.send(msg) # Legacy protocol aka "V1 Protocol" which has less features
|
||||
else:
|
||||
await ws.send(json.dumps({"type": "message", "content": msg})) # New protocol aka "V2 Protocol2
|
||||
|
||||
|
||||
async def handle_client(websocket, path):
|
||||
# Add client to connected clients
|
||||
clientdata = {"socket": websocket, "username": "Unknown", "legacy": False, "extradata": None}
|
||||
connected.append(clientdata)
|
||||
strikes = 0
|
||||
maxstrikes = 5
|
||||
try:
|
||||
# Get the username from the first message
|
||||
handshake = await websocket.recv()
|
||||
try:
|
||||
handshake = json.loads(handshake)
|
||||
username = handshake["username"]
|
||||
clientdata["extradata"] = handshake["clientdata"]
|
||||
except json.JSONDecodeError as e:
|
||||
print("Legacy handshake detected!")
|
||||
clientdata["legacy"] = True
|
||||
clientdata["extradata"] = {}
|
||||
username = handshake
|
||||
await sendwithappropriate(websocket, clientdata,
|
||||
"SYSTEM: Attention! Your client is outdated (or does not support new handshake yet). Please update to use new features. Legacy support is still available for now, so you're okay for now!")
|
||||
if profanity.contains_profanity(username) and not ignore_profanity:
|
||||
await sendwithappropriate(websocket, clientdata,
|
||||
f"SYSTEM: Your username '{username}' contains profanity. Please change it and reload the page to try again...")
|
||||
raise Kick("profane username")
|
||||
# Notify other clients about the new user
|
||||
await joinMessage(username)
|
||||
clientdata["username"] = username
|
||||
async for jsonpacket in websocket:
|
||||
try:
|
||||
packet = json.loads(jsonpacket)
|
||||
except json.JSONDecodeError as e:
|
||||
print("Legacy message, forging one that complies with the new standards")
|
||||
packet = {"type": "message", "message": jsonpacket}
|
||||
if packet["type"] == "message":
|
||||
message = packet["message"]
|
||||
# Broadcast the message to all clients
|
||||
if message.strip() == "/online":
|
||||
await sendwithappropriate(websocket, clientdata, "People online:")
|
||||
for client in connected:
|
||||
await sendwithappropriate(websocket, clientdata, client["username"])
|
||||
if profanity.contains_profanity(message) and not ignore_profanity:
|
||||
strikes += 1
|
||||
await sendwithappropriate(websocket, clientdata,
|
||||
f"SYSTEM: {strikes}/{maxstrikes} strikes. Go above and you are kicked.")
|
||||
if strikes > maxstrikes:
|
||||
raise Kick("excessive swearing")
|
||||
await broadcast(f"{username}: {message}")
|
||||
elif packet["type"] == "unhandled":
|
||||
print(f"{clientdata.username}'s client couldn't handle packet {packet.packet}")
|
||||
except websockets.exceptions.ConnectionClosedError:
|
||||
pass
|
||||
except Kick as e:
|
||||
print("Kicked due to", e)
|
||||
await websocket.send("You have been kicked due to " + str(e))
|
||||
finally:
|
||||
# Remove client from connected clients
|
||||
connected.remove(clientdata)
|
||||
|
||||
# Notify other clients about the user leaving
|
||||
try:
|
||||
await leaveMessage(username)
|
||||
except UnboundLocalError:
|
||||
pass # This causes an error if the user closes the tab using an old client just before joining fully
|
||||
# so we catch it.
|
||||
|
||||
async def joinMessage(username):
|
||||
# Send special kind of message when someone joins
|
||||
print(f"{username} joined the chat")
|
||||
if connected:
|
||||
for clientdata in connected:
|
||||
client = clientdata["socket"]
|
||||
|
||||
if clientdata["legacy"] == True:
|
||||
await sendwithappropriate(client, clientdata, f"{username} joined the chat")
|
||||
else:
|
||||
await client.send(json.dumps({"type": "join", "username": username}))
|
||||
|
||||
async def leaveMessage(username):
|
||||
# Send special kind of message when someone joins
|
||||
print(f"{username} left the chat")
|
||||
if connected:
|
||||
for clientdata in connected:
|
||||
client = clientdata["socket"]
|
||||
|
||||
if clientdata["legacy"] == True:
|
||||
await sendwithappropriate(client, clientdata, f"{username} left the chat")
|
||||
else:
|
||||
await client.send(json.dumps({"type": "leave", "username": username}))
|
||||
|
||||
async def broadcast(message):
|
||||
if message.replace(message[:message.find(": ") + 2], "").replace("\n", "") == "":
|
||||
return
|
||||
# Send message to all connected clients
|
||||
print(profanity.censor(message.replace("\n", " "))) # Not even the server host wants to see stuff like that
|
||||
if connected:
|
||||
for clientdata in connected:
|
||||
client = clientdata["socket"]
|
||||
|
||||
if True:
|
||||
if ignore_profanity:
|
||||
await sendwithappropriate(client, clientdata, message)
|
||||
else:
|
||||
await sendwithappropriate(client, clientdata, profanity.censor(message))
|
||||
|
||||
|
||||
# Start the WebSocket server
|
||||
print("Serving...")
|
||||
start_server = websockets.serve(handle_client, "0.0.0.0", 8765)
|
||||
print("Adding to loop...")
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
4
main.sh
Normal file
4
main.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
cd /scripts/chatserv
|
||||
/scripts/chatserv_venv/bin/pip3 install -r requirements.txt
|
||||
/scripts/chatserv_venv/bin/python3 main.py
|
||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
websockets
|
||||
better-profanity
|
||||
html-sanitizer
|
||||
Reference in New Issue
Block a user