switch to different guac implementation, shuffle some stuff around
This commit is contained in:
@@ -1,68 +1,9 @@
|
||||
from typing import List, Optional
|
||||
from enum import IntEnum
|
||||
|
||||
def guac_decode(string: str) -> Optional[List[str]]:
|
||||
"""Implementation of guacamole decoder
|
||||
Example: guac_decode(\"4.chat,5.hello\") -> [\"chat\", \"hello\"]"""
|
||||
|
||||
if not string:
|
||||
return []
|
||||
|
||||
idx: int = 0
|
||||
distance: int
|
||||
result: List[str] = []
|
||||
chars: List[str] = list(string)
|
||||
|
||||
while True:
|
||||
dist_str: str = ""
|
||||
|
||||
while chars[idx].isdecimal():
|
||||
dist_str += chars[idx]
|
||||
idx = idx + 1
|
||||
|
||||
if idx >= 1:
|
||||
idx -= 1
|
||||
|
||||
if not dist_str.isdigit():
|
||||
return None
|
||||
|
||||
distance = int(dist_str)
|
||||
idx += 1
|
||||
|
||||
if chars[idx] != ".":
|
||||
return None
|
||||
|
||||
idx += 1
|
||||
|
||||
addition: str = ""
|
||||
for num in range(idx, idx + distance):
|
||||
addition += chars[num]
|
||||
|
||||
result.append(addition)
|
||||
|
||||
idx += distance
|
||||
if idx >= len(chars):
|
||||
return None
|
||||
|
||||
if chars[idx] == ",":
|
||||
pass
|
||||
elif chars[idx] == ";":
|
||||
break
|
||||
else:
|
||||
return None
|
||||
|
||||
idx += 1
|
||||
|
||||
return result
|
||||
|
||||
def guac_encode(*args: str) -> str:
|
||||
"""Implementation of guacamole encoder
|
||||
Example: guac_encode(\"chat\", \"hello\") -> \"4.chat,5.hello;\" """
|
||||
|
||||
return f"{','.join(f'{len(arg)}.{arg}' for arg in args)};"
|
||||
|
||||
# ENUMS
|
||||
class CollabVMState(IntEnum):
|
||||
"""Represents client connection states."""
|
||||
|
||||
WS_DISCONNECTED = -1
|
||||
"""WebSocket is disconnected."""
|
||||
WS_CONNECTED = 0
|
||||
@@ -74,6 +15,7 @@ class CollabVMState(IntEnum):
|
||||
|
||||
class CollabVMRank(IntEnum):
|
||||
"""Represents user ranks."""
|
||||
|
||||
Unregistered = 0
|
||||
"""Represents an unregistered user."""
|
||||
Registered = 1
|
||||
@@ -85,6 +27,7 @@ class CollabVMRank(IntEnum):
|
||||
|
||||
class CollabVMClientRenameStatus(IntEnum):
|
||||
"""Represents the status of a client rename attempt."""
|
||||
|
||||
SUCCEEDED = 0
|
||||
"""The rename attempt was successful."""
|
||||
FAILED_TAKEN = 1
|
||||
@@ -92,4 +35,51 @@ class CollabVMClientRenameStatus(IntEnum):
|
||||
FAILED_INVALID = 2
|
||||
"""The desired name is invalid."""
|
||||
FAILED_REJECTED = 3
|
||||
"""The rename attempt was authoritatively rejected."""
|
||||
"""The rename attempt was authoritatively rejected."""
|
||||
|
||||
# GUACAMOLE
|
||||
def guac_encode(elements: list) -> str:
|
||||
return ','.join([f'{len(element)}.{element}' for element in elements]) + ';'
|
||||
|
||||
def guac_decode(instruction: str) -> list:
|
||||
elements = []
|
||||
position = 0
|
||||
|
||||
# Loop and collect elements
|
||||
continueScanning = True
|
||||
while continueScanning:
|
||||
# Ensure current position is not out of bounds
|
||||
if position >= len(instruction):
|
||||
raise ValueError(f"Unexpected EOL in guacamole instruction at character {position}")
|
||||
# Get position of separator
|
||||
separatorPosition = instruction.index('.', position)
|
||||
# Read and validate element length
|
||||
try:
|
||||
elementLength = int(instruction[position:separatorPosition])
|
||||
except ValueError:
|
||||
raise ValueError(f"Malformed element length in guacamole exception at character {position}")
|
||||
if elementLength < 0 or elementLength > len(instruction) - separatorPosition - 1:
|
||||
raise ValueError(f"Invalid element length in guacamole exception at character {position}")
|
||||
position = separatorPosition + 1
|
||||
|
||||
# Collect element
|
||||
element = instruction[position:position+elementLength]
|
||||
|
||||
position = position + elementLength
|
||||
|
||||
elements.append(element)
|
||||
|
||||
# Check separator
|
||||
if position >= len(instruction):
|
||||
raise ValueError(f"Unexpected EOL in guacamole instruction at character {position}")
|
||||
|
||||
# Check terminator
|
||||
match instruction[position]:
|
||||
case ',':
|
||||
position = position + 1
|
||||
case ';':
|
||||
continueScanning = False
|
||||
case _:
|
||||
raise ValueError(f"Unexpected '{instruction[position]}' in guacamole instruction at character {position}")
|
||||
|
||||
return elements
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List, Optional
|
||||
from typing import List
|
||||
from cvmlib import guac_decode, guac_encode, CollabVMRank, CollabVMState, CollabVMClientRenameStatus
|
||||
import config
|
||||
import os, random, websockets, asyncio
|
||||
@@ -39,10 +39,10 @@ def get_origin_from_ws_url(ws_url: str) -> str:
|
||||
|
||||
async def send_chat_message(websocket, message: str):
|
||||
log.debug(f"Sending chat message: {message}")
|
||||
await websocket.send(guac_encode("chat", message))
|
||||
await websocket.send(guac_encode(["chat", message]))
|
||||
|
||||
async def send_guac(websocket, *args: str):
|
||||
await websocket.send(guac_encode(*args))
|
||||
await websocket.send(guac_encode(list(args)))
|
||||
|
||||
async def connect(vm_name: str):
|
||||
global STATE
|
||||
@@ -72,7 +72,7 @@ async def connect(vm_name: str):
|
||||
vm_botuser[vm_name] = ""
|
||||
# response = await websocket.recv()
|
||||
async for message in websocket:
|
||||
decoded: Optional[List[str]] = guac_decode(str(message))
|
||||
decoded: List[str] = guac_decode(str(message))
|
||||
match decoded:
|
||||
case ["nop"]:
|
||||
await send_guac(websocket, "nop")
|
||||
|
||||
Reference in New Issue
Block a user