This repository has been archived on 2026-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
TyChat-TUI/socket_manager.py

153 lines
7.3 KiB
Python

import socketio
import base64
import numpy as np
import threading
import sounddevice as sd
sio = socketio.Client()
_client_instance = None
def init_network(client_instance):
global _client_instance
_client_instance = client_instance
@sio.event
def incoming_packet(data):
if not _client_instance: return
from_uin = data["from_uin"]
payload_base64 = data["payload"]
try:
raw_bytes = base64.b64decode(payload_base64.encode('utf-8'))
if raw_bytes.startswith(b"SERVICE:"):
parts = raw_bytes.split(b":", 2)
proto_name = parts[1].decode('utf-8')
sig_bytes = parts[2]
sig_type = _client_instance.plugin_manager.safe_decode(proto_name, sig_bytes)
if not sig_type:
sig_type = _client_instance.plugin_manager.protocols.get(proto_name, {}).get("instance").detect_service_signal(sig_bytes)
if sig_type:
if from_uin not in _client_instance.contacts: return
if sig_type == "QUERY":
if _client_instance.is_busy:
_client_instance.send_service_tone(from_uin, 1600)
else:
_client_instance.pending_windows.append({"type": "query", "uin": from_uin})
_client_instance.refresh_ui()
elif sig_type == "ALERT":
_client_instance.pending_windows.append({"type": "alert", "uin": from_uin})
_client_instance.refresh_ui()
elif sig_type == "RESP_YES":
if _client_instance.dialing_uin == from_uin:
_client_instance.dialing_uin = None
_client_instance.add_to_history(from_uin, "[SYSTEM]: Peer reports they are currently BUSY.")
elif sig_type == "RESP_NO":
if _client_instance.dialing_uin == from_uin:
_client_instance.dialing_uin = None
_client_instance.add_to_history(from_uin, "[SYSTEM]: Peer reports they are AVAILABLE.")
return
if raw_bytes.startswith(b"NATIVE:"):
parts = raw_bytes.split(b":", 2)
proto_name = parts[1].decode('utf-8')
enc_bytes = parts[2]
if not _client_instance.plugin_manager.protocols.get(proto_name, {}).get("enabled"):
return
decoded_text = _client_instance.plugin_manager.safe_decode(proto_name, enc_bytes)
if decoded_text is None:
return
_client_instance.peer_session_protocols[from_uin] = proto_name
if decoded_text.startswith("SYS:"):
cmd = decoded_text[4:]
if cmd == "REQ_ADD":
if from_uin not in _client_instance.contacts:
if from_uin not in _client_instance.pending_requests:
_client_instance.pending_requests.append(from_uin)
_client_instance.refresh_ui()
else:
_client_instance.send_sys_packet(from_uin, "RES_ACC")
return
elif cmd == "RES_ACC":
if _client_instance.dialing_uin == from_uin:
_client_instance.dialing_uin = None
if from_uin not in _client_instance.contacts:
_client_instance.contacts[from_uin] = {"status": "online", "unread": 0, "attention": False}
_client_instance.history[from_uin] = ["[SYSTEM]: System connection handshakes accepted and bound!"]
_client_instance.save_config()
_client_instance.active_chat = from_uin
_client_instance.refresh_ui()
return
elif cmd == "RES_DEC":
if _client_instance.dialing_uin == from_uin:
_client_instance.dialing_uin = None
return
elif cmd.startswith("REQ_JOIN_ROOM:"):
r_name = cmd.split(":", 1)[1]
r_id = f"ROOM:{_client_instance.uin}:{r_name}"
if r_id in _client_instance.groups:
if from_uin not in _client_instance.groups[r_id]["members"]:
_client_instance.groups[r_id]["members"].append(from_uin)
_client_instance.save_config()
_client_instance.send_sys_packet(from_uin, f"RES_JOIN_ROOM_OK:{r_name}:" + ",".join(_client_instance.groups[r_id]["members"]))
_client_instance.add_to_history(r_id, f"[SYSTEM]: User UIN {from_uin} joined the room sync list.")
return
elif cmd.startswith("RES_JOIN_ROOM_OK:"):
parts = cmd.split(":", 2)
r_name = parts[1]
m_list = parts[2].split(",")
r_id = f"ROOM:{from_uin}:{r_name}"
if r_id in _client_instance.groups:
_client_instance.groups[r_id]["members"] = m_list
_client_instance.save_config()
_client_instance.add_to_history(r_id, f"[SYSTEM]: Room synchronization complete. Members online: {len(m_list)}")
return
elif cmd.startswith("ROOM_MSG:"):
parts = cmd.split(":", 3)
r_id = parts[1]
sender_uin = parts[2]
msg_body = parts[3]
if r_id in _client_instance.groups:
_client_instance.add_to_history(r_id, f"[UIN {sender_uin}]: {msg_body}")
if _client_instance.uin == _client_instance.groups[r_id]["owner"]:
for m in _client_instance.groups[r_id]["members"]:
if m != _client_instance.uin and m != sender_uin and _client_instance.contacts.get(m, {}).get("status") == "online":
sio.emit("relay_packet", {"to_uin": m, "payload": payload_base64})
return
if from_uin not in _client_instance.contacts: return
if _client_instance.active_chat != from_uin:
_client_instance.contacts[from_uin]["unread"] += 1
sender_name = f"UIN {from_uin}"
_client_instance.add_to_history(from_uin, f"[{sender_name}]: {decoded_text}")
except:
pass
@sio.event
def online_statuses_response(data):
if not _client_instance: return
for uin, status in data.items():
if uin in _client_instance.contacts:
_client_instance.contacts[uin]["status"] = status
_client_instance.refresh_ui()
@sio.event
def error(data):
if not _client_instance: return
msg = data.get("message")
target = data.get("target_uin")
if msg == "offline" and target:
if _client_instance.dialing_uin == target:
_client_instance.dialing_uin = None
if target in _client_instance.contacts:
_client_instance.contacts[target]["status"] = "offline"
_client_instance.add_to_history(target, "[SYSTEM]: Contact went offline. Transmission preserved.")
_client_instance.refresh_ui()