_globalInstance <- -1; local _clientTokens = {}; class PyG2O { _connection = -1; _silent = false; _url = -1; _reconnect_attempts = 0; _max_reconnect_attempts = 0; constructor(url, silent = false, headers = {}, max_reconnect_attempts = 0) { _url = url; _max_reconnect_attempts = max_reconnect_attempts; _silent = silent; _connection = WebsocketClient(); _connection.silent = _silent; _connection.setUrl(_url); _connection.headers = headers; _connection.onOpen = _onOpen.bindenv(this); _connection.onClose = _onClose.bindenv(this); _connection.onMessage = _onMessage.bindenv(this); if (_globalInstance == -1) _globalInstance = this; } function start() { _connection.start(); if (_connection.running) print("[PyG2O] Initializing connection on " + _url); } function stop() { _connection.stop(); if (!_connection.running) print("[PyG2O] Stopped connection"); } function _send(data, uuid = "none") { if (uuid != "none") data["uuid"] <- uuid; _connection.send(JSON.dump_ansi(data, 2)); } function _onOpen(url) { if (!_silent) print("[PyG2O] Successfully connected to " + url); _send({"init_temp_tokens": _clientTokens}); } function _onClose(url, message) { if (_max_reconnect_attempts == 0) return; _reconnect_attempts += 1; if (_reconnect_attempts < _max_reconnect_attempts) return; _connection.stop(); } function _onMessage(url, message) { local request = JSON.parse_ansi(message); if (!("uuid" in request) || !("data" in request)) return; _message_call.bindenv(this)(request); } function generateClientPassword() { local chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"; local result = ""; local length = 32; for (local i = 0; i < length; i++) { local randomIndex = rand() % chars.len(); result += chars.slice(randomIndex, randomIndex + 1); } return result; } } addEventHandler("onPlayerJoin", function(playerid){ local new_token = _globalInstance.generateClientPassword(); _globalInstance._send({"create_temp_token": new_token}) _clientTokens[playerid] <- new_token; local packet = Packet(); packet.writeUInt8(250); packet.writeString(new_token); packet.send(playerid, RELIABLE); }); addEventHandler("onPlayerDisconnect", function(playerid, reason){ _globalInstance._send({"remove_temp_token": _clientTokens[playerid]}); delete _clientTokens[playerid]; });