From e694dcddcd8ad2bee1c4efcf43bb9656980168bb Mon Sep 17 00:00:00 2001 From: Linventif Date: Fri, 9 Feb 2024 20:56:17 +0100 Subject: [PATCH] big rewrite of everything --- lua/autorun/gmod_integration.lua | 2 +- .../client/cl_context_menu.lua | 12 + .../client/{cl_gui.lua => cl_gui_admin.lua} | 52 +-- lua/gmod_integration/client/cl_gui_link.lua | 52 +++ lua/gmod_integration/client/cl_hook.lua | 2 +- lua/gmod_integration/client/cl_main.lua | 61 +--- lua/gmod_integration/client/cl_net.lua | 1 + .../client/cl_screenshots.lua | 71 +++++ .../server/sv__api_format.lua | 14 + lua/gmod_integration/server/sv__websocket.lua | 14 +- lua/gmod_integration/server/sv_con.lua | 4 - lua/gmod_integration/server/sv_filtrers.lua | 85 +++++ lua/gmod_integration/server/sv_hook.lua | 40 --- .../server/{sv_log.lua => sv_logs.lua} | 62 ++-- lua/gmod_integration/server/sv_main.lua | 300 ------------------ lua/gmod_integration/server/sv_meta.lua | 12 - lua/gmod_integration/server/sv_net.lua | 6 +- lua/gmod_integration/server/sv_players.lua | 145 +++++++++ lua/gmod_integration/server/sv_rcon.lua | 8 + .../server/sv_screenshots.lua | 24 ++ lua/gmod_integration/server/sv_settings.lua | 65 ++++ lua/gmod_integration/server/sv_status.lua | 51 +++ lua/gmod_integration/server/sv_sync_bans.lua | 28 ++ lua/gmod_integration/server/sv_sync_chat.lua | 31 ++ lua/gmod_integration/server/sv_sync_names.lua | 33 ++ lua/gmod_integration/server/sv_sync_roles.lua | 35 ++ lua/gmod_integration/server/sv_sync_warns.lua | 15 + lua/gmod_integration/shared/sh_http.lua | 168 +++++----- 28 files changed, 815 insertions(+), 578 deletions(-) create mode 100644 lua/gmod_integration/client/cl_context_menu.lua rename lua/gmod_integration/client/{cl_gui.lua => cl_gui_admin.lua} (93%) create mode 100644 lua/gmod_integration/client/cl_gui_link.lua create mode 100644 lua/gmod_integration/client/cl_screenshots.lua create mode 100644 lua/gmod_integration/server/sv__api_format.lua create mode 100644 lua/gmod_integration/server/sv_filtrers.lua delete mode 100644 lua/gmod_integration/server/sv_hook.lua rename lua/gmod_integration/server/{sv_log.lua => sv_logs.lua} (82%) delete mode 100644 lua/gmod_integration/server/sv_main.lua delete mode 100644 lua/gmod_integration/server/sv_meta.lua create mode 100644 lua/gmod_integration/server/sv_players.lua create mode 100644 lua/gmod_integration/server/sv_rcon.lua create mode 100644 lua/gmod_integration/server/sv_screenshots.lua create mode 100644 lua/gmod_integration/server/sv_settings.lua create mode 100644 lua/gmod_integration/server/sv_status.lua create mode 100644 lua/gmod_integration/server/sv_sync_bans.lua create mode 100644 lua/gmod_integration/server/sv_sync_chat.lua create mode 100644 lua/gmod_integration/server/sv_sync_names.lua create mode 100644 lua/gmod_integration/server/sv_sync_roles.lua create mode 100644 lua/gmod_integration/server/sv_sync_warns.lua diff --git a/lua/autorun/gmod_integration.lua b/lua/autorun/gmod_integration.lua index 558500a..6125023 100644 --- a/lua/autorun/gmod_integration.lua +++ b/lua/autorun/gmod_integration.lua @@ -5,7 +5,7 @@ if game.SinglePlayer() then return end // gmInte = gmInte or {} -gmInte.version = "0.2.3" +gmInte.version = "0.3.0" gmInte.config = { ["redownloadMaterials"] = false, } diff --git a/lua/gmod_integration/client/cl_context_menu.lua b/lua/gmod_integration/client/cl_context_menu.lua new file mode 100644 index 0000000..17c337e --- /dev/null +++ b/lua/gmod_integration/client/cl_context_menu.lua @@ -0,0 +1,12 @@ +list.Set("DesktopWindows", "GmodIntegration:DesktopWindows", { + icon = "gmod_integration/logo_context.png", + title = "GM Integration", + width = 960, + height = 700, + onewindow = true, + init = function(icon, window) + window:Close() + gmInte.openAdminConfig() + end + } +) \ No newline at end of file diff --git a/lua/gmod_integration/client/cl_gui.lua b/lua/gmod_integration/client/cl_gui_admin.lua similarity index 93% rename from lua/gmod_integration/client/cl_gui.lua rename to lua/gmod_integration/client/cl_gui_admin.lua index 638e24d..fbb035b 100644 --- a/lua/gmod_integration/client/cl_gui.lua +++ b/lua/gmod_integration/client/cl_gui_admin.lua @@ -9,7 +9,7 @@ local configCat = { "Main", "Trust & Safety", "Punishment", - "Other" + "Advanced", } local possibleConfig = { @@ -118,7 +118,9 @@ local possibleConfig = { ["label"] = "Sync Ban", ["description"] = "Sync chat between the server and the discord server.", ["type"] = "checkbox", - ["disable"] = true, + ["condition"] = function(data) + return false // Disabled for now + end, ["value"] = function(setting, value) return value end, @@ -131,7 +133,9 @@ local possibleConfig = { ["label"] = "Sync Timeout", ["description"] = "Sync chat between the server and the discord server.", ["type"] = "checkbox", - ["disable"] = true, + ["condition"] = function(data) + return false // Disabled for now + end, ["value"] = function(setting, value) return value end, @@ -144,7 +148,9 @@ local possibleConfig = { ["label"] = "Sync Kick", ["description"] = "Sync chat between the server and the discord server.", ["type"] = "checkbox", - ["disable"] = true, + ["condition"] = function(data) + return false // Disabled for now + end, ["value"] = function(setting, value) return value end, @@ -157,7 +163,9 @@ local possibleConfig = { ["label"] = "Force Player Verif", ["description"] = "Sync chat between the server and the discord server.", ["type"] = "checkbox", - ["disable"] = true, + ["condition"] = function(data) + return false // Disabled for now + end, ["value"] = function(setting, value) return value end, @@ -170,7 +178,6 @@ local possibleConfig = { ["label"] = "Support Link", ["description"] = "Server ID found on the webpanel.", ["type"] = "textEntry", - ["disable"] = true, ["value"] = function(setting, value) return value end, @@ -190,7 +197,7 @@ local possibleConfig = { ["onEdit"] = function(setting, value) saveConfig(setting, value == "Enabled" && true || false) end, - ["category"] = "Other" + ["category"] = "Advanced" }, ['devInstance'] = { ["label"] = "Dev Instance", @@ -199,10 +206,13 @@ local possibleConfig = { ["value"] = function(setting, value) return value end, + ["condition"] = function(data) + return data.debug + end, ["onEdit"] = function(setting, value) saveConfig(setting, value == "Enabled" && true || false) end, - ["category"] = "Other" + ["category"] = "Advanced" } } @@ -245,6 +255,15 @@ local buttonsInfo = { } } +local colorTable = { + ["text"] = Color(255, 255, 255, 255), + ["background"] = Color(0, 0, 0, 200), + ["button"] = Color(0, 0, 0, 200), + ["buttonHover"] = Color(0, 0, 0, 255), + ["buttonText"] = Color(255, 255, 255, 255), + ["buttonTextHover"] = Color(255, 255, 255, 255), +} + function gmInte.needRestart() local frame = vgui.Create("DFrame") frame:SetSize(400, 120) @@ -360,7 +379,7 @@ function gmInte.openConfigMenu(data) end elseif (v.type == "checkbox") then input = vgui.Create("DComboBox", panel) - if (v.disable) then + if (v.condition && !v.condition(data)) then input:SetEnabled(false) end input:AddChoice("Enabled") @@ -420,17 +439,4 @@ function gmInte.openConfigMenu(data) frame.OnClose = function() if (needRestart) then gmInte.needRestart() end end -end - -list.Set("DesktopWindows", "GmodIntegration:DesktopWindows", { - icon = "gmod_integration/logo_context.png", - title = "GM Integration", - width = 960, - height = 700, - onewindow = true, - init = function(icon, window) - window:Close() - gmInte.openAdminConfig() - end - } -) \ No newline at end of file +end \ No newline at end of file diff --git a/lua/gmod_integration/client/cl_gui_link.lua b/lua/gmod_integration/client/cl_gui_link.lua new file mode 100644 index 0000000..5e4b520 --- /dev/null +++ b/lua/gmod_integration/client/cl_gui_link.lua @@ -0,0 +1,52 @@ +function gmInte.openVerifPopup() + local frame = vgui.Create("DFrame") + frame:SetSize(400, 140) + frame:Center() + frame:SetTitle("Gmod Integration - Verification Required") + frame:SetDraggable(false) + frame:ShowCloseButton(false) + frame:MakePopup() + + local messagePanel = vgui.Create("DPanel", frame) + messagePanel:Dock(TOP) + messagePanel:SetSize(300, 40) + messagePanel:DockMargin(10, 0, 10, 10) + messagePanel:SetBackgroundColor(Color(0, 0, 0, 0)) + + local messageLabel = vgui.Create("DLabel", messagePanel) + messageLabel:Dock(FILL) + messageLabel:SetText("Hey! It looks like you haven't linked your Steam account to Discord yet. This is required to play on this server. Please click the button below to link your account. After you've done that, click the refresh button.") + messageLabel:SetContentAlignment(5) + messageLabel:SetWrap(true) + + local buttonGrid = vgui.Create("DGrid", frame) + buttonGrid:Dock(BOTTOM) + buttonGrid:DockMargin(5, 10, 5, 5) + buttonGrid:SetCols(2) + buttonGrid:SetColWide(frame:GetWide() / 2 - 10) + buttonGrid:SetRowHeight(35) + + local button = vgui.Create("DButton") + button:SetText("Open Verification Page") + button.DoClick = function() + gui.OpenURL("https://verif.gmod-integration.com") + end + button:SetSize(buttonGrid:GetColWide(), buttonGrid:GetRowHeight()) + buttonGrid:AddItem(button) + + local button = vgui.Create("DButton") + button:SetText("Refresh Verification") + button.DoClick = function() + gmInte.get("/players/" .. LocalPlayer():SteamID64(), function(code, body) + gmInte.SendNet(6) + frame:Close() + end, + function(err) + LocalPlayer():ChatPrint("Failed to refresh verification: " .. err) + end) + end + button:SetSize(buttonGrid:GetColWide(), buttonGrid:GetRowHeight()) + buttonGrid:AddItem(button) +end + +gmInte.openVerifPopup() \ No newline at end of file diff --git a/lua/gmod_integration/client/cl_hook.lua b/lua/gmod_integration/client/cl_hook.lua index 86d960b..2a698c7 100644 --- a/lua/gmod_integration/client/cl_hook.lua +++ b/lua/gmod_integration/client/cl_hook.lua @@ -12,7 +12,7 @@ hook.Add("OnPlayerChat", "gmInte:OnPlayerChat:AdminCmd", function(ply, strText, strText = string.lower(strText) - if (strText == "/gminte") then + if (strText == "/gmi") then gmInte.openAdminConfig() return true end diff --git a/lua/gmod_integration/client/cl_main.lua b/lua/gmod_integration/client/cl_main.lua index aea0a93..2525b58 100644 --- a/lua/gmod_integration/client/cl_main.lua +++ b/lua/gmod_integration/client/cl_main.lua @@ -33,67 +33,8 @@ function gmInte.openAdminConfig() gmInte.SendNet(2) end -local ScreenshotRequested = false -hook.Add("PostRender", "gmInteScreenshot", function() - if (!ScreenshotRequested) then return end - ScreenshotRequested = false - - local captureData = { - format = "png", - x = 0, - y = 0, - w = ScrW(), - h = ScrH() - } - - local screenCapture = render.Capture(captureData) - screenCapture = util.Base64Encode(screenCapture) - gmInte.log("Screenshot Taken - " .. string.len(#screenCapture / 1024) .. "KB", true) - - gmInte.post("/player/screenshots", - { - ["steamID64"] = LocalPlayer():SteamID64(), - ["screenshot"] = screenCapture, - ["options"] = captureData, - ["name"] = LocalPlayer():Nick() - }, - function(code, body) - gmInte.log("Screenshot sent to Discord", true) - end, - function(code, body) - gmInte.log("Screenshot failed to send to Discord, error code: " .. code, true) - end - ) -end) - -function gmInte.takeScreenShot(serverID, authToken) - gmInte.config.id = serverID - gmInte.config.token = authToken - - timer.Simple(0.2, function() - ScreenshotRequested = true - end) -end - // // Concommands // -concommand.Add("gmod_integration_admin", gmInte.openAdminConfig) -concommand.Add("gmod_integration_screenshot", function() - gmInte.SendNet(4) -end) - -// -// Chat Commands -// - -hook.Add("OnPlayerChat", "gmInteChatCommands", function(ply, text, teamChat, isDead) - if (ply != LocalPlayer()) then return end - text = string.lower(text) - text = string.sub(text, 2) - - if (text == "screen") then - gmInte.SendNet(4) - end -end) \ No newline at end of file +concommand.Add("gmod_integration_admin", gmInte.openAdminConfig) \ No newline at end of file diff --git a/lua/gmod_integration/client/cl_net.lua b/lua/gmod_integration/client/cl_net.lua index 5938cfb..5e8608a 100644 --- a/lua/gmod_integration/client/cl_net.lua +++ b/lua/gmod_integration/client/cl_net.lua @@ -10,6 +10,7 @@ Upload 3 - Save Config 4 - Take ScreenShot 5 - Restart Map + 6 - Verify Me Receive 1 - Sync Chat 2 - Get Config diff --git a/lua/gmod_integration/client/cl_screenshots.lua b/lua/gmod_integration/client/cl_screenshots.lua new file mode 100644 index 0000000..36ce215 --- /dev/null +++ b/lua/gmod_integration/client/cl_screenshots.lua @@ -0,0 +1,71 @@ +// +// Hooks +// + +local ScreenshotRequested = false +hook.Add("PostRender", "gmInteScreenshot", function() + if (!ScreenshotRequested) then return end + ScreenshotRequested = false + + local captureData = { + format = "png", + x = 0, + y = 0, + w = ScrW(), + h = ScrH() + } + + local screenCapture = render.Capture(captureData) + screenCapture = util.Base64Encode(screenCapture) + gmInte.log("Screenshot Taken - " .. string.len(#screenCapture / 1024) .. "KB", true) + + gmInte.post("/screenshots", + { + ["steamID64"] = LocalPlayer():SteamID64(), + ["screenshot"] = screenCapture, + ["options"] = captureData, + ["name"] = LocalPlayer():Nick() + }, + function(code, body) + gmInte.log("Screenshot sent to Discord", true) + end, + function(code, body) + gmInte.log("Screenshot failed to send to Discord, error code: " .. code, true) + end + ) +end) + +// +// Methods +// + +function gmInte.takeScreenShot(serverID, authToken) + gmInte.config.id = serverID + gmInte.config.token = authToken + + timer.Simple(0.2, function() + ScreenshotRequested = true + end) +end + +// +// Console Commands +// + +concommand.Add("gmod_integration_screenshot", function() + gmInte.SendNet(4) +end) + +// +// Chat Commands +// + +hook.Add("OnPlayerChat", "gmInteChatCommands", function(ply, text, teamChat, isDead) + if (ply != LocalPlayer()) then return end + text = string.lower(text) + text = string.sub(text, 2) + + if (text == "screen") then + gmInte.SendNet(4) + end +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv__api_format.lua b/lua/gmod_integration/server/sv__api_format.lua new file mode 100644 index 0000000..11582f7 --- /dev/null +++ b/lua/gmod_integration/server/sv__api_format.lua @@ -0,0 +1,14 @@ +function gmInte.playerFormat(ply) + return { + steamID = ply:SteamID(), + steamID64 = ply:SteamID64(), + userGroup = ply:GetUserGroup(), + team = ply:Team(), + teamName = team.GetName(ply:Team()), + name = ply:Nick(), + kills = ply:Frags(), + deaths = ply:Deaths(), + customValues = ply:gmIntGetCustomValues(), + connectTime = math.Round(RealTime() - ply:gmIntGetConnectTime()), + } +end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv__websocket.lua b/lua/gmod_integration/server/sv__websocket.lua index c6faa6f..4e80cb8 100644 --- a/lua/gmod_integration/server/sv__websocket.lua +++ b/lua/gmod_integration/server/sv__websocket.lua @@ -1,3 +1,6 @@ +local websocketFQDN = "ws.gmod-integration.com" +local websocketDevFQDN = "dev-ws.gmod-integration.com" + // // WebSocket // @@ -30,16 +33,7 @@ if (!GWSockets) then end local function getWebSocketURL() - local url = "wss://ws.gmod-integration.com" - local devURL = "wss://dev-ws.gmod-integration.com" - - if (!gmInte.config.debug) then return url end - if (gmInte.config.devInstance) then - gmInte.log("Using dev Instance", true) - return devURL - end - - return url + return "wss://" .. (gmInte.config.dev and websocketDevFQDN or websocketFQDN) end local socket = GWSockets.createWebSocket(getWebSocketURL()) diff --git a/lua/gmod_integration/server/sv_con.lua b/lua/gmod_integration/server/sv_con.lua index b9648b7..4bae5d6 100644 --- a/lua/gmod_integration/server/sv_con.lua +++ b/lua/gmod_integration/server/sv_con.lua @@ -1,7 +1,3 @@ -// -// Console Commands -// - local conFuncs = { ["version"] = function() gmInte.log("Version: " .. gmInte.version) diff --git a/lua/gmod_integration/server/sv_filtrers.lua b/lua/gmod_integration/server/sv_filtrers.lua new file mode 100644 index 0000000..44571d7 --- /dev/null +++ b/lua/gmod_integration/server/sv_filtrers.lua @@ -0,0 +1,85 @@ +// +// Methods +// + +local function filterMessage(reason) + local Message = { + "", + "This server has player filtering enabled", + "You are not allowed to join this server", + "", + "Reason: " .. reason, + "", + "For more information, please contact the server owner", + "Help URL: " .. (gmInte.config.supportLink && gmInte.config.supportLink || "No Support Link"), + "", + "You can also contact us on our discord server", + "https://gmod-integration.com/discord", + "", + "Have a nice day", + "", + "Service provided by Gmod Integration", + } + + for k, v in pairs(Message) do + Message[k] = v .. "\n" + end + + return table.concat(Message) +end + +local function checkTrustFactor(trustLevel) + if (gmInte.config.filterOnTrust && (trustLevel < gmInte.config.minimalTrust)) then + return false + end + + return true +end + +local function checkBanStatus(banStatus) + if (gmInte.config.filterOnBan && banStatus) then + return false + end + + return true +end + +local function checkDiscordBanStatus(banStatus) + if (gmInte.config.syncBan && banStatus) then + return false + end + + return true +end + +local function playerFilter(data) + if (data.bot == 1) then return end + data.steamID64 = util.SteamIDTo64(data.networkid) + + gmInte.get("/players/" .. data.steamID64, + function(code, body) + if (!body.trust) then return end + + if (!checkBanStatus(body.ban)) then + game.KickID(data.networkid, filterMessage("You are banned from this server")) + end + + if (!checkDiscordBanStatus(body.discord_ban)) then + game.KickID(data.networkid, filterMessage("You are banned from our discord server")) + end + + if (!checkTrustFactor(body.trust)) then + game.KickID(data.networkid, filterMessage("Your trust factor is too low")) + end + end + ) +end + +// +// Hooks +// + +gameevent.Listen("player_connect") +hook.Add("player_connect", "gmInte:Player:Connect:Filter", function(data) + playerFilter(data) +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_hook.lua b/lua/gmod_integration/server/sv_hook.lua deleted file mode 100644 index d28a4ba..0000000 --- a/lua/gmod_integration/server/sv_hook.lua +++ /dev/null @@ -1,40 +0,0 @@ -// -// Server Hooks -// - -hook.Add("ShutDown", "gmInte:Server:ShutDown", function() - gmInte.serverShutDown() -end) - -hook.Add("Initialize", "gmInte.sendStatus", function() - timer.Simple(1, function() - gmInte.serverStart() - end) -end) - -// -// Player Hooks -// - -gameevent.Listen("player_connect") -hook.Add("player_connect", "gmInte:Player:Connect", function(data) - gmInte.playerConnect(data) - gmInte.playerFilter(data) -end) - -gameevent.Listen("server_addban") -hook.Add("server_addban", "gmInte:Player:Ban", function(data) - gmInte.playerBan(data) -end) - -hook.Add("PlayerDisconnected", "gmInte:Player:Disconnect", function(ply) - gmInte.playerDisconnected(ply) -end) - -hook.Add("onPlayerChangedName", "gmInte:PlayerChangeName", function(ply, old, new) - gmInte.playerChangeName(ply, old, new) -end) - -hook.Add("PlayerSay", "gmInte:PlayerSay", function(ply, text, team) - gmInte.playerSay(ply, text, team) -end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_log.lua b/lua/gmod_integration/server/sv_logs.lua similarity index 82% rename from lua/gmod_integration/server/sv_log.lua rename to lua/gmod_integration/server/sv_logs.lua index 038c2ff..310baff 100644 --- a/lua/gmod_integration/server/sv_log.lua +++ b/lua/gmod_integration/server/sv_logs.lua @@ -41,16 +41,6 @@ local function logFormatTeam(teamID, data) return data end -local function logFormatPlayer(ply, data) - data = data or {} - data.steamID64 = ply:SteamID64() - data.steamID = ply:SteamID() - data.nick = ply:Nick() - data.userGroup = ply:GetUserGroup() - data.team = logFormatTeam(ply:Team()) - return data -end - local function logDisable() return !gmInte.config.sendLog end @@ -73,9 +63,9 @@ end function gmInte.postLogPlayerSay(ply, text, teamChat) if (!validLogAndPlayers({ply})) then return end - gmInte.post("/server/log/playerSay", + gmInte.post("/logs/playerSay", { - ["ply"] = logFormatPlayer(ply), + ["ply"] = gmInte.playerFormat(ply), ["text"] = text, ["teamChat"] = teamChat } @@ -85,11 +75,11 @@ end function gmInte.postLogPlayerDeath(ply, inflictor, attacker) if (!validLogAndPlayers({ply, attacker})) then return end - gmInte.post("/server/log/playerDeath", + gmInte.post("/logs/playerDeath", { - ["ply"] = logFormatPlayer(ply), + ["ply"] = gmInte.playerFormat(ply), ["inflictor"] = logFormatEntity(inflictor), - ["attacker"] = logFormatPlayer(attacker) + ["attacker"] = gmInte.playerFormat(attacker) } ) end @@ -97,9 +87,9 @@ end function gmInte.postLogPlayerInitialSpawn(ply) if (!validLogAndPlayers({ply})) then return end - gmInte.post("/server/log/playerInitialSpawn", + gmInte.post("/logs/playerInitialSpawn", { - ["ply"] = logFormatPlayer(ply) + ["ply"] = gmInte.playerFormat(ply) } ) end @@ -119,10 +109,10 @@ function gmInte.postLogPlayerHurt(ply, attacker, healthRemaining, damageTaken) return end - gmInte.post("/server/log/playerHurt", + gmInte.post("/logs/playerHurt", { - ["ply"] = logFormatPlayer(ply), - ["attacker"] = logFormatPlayer(attacker), + ["ply"] = gmInte.playerFormat(ply), + ["attacker"] = gmInte.playerFormat(attacker), ["healthRemaining"] = healthRemaining, ["damageTaken"] = ply.gmodInteTotalDamage } @@ -133,10 +123,10 @@ end function gmInte.postLogPlayerSpawnedSomething(object, ply, ent, model) if (!validLogAndPlayers({ply})) then return end - gmInte.post("/server/log/playerSpawnedSomething", + gmInte.post("/logs/playerSpawnedSomething", { ["object"] = object, - ["ply"] = logFormatPlayer(ply), + ["ply"] = gmInte.playerFormat(ply), ["ent"] = logFormatEntity(ent), ["model"] = model || "" } @@ -146,9 +136,9 @@ end function gmInte.postLogPlayerSpawn(ply) if (!validLogAndPlayers({ply})) then return end - gmInte.post("/server/log/playerSpawn", + gmInte.post("/logs/playerSpawn", { - ["ply"] = logFormatPlayer(ply) + ["ply"] = gmInte.playerFormat(ply) } ) end @@ -156,9 +146,9 @@ end function gmInte.postLogPlayerDisconnect(ply) if (!validLogAndPlayers({ply})) then return end - gmInte.post("/server/log/playerDisconnect", + gmInte.post("/logs/playerDisconnect", { - ["ply"] = logFormatPlayer(ply) + ["ply"] = gmInte.playerFormat(ply) } ) end @@ -166,7 +156,7 @@ end function gmInte.postLogPlayerConnect(data) if (logDisable() || data.bot) then return end - gmInte.post("/server/log/playerConnect", + gmInte.post("/logs/playerConnect", { ["steamID64"] = util.SteamIDTo64(data.networkid), ["steamID"] = data.networkid, @@ -179,9 +169,9 @@ end function gmInte.postLogPlayerGivet(ply, class, swep) if (!validLogAndPlayers({ply})) then return end - gmInte.post("/server/log/playerGive", + gmInte.post("/logs/playerGive", { - ["ply"] = logFormatPlayer(ply), + ["ply"] = gmInte.playerFormat(ply), ["class"] = class, ["swep"] = swep } @@ -194,13 +184,16 @@ end gameevent.Listen("player_connect") -// Sandbox - Player +// Base - Player hook.Add("PlayerSay", "gmInte:Log:PlayerSay", function(ply, text, teamChat) gmInte.postLogPlayerSay(ply, text, teamChat) end) hook.Add("PlayerSpawn", "gmInte:Log:PlayerSpawn", function(ply) gmInte.postLogPlayerSpawn(ply) end) +hook.Add("player_connect", "gmInte:Log:PlayerConnect", function(data) + gmInte.postLogPlayerConnect(data) +end) hook.Add("PlayerInitialSpawn", "gmInte:Log:PlayerInitialSpawn", function(ply) gmInte.postLogPlayerInitialSpawn(ply) end) @@ -211,12 +204,7 @@ hook.Add("PlayerGiveSWEP", "gmInte:Log:PlayerSWEPs", function( ply, class, swep gmInte.postLogPlayerGivet(ply, class, swep) end) -// Sandbox - Server Events -hook.Add("player_connect", "gmInte:Log:PlayerConnect", function(data) - gmInte.postLogPlayerConnect(data) -end) - -// Sandbox - Player Combat +// Base - Player Combat hook.Add("PlayerDeath", "gmInte:Log:PlayerDeath", function(ply, inflictor, attacker) gmInte.postLogPlayerDeath(ply, inflictor, attacker) end) @@ -224,7 +212,7 @@ hook.Add("PlayerHurt", "gmInte:Log:PlayerHurt", function(ply, attacker, healthRe gmInte.postLogPlayerHurt(ply, attacker, healthRemaining, damageTaken) end) -// Sandbox - Spawnables +// Base - Spawnables hook.Add("PlayerSpawnedProp", "gmInte:Log:PlayerSpawnedProp", function(ply, model, ent) gmInte.postLogPlayerSpawnedSomething("SENT", ply, ent, model) end) diff --git a/lua/gmod_integration/server/sv_main.lua b/lua/gmod_integration/server/sv_main.lua deleted file mode 100644 index b56919a..0000000 --- a/lua/gmod_integration/server/sv_main.lua +++ /dev/null @@ -1,300 +0,0 @@ -// -// Functions -// - -function gmInte.removePort(ip) - return string.Explode(":", ip)[1] -end - -function gmInte.plyValid(ply) - return ply:IsValid() && ply:IsPlayer() && !ply:IsBot() -end - -function gmInte.saveSetting(setting, value) - // save this in data/gmod_integration/setting.json but first check if variable is valid - if gmInte.config[setting] == nil then - gmInte.log("Unknown Setting") - return - end - - // Boolean - if (value == "true") then value = true end - if (value == "false") then value = false end - - // Number - if (tonumber(value) != nil) then value = tonumber(value) end - - gmInte.config[setting] = value - file.Write("gm_integration/config.json", util.TableToJSON(gmInte.config, true)) - gmInte.log("Setting Saved") -end - -function gmInte.playerConnect(data) - if (data.bot == 1) then return end - - data.steam = util.SteamIDTo64(data.networkid) - - gmInte.post("/server/user/connect", data) -end - -local function getCustomValues(ply) - local customValues = {} - - customValues.money = ply:gmInteGetTotalMoney() || 0 - - return customValues -end - -local function getTriggerInfo(text) - for k, v in pairs(gmInte.config.chatTrigger) do - if (string.StartWith(text, k)) then - local defaultConfig = { - ["trigger"] = k, - ["prefix"] = "", - ["show_rank"] = false, - ["anonymous"] = false, - ["channel"] = "admin_sync_chat" - } - for k2, v2 in pairs(v) do - defaultConfig[k2] = v2 - end - return defaultConfig - end - end - - return false -end - -function gmInte.playerSay(ply, text, team) - if (!gmInte.config.syncChat) then return end - - gmInte.post("/server/user/say", - { - ["steamID64"] = ply:SteamID64(), - ["message"] = text, - ["name"] = ply:Nick(), - ["usergroup"] = ply:GetUserGroup(), - ["message_info"] = triggerInfo - } - ) -end - -function gmInte.wsPlayerSay(data) - gmInte.SendNet(1, data, nil) -end - -function gmInte.generatePlayerToken(steamID64) - return util.SHA256(steamID64 .. '-' .. gmInte.config.token .. '-' .. gmInte.publicTempToken) -end - -function gmInte.takeScreenshot(ply) - gmInte.SendNet(4, { - ["serverID"] = gmInte.config.id, - ["authToken"] = gmInte.generatePlayerToken(ply:SteamID64()) - }, ply) -end - -function gmInte.wsPlayerScreen(data) - for _, ply in pairs(player.GetAll()) do - if (ply:SteamID64() == data.steamID64) then - gmInte.takeScreenshot(ply) - end - end -end - -function gmInte.wsRcon(data) - gmInte.log("Rcon Command from Discord '" .. data.command .. "' by " .. data.steamID) - game.ConsoleCommand(data.command .. "\n") -end - -function gmInte.playerBan(data) - data.steam = util.SteamIDTo64(data.networkid) - gmInte.post("/server/user/ban", data) -end - -function gmInte.userFinishConnect(ply) - if (!gmInte.plyValid(ply)) then return end - - gmInte.post("/server/user/finishConnect", - { - ["steam"] = ply:SteamID64(), - ["name"] = ply:Nick(), - } - ) -end - -function gmInte.serverShutDown() - gmInte.post("/server/shutdown") -end - -function gmInte.sendStatus(start) - if (gmInte.config.id == "" || gmInte.config.token == "") then - gmInte.logError("ID or Token is empty: (id: " .. (gmInte.config.id == "" && "empty" || gmInte.config.id) .. ", token: " .. (gmInte.config.token == "" && "empty" || "not empty but hide") .. ")") - gmInte.logHint("Use 'gmod-integration setting id YOUR_SERVER_ID' and 'gmod-integration setting token YOUR_SERVER_TOKEN' to set your credentials, you can find them on https://gmod-integration.com/config/servers") - return - end - gmInte.post("/server/status", - { - ["start"] = start || false, - ["hostname"] = GetHostName(), - ["ip"] = game.GetIPAddress(), - ["port"] = GetConVar("hostport"):GetInt(), - ["map"] = game.GetMap(), - ["players"] = #player.GetAll(), - ["maxplayers"] = game.MaxPlayers(), - ["gamemode"] = engine.ActiveGamemode() - }, - function(code, body) - if (body.publicTempToken) then - gmInte.publicTempToken = body.publicTempToken - end - end, - function(code, body, headers) - gmInte.logError("Your Credentials are Invalid: (id: " .. (gmInte.config.id == "" && "empty" || gmInte.config.id) .. ", token: " .. (gmInte.config.token == "" && "empty" || "not empty but hide") .. ")") - gmInte.logHint("Use 'gmod-integration setting id YOUR_SERVER_ID' and 'gmod-integration setting token YOUR_SERVER_TOKEN' to set your credentials, you can find them on https://gmod-integration.com/config/servers") - end - ) -end - -function gmInte.serverStart() - gmInte.sendStatus(true) -end - -// every 5 minutes -timer.Create("gmInte.sendStatus", 300, 0, function() - gmInte.sendStatus() -end) - -function gmInte.playerChangeName(ply, old, new) - if (!gmInte.plyValid(ply)) then return end - - gmInte.post("/server/user/changeName", - { - ["steamID64"] = ply:SteamID64(), - ["oldName"] = old, - ["newName"] = new, - } - ) -end - -function gmInte.playerDisconnected(ply) - if (!gmInte.plyValid(ply)) then return end - - gmInte.post("/server/user/disconnect", - { - ["steam"] = ply:SteamID64(), - ["kills"] = ply:Frags() || 0, - ["deaths"] = ply:Deaths() || 0, - ["customValues"] = getCustomValues(ply), - ["rank"] = ply:GetUserGroup() || "user", - ["time"] = math.Round(RealTime() - ply.gmIntTimeConnect) || 0, - } - ) -end - -function gmInte.tryConfig() - gmInte.get("/server", - function(code, body) - print(" ") - gmInte.log("Congratulations your server is now connected to Gmod Integration") - gmInte.log("Server Name: " .. body.name) - gmInte.log("Server ID: " .. body.id) - print(" ") - end) -end - -function gmInte.testConnection(ply) - gmInte.get("/server", - function(code, body) - gmInte.SendNet(3, body, ply) - end, - function(code, body, headers) - gmInte.SendNet(3, body, ply) - end) -end - -function gmInte.serverShutDown() - for ply, ply in pairs(player.GetAll()) do - gmInte.playerDisconnected(ply) - end -end - -function gmInte.refreshSettings() - gmInte.config = util.JSONToTable(file.Read("gm_integration/config.json", "DATA")) - gmInte.log("Settings Refreshed") - gmInte.tryConfig() -end - -local function filterMessage(reason) - local Message = { - [1] = "\n", - [2] = "This server has player filtering enabled", - [3] = "You are not allowed to join this server", - [4] = "", - [5] = "Reason: " .. reason, - [6] = "", - [7] = "For more information, please contact the server owner", - [8] = "Help URL: " .. (gmInte.config.supportLink && gmInte.config.supportLink || "No Support Link"), - [9] = "", - [10] = "You can also contact us on our discord server", - [11] = "https://gmod-integration.com/discord", - [12] = "", - [13] = "Have a nice day", - [14] = "", - [15] = "Service provided by Gmod Integration", - } - for k, v in pairs(Message) do - Message[k] = v .. "\n" - end - return table.concat(Message) -end - -function gmInte.playerFilter(data) - if (data.bot == 1) then return end - - data.steamID64 = util.SteamIDTo64(data.networkid) - - // get data - gmInte.get("/server/user" .. "?steamID64=" .. data.steamID64, - function(code, body) - if (!body || !body.trust) then return end - - // Gmod Integration Trust - if (gmInte.config.filterOnTrust && (body.trust < gmInte.config.minimalTrust)) then - // kick player - game.KickID(data.networkid, filterMessage("Insufficient Trust Level\nYour Trust Level: " .. body.trust .. "\nMinimal Trust Level: " .. gmInte.config.minimalTrust)) - end - - // Gmod Integration Ban - if (gmInte.config.filterOnBan && body.ban) then - // kick player - game.KickID(data.networkid, filterMessage("You are banned from Gmod Integration")) - end - - // Server Discord Ban - if (gmInte.config.syncBan && body.discord_ban) then - // kick player - game.KickID(data.networkid, filterMessage("You are banned from the discord server\nReason: " .. (body.discord_ban_reason && body.discord_ban_reason || "No Reason"))) - end - end - ) -end - -function gmInte.superadminGetConfig(ply) - if (!gmInte.plyValid(ply) || !ply:IsSuperAdmin()) then return end - - gmInte.config.websocket = GWSockets && true || false - gmInte.SendNet(2, gmInte.config, ply) -end - -function gmInte.superadminSetConfig(ply, data) - if (!gmInte.plyValid(ply) || !ply:IsSuperAdmin()) then return end - - for k, v in pairs(data) do - gmInte.saveSetting(k, v) - end - - if data.token || data.id then - gmInte.testConnection(ply) - end -end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_meta.lua b/lua/gmod_integration/server/sv_meta.lua deleted file mode 100644 index ec90cd1..0000000 --- a/lua/gmod_integration/server/sv_meta.lua +++ /dev/null @@ -1,12 +0,0 @@ -// Meta -local ply = FindMetaTable("Player") - -function ply:gmInteGetTotalMoney() - // if darkrp - if DarkRP then - return self:getDarkRPVar("money") - end - - // else - return 0 -end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_net.lua b/lua/gmod_integration/server/sv_net.lua index 11452ee..431ad1c 100644 --- a/lua/gmod_integration/server/sv_net.lua +++ b/lua/gmod_integration/server/sv_net.lua @@ -23,7 +23,7 @@ util.AddNetworkString("gmIntegration") function gmInte.SendNet(id, data, ply, func) net.Start("gmIntegration") net.WriteUInt(id, 8) - net.WriteString(util.TableToJSON(data)) + net.WriteString(util.TableToJSON(data || {})) if (func) then func() end if (ply == nil) then net.Broadcast() @@ -36,7 +36,6 @@ end local netFuncs = { [0] = function(ply) gmInte.userFinishConnect(ply) - ply.gmIntTimeConnect = math.Round(RealTime()) end, [1] = function(ply, data) gmInte.testConnection(ply, data) @@ -54,6 +53,9 @@ local netFuncs = { if (!ply:IsSuperAdmin()) then return end RunConsoleCommand("changelevel", game.GetMap()) end, + [6] = function(ply) + gmInte.verifyPlayer(ply) + end } net.Receive("gmIntegration", function(len, ply) diff --git a/lua/gmod_integration/server/sv_players.lua b/lua/gmod_integration/server/sv_players.lua new file mode 100644 index 0000000..8d1ee1f --- /dev/null +++ b/lua/gmod_integration/server/sv_players.lua @@ -0,0 +1,145 @@ +// +// Meta +// + +local ply = FindMetaTable("Player") + +function ply:gmIntGetConnectTime() + return self.gmIntTimeConnect || 0 +end + +function ply:gmIntSetCustomValue(key, value) + self.gmIntCustomValues = self.gmIntCustomValues || {} + self.gmIntCustomValues[key] = value +end + +function ply:gmIntGetCustomValue(key) + return self.gmIntCustomValues && self.gmIntCustomValues[key] +end + +function ply:gmIntRemoveCustomValue(key) + if (self.gmIntCustomValues) then + self.gmIntCustomValues[key] = nil + end +end + +// +// Compatibility +// + +local function getCustomCompatability(ply) + local values = {} + + // DarkRP + if (DarkRP) then + values.money = ply:getDarkRPVar("money") + values.job = ply:getDarkRPVar("job") + end + + // GUI Level System + if (GUILevelSystem) then + values.level = ply:GetLevel() + values.xp = ply:GetXP() + end + + return values +end + +// +// Methods +// + +local function getCustomValues(ply) + local values = {} + + // Get compatability values + for key, value in pairs(getCustomCompatability(ply)) do + values[key] = value + end + + // Get custom values or overwrite compatability values + if (ply.gmIntCustomValues) then + for key, value in pairs(ply.gmIntCustomValues) do + values[key] = value + end + end + + return values +end + +function ply:gmIntGetCustomValues() + return getCustomValues(self) +end + +function gmInte.plyValid(ply) + return ply:IsValid() && ply:IsPlayer() && !ply:IsBot() +end + +function gmInte.verifyPlayer(ply) + if (!gmInte.plyValid(ply)) then return end + gmInte.get("/players/" .. ply:SteamID64(), function(data) + if (data.discordID && ply.gmIntUnVerified) then + ply:Freeze(false) + ply.gmIntUnVerified = false + end + end) +end + +// Generate a unique token that allow player to update data link to this server (ex: screnshot, report bug, etc.) +function gmInte.getClientOneTimeToken(ply, callback) + gmInte.get("/players/" .. ply:SteamID64() .. "/get-one-time-token", function(data) + callback(data.token) + end) +end + +function gmInte.playerConnect(data) + gmInte.post("/players/" .. util.SteamIDTo64(data.networkid) .. "/connect", data) +end + +function gmInte.userFinishConnect(ply) + if (!gmInte.plyValid(ply)) then return end + ply.gmIntTimeConnect = math.Round(RealTime()) + + gmInte.post("/players/" .. ply:SteamID64() .. "/finish-connect", + { + ["player"] = gmInte.playerFormat(ply), + } + ) + + if (!gmInte.config.forcePlayerLink) then return end + gmInte.get("/players/" .. ply:SteamID64(), function(data) + if (!data.discordID) then + ply:Freeze(true) + ply.gmIntUnVerified = true + end + end) +end + +function gmInte.playerDisconnected(ply) + if (!gmInte.plyValid(ply)) then return end + + gmInte.post("/players/" .. ply:SteamID64() .. "/disconnect", + { + ["player"] = gmInte.playerFormat(ply), + } + ) +end + +// +// Hooks +// + +hook.Add("ShutDown", "gmInte:Server:Shutdown:SavePlayers", function() + for ply, ply in pairs(player.GetAll()) do + gmInte.playerDisconnected(ply) + end +end) + +gameevent.Listen("player_connect") +hook.Add("player_connect", "gmInte:Player:Connect", function(data) + gmInte.playerConnect(data) +end) + +hook.Add("PlayerDisconnected", "gmInte:Player:Disconnect", function(ply) + gmInte.playerDisconnected(ply) +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_rcon.lua b/lua/gmod_integration/server/sv_rcon.lua new file mode 100644 index 0000000..8cb8259 --- /dev/null +++ b/lua/gmod_integration/server/sv_rcon.lua @@ -0,0 +1,8 @@ +// +// Websocket +// + +function gmInte.wsRcon(data) + gmInte.log("Rcon Command from Discord '" .. data.command .. "' by " .. data.steamID) + game.ConsoleCommand(data.command .. "\n") +end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_screenshots.lua b/lua/gmod_integration/server/sv_screenshots.lua new file mode 100644 index 0000000..97a0536 --- /dev/null +++ b/lua/gmod_integration/server/sv_screenshots.lua @@ -0,0 +1,24 @@ +// +// Websocket +// + +function gmInte.wsPlayerScreen(data) + for _, ply in pairs(player.GetAll()) do + if (ply:SteamID64() == data.steamID64) then + gmInte.takeScreenshot(ply) + end + end +end + +// +// Methods +// + +function gmInte.takeScreenshot(ply) + gmInte.getClientOneTimeToken(ply, function(oneTime) + gmInte.SendNet(4, { + ["serverID"] = gmInte.config.id, + ["oneTimeToken"] = oneTime + }, ply) + end) +end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_settings.lua b/lua/gmod_integration/server/sv_settings.lua new file mode 100644 index 0000000..a0c1eaf --- /dev/null +++ b/lua/gmod_integration/server/sv_settings.lua @@ -0,0 +1,65 @@ +function gmInte.saveSetting(setting, value) + if gmInte.config[setting] == nil then + gmInte.log("Unknown Setting") + return + end + + // Boolean + if (value == "true") then value = true end + if (value == "false") then value = false end + + // Number + if (tonumber(value) != nil) then value = tonumber(value) end + + gmInte.config[setting] = value + file.Write("gm_integration/config.json", util.TableToJSON(gmInte.config, true)) + gmInte.log("Setting Saved") +end + +function gmInte.tryConfig() + gmInte.get("", + function(code, body) + print(" ") + gmInte.log("Congratulations your server is now connected to Gmod Integration") + gmInte.log("Server Name: " .. body.name) + gmInte.log("Server ID: " .. body.id) + print(" ") + end + ) +end + +function gmInte.testConnection(ply) + gmInte.get("", + function(code, body) + if (ply) then gmInte.SendNet(3, body, ply) end + end, + function(code, body) + if (ply) then gmInte.SendNet(3, body, ply) end + end + ) +end + +function gmInte.refreshSettings() + gmInte.config = util.JSONToTable(file.Read("gm_integration/config.json", "DATA")) + gmInte.log("Settings Refreshed") + gmInte.tryConfig() +end + +function gmInte.superadminGetConfig(ply) + if (!gmInte.plyValid(ply) || !ply:IsSuperAdmin()) then return end + + gmInte.config.websocket = GWSockets && true || false + gmInte.SendNet(2, gmInte.config, ply) +end + +function gmInte.superadminSetConfig(ply, data) + if (!gmInte.plyValid(ply) || !ply:IsSuperAdmin()) then return end + + for k, v in pairs(data) do + gmInte.saveSetting(k, v) + end + + if data.token || data.id then + gmInte.testConnection(ply) + end +end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_status.lua b/lua/gmod_integration/server/sv_status.lua new file mode 100644 index 0000000..aafffc2 --- /dev/null +++ b/lua/gmod_integration/server/sv_status.lua @@ -0,0 +1,51 @@ +// +// Methods +// + +local function getServerFormat() + return { + ["hostname"] = GetHostName(), + ["ip"] = game.GetIPAddress(), + ["port"] = GetConVar("hostport"):GetInt(), + ["map"] = game.GetMap(), + ["players"] = #player.GetAll(), + ["maxplayers"] = game.MaxPlayers(), + ["gamemode"] = engine.ActiveGamemode(), + ["uptime"] = math.Round(RealTime() / 60) + } +end + +function gmInte.sendStatus() + gmInte.post("/status", getServerFormat()) +end + +-- function gmInte.serverStart() +-- gmInte.post("/start", getServerFormat()) +-- end + +function gmInte.serverShutDown() + gmInte.post("/shutdown") +end + +// +// Timers +// + +timer.Create("gmInte.sendStatus", 300, 0, function() + gmInte.sendStatus() +end) + +// +// Hooks +// + +hook.Add("Initialize", "gmInte:Server:Initialize:SendStatus", function() + timer.Simple(1, function() + -- gmInte.serverStart() + gmInte.sendStatus() + end) +end) + +hook.Add("ShutDown", "gmInte:Server:ShutDown:SendStatus", function() + gmInte.serverShutDown() +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_sync_bans.lua b/lua/gmod_integration/server/sv_sync_bans.lua new file mode 100644 index 0000000..121b160 --- /dev/null +++ b/lua/gmod_integration/server/sv_sync_bans.lua @@ -0,0 +1,28 @@ +// +// Websocket +// + +function gmInte.wsSyncBan(data) + for _, ply in ipairs(player.GetAll()) do + if (ply:SteamID64() == data.steam) then + ply:Kick(data.reason || "You have been banned from the server.") + end + end +end + +// +// Methods +// + +function gmInte.playerBan(data) + gmInte.post("/players/" .. util.SteamIDTo64(data.networkid) .. "/bans", data) +end + +// +// Hooks +// + +gameevent.Listen("server_addban") +hook.Add("server_addban", "gmInte:Player:Ban", function(data) + gmInte.playerBan(data) +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_sync_chat.lua b/lua/gmod_integration/server/sv_sync_chat.lua new file mode 100644 index 0000000..b567815 --- /dev/null +++ b/lua/gmod_integration/server/sv_sync_chat.lua @@ -0,0 +1,31 @@ +// +// Websocket +// + +function gmInte.wsPlayerSay(data) + gmInte.SendNet(1, data, nil) +end + +// +// Methods +// + +function gmInte.playerSay(ply, text, team) + if (!gmInte.config.syncChat) then return end + + gmInte.post("/players/" .. ply:SteamID64() .. "/say", + { + ["player"] = gmInte.playerFormat(ply), + ["text"] = text, + ["team"] = team, + } + ) +end + +// +// Hooks +// + +hook.Add("PlayerSay", "gmInte:PlayerSay:SyncChat", function(ply, text, team) + gmInte.playerSay(ply, text, team) +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_sync_names.lua b/lua/gmod_integration/server/sv_sync_names.lua new file mode 100644 index 0000000..601bb48 --- /dev/null +++ b/lua/gmod_integration/server/sv_sync_names.lua @@ -0,0 +1,33 @@ +// +// Websocket +// + +function gmInte.wsSyncName(data) + local ply = player.GetBySteamID(data.player.steamID64) + if not IsValid(ply) then return end + ply:SetName(data.newName) +end + +// +// Methods +// + +function gmInte.playerChangeName(ply, oldName, newName) + if (!gmInte.plyValid(ply)) then return end + + gmInte.post("/players/" .. ply:SteamID64() .. "/name", + { + ["player"] = gmInte.playerFormat(ply), + ["oldName"] = oldName, + ["newName"] = newName, + } + ) +end + +// +// Hooks +// + +hook.Add("onPlayerChangedName", "gmInte:PlayerChangeName", function(ply, old, new) + gmInte.playerChangeName(ply, old, new) +end) \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_sync_roles.lua b/lua/gmod_integration/server/sv_sync_roles.lua new file mode 100644 index 0000000..6baff9e --- /dev/null +++ b/lua/gmod_integration/server/sv_sync_roles.lua @@ -0,0 +1,35 @@ +// +// Websocket +// + +function gmInte.wsSyncRoles(data) + local ply = player.GetBySteamID(data.steamID) + if (ply:IsValid()) then + ply:SetUserGroup(data.role) + end + + // ULX + if (ULib) then + ULib.ucl.addUser(data.steamID, nil, nil, data.role) + end + + // FAdmin + if (CAMI) then + CAMI.PlayerRank(data.steamID64, data.role, "user") + end + + // ServerGuard + if (serverguard) then + serverguard.player:SetRank(data.steamID64, data.role) + end + + // Evolve + if (evolve) then + evolve:RankPlayer(data.steamID64, data.role) + end + + // SAM + if (SAM) then + SAM:PlayerSetRank(data.steamID64, data.role) + end +end \ No newline at end of file diff --git a/lua/gmod_integration/server/sv_sync_warns.lua b/lua/gmod_integration/server/sv_sync_warns.lua new file mode 100644 index 0000000..3167988 --- /dev/null +++ b/lua/gmod_integration/server/sv_sync_warns.lua @@ -0,0 +1,15 @@ +// +// Websocket +// + +function gmInte.wsSyncWarns(data) + // +end + +// +// Methods +// + +function gmInte.playerWarn(data) + // +end \ No newline at end of file diff --git a/lua/gmod_integration/shared/sh_http.lua b/lua/gmod_integration/shared/sh_http.lua index b592152..0b16146 100644 --- a/lua/gmod_integration/shared/sh_http.lua +++ b/lua/gmod_integration/shared/sh_http.lua @@ -1,126 +1,118 @@ +local apiVersion = "v3" +local apiFQDN = "api.gmod-integration.com" +local apiDevFQDN = "dev-api.gmod-integration.com" + // // HTTP // -local failMessage = { - ["401"] = "Bad Credentials", - ["403"] = "Forbidden", - ["404"] = "Not Found", - ["500"] = "Internal Server Error", - ["503"] = "Service Unavailable", - ["504"] = "Gateway Timeout", -} +local function getAPIURL(endpoint) + local url = "https://" .. (gmInte.config.devInstance && apiDevFQDN || apiFQDN) .. "/" .. apiVersion -local function errorMessage(body, code) - if (body && body.error) then - if (failMessage[code]) then - return failMessage[code] - else - return body.error - end - elseif (failMessage[code]) then - return failMessage[code] - else - return code - end -end - -local function getAPIURL() - local url = "https://api.gmod-integration.com" - local devURL = "https://dev-api.gmod-integration.com" - - if (!gmInte.config.debug) then return url end - if (gmInte.config.devInstance) then - gmInte.log("Using dev Instance", true) - return devURL + if (SERVER) then + url = url .. "/servers/" .. gmInte.config.id + elseif (endpoint == "/players") then + url = url .. "/clients/" .. LocalPlayer():SteamID64() end - return url + return url .. endpoint end -local function sendHTTP(params) - // Log the HTTP request - gmInte.log("HTTP Request: " .. params.method .. " " .. params.endpoint, true) - gmInte.log("HTTP Body: " .. (params.body || "No body"), true) +function gmInte.requestAPI(params) + local body = params.body || "" + local bodyLength = string.len(body) + local token = params.token || gmInte.config.token || "" + local url = getAPIURL(params.endpoint) + local method = params.method + local success = params.success || function() end + local failed = params.failed || function(error) gmInte.logError(error.error || error) end + local version = gmInte.config.version - // Send the HTTP request + local headers = { + ["Content-Type"] = "application/json", + ["Content-Length"] = bodyLength, + ["Authorization"] = "Bearer " .. token, + ["Version"] = version + } + local type = "application/json" + + // Log + if (gmInte.config.devInstance) then gmInte.log("HTTP Using dev Instance", true) end + gmInte.log("HTTP Request: " .. method .. " " .. url, true) + gmInte.log("HTTP Body: " .. body, true) + + // Send HTTP({ - url = getAPIURL() .. params.endpoint, - method = params.method, - headers = { - ["Content-Type"] = "application/json", - ["Content-Length"] = params.body && string.len(params.body) || 0, - ["id"] = gmInte.config.id, - ["token"] = gmInte.config.token, - ["version"] = gmInte.version - }, - body = params.body && params.body || "", - type = "application/json", - success = function(code, body, headers) - // Log the HTTP response + ["url"] = url, + ["method"] = method, + ["headers"] = headers, + ["body"] = body, + ["type"] = type, + ["success"] = function(code, body, headers) + // Log gmInte.log("HTTP Response: " .. code, true) if (gmInte.config.debug) then gmInte.log("HTTP Body: " .. body, true) end - // if body and is json extract it - if (body && string.sub(headers["Content-Type"], 1, 16) == "application/json") then - body = util.JSONToTable(body) + // if not 2xx return failed + if (code < 200 || code >= 300) then + return failed(body, code, headers) end - // Check if the request was successful - if (string.sub(code, 1, 1) == "2") then - if (params.success) then - params.success(code, body, headers) - else - gmInte.log("HTTP Request Successful", true) - end - else - if (params.failed) then - params.failed(code, body, headers) - else - gmInte.logError(errorMessage(body, code)) - end + // if not application/json return failed + if (string.sub(headers["Content-Type"], 1, 16) != "application/json") then + return failed({ ["error"] = "Invalid Content-Type" }, code, headers) end + + // Tableify the body if it's JSON + body = util.JSONToTable(body || "{}") + + // Return success + return success(code, body, headers) end, - failed = function(error) + ["failed"] = function(error) gmInte.logError(error) end }) end +// +// HTTP Methods +// + function gmInte.get(endpoint, onSuccess, onFailed) - sendHTTP({ - endpoint = endpoint, - method = "GET", - success = onSuccess, - failed = onFailed + gmInte.requestAPI({ + ["endpoint"] = endpoint, + ["method"] = "GET", + ["success"] = onSuccess, + ["failed"] = onFailed }) end function gmInte.post(endpoint, data, onSuccess, onFailed) - sendHTTP({ - endpoint = endpoint, - method = "POST", - body = util.TableToJSON(data), - success = onSuccess, - failed = onFailed + gmInte.requestAPI({ + ["endpoint"] = endpoint, + ["method"] = "POST", + ["body"] = util.TableToJSON(data), + ["success"] = onSuccess, + ["failed"] = onFailed }) end function gmInte.put(endpoint, data, onSuccess, onFailed) - sendHTTP({ - endpoint = endpoint, - method = "PUT", - body = util.TableToJSON(data), - success = onSuccess, - failed = onFailed + gmInte.requestAPI({ + ["endpoint"] = endpoint, + ["method"] = "PUT", + ["body"] = util.TableToJSON(data), + ["success"] = onSuccess, + ["failed"] = onFailed }) end function gmInte.delete(endpoint, onSuccess, onFailed) - sendHTTP({ - endpoint = endpoint, - method = "DELETE", - success = onSuccess, - failed = onFailed + gmInte.requestAPI({ + ["endpoint"] = endpoint, + ["method"] = "DELETE", + ["success"] = onSuccess, + ["failed"] = onFailed }) end \ No newline at end of file