mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 22:03:20 +00:00
Work on overlay natives
This commit is contained in:
parent
9a5aa5dd5f
commit
74f04f4847
6 changed files with 543 additions and 117 deletions
84
scripting/include/overlay.inc
Normal file
84
scripting/include/overlay.inc
Normal file
|
@ -0,0 +1,84 @@
|
|||
#if defined _overlay_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _overlay_included
|
||||
#include <ripext>
|
||||
|
||||
native bool SendTempUI(int client, const char[] id, int lifetime, JSONObject element);
|
||||
|
||||
native bool ShowUI(int client, const char[] elemNamespace, const char[] elemId, JSONObject variables);
|
||||
|
||||
native bool HideUI(int client, const char[] elemNamespace, const char[] elemId);
|
||||
|
||||
native bool PlayAudio(int client, const char[] url);
|
||||
|
||||
native bool IsOverlayConnected();
|
||||
|
||||
forward void OnUIAction(const char[] elemNamespace, const char[] elemId, const char[] action);
|
||||
|
||||
typedef UIActionCallback = function void (const char[][] args, int numArgs);
|
||||
|
||||
methodmap UIElement < JSONObject {
|
||||
public UIElement(const char[] elemNamespace, const char[] elemId) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("namespace", elemNamespace);
|
||||
obj.SetString("id", elemId);
|
||||
obj.SetBool("visibility", false);
|
||||
|
||||
return view_as<UIElement>(obj);
|
||||
}
|
||||
|
||||
property bool Visible {
|
||||
public get() {
|
||||
return view_as<JSONObject>(this).GetBool("visibility");
|
||||
}
|
||||
public set(bool value) {
|
||||
view_as<JSONObject>(this).SetBool("visibility", value);
|
||||
this.Send();
|
||||
}
|
||||
}
|
||||
|
||||
/** Is the UI element globally sent to all connected players?
|
||||
* Specify players with .AddClient() or clear with .ClearClients()
|
||||
*/
|
||||
property bool Global {
|
||||
public get() {
|
||||
return !view_as<JSONObject>(this).HasKey("steamids")
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVariable(const char[] id, int value) {
|
||||
view_as<JSONObject>(this).SetInt(id, value);
|
||||
}
|
||||
|
||||
public void SetVariableFloat(const char[] id, float value) {
|
||||
view_as<JSONObject>(this).SetFloat(id, value);
|
||||
}
|
||||
|
||||
public void SetVariableString(const char[] id, const char[] value) {
|
||||
view_as<JSONObject>(this).SetString(id, value);
|
||||
}
|
||||
|
||||
public void SetVariableBool(const char[] id, bool value) {
|
||||
view_as<JSONObject>(this).SetBool(id, value);
|
||||
}
|
||||
|
||||
public void SetActionCallback(UIActionCallback callback) {}
|
||||
|
||||
public void AddClient(const char[] steamid) {
|
||||
// if(!IsClientInGame(client) || steamidCache[client][0] == '\0') ThrowError("Client %d is not connected, ingame, or authorized");
|
||||
JSONObject obj = view_as<JSONObject>(this);
|
||||
JSONArray steamids = view_as<JSONArray>(obj.Get("steamids"));
|
||||
if(steamids == null) {
|
||||
steamids = new JSONArray();
|
||||
obj.Set("steamids", steamids)
|
||||
}
|
||||
steamids.PushString(steamid);
|
||||
}
|
||||
|
||||
public void ClearClients() {
|
||||
view_as<JSONObject>(this).Remove("steamids");
|
||||
}
|
||||
|
||||
public native bool Send();
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <ripext/json>
|
||||
#include <ripext/http>
|
||||
#include <ripext/websocket>
|
||||
#include <ripext/crypto>
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
|
|
35
scripting/include/ripext/crypto.inc
Normal file
35
scripting/include/ripext/crypto.inc
Normal file
|
@ -0,0 +1,35 @@
|
|||
methodmap Crypto
|
||||
{
|
||||
|
||||
public native bool MD5(const char[] source, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool MD5File(const char[] file, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool SHA1(const char[] source, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool SHA1File(const char[] file, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool SHA256(const char[] source, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool SHA256File(const char[] file, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool SHA512(const char[] source, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool SHA512File(const char[] file, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool CRC16(const char[] source, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool CRC16File(const char[] file, char[] buffer, int maxlength, bool uppercase = true);
|
||||
|
||||
public native bool CRC32(const char[] source, char[] buffer, int maxlength, bool uppercase = true, bool hexdecimal = true);
|
||||
|
||||
public native bool CRC32File(const char[] file, char[] buffer, int maxlength, bool uppercase = true, bool hexdecimal = true);
|
||||
|
||||
// - 1 is returned on success (the string output buffer is sufficient)
|
||||
// otherwise it is the minimum buffer length required
|
||||
public native int Base64Encode(const char[] source, char[] buffer, int maxlength);
|
||||
|
||||
// - 1 is returned on success (the string output buffer is sufficient)
|
||||
// otherwise it is the minimum buffer length required
|
||||
public native int Base64Decode(const char[] source, char[] buffer, int maxlength);
|
||||
};
|
|
@ -76,6 +76,15 @@ typeset HTTPFileCallback
|
|||
function void (HTTPStatus status, any value, const char[] error);
|
||||
};
|
||||
|
||||
typeset HTTPFileProgressCallback
|
||||
{
|
||||
// dltotal is the total number of bytes libcurl expects to download in this transfer
|
||||
// dlnow is the number of bytes downloaded so far
|
||||
// ultotal is the total number of bytes libcurl expects to upload in this transfer
|
||||
// ulnow is the number of bytes uploaded so far
|
||||
function void (bool isUpload, int dltotal, int dlnow, int ultotal, int ulnow);
|
||||
};
|
||||
|
||||
methodmap HTTPRequest < Handle
|
||||
{
|
||||
// Creates an HTTP request.
|
||||
|
@ -110,6 +119,27 @@ methodmap HTTPRequest < Handle
|
|||
// @param password Password to use.
|
||||
public native void SetBasicAuth(const char[] username, const char[] password);
|
||||
|
||||
/**
|
||||
* Sets proxy for the request.
|
||||
*
|
||||
* @param proxy Hostname or dotted numerical IP address. A numerical IPv6 address must be written within [brackets].
|
||||
* To specify port number in this string, append :[port] to the end of the host name (default: 1080).
|
||||
* The proxy string may be prefixed with [scheme]:// to specify which kind of proxy is used.
|
||||
* http://
|
||||
* HTTP Proxy. Default when no scheme is specified.
|
||||
* https://
|
||||
* HTTPS Proxy.
|
||||
* socks4://
|
||||
* SOCKS4 Proxy.
|
||||
* socks4a://
|
||||
* SOCKS4a Proxy. Proxy resolves URL hostname.
|
||||
* socks5://
|
||||
* SOCKS5 Proxy.
|
||||
* socks5h://
|
||||
* SOCKS5 Proxy. Proxy resolves URL hostname.
|
||||
*/
|
||||
public native void SetProxy(const char[] proxy);
|
||||
|
||||
// Sets an HTTP header.
|
||||
//
|
||||
// @param name Header name.
|
||||
|
@ -167,7 +197,7 @@ methodmap HTTPRequest < Handle
|
|||
// @param path File path to write to.
|
||||
// @param callback A function to use as a callback when the download has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
public native void DownloadFile(const char[] path, HTTPFileCallback callback, any value = 0);
|
||||
public native void DownloadFile(const char[] path, HTTPFileCallback callback, HTTPFileProgressCallback progresscallback, any value = 0);
|
||||
|
||||
// Uploads a file.
|
||||
//
|
||||
|
@ -177,7 +207,7 @@ methodmap HTTPRequest < Handle
|
|||
// @param path File path to read from.
|
||||
// @param callback A function to use as a callback when the upload has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
public native void UploadFile(const char[] path, HTTPFileCallback callback, any value = 0);
|
||||
public native void UploadFile(const char[] path, HTTPFileCallback callback, HTTPFileProgressCallback progresscallback, any value = 0);
|
||||
|
||||
// Performs an HTTP POST request with form data.
|
||||
//
|
||||
|
@ -228,6 +258,13 @@ methodmap HTTPResponse
|
|||
// @return True on success, false if the header was not found.
|
||||
public native bool GetHeader(const char[] name, char[] buffer, int maxlength);
|
||||
|
||||
// Retrieves an HTTP response string from the response.
|
||||
//
|
||||
// @param buffer String buffer to store value.
|
||||
// @param maxlength Maximum length of the string buffer.
|
||||
// @return True on success, false if the response string was not found.
|
||||
public native bool GetResponseStr(char[] buffer, int maxlength);
|
||||
|
||||
// Retrieves the JSON data of the response.
|
||||
//
|
||||
// @error Invalid JSON response.
|
||||
|
@ -239,121 +276,9 @@ methodmap HTTPResponse
|
|||
property HTTPStatus Status {
|
||||
public native get();
|
||||
}
|
||||
};
|
||||
|
||||
// Deprecated. Use HTTPRequest instead.
|
||||
methodmap HTTPClient < Handle
|
||||
{
|
||||
// Creates an HTTP client.
|
||||
//
|
||||
// The HTTPClient must be freed via delete or CloseHandle().
|
||||
//
|
||||
// @param baseURL Base URL to the REST API.
|
||||
#pragma deprecated Use HTTPRequest instead.
|
||||
public native HTTPClient(const char[] baseURL);
|
||||
|
||||
// Sets an HTTP header to be used for all requests.
|
||||
//
|
||||
// @param name Header name.
|
||||
// @param value String value to set.
|
||||
#pragma deprecated Use HTTPRequest.SetHeader() instead.
|
||||
public native void SetHeader(const char[] name, const char[] value);
|
||||
|
||||
// Performs an HTTP GET request.
|
||||
//
|
||||
// @param endpoint API endpoint to request.
|
||||
// @param callback A function to use as a callback when the request has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.Get() instead.
|
||||
public native void Get(const char[] endpoint, HTTPRequestCallback callback, any value = 0);
|
||||
|
||||
// Performs an HTTP POST request.
|
||||
//
|
||||
// @param endpoint API endpoint to request.
|
||||
// @param data JSON data to send.
|
||||
// @param callback A function to use as a callback when the request has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.Post() instead.
|
||||
public native void Post(const char[] endpoint, JSON data, HTTPRequestCallback callback, any value = 0);
|
||||
|
||||
// Performs an HTTP PUT request.
|
||||
//
|
||||
// @param endpoint API endpoint to request.
|
||||
// @param data JSON data to send.
|
||||
// @param callback A function to use as a callback when the request has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.Put() instead.
|
||||
public native void Put(const char[] endpoint, JSON data, HTTPRequestCallback callback, any value = 0);
|
||||
|
||||
// Performs an HTTP PATCH request.
|
||||
//
|
||||
// @param endpoint API endpoint to request.
|
||||
// @param data JSON data to send.
|
||||
// @param callback A function to use as a callback when the request has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.Patch() instead.
|
||||
public native void Patch(const char[] endpoint, JSON data, HTTPRequestCallback callback, any value = 0);
|
||||
|
||||
// Performs an HTTP DELETE request.
|
||||
//
|
||||
// @param endpoint API endpoint to request.
|
||||
// @param callback A function to use as a callback when the request has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.Delete() instead.
|
||||
public native void Delete(const char[] endpoint, HTTPRequestCallback callback, any value = 0);
|
||||
|
||||
// Downloads a file.
|
||||
//
|
||||
// @param endpoint API endpoint to download from.
|
||||
// @param path File path to write to.
|
||||
// @param callback A function to use as a callback when the download has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.DownloadFile() instead.
|
||||
public native void DownloadFile(const char[] endpoint, const char[] path, HTTPFileCallback callback, any value = 0);
|
||||
|
||||
// Uploads a file.
|
||||
//
|
||||
// This function performs an HTTP PUT request. The file contents are sent in the request body.
|
||||
//
|
||||
// @param endpoint API endpoint to upload to.
|
||||
// @param path File path to read from.
|
||||
// @param callback A function to use as a callback when the upload has finished.
|
||||
// @param value Optional value to pass to the callback function.
|
||||
#pragma deprecated Use HTTPRequest.UploadFile() instead.
|
||||
public native void UploadFile(const char[] endpoint, const char[] path, HTTPFileCallback callback, any value = 0);
|
||||
|
||||
// Connect timeout in seconds. Defaults to 10.
|
||||
#pragma deprecated Use HTTPRequest.ConnectTimeout instead.
|
||||
property int ConnectTimeout {
|
||||
// Retrieves the HTTP response length.
|
||||
property int ResponseDataLength {
|
||||
public native get();
|
||||
public native set(int connectTimeout);
|
||||
}
|
||||
|
||||
// Follow HTTP 3xx redirects. Defaults to true.
|
||||
#pragma deprecated Use HTTPRequest.MaxRedirects instead.
|
||||
property bool FollowLocation {
|
||||
public native get();
|
||||
public native set(bool followLocation);
|
||||
}
|
||||
|
||||
// Timeout in seconds. Defaults to 30.
|
||||
#pragma deprecated Use HTTPRequest.Timeout instead.
|
||||
property int Timeout {
|
||||
public native get();
|
||||
public native set(int timeout);
|
||||
}
|
||||
|
||||
// Maximum upload speed in bytes per second. Defaults to unlimited speed.
|
||||
#pragma deprecated Use HTTPRequest.MaxSendSpeed instead.
|
||||
property int MaxSendSpeed {
|
||||
public native get();
|
||||
public native set(int speed);
|
||||
}
|
||||
|
||||
// Maximum download speed in bytes per second. Defaults to unlimited speed.
|
||||
#pragma deprecated Use HTTPRequest.MaxRecvSpeed instead.
|
||||
property int MaxRecvSpeed {
|
||||
public native get();
|
||||
public native set(int speed);
|
||||
}
|
||||
};
|
42
scripting/include/ripext/websocket.inc
Normal file
42
scripting/include/ripext/websocket.inc
Normal file
|
@ -0,0 +1,42 @@
|
|||
typeset WebSocket_ReadCallback
|
||||
{
|
||||
//WebSocket_JSON
|
||||
function void (WebSocket ws, JSON message, any data);
|
||||
//Websocket_STRING
|
||||
function void (WebSocket ws, const char[] buffer, any data);
|
||||
}
|
||||
|
||||
typeset WebSocket_ConnectCallback
|
||||
{
|
||||
function void (WebSocket ws, any data);
|
||||
}
|
||||
|
||||
enum WebSocket_Protocol {
|
||||
WebSocket_JSON,
|
||||
Websocket_STRING,
|
||||
}
|
||||
|
||||
methodmap WebSocket < Handle {
|
||||
|
||||
// Creates an WebSocket request.
|
||||
//
|
||||
// The Handle must be freed via delete or CloseHandle().
|
||||
//
|
||||
// @param url URL to the Websocket endpoint Such as [scheme]://[hostname]:[port]?[QueryParam1]&[QueryParam2].
|
||||
// [scheme] Support ws or wss
|
||||
// [hostname] Support Domain or IP
|
||||
// For example ws://[hostname]:[port]?test1=1&test2=2 Or wss://[hostname]:[port]?test1=1&test2=2
|
||||
public native WebSocket(const char[] url);
|
||||
public native bool SetHeader(const char[] header, const char[] value);
|
||||
public native bool Connect();
|
||||
public native bool Close();
|
||||
public native bool SetReadCallback(WebSocket_Protocol protocol, WebSocket_ReadCallback callback, any data=0);
|
||||
public native bool SetConnectCallback(WebSocket_ConnectCallback callback, any data=0);
|
||||
public native bool SetDisconnectCallback(WebSocket_ConnectCallback callback, any data=0);
|
||||
public native bool Write(JSON json);
|
||||
public native bool WriteString(const char[] content);
|
||||
// Returns whether the tcp stream is open
|
||||
public native bool SocketOpen();
|
||||
// Returns the websocket connect status
|
||||
public native bool WsOpen();
|
||||
}
|
338
scripting/sm_overlay.sp
Normal file
338
scripting/sm_overlay.sp
Normal file
|
@ -0,0 +1,338 @@
|
|||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
#define USER_AGENT "OverlayServer/v1.0.0"
|
||||
#define MAX_ATTEMPT_TIMEOUT 120.0
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
//#include <sdkhooks>
|
||||
#include <ripext>
|
||||
|
||||
WebSocket g_ws;
|
||||
ConVar cvarManagerUrl; char managerUrl[128];
|
||||
ConVar cvarManagerToken; char authToken[512];
|
||||
int connectAttempts;
|
||||
authState g_authState;
|
||||
JSONObject g_globalVars;
|
||||
|
||||
enum authState {
|
||||
AuthError = -1,
|
||||
NotAuthorized,
|
||||
Authorized,
|
||||
}
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Overlay",
|
||||
author = "jackzmc",
|
||||
description = "",
|
||||
version = PLUGIN_VERSION,
|
||||
url = "https://github.com/Jackzmc/sourcemod-plugins"
|
||||
};
|
||||
|
||||
enum outEvent {
|
||||
Event_PlayerJoin,
|
||||
Event_PlayerLeft,
|
||||
Event_GameState,
|
||||
Event_RegisterTempUI,
|
||||
Event_UpdateUI,
|
||||
Event_Invalid
|
||||
}
|
||||
char OUT_EVENT_IDS[view_as<int>(Event_Invalid)][] = {
|
||||
"player_joined",
|
||||
"player_left",
|
||||
"game_state",
|
||||
"register_temp_ui",
|
||||
"update_ui"
|
||||
};
|
||||
char steamidCache[MAXPLAYERS+1][32];
|
||||
|
||||
// TODO: add natives
|
||||
|
||||
public void OnPluginStart() {
|
||||
EngineVersion g_Game = GetEngineVersion();
|
||||
if(g_Game != Engine_Left4Dead && g_Game != Engine_Left4Dead2) {
|
||||
SetFailState("This plugin is for L4D/L4D2 only.");
|
||||
}
|
||||
|
||||
g_globalVars = new JSONObject();
|
||||
|
||||
cvarManagerUrl = CreateConVar("sm_overlay_manager_url", "ws://localhost:3011/socket", "");
|
||||
cvarManagerUrl.AddChangeHook(OnUrlChanged);
|
||||
OnUrlChanged(cvarManagerUrl, "", "");
|
||||
|
||||
cvarManagerToken = CreateConVar("sm_overlay_manager_token", "", "The auth token for this server");
|
||||
cvarManagerToken.AddChangeHook(OnTokenChanged);
|
||||
OnTokenChanged(cvarManagerToken, "", "");
|
||||
|
||||
HookEvent("player_disconnect", Event_PlayerDisconnect);
|
||||
|
||||
RegAdminCmd("sm_overlay", Command_Overlay, ADMFLAG_GENERIC);
|
||||
|
||||
AutoExecConfig(true);
|
||||
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientInGame(i) && !IsFakeClient(i)) {
|
||||
OnClientAuthorized(i, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPluginEnd() {
|
||||
if(g_ws != null) {
|
||||
g_ws.Close();
|
||||
delete g_ws;
|
||||
}
|
||||
}
|
||||
|
||||
bool isManagerReady() {
|
||||
return g_ws != null && g_ws.WsOpen() && g_authState == Authorized;
|
||||
}
|
||||
|
||||
void SendAllPlayers() {
|
||||
if(!isManagerReady) return;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientInGame(i) && !IsFakeClient(i)) {
|
||||
SendEvent_PlayerJoined(steamidCache[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Action Command_Overlay(int client, int args) {
|
||||
char arg[32];
|
||||
GetCmdArg(1, arg, sizeof(arg));
|
||||
if(StrEqual(arg, "info")) {
|
||||
ReplyToCommand(client, "URL: %s", managerUrl);
|
||||
ReplyToCommand(client, "Socket Connected: %b | WS Connected: %b", g_ws.SocketOpen(), g_ws.WsOpen());
|
||||
ReplyToCommand(client, "Auth State: %d", g_authState);
|
||||
} else if(StrEqual(arg, "test")) {
|
||||
SendAllPlayers();
|
||||
|
||||
JSONObject temp = new JSONObject();
|
||||
temp.SetString("type", "text");
|
||||
temp.SetString("text", "Blah blah blah");
|
||||
JSONObject defaults = new JSONObject();
|
||||
defaults.SetString("title", "Test Element");
|
||||
JSONObject pos = new JSONObject();
|
||||
pos.SetInt("x", 200);
|
||||
pos.SetInt("y", 200);
|
||||
defaults.Set("pos", pos);
|
||||
temp.Set("defaults", defaults);
|
||||
SendEvent_RegisterTempUI("temp", 180, temp);
|
||||
ReplyToCommand(client, "Sent");
|
||||
} else if(StrEqual(arg, "connect")) {
|
||||
ConnectManager();
|
||||
} else {
|
||||
ReplyToCommand(client, "Unknown arg");
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
void OnUrlChanged(ConVar cvar, const char[] oldValue, const char[] newValue) {
|
||||
cvarManagerUrl.GetString(managerUrl, sizeof(managerUrl));
|
||||
if(g_ws != null) {
|
||||
DisconnectManager();
|
||||
delete g_ws;
|
||||
}
|
||||
g_ws = new WebSocket(managerUrl);
|
||||
g_ws.SetHeader("User-Agent", USER_AGENT);
|
||||
g_ws.SetConnectCallback(OnWSConnect);
|
||||
g_ws.SetDisconnectCallback(OnWSDisconnect);
|
||||
g_ws.SetReadCallback(WebSocket_JSON, OnWSJson);
|
||||
PrintToServer("[Overlay] Changed url to: %s", managerUrl);
|
||||
}
|
||||
void OnTokenChanged(ConVar cvar, const char[] oldValue, const char[] newValue) {
|
||||
cvarManagerToken.GetString(authToken, sizeof(authToken));
|
||||
}
|
||||
|
||||
public void OnClientAuthorized(int client, const char[] auth) {
|
||||
if(!g_ws.SocketOpen())
|
||||
ConnectManager();
|
||||
if(!IsFakeClient(client)) {
|
||||
GetClientAuthId(client, AuthId_Steam2, steamidCache[client], 32);
|
||||
SendEvent_PlayerJoined(steamidCache[client]);
|
||||
}
|
||||
}
|
||||
|
||||
void Event_PlayerDisconnect(Event event, const char[] name, bool dontBroadcast) {
|
||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||
if(client > 0 && !IsFakeClient(client)) {
|
||||
SendEvent_PlayerLeft(steamidCache[client]);
|
||||
}
|
||||
if(GetClientCount(false) == 0) {
|
||||
DisconnectManager();
|
||||
}
|
||||
}
|
||||
|
||||
void OnWSConnect(WebSocket ws, any arg) {
|
||||
connectAttempts = 0;
|
||||
g_authState = NotAuthorized;
|
||||
PrintToServer("[Overlay] Connected, authenticating");
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("type", "server");
|
||||
obj.SetString("auth_token", authToken);
|
||||
ws.Write(obj);
|
||||
delete obj;
|
||||
}
|
||||
|
||||
void OnWSDisconnect(WebSocket ws, int attempt) {
|
||||
if(g_authState == AuthError) {
|
||||
return;
|
||||
}
|
||||
connectAttempts++;
|
||||
float nextAttempt = Exponential(float(connectAttempts) / 2.0) + 2.0;
|
||||
if(nextAttempt > MAX_ATTEMPT_TIMEOUT) nextAttempt = MAX_ATTEMPT_TIMEOUT;
|
||||
PrintToServer("[Overlay] Disconnected, retrying in %.0f seconds", nextAttempt);
|
||||
CreateTimer(nextAttempt, Timer_Reconnect);
|
||||
}
|
||||
|
||||
Action Timer_Reconnect(Handle h) {
|
||||
ConnectManager();
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
void OnWSJson(WebSocket ws, JSON message, any data) {
|
||||
JSONObject obj = view_as<JSONObject>(message);
|
||||
if(obj.HasKey("error")) {
|
||||
if(g_authState == NotAuthorized) {
|
||||
g_authState = AuthError;
|
||||
}
|
||||
char buffer[2048];
|
||||
message.ToString(buffer, sizeof(buffer));
|
||||
PrintToServer("[Overlay] Error: %s", buffer);
|
||||
} else {
|
||||
char buffer[2048];
|
||||
message.ToString(buffer, sizeof(buffer));
|
||||
PrintToServer("[Overlay] Got JSON: %s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConnectManager() {
|
||||
DisconnectManager();
|
||||
if(authToken[0] == '\0') return;
|
||||
|
||||
PrintToServer("[Overlay] Connecting to \"%s\"", managerUrl);
|
||||
if(g_ws.Connect()) {
|
||||
PrintToServer("[Overlay] Connected");
|
||||
}
|
||||
}
|
||||
|
||||
void DisconnectManager() {
|
||||
if(g_ws.WsOpen()) {
|
||||
g_ws.Close();
|
||||
}
|
||||
}
|
||||
|
||||
void SendEvent_PlayerJoined(const char[] steamid) {
|
||||
if(!isManagerReady()) return;
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("type", OUT_EVENT_IDS[Event_PlayerJoin]);
|
||||
obj.SetString("steamid", steamid);
|
||||
g_ws.Write(obj);
|
||||
obj.Clear();
|
||||
delete obj;
|
||||
}
|
||||
|
||||
void SendEvent_PlayerLeft(const char[] steamid) {
|
||||
if(!isManagerReady()) return;
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("type", OUT_EVENT_IDS[Event_PlayerLeft]);
|
||||
obj.SetString("steamid", steamid);
|
||||
g_ws.Write(obj);
|
||||
obj.Clear();
|
||||
delete obj;
|
||||
}
|
||||
|
||||
void SendEvent_RegisterTempUI(const char[] elemId, int expiresSeconds = 0, JSONObject element) {
|
||||
if(!isManagerReady()) return;
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.SetString("type", OUT_EVENT_IDS[Event_RegisterTempUI]);
|
||||
obj.SetString("elem_id", elemId);
|
||||
if(expiresSeconds > 0)
|
||||
obj.SetInt("expires_seconds", expiresSeconds);
|
||||
obj.Set("element", element);
|
||||
g_ws.Write(obj);
|
||||
obj.Clear();
|
||||
delete obj;
|
||||
}
|
||||
|
||||
// namespace optional
|
||||
void SendEvent_UpdateUI(const char[] elemNamespace, const char[] elemId, bool visibility, JSONObject variables) {
|
||||
if(!isManagerReady()) return;
|
||||
JSONObject obj = new JSONObject();
|
||||
if(elemNamespace[0] != '\0')
|
||||
obj.SetString("namespace", elemNamespace);
|
||||
obj.SetString("elem_id", elemId);
|
||||
obj.SetBool("visibility", visibility);
|
||||
obj.Set("variables", variables);
|
||||
g_ws.Write(obj);
|
||||
obj.Clear();
|
||||
delete obj;
|
||||
}
|
||||
|
||||
//SendTempUI(int client, const char[] id, int lifetime, JSONObject element);
|
||||
bool Native_SendTempUI(Handle plugin, int numParams) {
|
||||
if(!isManagerReady()) return false;
|
||||
|
||||
int client = GetNativeCell(1);
|
||||
if(steamidCache[client][0] == '\0') return false;
|
||||
|
||||
char id[64];
|
||||
GetNativeString(2, id, sizeof(id));
|
||||
|
||||
int lifetime = GetNativeCell(3);
|
||||
|
||||
JSONObject obj = GetNativeCell(4);
|
||||
|
||||
SendEvent_RegisterTempUI(id, lifetime, obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
//ShowUI(int client, const char[] elemNamespace, const char[] elemId, JSONObject variables);
|
||||
bool Native_ShowUI(Handle plugin, int numParams) {
|
||||
if(!isManagerReady()) return false;
|
||||
|
||||
char elemNamespace[64], id[64];
|
||||
GetNativeString(1, elemNamespace, sizeof(elemNamespace));
|
||||
GetNativeString(2, id, sizeof(id));
|
||||
|
||||
JSONObject variables = GetNativeCell(3);
|
||||
|
||||
SendEvent_UpdateUI(elemNamespace, id, true, variables);
|
||||
return true;
|
||||
}
|
||||
|
||||
//HideUI(int client, const char[] elemNamespace, const char[] elemId);
|
||||
bool Native_HideUI(Handle plugin, int numParams) {
|
||||
if(!isManagerReady()) return false;
|
||||
|
||||
char elemNamespace[64], id[64];
|
||||
GetNativeString(1, elemNamespace, sizeof(elemNamespace));
|
||||
GetNativeString(2, id, sizeof(id));
|
||||
|
||||
SendEvent_UpdateUI(elemNamespace, id, false, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
//PlayAudio(int client, const char[] url);
|
||||
bool Native_PlayAudio(Handle plugin, int numParams) {
|
||||
if(!isManagerReady()) return false;
|
||||
|
||||
char url[256];
|
||||
GetNativeString(1, url, sizeof(url));
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//IsOverlayConnected();
|
||||
bool Native_IsOverlayConnected(Handle plugin, int numParams) {
|
||||
return isManagerReady();
|
||||
}
|
||||
|
||||
void OnUIAction(const char[] elemNamespace, const char[] elemId, const char[] action);
|
Loading…
Add table
Add a link
Reference in a new issue