153 lines
7.3 KiB
Python
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() |