1
0

switch to different guac implementation, shuffle some stuff around

This commit is contained in:
2025-10-03 01:17:36 -04:00
parent 04d14ed898
commit f758dd41b9
2 changed files with 56 additions and 66 deletions

View File

@@ -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

View File

@@ -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")