refactor: now using glualint

This commit is contained in:
Linventif 2024-07-05 21:50:00 +00:00
parent e7f160df05
commit 90de28575c
33 changed files with 498 additions and 1213 deletions

View File

@ -1,30 +1,17 @@
if (game.SinglePlayer()) then return print("Gmod Integration is not supported in Singleplayer!") end if game.SinglePlayer() then return print("Gmod Integration is not supported in Singleplayer!") end
//
// Variables
//
gmInte = gmInte || {} gmInte = gmInte || {}
gmInte.version = "0.3.6" gmInte.version = "0.3.6"
gmInte.config = {} gmInte.config = {}
gmInte.materials = {} gmInte.materials = {}
//
// Functions
//
local function loadServerConfig() local function loadServerConfig()
RunConsoleCommand("sv_hibernate_think", "1") RunConsoleCommand("sv_hibernate_think", "1")
if !file.Exists("gm_integration", "DATA") || !file.Exists("gm_integration/config.json", "DATA") then
if (!file.Exists("gm_integration", "DATA") || !file.Exists("gm_integration/config.json", "DATA")) then
file.CreateDir("gm_integration") file.CreateDir("gm_integration")
file.Write("gm_integration/config.json", util.TableToJSON(gmInte.config, true)) file.Write("gm_integration/config.json", util.TableToJSON(gmInte.config, true))
else else
if (gmInte.config.id && gmInte.config.id != "") then return end if gmInte.config.id && gmInte.config.id != "" then return end
local oldConfig = util.JSONToTable(file.Read("gm_integration/config.json", "DATA")) local oldConfig = util.JSONToTable(file.Read("gm_integration/config.json", "DATA"))
if (!oldConfig.version || (oldConfig.version < gmInte.version)) then if !oldConfig.version || (oldConfig.version < gmInte.version) then
print(" | Merging Config | gmod_integration/sv_config.lua") print(" | Merging Config | gmod_integration/sv_config.lua")
table.Merge(gmInte.config, oldConfig) table.Merge(gmInte.config, oldConfig)
gmInte.config.version = gmInte.version gmInte.config.version = gmInte.version
@ -37,29 +24,26 @@ end
local function loadAllFiles(folder) local function loadAllFiles(folder)
local files, folders = file.Find(folder .. "/*", "LUA") local files, folders = file.Find(folder .. "/*", "LUA")
for k, fileName in SortedPairs(files) do for k, fileName in SortedPairs(files) do
local path = folder .. "/" .. fileName local path = folder .. "/" .. fileName
print(" | Loading File | " .. path) print(" | Loading File | " .. path)
if string.StartWith(fileName, "cl_") then
if (string.StartWith(fileName, "cl_")) then
if SERVER then if SERVER then
AddCSLuaFile(path) AddCSLuaFile(path)
else else
include(path) include(path)
end end
elseif (string.StartWith(fileName, "sv_")) then elseif string.StartWith(fileName, "sv_") then
if SERVER then if SERVER then include(path) end
include(path) elseif string.StartWith(fileName, "sh_") then
end if SERVER then AddCSLuaFile(path) end
elseif (string.StartWith(fileName, "sh_")) then
if SERVER then
AddCSLuaFile(path)
end
include(path) include(path)
end end
if (fileName == "sv_config.lua") then loadServerConfig() continue end if fileName == "sv_config.lua" then
loadServerConfig()
continue
end
end end
for k, v in SortedPairs(folders, true) do for k, v in SortedPairs(folders, true) do
@ -67,11 +51,6 @@ local function loadAllFiles(folder)
end end
end end
//
// Load Files
//
print(" ") print(" ")
print(" ") print(" ")
print(" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ") print(" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")

View File

@ -23,19 +23,14 @@ function gmInte.getColor(name)
end end
function gmInte.applyPaint(element, id) function gmInte.applyPaint(element, id)
if (element.DoClick) then if element.DoClick then
element:SetTextColor(gmInte.getColor("font")) element:SetTextColor(gmInte.getColor("font"))
element.Paint = function(self, w, h) element.Paint = function(self, w, h)
local color = gmInte.getColor("primary") local color = gmInte.getColor("primary")
if self:IsHovered() then color = gmInte.getColor("primary-active") end
if (self:IsHovered()) then
color = gmInte.getColor("primary-active")
end
draw.RoundedBox(0, 0, 0, w, h, color) draw.RoundedBox(0, 0, 0, w, h, color)
end end
elseif (element.SetTitle) then elseif element.SetTitle then
element.Paint = function(self, w, h) element.Paint = function(self, w, h)
draw.RoundedBox(0, 0, 0, w, h, gmInte.getColor("background")) draw.RoundedBox(0, 0, 0, w, h, gmInte.getColor("background"))
// first 20px = title bar = primary // first 20px = title bar = primary

View File

@ -8,5 +8,4 @@ list.Set("DesktopWindows", "GmodIntegration:DesktopWindows", {
window:Close() window:Close()
gmInte.openAdminConfig() gmInte.openAdminConfig()
end end
} })
)

View File

@ -8,7 +8,7 @@ local configCat = {
"Authentication", "Authentication",
"Main", "Main",
"Trust & Safety", "Trust & Safety",
-- "Punishment", // "Punishment",
"Advanced", "Advanced",
} }
@ -18,242 +18,210 @@ local possibleConfig = {
["label"] = "Server ID", ["label"] = "Server ID",
["description"] = "Server ID found on the webpanel.", ["description"] = "Server ID found on the webpanel.",
["type"] = "textEntry", ["type"] = "textEntry",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value ["onEdit"] = function(setting, value) saveConfig(setting, value) end,
end,
["onEdit"] = function(setting, value)
saveConfig(setting, value)
end,
["onEditDelay"] = 0.5, ["onEditDelay"] = 0.5,
["category"] = "Authentication" ["category"] = "Authentication"
}, },
{ {
["id"]= "token", ["id"] = "token",
["label"] = "Server Token", ["label"] = "Server Token",
["description"] = "Server Token found on the webpanel.", ["description"] = "Server Token found on the webpanel.",
["type"] = "textEntry", ["type"] = "textEntry",
["secret"] = true, ["secret"] = true,
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value ["onEdit"] = function(setting, value) saveConfig(setting, value) end,
end,
["onEdit"] = function(setting, value)
saveConfig(setting, value)
end,
["onEditDelay"] = 0.5, ["onEditDelay"] = 0.5,
["category"] = "Authentication" ["category"] = "Authentication"
}, },
-- { // {
-- ["id"]= "sendLog", // ["id"]= "sendLog",
-- ["label"] = "Logs", // ["label"] = "Logs",
-- ["description"] = "Activate or deactivate logs.", // ["description"] = "Activate or deactivate logs.",
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Main" // ["category"] = "Main"
-- }, // },
-- { // {
-- ["id"]= "logBotActions", // ["id"]= "logBotActions",
-- ["label"] = "Log Bot Actions", // ["label"] = "Log Bot Actions",
-- ["description"] = "Activate or deactivate logs for bot actions.", // ["description"] = "Activate or deactivate logs for bot actions.",
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Main" // ["category"] = "Main"
-- }, // },
{ {
["id"]= "maintenance", ["id"] = "maintenance",
["label"] = "Maintenance", ["label"] = "Maintenance",
["description"] = "Activate or deactivate maintenance mode.", ["description"] = "Activate or deactivate maintenance mode.",
["type"] = "checkbox", ["type"] = "checkbox",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value ["onEdit"] = function(setting, value) saveConfig(setting, value == "Enabled" && true || false) end,
end,
["onEdit"] = function(setting, value)
saveConfig(setting, value == "Enabled" && true || false)
end,
["category"] = "Main" ["category"] = "Main"
}, },
{ {
["id"]= "filterOnBan", ["id"] = "filterOnBan",
["label"] = "Block Discord Ban Player", ["label"] = "Block Discord Ban Player",
["description"] = "Block players banned on the discord server.", ["description"] = "Block players banned on the discord server.",
["type"] = "checkbox", ["type"] = "checkbox",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value ["onEdit"] = function(setting, value) saveConfig(setting, value == "Enabled" && true || false) end,
end,
["onEdit"] = function(setting, value)
saveConfig(setting, value == "Enabled" && true || false)
end,
["category"] = "Trust & Safety" ["category"] = "Trust & Safety"
}, },
-- { // {
-- ["id"]= "filterOnTrust", // ["id"]= "filterOnTrust",
-- ["label"] = "Block UnTrust Player", // ["label"] = "Block UnTrust Player",
-- ["description"] = "Block players with a trust level lower than the minimal trust level set in the config.", // ["description"] = "Block players with a trust level lower than the minimal trust level set in the config.",
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Trust & Safety" // ["category"] = "Trust & Safety"
-- }, // },
-- { // {
-- ["id"]= "minimalTrust", // ["id"]= "minimalTrust",
-- ["label"] = "Minimal Trust Level", // ["label"] = "Minimal Trust Level",
-- ["description"] = "The minimal trust level to be able to join the server.", // ["description"] = "The minimal trust level to be able to join the server.",
-- ["type"] = "textEntry", // ["type"] = "textEntry",
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value) // saveConfig(setting, value)
-- end, // end,
-- ["onEditDelay"] = 0.5, // ["onEditDelay"] = 0.5,
-- ["category"] = "Trust & Safety" // ["category"] = "Trust & Safety"
-- }, // },
-- { // {
-- ["id"]= "syncChat", // ["id"]= "syncChat",
-- ["label"] = "Sync Chat", // ["label"] = "Sync Chat",
-- ["description"] = "Sync chat between the server and the discord server.", // ["description"] = "Sync chat between the server and the discord server.",
-- ["websocket"] = true, // ["websocket"] = true,
-- ["restart"] = true, // ["restart"] = true,
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Main" // ["category"] = "Main"
-- }, // },
-- { // {
-- ["id"]= "syncBan", // ["id"]= "syncBan",
-- ["label"] = "Sync Ban", // ["label"] = "Sync Ban",
-- ["description"] = "Sync chat between the server and the discord server.", // ["description"] = "Sync chat between the server and the discord server.",
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["condition"] = function(data) // ["condition"] = function(data)
-- return false // Disabled for now // return false // Disabled for now
-- end, // end,
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Punishment" // ["category"] = "Punishment"
-- }, // },
-- { // {
-- ["id"]= "syncTimeout", // ["id"]= "syncTimeout",
-- ["label"] = "Sync Timeout", // ["label"] = "Sync Timeout",
-- ["description"] = "Sync chat between the server and the discord server.", // ["description"] = "Sync chat between the server and the discord server.",
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["condition"] = function(data) // ["condition"] = function(data)
-- return false // Disabled for now // return false // Disabled for now
-- end, // end,
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Punishment" // ["category"] = "Punishment"
-- }, // },
-- { // {
-- ["id"]= "syncKick", // ["id"]= "syncKick",
-- ["label"] = "Sync Kick", // ["label"] = "Sync Kick",
-- ["description"] = "Sync chat between the server and the discord server.", // ["description"] = "Sync chat between the server and the discord server.",
-- ["type"] = "checkbox", // ["type"] = "checkbox",
-- ["condition"] = function(data) // ["condition"] = function(data)
-- return false // Disabled for now // return false // Disabled for now
-- end, // end,
-- ["value"] = function(setting, value) // ["value"] = function(setting, value)
-- return value // return value
-- end, // end,
-- ["onEdit"] = function(setting, value) // ["onEdit"] = function(setting, value)
-- saveConfig(setting, value == "Enabled" && true || false) // saveConfig(setting, value == "Enabled" && true || false)
-- end, // end,
-- ["category"] = "Punishment" // ["category"] = "Punishment"
-- }, // },
{ {
["id"]= "forcePlayerLink", ["id"] = "forcePlayerLink",
["label"] = "Force Player Verif", ["label"] = "Force Player Verif",
["description"] = "Sync chat between the server and the discord server.", ["description"] = "Sync chat between the server and the discord server.",
["type"] = "checkbox", ["type"] = "checkbox",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value ["onEdit"] = function(setting, value) saveConfig(setting, value == "Enabled" && true || false) end,
end,
["onEdit"] = function(setting, value)
saveConfig(setting, value == "Enabled" && true || false)
end,
["category"] = "Main" ["category"] = "Main"
}, },
{ {
["id"]= "supportLink", ["id"] = "supportLink",
["label"] = "Support Link", ["label"] = "Support Link",
["description"] = "Server ID found on the webpanel.", ["description"] = "Server ID found on the webpanel.",
["type"] = "textEntry", ["type"] = "textEntry",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value ["onEdit"] = function(setting, value) saveConfig(setting, value) end,
end,
["onEdit"] = function(setting, value)
saveConfig(setting, value)
end,
["onEditDelay"] = 0.5, ["onEditDelay"] = 0.5,
["category"] = "Trust & Safety" ["category"] = "Trust & Safety"
}, },
{ {
["id"]= "debug", ["id"] = "debug",
["label"] = "Debug", ["label"] = "Debug",
["description"] = "Activate or deactivate debug mode.", ["description"] = "Activate or deactivate debug mode.",
["type"] = "checkbox", ["type"] = "checkbox",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value
end,
["position"] = 1, ["position"] = 1,
["onEdit"] = function(setting, value) ["onEdit"] = function(setting, value) saveConfig(setting, value == "Enabled" && true || false) end,
saveConfig(setting, value == "Enabled" && true || false)
end,
["category"] = "Advanced" ["category"] = "Advanced"
}, },
{ {
["id"]= "websocketFQDN", ["id"] = "websocketFQDN",
["label"] = "Websocket FQDN", ["label"] = "Websocket FQDN",
["description"] = "Websocket FQDN that will be used for the Websocket connection.", ["description"] = "Websocket FQDN that will be used for the Websocket connection.",
["type"] = "textEntry", ["type"] = "textEntry",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value
end,
["resetIfEmpty"] = true, ["resetIfEmpty"] = true,
["defaultValue"] = "ws.gmod-integration.com", ["defaultValue"] = "ws.gmod-integration.com",
["onEdit"] = function(setting, value) ["onEdit"] = function(setting, value)
if (!value || value == "") then return end if !value || value == "" then return end
saveConfig(setting, value) saveConfig(setting, value)
end, end,
["onEditDelay"] = 0.5, ["onEditDelay"] = 0.5,
["category"] = "Advanced" ["category"] = "Advanced"
}, },
{ {
["id"]= "apiFQDN", ["id"] = "apiFQDN",
["label"] = "API FQDN", ["label"] = "API FQDN",
["description"] = "API FQDN that will be used for the API connection.", ["description"] = "API FQDN that will be used for the API connection.",
["type"] = "textEntry", ["type"] = "textEntry",
["resetIfEmpty"] = true, ["resetIfEmpty"] = true,
["defaultValue"] = "api.gmod-integration.com", ["defaultValue"] = "api.gmod-integration.com",
["value"] = function(setting, value) ["value"] = function(setting, value) return value end,
return value
end,
["onEdit"] = function(setting, value) ["onEdit"] = function(setting, value)
if (!value || value == "") then return end if !value || value == "" then return end
saveConfig(setting, value) saveConfig(setting, value)
end, end,
["onEditDelay"] = 0.5, ["onEditDelay"] = 0.5,
@ -264,42 +232,32 @@ local possibleConfig = {
local buttonsInfo = { local buttonsInfo = {
{ {
["label"] = "Open Webpanel", ["label"] = "Open Webpanel",
["func"] = function() ["func"] = function() gui.OpenURL("https://gmod-integration.com/config/server") end,
gui.OpenURL("https://gmod-integration.com/config/server")
end,
}, },
{ {
["label"] = "Test Connection", ["label"] = "Test Connection",
["func"] = function() ["func"] = function() gmInte.SendNet("testConnection") end,
gmInte.SendNet("testConnection")
end,
}, },
{ {
["label"] = "Buy Premium", ["label"] = "Buy Premium",
["func"] = function() ["func"] = function() gui.OpenURL("https://gmod-integration.com/premium") end,
gui.OpenURL("https://gmod-integration.com/premium")
end,
}, },
{ {
["label"] = "Install Websocket", ["label"] = "Install Websocket",
["condition"] = function(data) ["condition"] = function(data) return !data.websocket end,
return !data.websocket ["func"] = function() gui.OpenURL("https://github.com/FredyH/GWSockets/releases") end,
end,
["func"] = function()
gui.OpenURL("https://github.com/FredyH/GWSockets/releases")
end,
}, },
-- {
-- ["label"] = "Load Server Config",
-- ["condition"] = function(data)
-- return data.debug
-- end,
-- ["func"] = function(data)
-- gmInte.config = data
-- end,
-- }
} }
// {
// ["label"] = "Load Server Config",
// ["condition"] = function(data)
// return data.debug
// end,
// ["func"] = function(data)
// gmInte.config = data
// end,
// }
local colorTable = { local colorTable = {
["text"] = Color(255, 255, 255, 255), ["text"] = Color(255, 255, 255, 255),
["background"] = Color(0, 0, 0, 200), ["background"] = Color(0, 0, 0, 200),
@ -318,52 +276,44 @@ function gmInte.needRestart()
frame:ShowCloseButton(true) frame:ShowCloseButton(true)
frame:MakePopup() frame:MakePopup()
gmInte.applyPaint(frame) gmInte.applyPaint(frame)
local messagePanel = vgui.Create("DPanel", frame) local messagePanel = vgui.Create("DPanel", frame)
messagePanel:Dock(TOP) messagePanel:Dock(TOP)
messagePanel:SetSize(300, 40) messagePanel:SetSize(300, 40)
messagePanel:DockMargin(10, 0, 10, 10) messagePanel:DockMargin(10, 0, 10, 10)
messagePanel:SetBackgroundColor(Color(0, 0, 0, 0)) messagePanel:SetBackgroundColor(Color(0, 0, 0, 0))
local messageLabel = vgui.Create("DLabel", messagePanel) local messageLabel = vgui.Create("DLabel", messagePanel)
messageLabel:Dock(FILL) messageLabel:Dock(FILL)
messageLabel:SetText("Some changes require a restart to be applied.\nRestart now ?") messageLabel:SetText("Some changes require a restart to be applied.\nRestart now ?")
messageLabel:SetContentAlignment(5) messageLabel:SetContentAlignment(5)
messageLabel:SetWrap(true) messageLabel:SetWrap(true)
local buttonGrid = vgui.Create("DGrid", frame) local buttonGrid = vgui.Create("DGrid", frame)
buttonGrid:Dock(BOTTOM) buttonGrid:Dock(BOTTOM)
buttonGrid:DockMargin(5, 10, 5, 5) buttonGrid:DockMargin(5, 10, 5, 5)
buttonGrid:SetCols(2) buttonGrid:SetCols(2)
buttonGrid:SetColWide(frame:GetWide() / 2 - 5) buttonGrid:SetColWide(frame:GetWide() / 2 - 5)
buttonGrid:SetRowHeight(35) buttonGrid:SetRowHeight(35)
local button = vgui.Create("DButton") local button = vgui.Create("DButton")
button:SetText("Restart") button:SetText("Restart")
button.DoClick = function() button.DoClick = function()
frame:Close() frame:Close()
gmInte.SendNet("restartMap") gmInte.SendNet("restartMap")
end end
button:SetSize(buttonGrid:GetColWide() -10, buttonGrid:GetRowHeight())
button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight())
gmInte.applyPaint(button) gmInte.applyPaint(button)
buttonGrid:AddItem(button) buttonGrid:AddItem(button)
local button = vgui.Create("DButton") local button = vgui.Create("DButton")
button:SetText("Maybe Later") button:SetText("Maybe Later")
button.DoClick = function() button.DoClick = function() frame:Close() end
frame:Close() button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight())
end
button:SetSize(buttonGrid:GetColWide() -10, buttonGrid:GetRowHeight())
gmInte.applyPaint(button) gmInte.applyPaint(button)
buttonGrid:AddItem(button) buttonGrid:AddItem(button)
end end
function gmInte.openConfigMenu(data) function gmInte.openConfigMenu(data)
local needRestart = false local needRestart = false
if gmInte.openAdminPanel then return end
if (gmInte.openAdminPanel) then return end
gmInte.openAdminPanel = true gmInte.openAdminPanel = true
local frame = vgui.Create("DFrame") local frame = vgui.Create("DFrame")
frame:SetSize(400, (600 / 1080) * ScrH()) frame:SetSize(400, (600 / 1080) * ScrH())
frame:Center() frame:Center()
@ -372,21 +322,17 @@ function gmInte.openConfigMenu(data)
frame:ShowCloseButton(true) frame:ShowCloseButton(true)
frame:MakePopup() frame:MakePopup()
gmInte.applyPaint(frame) gmInte.applyPaint(frame)
local scrollPanel = vgui.Create("DScrollPanel", frame) local scrollPanel = vgui.Create("DScrollPanel", frame)
scrollPanel:Dock(FILL) scrollPanel:Dock(FILL)
local messagePanel = vgui.Create("DPanel", scrollPanel) local messagePanel = vgui.Create("DPanel", scrollPanel)
messagePanel:Dock(TOP) messagePanel:Dock(TOP)
messagePanel:SetSize(300, 60) messagePanel:SetSize(300, 60)
messagePanel:DockMargin(10, 0, 10, 10) messagePanel:DockMargin(10, 0, 10, 10)
messagePanel:SetBackgroundColor(Color(0, 0, 0, 0)) messagePanel:SetBackgroundColor(Color(0, 0, 0, 0))
local messageLabel = vgui.Create("DLabel", messagePanel) local messageLabel = vgui.Create("DLabel", messagePanel)
messageLabel:Dock(FILL) messageLabel:Dock(FILL)
messageLabel:SetText("Here you can configure your server settings.\nServer ID and Token are available on the webpanel in the server settings.\nThe documentation is available at https://docs.gmod-integration.com/\nIf you need help, please contact us on our discord server.") messageLabel:SetText("Here you can configure your server settings.\nServer ID and Token are available on the webpanel in the server settings.\nThe documentation is available at https://docs.gmod-integration.com/\nIf you need help, please contact us on our discord server.")
messageLabel:SetWrap(true) messageLabel:SetWrap(true)
for k, catName in pairs(configCat) do for k, catName in pairs(configCat) do
local collapsibleCategory = vgui.Create("DCollapsibleCategory", scrollPanel) local collapsibleCategory = vgui.Create("DCollapsibleCategory", scrollPanel)
collapsibleCategory:Dock(TOP) collapsibleCategory:Dock(TOP)
@ -394,98 +340,69 @@ function gmInte.openConfigMenu(data)
collapsibleCategory:SetLabel(catName) collapsibleCategory:SetLabel(catName)
collapsibleCategory:SetExpanded(true) collapsibleCategory:SetExpanded(true)
gmInte.applyPaint(collapsibleCategory) gmInte.applyPaint(collapsibleCategory)
local configList = vgui.Create("DPanelList", collapsibleCategory) local configList = vgui.Create("DPanelList", collapsibleCategory)
configList:Dock(FILL) configList:Dock(FILL)
configList:SetSpacing(5) configList:SetSpacing(5)
configList:EnableHorizontal(false) configList:EnableHorizontal(false)
configList:EnableVerticalScrollbar(false) configList:EnableVerticalScrollbar(false)
collapsibleCategory:SetContents(configList) collapsibleCategory:SetContents(configList)
local categoryConfig = {} local categoryConfig = {}
for k, v in pairs(possibleConfig) do for k, v in pairs(possibleConfig) do
if v.category == catName then if v.category == catName then table.insert(categoryConfig, v) end
table.insert(categoryConfig, v)
end
end end
// Sort by position // Sort by position
table.sort(categoryConfig, function(a, b) table.sort(categoryConfig, function(a, b) return (a.position || 0) < (b.position || 0) end)
return (a.position || 0) < (b.position || 0)
end)
for k, actualConfig in pairs(categoryConfig) do for k, actualConfig in pairs(categoryConfig) do
local panel = vgui.Create("DPanel", configList) local panel = vgui.Create("DPanel", configList)
panel:Dock(TOP) panel:Dock(TOP)
panel:SetSize(300, 25) panel:SetSize(300, 25)
panel:SetBackgroundColor(Color(0, 0, 0, 0)) panel:SetBackgroundColor(Color(0, 0, 0, 0))
local label = vgui.Create("DLabel", panel) local label = vgui.Create("DLabel", panel)
label:Dock(LEFT) label:Dock(LEFT)
label:SetSize(140, 25) label:SetSize(140, 25)
label:SetText(actualConfig.label) label:SetText(actualConfig.label)
label:SetContentAlignment(4) label:SetContentAlignment(4)
local input local input
if actualConfig.type == "textEntry" then if actualConfig.type == "textEntry" then
input = vgui.Create("DTextEntry", panel) input = vgui.Create("DTextEntry", panel)
local value = actualConfig.value(actualConfig.id, data[actualConfig.id] || "") local value = actualConfig.value(actualConfig.id, data[actualConfig.id] || "")
if (actualConfig.secret) then if actualConfig.secret then
input:SetText("*** Click to show ***") input:SetText("*** Click to show ***")
else else
input:SetText(value) input:SetText(value)
end end
input.OnGetFocus = function(self)
if (actualConfig.secret) then input.OnGetFocus = function(self) if actualConfig.secret then self:SetText(value) end end
self:SetText(value) input.OnLoseFocus = function(self) if actualConfig.secret then self:SetText("*** Click to show ***") end end
end
end
input.OnLoseFocus = function(self)
if (actualConfig.secret) then
self:SetText("*** Click to show ***")
end
end
local isLastID = 0 local isLastID = 0
input.OnChange = function(self) input.OnChange = function(self)
if (actualConfig.resetIfEmpty && self:GetValue() == "" && actualConfig.defaultValue) then if actualConfig.resetIfEmpty && self:GetValue() == "" && actualConfig.defaultValue then
self:SetText(actualConfig.defaultValue) self:SetText(actualConfig.defaultValue)
return return
end end
isLastID = isLastID + 1 isLastID = isLastID + 1
local isLocalLastID = isLastID local isLocalLastID = isLastID
timer.Simple(actualConfig.onEditDelay || 0.5, function() timer.Simple(actualConfig.onEditDelay || 0.5, function() if isLocalLastID == isLastID then actualConfig.onEdit(actualConfig.id, self:GetValue()) end end)
if isLocalLastID == isLastID then
actualConfig.onEdit(actualConfig.id, self:GetValue())
end end
end) elseif actualConfig.type == "checkbox" then
end
elseif (actualConfig.type == "checkbox") then
input = vgui.Create("DComboBox", panel) input = vgui.Create("DComboBox", panel)
if (actualConfig.condition && !actualConfig.condition(data)) then if actualConfig.condition && !actualConfig.condition(data) then input:SetEnabled(false) end
input:SetEnabled(false)
end
input:AddChoice("Enabled") input:AddChoice("Enabled")
input:AddChoice("Disabled") input:AddChoice("Disabled")
input:SetText(actualConfig.value(actualConfig.id, data[actualConfig.id]) && "Enabled" || "Disabled") input:SetText(actualConfig.value(actualConfig.id, data[actualConfig.id]) && "Enabled" || "Disabled")
input.OnSelect = function(self, index, value) input.OnSelect = function(self, index, value)
if (actualConfig.restart) then if actualConfig.restart then needRestart = true end
needRestart = true
end
actualConfig.onEdit(actualConfig.id, value) actualConfig.onEdit(actualConfig.id, value)
end end
end end
input:Dock(FILL) input:Dock(FILL)
input:SetSize(150, 25) input:SetSize(150, 25)
if actualConfig.description then
if (actualConfig.description) then if actualConfig.websocket && !data.websocket then actualConfig.description = actualConfig.description .. "\n\nThis feature require a websocket connection to work properly." end
if (actualConfig.websocket && !data.websocket) then if actualConfig.disable then actualConfig.description = actualConfig.description .. "\n\nThis feature will be available soon." end
actualConfig.description = actualConfig.description .. "\n\nThis feature require a websocket connection to work properly."
end
if (actualConfig.disable) then
actualConfig.description = actualConfig.description .. "\n\nThis feature will be available soon."
end
input:SetTooltip(actualConfig.description) input:SetTooltip(actualConfig.description)
end end
@ -499,35 +416,28 @@ function gmInte.openConfigMenu(data)
buttonGrid:SetCols(2) buttonGrid:SetCols(2)
buttonGrid:SetColWide(frame:GetWide() / 2 - 5) buttonGrid:SetColWide(frame:GetWide() / 2 - 5)
buttonGrid:SetRowHeight(45) buttonGrid:SetRowHeight(45)
local buttonsCount = 0 local buttonsCount = 0
for k, v in pairs(buttonsInfo) do for k, v in pairs(buttonsInfo) do
if (v.condition && !v.condition(data)) then continue end if v.condition && !v.condition(data) then continue end
local button = vgui.Create("DButton") local button = vgui.Create("DButton")
button:SetText(v.label) button:SetText(v.label)
button.DoClick = function() button.DoClick = function() v.func(data) end
v.func(data)
end
gmInte.applyPaint(button) gmInte.applyPaint(button)
button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight() - 10) button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight() - 10)
buttonGrid:AddItem(button) buttonGrid:AddItem(button)
buttonsCount = buttonsCount + 1 buttonsCount = buttonsCount + 1
end end
if (buttonsCount % 2 == 1) then if buttonsCount % 2 == 1 then
local lastButton = buttonGrid:GetItems()[buttonsCount] local lastButton = buttonGrid:GetItems()[buttonsCount]
lastButton:SetWide(frame:GetWide() - 20) lastButton:SetWide(frame:GetWide() - 20)
end end
frame.OnClose = function() frame.OnClose = function()
gmInte.openAdminPanel = false gmInte.openAdminPanel = false
if (needRestart) then gmInte.needRestart() end if needRestart then gmInte.needRestart() end
end end
end end
//
// Concommands
//
concommand.Add("gmod_integration_admin", function() gmInte.SendNet("getConfig") end) concommand.Add("gmod_integration_admin", function() gmInte.SendNet("getConfig") end)
concommand.Add("gmi_admin", function() gmInte.SendNet("getConfig") end) concommand.Add("gmi_admin", function() gmInte.SendNet("getConfig") end)

View File

@ -7,7 +7,6 @@ function gmInte.openVerifPopup()
frame:ShowCloseButton(false) frame:ShowCloseButton(false)
frame:MakePopup() frame:MakePopup()
gmInte.applyPaint(frame) gmInte.applyPaint(frame)
local messageLabel = vgui.Create("DLabel", frame) local messageLabel = vgui.Create("DLabel", frame)
messageLabel:Dock(FILL) messageLabel:Dock(FILL)
messageLabel:DockMargin(10, 0, 10, 0) messageLabel:DockMargin(10, 0, 10, 0)
@ -15,34 +14,27 @@ function gmInte.openVerifPopup()
messageLabel:SetContentAlignment(5) messageLabel:SetContentAlignment(5)
messageLabel:SetFont("GmodIntegration_Roboto_16") messageLabel:SetFont("GmodIntegration_Roboto_16")
messageLabel:SetWrap(true) messageLabel:SetWrap(true)
local buttonGrid = vgui.Create("DGrid", frame) local buttonGrid = vgui.Create("DGrid", frame)
buttonGrid:Dock(BOTTOM) buttonGrid:Dock(BOTTOM)
buttonGrid:DockMargin(10, 0, 10, 10) buttonGrid:DockMargin(10, 0, 10, 10)
buttonGrid:SetCols(2) buttonGrid:SetCols(2)
buttonGrid:SetColWide(frame:GetWide() / 2 - 10) buttonGrid:SetColWide(frame:GetWide() / 2 - 10)
buttonGrid:SetRowHeight(35) buttonGrid:SetRowHeight(35)
local button = vgui.Create("DButton") local button = vgui.Create("DButton")
button:SetText("Open Verification Page") button:SetText("Open Verification Page")
button.DoClick = function() button.DoClick = function() gui.OpenURL("https://verif.gmod-integration.com") end
gui.OpenURL("https://verif.gmod-integration.com")
end
button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight()) button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight())
gmInte.applyPaint(button) gmInte.applyPaint(button)
buttonGrid:AddItem(button) buttonGrid:AddItem(button)
local button = vgui.Create("DButton") local button = vgui.Create("DButton")
button:SetText("Refresh Verification") button:SetText("Refresh Verification")
button.DoClick = function() button.DoClick = function()
gmInte.http.get("/users?steamID64" .. LocalPlayer():SteamID64(), function(code, body) gmInte.http.get("/users?steamID64" .. LocalPlayer():SteamID64(), function(code, body)
gmInte.SendNet("verifyMe") gmInte.SendNet("verifyMe")
frame:Close() frame:Close()
end, end, function(code, body) LocalPlayer():ChatPrint("Failed to refresh verification: " .. code) end)
function(code, body)
LocalPlayer():ChatPrint("Failed to refresh verification: " .. code)
end)
end end
button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight()) button:SetSize(buttonGrid:GetColWide() - 10, buttonGrid:GetRowHeight())
gmInte.applyPaint(button) gmInte.applyPaint(button)
buttonGrid:AddItem(button) buttonGrid:AddItem(button)

View File

@ -1,18 +1,8 @@
// hook.Add("InitPostEntity", "gmInte:Ply:Ready", function() gmInte.SendNet("ready") end)
// Hook
//
// Player Finish Init
hook.Add("InitPostEntity", "gmInte:Ply:Ready", function()
gmInte.SendNet("ready")
end)
hook.Add("OnPlayerChat", "gmInte:OnPlayerChat:AdminCmd", function(ply, strText, bTeamOnly, bPlayerIsDead) hook.Add("OnPlayerChat", "gmInte:OnPlayerChat:AdminCmd", function(ply, strText, bTeamOnly, bPlayerIsDead)
if (ply != LocalPlayer()) then return end if ply != LocalPlayer() then return end
strText = string.lower(strText) strText = string.lower(strText)
if strText == "/gmi" then
if (strText == "/gmi") then
gmInte.openAdminConfig() gmInte.openAdminConfig()
return true return true
end end

View File

@ -1,18 +1,15 @@
//
// Main
//
function gmInte.chatAddText(data) function gmInte.chatAddText(data)
local args = {} local args = {}
for _, v in ipairs(data) do for _, v in ipairs(data) do
table.insert(args, v.color) table.insert(args, v.color)
table.insert(args, v.text) table.insert(args, v.text)
end end
chat.AddText(unpack(args)) chat.AddText(unpack(args))
end end
function gmInte.showTestConnection(data) function gmInte.showTestConnection(data)
if (data && data.id) then if data && data.id then
chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(63, 102, 63), "Connection Successfull", Color(255, 255, 255), ", server logged as '" .. data.name .. "'") chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(63, 102, 63), "Connection Successfull", Color(255, 255, 255), ", server logged as '" .. data.name .. "'")
else else
chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(102, 63, 63), "Connection Failed", Color(255, 255, 255), ", please check your ID and Token") chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(102, 63, 63), "Connection Failed", Color(255, 255, 255), ", please check your ID and Token")
@ -20,7 +17,7 @@ function gmInte.showTestConnection(data)
end end
function gmInte.openAdminConfig() function gmInte.openAdminConfig()
if (!LocalPlayer():IsSuperAdmin()) then if !LocalPlayer():IsSuperAdmin() then
chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(102, 63, 63), "You are not superadmin") chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(102, 63, 63), "You are not superadmin")
return return
end end

View File

@ -1,21 +1,8 @@
//
// Variables
//
local ImageCache = {} local ImageCache = {}
//
// Functions
//
function gmInte.createImgurMaterials(materials, addon_var, folder, name) function gmInte.createImgurMaterials(materials, addon_var, folder, name)
if !file.Exists(folder, "DATA") then if !file.Exists(folder, "DATA") then file.CreateDir(folder) end
file.CreateDir(folder)
end
local function getMatFromUrl(url, id) local function getMatFromUrl(url, id)
materials[id] = Material("nil") materials[id] = Material("nil")
if file.Exists(folder .. "/" .. id .. ".png", "DATA") && !gmInte.config.redownloadMaterials then if file.Exists(folder .. "/" .. id .. ".png", "DATA") && !gmInte.config.redownloadMaterials then
addon_var[id] = Material("../data/" .. folder .. "/" .. id .. ".png", "noclamp smooth") addon_var[id] = Material("../data/" .. folder .. "/" .. id .. ".png", "noclamp smooth")
gmInte.log("materials", name .. " - Image Loaded - " .. id .. ".png") gmInte.log("materials", name .. " - Image Loaded - " .. id .. ".png")
@ -30,6 +17,7 @@ function gmInte.createImgurMaterials(materials, addon_var, folder, name)
["addon_var"] = addon_var, ["addon_var"] = addon_var,
["id"] = id ["id"] = id
} }
gmInte.log("materials", name .. " - Image Downloaded - " .. id .. ".png") gmInte.log("materials", name .. " - Image Downloaded - " .. id .. ".png")
end) end)
end end
@ -46,10 +34,7 @@ function gmInte.redowloadMaterials()
end end
end end
concommand.Add("gmod_integration_reload_materials", function() concommand.Add("gmod_integration_reload_materials", function() gmInte.redowloadMaterials() end)
gmInte.redowloadMaterials()
end)
local materialsList = { local materialsList = {
["logo"] = "y3Mypbn" ["logo"] = "y3Mypbn"
} }

View File

@ -1,7 +1,3 @@
//
// Send Net
//
local netSend = { local netSend = {
["ready"] = 0, ["ready"] = 0,
["testConnection"] = 1, ["testConnection"] = 1,
@ -16,42 +12,26 @@ function gmInte.SendNet(id, args, func)
net.Start("gmIntegration") net.Start("gmIntegration")
net.WriteUInt(netSend[id], 8) net.WriteUInt(netSend[id], 8)
net.WriteString(util.TableToJSON(args || {})) net.WriteString(util.TableToJSON(args || {}))
if (func) then func() end if func then func() end
net.SendToServer() net.SendToServer()
end end
//
// Receive Net
//
local netReceive = { local netReceive = {
[1] = function(data) [1] = function(data) gmInte.discordSyncChatPly(data) end,
gmInte.discordSyncChatPly(data) [2] = function(data) gmInte.openConfigMenu(data) end,
end, [3] = function(data) gmInte.showTestConnection(data) end,
[2] = function(data)
gmInte.openConfigMenu(data)
end,
[3] = function(data)
gmInte.showTestConnection(data)
end,
[5] = function(data) [5] = function(data)
gmInte.config = table.Merge(gmInte.config, data.config) gmInte.config = table.Merge(gmInte.config, data.config)
gmInte.version = data.other.version gmInte.version = data.other.version
if (!data.other.aprovedCredentials) then RunConsoleCommand("gmod_integration_admin") end if !data.other.aprovedCredentials then RunConsoleCommand("gmod_integration_admin") end
end, end,
[6] = function(data) [6] = function(data) gmInte.chatAddText(data) end,
gmInte.chatAddText(data) [7] = function() gmInte.openVerifPopup() end,
end, [8] = function(data) gmInte.config.token = data.token end
[7] = function()
gmInte.openVerifPopup()
end,
[8] = function(data)
gmInte.config.token = data.token
end
} }
net.Receive("gmIntegration", function() net.Receive("gmIntegration", function()
local id = net.ReadUInt(8) local id = net.ReadUInt(8)
local args = util.JSONToTable(net.ReadString()) local args = util.JSONToTable(net.ReadString())
if (netReceive[id]) then netReceive[id](args) end if netReceive[id] then netReceive[id](args) end
end) end)

View File

@ -1,13 +1,8 @@
//
// Hooks
//
local ScreenshotRequested = false local ScreenshotRequested = false
local FailAttempts = 0 local FailAttempts = 0
hook.Add("PostRender", "gmInteScreenshot", function() hook.Add("PostRender", "gmInteScreenshot", function()
if (!ScreenshotRequested) then return end if !ScreenshotRequested then return end
ScreenshotRequested = false ScreenshotRequested = false
local captureData = { local captureData = {
format = "jpeg", format = "jpeg",
x = 0, x = 0,
@ -18,8 +13,8 @@ hook.Add("PostRender", "gmInteScreenshot", function()
} }
local screenCapture = render.Capture(captureData) local screenCapture = render.Capture(captureData)
if (!screenCapture) then if !screenCapture then
if (FailAttempts < 3) then if FailAttempts < 3 then
timer.Simple(0.5, function() timer.Simple(0.5, function()
ScreenshotRequested = true ScreenshotRequested = true
FailAttempts = FailAttempts + 1 FailAttempts = FailAttempts + 1
@ -34,54 +29,29 @@ hook.Add("PostRender", "gmInteScreenshot", function()
end end
local base64Capture = util.Base64Encode(screenCapture) local base64Capture = util.Base64Encode(screenCapture)
local size = math.Round(string.len(base64Capture) / 1024) local size = math.Round(string.len(base64Capture) / 1024)
gmInte.log("Screenshot Taken - " .. size .. "KB", true) gmInte.log("Screenshot Taken - " .. size .. "KB", true)
gmInte.http.post("/clients/:steamID64/servers/:serverID/screenshots", {
gmInte.http.post("/clients/:steamID64/servers/:serverID/screenshots",
{
["player"] = gmInte.getPlayerFormat(LocalPlayer()), ["player"] = gmInte.getPlayerFormat(LocalPlayer()),
["screenshot"] = base64Capture, ["screenshot"] = base64Capture,
["captureData"] = captureData, ["captureData"] = captureData,
["size"] = size .. "KB" ["size"] = size .. "KB"
}, }, function(code, body)
function(code, body)
gmInte.log("Screenshot sent to Discord", true) gmInte.log("Screenshot sent to Discord", true)
chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(255, 255, 255), "Screenshot sent to Discord.") chat.AddText(Color(255, 130, 92), "[Gmod Integration] ", Color(255, 255, 255), "Screenshot sent to Discord.")
end, end, function(code, body) gmInte.log("Screenshot failed to send to Discord, error code: " .. code, true) end)
function(code, body)
gmInte.log("Screenshot failed to send to Discord, error code: " .. code, true)
end
)
end) end)
//
// Methods
//
function gmInte.takeScreenShot() function gmInte.takeScreenShot()
timer.Simple(0.5, function() timer.Simple(0.5, function() ScreenshotRequested = true end)
ScreenshotRequested = true
end)
end end
//
// Console Commands
//
concommand.Add("gmod_integration_screenshot", gmInte.takeScreenShot)
concommand.Add("gmi_screen", gmInte.takeScreenShot) concommand.Add("gmi_screen", gmInte.takeScreenShot)
//
// Chat Commands
//
hook.Add("OnPlayerChat", "gmInteChatCommands", function(ply, text, teamChat, isDead) hook.Add("OnPlayerChat", "gmInteChatCommands", function(ply, text, teamChat, isDead)
if (ply != LocalPlayer()) then return end if ply != LocalPlayer() then return end
text = string.lower(text) text = string.lower(text)
text = string.sub(text, 2) text = string.sub(text, 2)
if text == "screen" then
if (text == "screen") then
gmInte.takeScreenShot() gmInte.takeScreenShot()
return true return true
end end

View File

@ -1,57 +0,0 @@
//
// Hooks
//
local StreamsRequeted = false
hook.Add("PostRender", "gmInte:PostRender:Stream:Frame", function()
if (!StreamsRequeted) then return end
StreamsRequeted = false
// Capture frame
local captureConfig = {
format = "jpeg",
x = 0,
y = 0,
w = ScrW(),
h = ScrH(),
quality = 30,
}
local screenCapture = render.Capture(captureConfig)
if (!screenCapture) then return end
screenCapture = util.Base64Encode(screenCapture)
local size = math.Round(string.len(screenCapture) / 1024)
gmInte.log("Frame captured, size: " .. size .. "KB", true)
gmInte.http.post("/clients/:steamID64/servers/:serverID/streams/frames",
{
["player"] = gmInte.getPlayerFormat(LocalPlayer()),
["base64Capture"] = screenCapture,
["captureConfig"] = captureConfig,
["size"] = size .. "KB"
},
function(code, body)
gmInte.log("Frame sent to WebPanel, size: " .. size .. "KB", true)
end,
function(code, body)
gmInte.log("Failed to send frame to WebPanel", true)
end
)
end)
local Steam = false
timer.Create("gmInte:Stream:Frame", 0.5, 0, function()
if (Steam) then
StreamsRequeted = true
end
end)
//
// Console Commands
//
concommand.Add("gmod_integration_stream", function()
Steam = !Steam
gmInte.log("Streaming frames to WebPanel: " .. tostring(Steam))
end)

View File

@ -1,10 +1,7 @@
local function formatName(name) local function formatName(name)
// all un down case
name = string.lower(name) name = string.lower(name)
// first leter in upper case
name = string.upper(string.sub(name, 1, 1)) .. string.sub(name, 2) name = string.upper(string.sub(name, 1, 1)) .. string.sub(name, 2)
// every letter after a space in upper case name = string.gsub(name, "(%a)([%w_']*)", function(a, b) return string.upper(a) .. string.lower(b) end)
name = string.gsub(name, "(%a)([%w_']*)", function(a,b) return string.upper(a) .. string.lower(b) end)
return name return name
end end

View File

@ -1,15 +1,8 @@
//
// WebSocket
//
local function websocketDLLExist() local function websocketDLLExist()
local files, _ = file.Find("lua/bin/*", "GAME") local files, _ = file.Find("lua/bin/*", "GAME")
for k, v in pairs(files) do for k, v in pairs(files) do
if (v:find("gwsockets")) then if v:find("gwsockets") then return true end
return true
end end
end
return false return false
end end
@ -22,18 +15,14 @@ if !websocketDLLExist() then
end end
require("gwsockets") require("gwsockets")
local function getWebSocketURL() local function getWebSocketURL()
local method = gmInte.isPrivateIP(gmInte.config.websocketFQDN) && "ws" || "wss" local method = gmInte.isPrivateIP(gmInte.config.websocketFQDN) && "ws" || "wss"
return method .. "://" .. gmInte.config.websocketFQDN return method .. "://" .. gmInte.config.websocketFQDN
end end
local socket = GWSockets.createWebSocket(getWebSocketURL()) local socket = GWSockets.createWebSocket(getWebSocketURL())
// Authentication
socket:setHeader("id", gmInte.config.id) socket:setHeader("id", gmInte.config.id)
socket:setHeader("token", gmInte.config.token) socket:setHeader("token", gmInte.config.token)
function gmInte.resetWebSocket() function gmInte.resetWebSocket()
socket:closeNow() socket:closeNow()
socket = GWSockets.createWebSocket(getWebSocketURL()) socket = GWSockets.createWebSocket(getWebSocketURL())
@ -47,12 +36,10 @@ function socket:onConnected()
gmInte.log("WebSocket Connected", true) gmInte.log("WebSocket Connected", true)
end end
// log on message
function socket:onMessage(txt) function socket:onMessage(txt)
gmInte.log("WebSocket Message: " .. txt, true) gmInte.log("WebSocket Message: " .. txt, true)
local data = util.JSONToTable(txt) local data = util.JSONToTable(txt)
if (gmInte[data.method]) then if gmInte[data.method] then
gmInte[data.method](data) gmInte[data.method](data)
else else
gmInte.logError("WebSocket Message: " .. txt .. " is not a valid method !", true) gmInte.logError("WebSocket Message: " .. txt .. " is not a valid method !", true)
@ -60,7 +47,7 @@ function socket:onMessage(txt)
end end
function socket:onDisconnected() function socket:onDisconnected()
if (hasConnected) then if hasConnected then
hasConnected = false hasConnected = false
gmInte.log("WebSocket Disconnected", true) gmInte.log("WebSocket Disconnected", true)
else else
@ -73,7 +60,7 @@ function socket:onError(txt)
end end
timer.Create("gmInte:WebSocket:CheckConnection", 4, 0, function() timer.Create("gmInte:WebSocket:CheckConnection", 4, 0, function()
if (!socket:isConnected()) then if !socket:isConnected() then
gmInte.resetWebSocket() gmInte.resetWebSocket()
socket:open() socket:open()
end end

View File

@ -1,50 +1,22 @@
local conFuncs = { local conFuncs = {
["version"] = function() ["version"] = function() gmInte.log("Version: " .. gmInte.version) end,
gmInte.log("Version: " .. gmInte.version) ["setting"] = function(args) gmInte.saveSetting(args[2], args[3]) end,
end, ["try"] = function() gmInte.tryConfig() end,
["setting"] = function(args) ["refresh"] = function() gmInte.refreshSettings() end,
gmInte.saveSetting(args[2], args[3]) ["get-server-id"] = function() print(gmInte.config.id || "none") end,
end,
["try"] = function()
gmInte.tryConfig()
end,
["refresh"] = function()
gmInte.refreshSettings()
end,
["get-server-id"] = function()
print(gmInte.config.id || "none")
end,
["screenshot"] = function(args) ["screenshot"] = function(args)
if (!args[2]) then return gmInte.log("No SteamID64 provided") end if !args[2] then return gmInte.log("No SteamID64 provided") end
for _, ply in pairs(player.GetAll()) do for _, ply in pairs(player.GetAll()) do
if (ply:SteamID64() == args[2]) then return gmInte.takeScreenshot(ply) end if ply:SteamID64() == args[2] then return gmInte.takeScreenshot(ply) end
end end
end, end,
} }
concommand.Add("gmod-integration", function(ply, cmd, args) concommand.Add("gmi", function(ply, cmd, args)
// only usable by server console and superadmins
if ply:IsPlayer() && !ply:IsSuperAdmin() then return end if ply:IsPlayer() && !ply:IsSuperAdmin() then return end
// check if argument is valid
if conFuncs[args[1]] then if conFuncs[args[1]] then
conFuncs[args[1]](args) conFuncs[args[1]](args)
else else
gmInte.log("Unknown Command Argument") gmInte.log("Unknown Command Argument")
end end
end) end)
concommand.Add("gm_integration", function(ply, cmd, args)
// run the old command
RunConsoleCommand("gmod-integration", unpack(args))
end)
concommand.Add("gmod_integration", function(ply, cmd, args)
// run the old command
RunConsoleCommand("gmod-integration", unpack(args))
end)
concommand.Add("gm-integration", function(ply, cmd, args)
// run the old command
RunConsoleCommand("gmod-integration", unpack(args))
end)

View File

@ -1,86 +1,38 @@
//
// Methods
//
local function filterMessage(reason) local function filterMessage(reason)
local Message = { local Message = {"\n----------------------------------------\n", "You cannot join this server", "", "Reason: " .. (reason && reason || "none"), "Help URL: " .. (gmInte.config.supportLink && gmInte.config.supportLink || "none"), "", "Have a nice day", "\n----------------------------------------\n", "Service provided by Gmod Integration",}
"\n----------------------------------------\n",
"You cannot join this server",
"",
"Reason: " .. (reason && reason || "none"),
"Help URL: " .. (gmInte.config.supportLink && gmInte.config.supportLink || "none"),
"",
"Have a nice day",
"\n----------------------------------------\n",
"Service provided by Gmod Integration",
}
for k, v in pairs(Message) do for k, v in pairs(Message) do
Message[k] = "\n" .. v Message[k] = "\n" .. v
end end
return table.concat(Message) return table.concat(Message)
end end
local function checkTrustFactor(trustLevel) local function checkTrustFactor(trustLevel)
if (gmInte.config.filterOnTrust && (trustLevel < gmInte.config.minimalTrust)) then if gmInte.config.filterOnTrust && (trustLevel < gmInte.config.minimalTrust) then return false end
return false
end
return true return true
end end
local function checkBanStatus(banStatus) local function checkBanStatus(banStatus)
if (gmInte.config.filterOnBan && banStatus) then if gmInte.config.filterOnBan && banStatus then return false end
return false
end
return true return true
end end
local function checkDiscordBanStatus(banStatus) local function checkDiscordBanStatus(banStatus)
if (gmInte.config.syncBan && banStatus) then if gmInte.config.syncBan && banStatus then return false end
return false
end
return true return true
end end
local function playerFilter(data) local function playerFilter(data)
if (data.bot == 1) then return end if data.bot == 1 then return end
data.steamID64 = util.SteamIDTo64(data.networkid) data.steamID64 = util.SteamIDTo64(data.networkid)
gmInte.http.get("/servers/:serverID/players/" .. data.steamID64, function(code, body)
gmInte.http.get("/servers/:serverID/players/" .. data.steamID64, if gmInte.config.maintenance && !body.bypassMaintenance && !body.discordAdmin then game.KickID(data.networkid, filterMessage("The server is currently under maintenance and you are not whitelisted.")) end
function(code, body) if !checkBanStatus(body.ban) then game.KickID(data.networkid, filterMessage("You are banned from this server.")) end
if (gmInte.config.maintenance && !body.bypassMaintenance && !body.discordAdmin) then if !checkDiscordBanStatus(body.discord_ban) then game.KickID(data.networkid, filterMessage("You are banned from our discord server.")) end
game.KickID(data.networkid, filterMessage("The server is currently under maintenance and you are not whitelisted.")) // if (!checkTrustFactor(body.trust)) then
end // game.KickID(data.networkid, filterMessage("Your trust factor is too low."))
// end
if (!checkBanStatus(body.ban)) then end, function(code, body) if gmInte.config.maintenance then game.KickID(data.networkid, filterMessage("The server is currently under maintenance and we cannot verify your account.\nVerification URL: https://verif.gmod-integration.com")) end end)
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,
function (code, body)
if (gmInte.config.maintenance) then
game.KickID(data.networkid, filterMessage("The server is currently under maintenance and we cannot verify your account.\nVerification URL: https://verif.gmod-integration.com"))
end
end
)
end end
//
// Hooks
//
gameevent.Listen("player_connect") gameevent.Listen("player_connect")
hook.Add("player_connect", "gmInte:Player:Connect:Filter", function(data) hook.Add("player_connect", "gmInte:Player:Connect:Filter", function(data) playerFilter(data) end)
playerFilter(data)
end)

View File

@ -1,13 +1,4 @@
//
// Networking
//
util.AddNetworkString("gmIntegration") util.AddNetworkString("gmIntegration")
//
// Send Net
//
local netSend = { local netSend = {
["wsRelayDiscordChat"] = 1, ["wsRelayDiscordChat"] = 1,
["adminConfig"] = 2, ["adminConfig"] = 2,
@ -20,58 +11,36 @@ local netSend = {
// Send // Send
function gmInte.SendNet(id, data, ply, func) function gmInte.SendNet(id, data, ply, func)
if (!netSend[id]) then return end if !netSend[id] then return end
net.Start("gmIntegration") net.Start("gmIntegration")
net.WriteUInt(netSend[id], 8) net.WriteUInt(netSend[id], 8)
net.WriteString(util.TableToJSON(data || {})) net.WriteString(util.TableToJSON(data || {}))
if (func) then func() end if func then func() end
if (ply == nil) then if ply == nil then
net.Broadcast() net.Broadcast()
else else
net.Send(ply) net.Send(ply)
end end
end end
//
// Receive net
//
local netReceive = { local netReceive = {
[0] = function(ply) [0] = function(ply) hook.Run("gmInte:PlayerReady", ply) end,
hook.Run("gmInte:PlayerReady", ply) [1] = function(ply, data) gmInte.testConnection(ply, data) end,
end, [2] = function(ply) gmInte.superadminGetConfig(ply) end,
[1] = function(ply, data) [3] = function(ply, data) gmInte.superadminSetConfig(ply, data) end,
gmInte.testConnection(ply, data) [4] = function(ply) gmInte.takeScreenshot(ply) end,
end,
[2] = function(ply)
gmInte.superadminGetConfig(ply)
end,
[3] = function(ply, data)
gmInte.superadminSetConfig(ply, data)
end,
[4] = function(ply)
gmInte.takeScreenshot(ply)
end,
[5] = function(ply) [5] = function(ply)
if (!ply:IsSuperAdmin()) then return end if !ply:IsSuperAdmin() then return end
RunConsoleCommand("changelevel", game.GetMap()) RunConsoleCommand("changelevel", game.GetMap())
end, end,
[6] = function(ply) [6] = function(ply) gmInte.verifyPlayer(ply) end,
gmInte.verifyPlayer(ply) [7] = function(ply, data) sendPlayerToken(ply) end
end,
[7] = function(ply, data)
sendPlayerToken(ply)
end
} }
net.Receive("gmIntegration", function(len, ply) net.Receive("gmIntegration", function(len, ply)
if (!ply || ply && !ply:IsValid()) then return end if !ply || ply && !ply:IsValid() then return end
local id = net.ReadUInt(8) local id = net.ReadUInt(8)
local data = util.JSONToTable(net.ReadString() || "{}") local data = util.JSONToTable(net.ReadString() || "{}")
if !netReceive[id] then return end
if (!netReceive[id]) then return end
netReceive[id](ply, data) netReceive[id](ply, data)
end) end)

View File

@ -1,16 +1,9 @@
//
// Methods
//
function gmInte.playerReady(ply) function gmInte.playerReady(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
// Initialize Time // Initialize Time
ply.gmIntTimeConnect = math.Round(RealTime()) ply.gmIntTimeConnect = math.Round(RealTime())
// Send Public Config // Send Public Config
gmInte.publicGetConfig(ply) gmInte.publicGetConfig(ply)
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/ready", { gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/ready", {
["player"] = gmInte.getPlayerFormat(ply) ["player"] = gmInte.getPlayerFormat(ply)
}) })
@ -22,109 +15,80 @@ function gmInte.playerConnect(data)
end end
function gmInte.playerDisconnected(ply) function gmInte.playerDisconnected(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/disconnect", {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/disconnect",
{
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
} })
)
end end
function gmInte.playerSpawn(ply) function gmInte.playerSpawn(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/spawn", {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/spawn",
{
["player"] = gmInte.getPlayerFormat(ply) ["player"] = gmInte.getPlayerFormat(ply)
} })
)
end end
function gmInte.playerDeath(ply, inflictor, attacker) function gmInte.playerDeath(ply, inflictor, attacker)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
if (!attacker:IsValid() || !attacker:IsPlayer(attacker)) then return end if !attacker:IsValid() || !attacker:IsPlayer(attacker) then return end
if (!inflictor:IsValid()) then return end if !inflictor:IsValid() then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/death", {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/death",
{
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
["inflictor"] = gmInte.getEntityFormat(inflictor), ["inflictor"] = gmInte.getEntityFormat(inflictor),
["attacker"] = gmInte.getPlayerFormat(attacker) ["attacker"] = gmInte.getPlayerFormat(attacker)
} })
)
end end
function gmInte.playerInitialSpawn(ply) function gmInte.playerInitialSpawn(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/initial-spawn", {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/initial-spawn",
{
["player"] = gmInte.getPlayerFormat(ply) ["player"] = gmInte.getPlayerFormat(ply)
} })
)
end end
function gmInte.postLogPlayerHurt(ply, attacker, healthRemaining, damageTaken) function gmInte.postLogPlayerHurt(ply, attacker, healthRemaining, damageTaken)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
if (!attacker:IsValid() || !attacker:IsPlayer(attacker)) then return end if !attacker:IsValid() || !attacker:IsPlayer(attacker) then return end
// Wait a second to see if the player is going to be hurt again // Wait a second to see if the player is going to be hurt again
ply.gmodInteLastHurt = ply.gmodInteLastHurt || {} ply.gmodInteLastHurt = ply.gmodInteLastHurt || {}
local locCurTime = CurTime() local locCurTime = CurTime()
ply.gmodInteLastHurt[attacker:SteamID64()] = locCurTime ply.gmodInteLastHurt[attacker:SteamID64()] = locCurTime
timer.Simple(1, function() timer.Simple(1, function()
if (ply.gmodInteLastHurt[attacker:SteamID64()] != locCurTime) then if ply.gmodInteLastHurt[attacker:SteamID64()] != locCurTime then
ply.gmodInteTotalDamage = ply.gmodInteTotalDamage || 0 ply.gmodInteTotalDamage = ply.gmodInteTotalDamage || 0
ply.gmodInteTotalDamage = ply.gmodInteTotalDamage + damageTaken ply.gmodInteTotalDamage = ply.gmodInteTotalDamage + damageTaken
return return
end end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/hurt", gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/hurt", {
{
["victim"] = gmInte.getPlayerFormat(ply), ["victim"] = gmInte.getPlayerFormat(ply),
["attacker"] = gmInte.getPlayerFormat(attacker), ["attacker"] = gmInte.getPlayerFormat(attacker),
["healthRemaining"] = math.Round(healthRemaining), ["healthRemaining"] = math.Round(healthRemaining),
["damageTaken"] = math.Round(damageTaken) ["damageTaken"] = math.Round(damageTaken)
} })
)
end) end)
end end
function gmInte.postLogPlayerSpawnedSomething(object, ply, ent, model) function gmInte.postLogPlayerSpawnedSomething(object, ply, ent, model)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
if (!ent:IsValid()) then return end if !ent:IsValid() then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/spawn/" .. object, {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/spawn/" .. object,
{
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
["entity"] = gmInte.getEntityFormat(ent), ["entity"] = gmInte.getEntityFormat(ent),
["model"] = model || "" ["model"] = model || ""
} })
)
end end
function gmInte.postLogPlayerGive(ply, class, swep) function gmInte.postLogPlayerGive(ply, class, swep)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/give", {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/give",
{
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
["class"] = class, ["class"] = class,
["swep"] = swep ["swep"] = swep
} })
)
end end
// hook.Add("gmInte:PlayerReady", "gmInte:Player:Ready", function(ply) gmInte.playerReady(ply) end)
// Hooks
//
hook.Add("gmInte:PlayerReady", "gmInte:Player:Ready", function(ply)
gmInte.playerReady(ply)
end)
hook.Add("ShutDown", "gmInte:Server:Shutdown:SavePlayers", function() hook.Add("ShutDown", "gmInte:Server:Shutdown:SavePlayers", function()
for ply, ply in pairs(player.GetAll()) do for ply, ply in pairs(player.GetAll()) do
gmInte.playerDisconnected(ply) gmInte.playerDisconnected(ply)
@ -132,58 +96,17 @@ hook.Add("ShutDown", "gmInte:Server:Shutdown:SavePlayers", function()
end) end)
gameevent.Listen("player_connect") gameevent.Listen("player_connect")
hook.Add("player_connect", "gmInte:Player:Connect", function(data) hook.Add("player_connect", "gmInte:Player:Connect", function(data) gmInte.playerConnect(data) end)
gmInte.playerConnect(data) hook.Add("PlayerDisconnected", "gmInte:Player:Disconnect", function(ply) gmInte.playerDisconnected(ply) end)
end) hook.Add("PlayerSpawn", "gmInte:Player:Spawn", function(ply) gmInte.playerSpawn(ply) end)
hook.Add("PlayerInitialSpawn", "gmInte:Player:InitialSpawn", function(ply) gmInte.playerInitialSpawn(ply) end)
hook.Add("PlayerDisconnected", "gmInte:Player:Disconnect", function(ply) hook.Add("PlayerGiveSWEP", "gmInte:Player:SWEPs", function(ply, class, swep) gmInte.postLogPlayerGive(ply, class, swep) end)
gmInte.playerDisconnected(ply) hook.Add("PlayerDeath", "gmInte:Player:Death", function(ply, inflictor, attacker) gmInte.playerDeath(ply, inflictor, attacker) end)
end) hook.Add("PlayerHurt", "gmInte:Player:Hurt", function(ply, attacker, healthRemaining, damageTaken) gmInte.postLogPlayerHurt(ply, attacker, healthRemaining, damageTaken) end)
hook.Add("PlayerSpawnedProp", "gmInte:Player:SpawnedProp", function(ply, model, ent) gmInte.postLogPlayerSpawnedSomething("prop", ply, ent, model) end)
hook.Add("PlayerSpawn", "gmInte:Player:Spawn", function(ply) hook.Add("PlayerSpawnedSENT", "gmInte:Player:SpawnedSENT", function(ply, ent) gmInte.postLogPlayerSpawnedSomething("sent", ply, ent) end)
gmInte.playerSpawn(ply) hook.Add("PlayerSpawnedNPC", "gmInte:Player:SpawnedNPC", function(ply, ent) gmInte.postLogPlayerSpawnedSomething("npc", ply, ent) end)
end) hook.Add("PlayerSpawnedVehicle", "gmInte:Player:SpawnedVehicle", function(ply, ent) gmInte.postLogPlayerSpawnedSomething("vehicle", ply, ent) end)
hook.Add("PlayerSpawnedEffect", "gmInte:Player:SpawnedEffect", function(ply, model, ent) gmInte.postLogPlayerSpawnedSomething("effect", ply, ent, model) end)
hook.Add("PlayerInitialSpawn", "gmInte:Player:InitialSpawn", function(ply) hook.Add("PlayerSpawnedRagdoll", "gmInte:Player:SpawnedRagdoll", function(ply, model, ent) gmInte.postLogPlayerSpawnedSomething("ragdoll", ply, ent, model) end)
gmInte.playerInitialSpawn(ply) hook.Add("PlayerSpawnedSWEP", "gmInte:Player:SpawnedSWEP", function(ply, ent) gmInte.postLogPlayerSpawnedSomething("swep", ply, ent) end)
end)
hook.Add("PlayerGiveSWEP", "gmInte:Player:SWEPs", function( ply, class, swep )
gmInte.postLogPlayerGive(ply, class, swep)
end)
hook.Add("PlayerDeath", "gmInte:Player:Death", function(ply, inflictor, attacker)
gmInte.playerDeath(ply, inflictor, attacker)
end)
hook.Add("PlayerHurt", "gmInte:Player:Hurt", function(ply, attacker, healthRemaining, damageTaken)
gmInte.postLogPlayerHurt(ply, attacker, healthRemaining, damageTaken)
end)
hook.Add("PlayerSpawnedProp", "gmInte:Player:SpawnedProp", function(ply, model, ent)
gmInte.postLogPlayerSpawnedSomething("prop", ply, ent, model)
end)
hook.Add("PlayerSpawnedSENT", "gmInte:Player:SpawnedSENT", function(ply, ent)
gmInte.postLogPlayerSpawnedSomething("sent", ply, ent)
end)
hook.Add("PlayerSpawnedNPC", "gmInte:Player:SpawnedNPC", function(ply, ent)
gmInte.postLogPlayerSpawnedSomething("npc", ply, ent)
end)
hook.Add("PlayerSpawnedVehicle", "gmInte:Player:SpawnedVehicle", function(ply, ent)
gmInte.postLogPlayerSpawnedSomething("vehicle", ply, ent)
end)
hook.Add("PlayerSpawnedEffect", "gmInte:Player:SpawnedEffect", function(ply, model, ent)
gmInte.postLogPlayerSpawnedSomething("effect", ply, ent, model)
end)
hook.Add("PlayerSpawnedRagdoll", "gmInte:Player:SpawnedRagdoll", function(ply, model, ent)
gmInte.postLogPlayerSpawnedSomething("ragdoll", ply, ent, model)
end)
hook.Add("PlayerSpawnedSWEP", "gmInte:Player:SpawnedSWEP", function(ply, ent)
gmInte.postLogPlayerSpawnedSomething("swep", ply, ent)
end)

View File

@ -1,24 +1,16 @@
//
// Methods
//
function gmInte.verifyPlayer(ply) function gmInte.verifyPlayer(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.http.get("/user?steamID64=" .. ply:SteamID64(), function(code, data) gmInte.http.get("/user?steamID64=" .. ply:SteamID64(), function(code, data)
if (data && data.discordID) then if data && data.discordID then ply.gmIntVerified = true end
ply.gmIntVerified = true if !gmInte.config.forcePlayerLink || !ply.gmIntIsReady then return end
end if ply:gmIntIsVerified() then
if (!gmInte.config.forcePlayerLink || !ply.gmIntIsReady) then return end
if (ply:gmIntIsVerified()) then
gmInte.SendNet("chatColorMessage", { gmInte.SendNet("chatColorMessage", {
[1] = { [1] = {
["text"] = "You have been verified", ["text"] = "You have been verified",
["color"] = Color(255, 255, 255) ["color"] = Color(255, 255, 255)
} }
}, ply) }, ply)
ply:Freeze(false) ply:Freeze(false)
else else
gmInte.SendNet("chatColorMessage", { gmInte.SendNet("chatColorMessage", {
@ -27,19 +19,15 @@ function gmInte.verifyPlayer(ply)
["color"] = Color(255, 0, 0) ["color"] = Color(255, 0, 0)
} }
}, ply) }, ply)
ply:Freeze(true) ply:Freeze(true)
gmInte.SendNet("openVerifPopup", nil, ply) gmInte.SendNet("openVerifPopup", nil, ply)
end end
end) end)
end end
//
// Hooks
//
hook.Add("gmInte:PlayerReady", "gmInte:Verif:PlayerReady", function(ply) hook.Add("gmInte:PlayerReady", "gmInte:Verif:PlayerReady", function(ply)
ply.gmIntIsReady = true ply.gmIntIsReady = true
if !gmInte.config.forcePlayerLink then return end
if (!gmInte.config.forcePlayerLink) then return end
gmInte.verifyPlayer(ply) gmInte.verifyPlayer(ply)
end) end)

View File

@ -1,7 +1,3 @@
//
// Websocket
//
function gmInte.wsRcon(data) function gmInte.wsRcon(data)
gmInte.log("Rcon Command from Discord '" .. data.command .. "' by " .. data.steamID) gmInte.log("Rcon Command from Discord '" .. data.command .. "' by " .. data.steamID)
game.ConsoleCommand(data.command .. "\n") game.ConsoleCommand(data.command .. "\n")

View File

@ -5,23 +5,17 @@ function gmInte.saveSetting(setting, value)
end end
// Boolean // Boolean
if (value == "true") then value = true end if value == "true" then value = true end
if (value == "false") then value = false end if value == "false" then value = false end
// Number // Number
if (tonumber(value) != nil) then value = tonumber(value) end if tonumber(value) != nil then value = tonumber(value) end
gmInte.config[setting] = value gmInte.config[setting] = value
file.Write("gm_integration/config.json", util.TableToJSON(gmInte.config, true)) file.Write("gm_integration/config.json", util.TableToJSON(gmInte.config, true))
gmInte.log("Setting Saved") gmInte.log("Setting Saved")
if value == "websocketFQDN" || value == "id" || value == "token" then gmInte.resetWebSocket() end
if (value == "websocketFQDN" || value == "id" || value == "token") then
gmInte.resetWebSocket()
end
// send to all players the new public config // send to all players the new public config
for _, ply in pairs(player.GetAll()) do for _, ply in pairs(player.GetAll()) do
if (ply:IsValid() && ply:IsPlayer(ply)) then if ply:IsValid() && ply:IsPlayer(ply) then
gmInte.log("Sending new Public Config to " .. ply:Nick(), true) gmInte.log("Sending new Public Config to " .. ply:Nick(), true)
gmInte.publicGetConfig(ply) gmInte.publicGetConfig(ply)
end end
@ -29,26 +23,17 @@ function gmInte.saveSetting(setting, value)
end end
function gmInte.tryConfig() function gmInte.tryConfig()
gmInte.http.get("/servers/:serverID", gmInte.http.get("/servers/:serverID", function(code, body)
function(code, body)
print(" ") print(" ")
gmInte.log("Congratulations your server is now connected to Gmod Integration") gmInte.log("Congratulations your server is now connected to Gmod Integration")
gmInte.log("Server Name: " .. body.name) gmInte.log("Server Name: " .. body.name)
gmInte.log("Server ID: " .. body.id) gmInte.log("Server ID: " .. body.id)
print(" ") print(" ")
end end)
)
end end
function gmInte.testConnection(ply) function gmInte.testConnection(ply)
gmInte.http.get("/servers/:serverID", gmInte.http.get("/servers/:serverID", function(code, body) if ply then gmInte.SendNet("testApiConnection", body, ply) end end, function(code, body) if ply then gmInte.SendNet("testApiConnection", body, ply) end end)
function(code, body)
if (ply) then gmInte.SendNet("testApiConnection", body, ply) end
end,
function(code, body)
if (ply) then gmInte.SendNet("testApiConnection", body, ply) end
end
)
end end
function gmInte.refreshSettings() function gmInte.refreshSettings()
@ -58,15 +43,13 @@ function gmInte.refreshSettings()
end end
function gmInte.superadminGetConfig(ply) function gmInte.superadminGetConfig(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply) || !ply:IsSuperAdmin()) then return end if !ply:IsValid() || !ply:IsPlayer(ply) || !ply:IsSuperAdmin() then return end
gmInte.config.websocket = GWSockets && true || false gmInte.config.websocket = GWSockets && true || false
gmInte.SendNet("adminConfig", gmInte.config, ply) gmInte.SendNet("adminConfig", gmInte.config, ply)
end end
function gmInte.publicGetConfig(ply) function gmInte.publicGetConfig(ply)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.SendNet("publicConfig", { gmInte.SendNet("publicConfig", {
["config"] = { ["config"] = {
["id"] = gmInte.config.id, ["id"] = gmInte.config.id,
@ -82,13 +65,10 @@ function gmInte.publicGetConfig(ply)
end end
function gmInte.superadminSetConfig(ply, data) function gmInte.superadminSetConfig(ply, data)
if (!ply:IsValid() || !ply:IsPlayer(ply) || !ply:IsSuperAdmin()) then return end if !ply:IsValid() || !ply:IsPlayer(ply) || !ply:IsSuperAdmin() then return end
for k, v in pairs(data) do for k, v in pairs(data) do
gmInte.saveSetting(k, v) gmInte.saveSetting(k, v)
end end
if data.token || data.id then if data.token || data.id then gmInte.testConnection(ply) end
gmInte.testConnection(ply)
end
end end

View File

@ -1,7 +1,3 @@
//
// Methods
//
function gmInte.sendStatus() function gmInte.sendStatus()
gmInte.http.post("/servers/:serverID/status", gmInte.getServerFormat()) gmInte.http.post("/servers/:serverID/status", gmInte.getServerFormat())
end end
@ -14,24 +10,6 @@ function gmInte.serverShutDown()
gmInte.http.post("/servers/:serverID/stop") gmInte.http.post("/servers/:serverID/stop")
end end
// timer.Create("gmInte.sendStatus", 300, 0, function() gmInte.sendStatus() end)
// Timers hook.Add("Initialize", "gmInte:Server:Initialize:SendStatus", function() timer.Simple(1, function() gmInte.serverStart() end) end)
// hook.Add("ShutDown", "gmInte:Server:ShutDown:SendStatus", function() gmInte.serverShutDown() end)
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()
end)
end)
hook.Add("ShutDown", "gmInte:Server:ShutDown:SendStatus", function()
gmInte.serverShutDown()
end)

View File

@ -1,29 +1,13 @@
//
// Websocket
//
function gmInte.wsSyncBan(data) function gmInte.wsSyncBan(data)
for _, ply in ipairs(player.GetAll()) do for _, ply in ipairs(player.GetAll()) do
if (ply:SteamID64() == data.steam) then if ply:SteamID64() == data.steam then ply:Kick(data.reason || "You have been banned from the server.") end
ply:Kick(data.reason || "You have been banned from the server.")
end
end end
end end
//
// Methods
//
function gmInte.playerBan(data) function gmInte.playerBan(data)
data.steamID64 = util.SteamIDTo64(data.networkid) data.steamID64 = util.SteamIDTo64(data.networkid)
gmInte.http.post("/servers/:serverID/players/" .. util.SteamIDTo64(data.networkid) .. "/ban", data) gmInte.http.post("/servers/:serverID/players/" .. util.SteamIDTo64(data.networkid) .. "/ban", data)
end end
//
// Hooks
//
gameevent.Listen("server_addban") gameevent.Listen("server_addban")
hook.Add("server_addban", "gmInte:Player:Ban", function(data) hook.Add("server_addban", "gmInte:Player:Ban", function(data) gmInte.playerBan(data) end)
gmInte.playerBan(data)
end)

View File

@ -1,29 +1,13 @@
//
// Websocket
//
function gmInte.wsPlayerSay(data) function gmInte.wsPlayerSay(data)
gmInte.SendNet("wsRelayDiscordChat", data, nil) gmInte.SendNet("wsRelayDiscordChat", data, nil)
end end
//
// Methods
//
function gmInte.playerSay(ply, text, teamOnly) function gmInte.playerSay(ply, text, teamOnly)
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/say", gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/say", {
{
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
["text"] = text, ["text"] = text,
["teamOnly"] = teamOnly, ["teamOnly"] = teamOnly,
} })
)
end end
// hook.Add("PlayerSay", "gmInte:SyncChat:PlayerSay", function(ply, text, team) gmInte.playerSay(ply, text, team) end)
// Hooks
//
hook.Add("PlayerSay", "gmInte:SyncChat:PlayerSay", function(ply, text, team)
gmInte.playerSay(ply, text, team)
end)

View File

@ -1,30 +1,12 @@
//
// Websocket
//
function gmInte.wsSyncKick(data) function gmInte.wsSyncKick(data)
for _, ply in ipairs(player.GetAll()) do for _, ply in ipairs(player.GetAll()) do
if (ply:SteamID64() == data.steam) then if ply:SteamID64() == data.steam then ply:Kick(data.reason || "You have been banned from the server.") end
ply:Kick(data.reason || "You have been banned from the server.")
end
end end
end end
//
// Methods
//
function gmInte.playerKick(data) function gmInte.playerKick(data)
gmInte.http.post("/servers/:serverID/players/" .. util.SteamIDTo64(data.networkid) .. "/kick", data) gmInte.http.post("/servers/:serverID/players/" .. util.SteamIDTo64(data.networkid) .. "/kick", data)
end end
//
// Hooks
//
gameevent.Listen("player_disconnect") gameevent.Listen("player_disconnect")
hook.Add("player_disconnect", "gmInte:SyncKick:Disconnect", function(data) hook.Add("player_disconnect", "gmInte:SyncKick:Disconnect", function(data) if string.StartWith(data.reason, "Kicked by ") || data.reason == "No reason provided." then gmInte.playerKick(data) end end)
if (string.StartWith(data.reason, "Kicked by ") || data.reason == "No reason provided.") then
gmInte.playerKick(data)
end
end)

View File

@ -1,33 +1,16 @@
//
// Websocket
//
function gmInte.wsSyncName(data) function gmInte.wsSyncName(data)
local ply = player.GetBySteamID(data.player.steamID64) local ply = player.GetBySteamID(data.player.steamID64)
if not IsValid(ply) then return end if !IsValid(ply) then return end
ply:SetName(data.newName) ply:SetName(data.newName)
end end
//
// Methods
//
function gmInte.playerChangeName(ply, oldName, newName) function gmInte.playerChangeName(ply, oldName, newName)
if (!ply:IsValid() || !ply:IsPlayer(ply)) then return end if !ply:IsValid() || !ply:IsPlayer(ply) then return end
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/name", {
gmInte.http.post("/servers/:serverID/players/" .. ply:SteamID64() .. "/name",
{
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
["oldName"] = oldName, ["oldName"] = oldName,
["newName"] = newName, ["newName"] = newName,
} })
)
end end
// hook.Add("onPlayerChangedName", "gmInte:PlayerChangeName", function(ply, old, new) gmInte.playerChangeName(ply, old, new) end)
// Hooks
//
hook.Add("onPlayerChangedName", "gmInte:PlayerChangeName", function(ply, old, new)
gmInte.playerChangeName(ply, old, new)
end)

View File

@ -1,31 +1,17 @@
//
// Websocket
//
local cachedPlayers = {} local cachedPlayers = {}
function gmInte.wsPlayerUpdateGroup(data) function gmInte.wsPlayerUpdateGroup(data)
if (cachedPlayers[steamID64] == data.group) then return end if cachedPlayers[steamID64] == data.group then return end
data.steamID = util.SteamIDFrom64(data.steamID64) data.steamID = util.SteamIDFrom64(data.steamID64)
data.group = data.add && data.group || "user" data.group = data.add && data.group || "user"
cachedPlayers[data.steamID64] = data.group cachedPlayers[data.steamID64] = data.group
local ply = player.GetBySteamID(data.steamID) local ply = player.GetBySteamID(data.steamID)
if (ply && ply:IsValid()) then if ply && ply:IsValid() then ply:SetUserGroup(data.group) end
ply:SetUserGroup(data.group)
end
// ULX // ULX
if (ULib) then if ULib then ULib.ucl.addUser(data.steamID, nil, nil, data.group) end
ULib.ucl.addUser(data.steamID, nil, nil, data.group)
end
// ServerGuard // ServerGuard
if (serverguard) then if serverguard then
local ply = player.GetBySteamID(data.steamID) local ply = player.GetBySteamID(data.steamID)
if (ply) then if ply then
local rankData = serverguard.ranks:GetRank(data.group) local rankData = serverguard.ranks:GetRank(data.group)
serverguard.player:SetRank(ply, data.group) serverguard.player:SetRank(ply, data.group)
serverguard.player:SetImmunity(ply, rankData.immunity) serverguard.player:SetImmunity(ply, rankData.immunity)
@ -37,52 +23,27 @@ function gmInte.wsPlayerUpdateGroup(data)
end end
// Evolve // Evolve
if (evolve) then if evolve then evolve:RankPlayer(data.steamID64, data.group) end
evolve:RankPlayer(data.steamID64, data.group)
end
// SAM // SAM
if (SAM) then if SAM then SAM:PlayerSetRank(data.steamID64, data.group) end
SAM:PlayerSetRank(data.steamID64, data.group)
end
// sam (wtf another one?) // sam (wtf another one?)
if (sam) then if sam then sam.player.setRank(data.steamID64, data.group) end
sam.player.setRank(data.steamID64, data.group)
end
// xAdmin // xAdmin
if (xAdmin) then if xAdmin then xAdmin.SetRank(data.steamID64, data.group) end
xAdmin.SetRank(data.steamID64, data.group)
end
// maestro // maestro
if (maestro) then if maestro then maestro.userrank(data.steamID64, data.group) end
maestro.userrank(data.steamID64, data.group)
end
// D3A // D3A
if (D3A) then if D3A then D3A.Ranks.SetSteamIDRank(data.steamID, data.group) end
D3A.Ranks.SetSteamIDRank(data.steamID, data.group)
end
// Mercury // Mercury
if (Mercury) then if Mercury then RunConsoleCommand("hg", "setrank", data.steamID, data.group) end
RunConsoleCommand("hg", "setrank", data.steamID, data.group)
end
// FAdmin // FAdmin
if (FAdmin) then if FAdmin then RunConsoleCommand("fadmin", "setaccess", data.steamID, data.group) end
RunConsoleCommand("fadmin", "setaccess", data.steamID, data.group)
end
gmInte.log("[Sync Role] Player " .. data.steamID .. " has been updated to group " .. data.group) gmInte.log("[Sync Role] Player " .. data.steamID .. " has been updated to group " .. data.group)
end end
function gmInte.playerChangeGroup(steamID64, oldGroup, newGroup) function gmInte.playerChangeGroup(steamID64, oldGroup, newGroup)
if (cachedPlayers[steamID64] == newGroup) then return end if cachedPlayers[steamID64] == newGroup then return end
cachedPlayers[steamID64] = newGroup cachedPlayers[steamID64] = newGroup
gmInte.http.post("/servers/:serverID/players/" .. steamID64 .. "/group", { gmInte.http.post("/servers/:serverID/players/" .. steamID64 .. "/group", {
["player"] = gmInte.getPlayerFormat(ply), ["player"] = gmInte.getPlayerFormat(ply),
["oldGroup"] = oldGroup || "user", ["oldGroup"] = oldGroup || "user",
@ -90,12 +51,12 @@ function gmInte.playerChangeGroup(steamID64, oldGroup, newGroup)
}) })
end end
hook.Add('CAMI.PlayerUsergroupChanged', 'gmInte:SyncChat:CAMI:PlayerUsergroupChanged', function(ply, old, new) hook.Add("CAMI.PlayerUsergroupChanged", "gmInte:SyncChat:CAMI:PlayerUsergroupChanged", function(ply, old, new)
if (ply:IsBot() || !ply:IsValid()) then return end if ply:IsBot() || !ply:IsValid() then return end
gmInte.playerChangeGroup(ply:SteamID64(), old, new) gmInte.playerChangeGroup(ply:SteamID64(), old, new)
end) end)
hook.Add('CAMI.SteamIDUsergroupChanged', 'gmInte:SyncChat:CAMI:SteamIDUsergroupChanged', function(SteamID64, old, new) hook.Add("CAMI.SteamIDUsergroupChanged", "gmInte:SyncChat:CAMI:SteamIDUsergroupChanged", function(SteamID64, old, new)
if (string.StartWith(SteamID64, "STEAM_")) then SteamID64 = util.SteamIDTo64(SteamID64) end if string.StartWith(SteamID64, "STEAM_") then SteamID64 = util.SteamIDTo64(SteamID64) end
gmInte.playerChangeGroup(SteamID64, old, new) gmInte.playerChangeGroup(SteamID64, old, new)
end) end)

View File

@ -1,11 +1,7 @@
//
// Methods
//
gmInte.serverPublicToken = gmInte.serverPublicToken || nil gmInte.serverPublicToken = gmInte.serverPublicToken || nil
function gmInte.getPublicServerToken(callback) function gmInte.getPublicServerToken(callback)
if (gmInte.serverPublicToken) then if gmInte.serverPublicToken then
if (callback) then callback(gmInte.serverPublicToken) end if callback then callback(gmInte.serverPublicToken) end
return return
end end
@ -15,24 +11,20 @@ function gmInte.getPublicServerToken(callback)
end) end)
end end
hook.Add("Initialize", "gmInte:Server:Initialize:GetPublicToken", function()
timer.Simple(1, function()
gmInte.getPublicServerToken(function(publicToken)
gmInte.log("Server Public Token Received: " .. publicToken)
end)
end)
end)
gmInte.serverPlayerTempTokens = gmInte.serverPlayerTempTokens || {} gmInte.serverPlayerTempTokens = gmInte.serverPlayerTempTokens || {}
function gmInte.getPlayerTempToken(ply, callback) function gmInte.getPlayerTempToken(ply, callback)
if (gmInte.serverPlayerTempTokens[ply:SteamID64()] && gmInte.serverPlayerTempTokens[ply:SteamID64()].userID == ply:UserID()) then if gmInte.serverPlayerTempTokens[ply:SteamID64()] && gmInte.serverPlayerTempTokens[ply:SteamID64()].userID == ply:UserID() then
if (callback) then callback(gmInte.serverPlayerTempTokens[ply:SteamID64()].token) end if callback then callback(gmInte.serverPlayerTempTokens[ply:SteamID64()].token) end
return return
end end
gmInte.getPublicServerToken(function(publicToken) gmInte.getPublicServerToken(function(publicToken)
local token = util.SHA256(ply:SteamID64() .. "-" .. publicToken .. "-" .. gmInte.config.token .. "-" .. ply:UserID()) .. " " .. ply:UserID() local token = util.SHA256(ply:SteamID64() .. "-" .. publicToken .. "-" .. gmInte.config.token .. "-" .. ply:UserID()) .. " " .. ply:UserID()
gmInte.serverPlayerTempTokens[ply:SteamID64()] = { token = token, userID = ply:UserID() } gmInte.serverPlayerTempTokens[ply:SteamID64()] = {
token = token,
userID = ply:UserID()
}
callback(token) callback(token)
end) end)
end end
@ -45,6 +37,5 @@ function sendPlayerToken(ply)
end) end)
end end
hook.Add("gmInte:PlayerReady", "gmInte:Verif:PlayerReady", function(ply) hook.Add("gmInte:PlayerReady", "gmInte:Verif:PlayerReady", function(ply) sendPlayerToken(ply) end)
sendPlayerToken(ply) hook.Add("Initialize", "gmInte:Server:Initialize:GetPublicToken", function() timer.Simple(1, function() gmInte.getPublicServerToken(function(publicToken) gmInte.log("Server Public Token Received: " .. publicToken) end) end) end)
end)

View File

@ -1,5 +1,5 @@
function gmInte.getPlayerFormat(ply) function gmInte.getPlayerFormat(ply)
if (!IsValid(ply) || !ply:IsPlayer()) then return end if !IsValid(ply) || !ply:IsPlayer() then return end
return { return {
["steamID"] = ply:SteamID(), ["steamID"] = ply:SteamID(),
["steamID64"] = ply:SteamID64(), ["steamID64"] = ply:SteamID64(),
@ -40,7 +40,7 @@ function gmInte.getServerFormat()
end end
function gmInte.getWeaponFormat(weapon) function gmInte.getWeaponFormat(weapon)
if (!IsValid(weapon) || !weapon:IsWeapon()) then return end if !IsValid(weapon) || !weapon:IsWeapon() then return end
return { return {
["class"] = weapon:GetClass(), ["class"] = weapon:GetClass(),
["printName"] = weapon:GetPrintName() ["printName"] = weapon:GetPrintName()
@ -48,7 +48,7 @@ function gmInte.getWeaponFormat(weapon)
end end
function gmInte.getEntityFormat(ent) function gmInte.getEntityFormat(ent)
if (!IsValid(ent)) then return end if !IsValid(ent) then return end
return { return {
["class"] = ent:GetClass(), ["class"] = ent:GetClass(),
["model"] = ent:GetModel(), ["model"] = ent:GetModel(),
@ -58,7 +58,7 @@ function gmInte.getEntityFormat(ent)
end end
function gmInte.getVectorFormat(vec) function gmInte.getVectorFormat(vec)
if (!isvector(vec)) then return end if !isvector(vec) then return end
return { return {
["x"] = math.Round(vec.x), ["x"] = math.Round(vec.x),
["y"] = math.Round(vec.y), ["y"] = math.Round(vec.y),
@ -67,7 +67,7 @@ function gmInte.getVectorFormat(vec)
end end
function gmInte.getAngleFormat(ang) function gmInte.getAngleFormat(ang)
if (!isangle(ang)) then return end if !isangle(ang) then return end
return { return {
["p"] = math.Round(ang.p), ["p"] = math.Round(ang.p),
["y"] = math.Round(ang.y), ["y"] = math.Round(ang.y),
@ -76,7 +76,7 @@ function gmInte.getAngleFormat(ang)
end end
function gmInte.getTeamFormat(teamID) function gmInte.getTeamFormat(teamID)
if (!isnumber(teamID)) then return end if !isnumber(teamID) then return end
return { return {
["id"] = teamID, ["id"] = teamID,
["name"] = team.GetName(teamID) ["name"] = team.GetName(teamID)

View File

@ -1,32 +1,22 @@
//
// Methods
//
local cacheErrors = {} local cacheErrors = {}
function gmInte.sendLuaErrorReport(err, realm, stack, name, id) function gmInte.sendLuaErrorReport(err, realm, stack, name, id)
cacheErrors[err] = { cacheErrors[err] = {
["time"] = CurTime(), ["time"] = CurTime(),
["count"] = cacheErrors[err] && cacheErrors[err].count + 1 || 1, ["count"] = cacheErrors[err] && cacheErrors[err].count + 1 || 1,
} }
if (!gmInte.config.id || !gmInte.config.token) then return end if !gmInte.config.id || !gmInte.config.token then return end
if (CLIENT && !IsValid(LocalPlayer())) then return end if CLIENT && !IsValid(LocalPlayer()) then return end
local count = cacheErrors[err].count local count = cacheErrors[err].count
timer.Simple(0.5, function() timer.Simple(0.5, function()
if (cacheErrors[err].count != count) then if cacheErrors[err].count != count then
if (cacheErrors[err].count == 100) then if cacheErrors[err].count != 100 then return end
else
return
end
else else
cacheErrors[err] = nil cacheErrors[err] = nil
end end
local endpoint = SERVER && "/servers/:serverID/errors" || "/clients/:steamID64/servers/:serverID/errors" local endpoint = SERVER && "/servers/:serverID/errors" || "/clients/:steamID64/servers/:serverID/errors"
gmInte.http.post(endpoint, gmInte.http.post(endpoint, {
{
["error"] = err, ["error"] = err,
["realm"] = realm, ["realm"] = realm,
["stack"] = stack, ["stack"] = stack,
@ -35,15 +25,8 @@ function gmInte.sendLuaErrorReport(err, realm, stack, name, id)
["count"] = count, ["count"] = count,
["uptime"] = math.Round(RealTime()), ["uptime"] = math.Round(RealTime()),
["identifier"] = SERVER && gmInte.config.id || CLIENT && LocalPlayer():SteamID64() ["identifier"] = SERVER && gmInte.config.id || CLIENT && LocalPlayer():SteamID64()
} })
)
end) end)
end end
// hook.Add("OnLuaError", "gmInte:OnLuaError:SendReport", function(err, realm, stack, name, id) gmInte.sendLuaErrorReport(err, realm, stack, name, id) end)
// Hooks
//
hook.Add("OnLuaError", "gmInte:OnLuaError:SendReport", function(err, realm, stack, name, id)
gmInte.sendLuaErrorReport(err, realm, stack, name, id)
end)

View File

@ -1,23 +1,14 @@
local apiVersion = "v3" local apiVersion = "v3"
gmInte.http = gmInte.http || {} gmInte.http = gmInte.http || {}
local function getAPIURL(endpoint) local function getAPIURL(endpoint)
local method = gmInte.isPrivateIP(gmInte.config.apiFQDN) && "http" || "https" local method = gmInte.isPrivateIP(gmInte.config.apiFQDN) && "http" || "https"
endpoint = string.gsub(endpoint, ":serverID", gmInte.config.id) endpoint = string.gsub(endpoint, ":serverID", gmInte.config.id)
if CLIENT then endpoint = string.gsub(endpoint, ":steamID64", LocalPlayer():SteamID64()) end
if (CLIENT) then
endpoint = string.gsub(endpoint, ":steamID64", LocalPlayer():SteamID64())
end
return method .. "://" .. gmInte.config.apiFQDN .. "/" .. apiVersion .. endpoint return method .. "://" .. gmInte.config.apiFQDN .. "/" .. apiVersion .. endpoint
end end
local function showableBody(endpoint) local function showableBody(endpoint)
if (string.sub(endpoint, 1, 8) == "/streams" || string.sub(endpoint, 1, 12) == "/screenshots") then if string.sub(endpoint, 1, 8) == "/streams" || string.sub(endpoint, 1, 12) == "/screenshots" then return false end
return false
end
return true return true
end end
@ -32,8 +23,7 @@ function gmInte.http.requestAPI(params)
local version = gmInte.version || "Unknown" local version = gmInte.version || "Unknown"
local showableBody = showableBody(params.endpoint) local showableBody = showableBody(params.endpoint)
local localRequestID = util.CRC(tostring(SysTime())) local localRequestID = util.CRC(tostring(SysTime()))
if token == "" then
if (token == "") then
return failed(401, { return failed(401, {
["error"] = "No token provided" ["error"] = "No token provided"
}) })
@ -51,7 +41,6 @@ function gmInte.http.requestAPI(params)
gmInte.log("HTTP Request ID: " .. localRequestID, true) gmInte.log("HTTP Request ID: " .. localRequestID, true)
gmInte.log("HTTP Request: " .. method .. " " .. url, true) gmInte.log("HTTP Request: " .. method .. " " .. url, true)
gmInte.log("HTTP Body: " .. (showableBody && body || "HIDDEN"), true) gmInte.log("HTTP Body: " .. (showableBody && body || "HIDDEN"), true)
HTTP({ HTTP({
["url"] = url, ["url"] = url,
["method"] = method, ["method"] = method,
@ -62,15 +51,13 @@ function gmInte.http.requestAPI(params)
gmInte.log("HTTP Request ID: " .. localRequestID, true) gmInte.log("HTTP Request ID: " .. localRequestID, true)
gmInte.log("HTTP Response: " .. code, true) gmInte.log("HTTP Response: " .. code, true)
gmInte.log("HTTP Body: " .. body, true) gmInte.log("HTTP Body: " .. body, true)
if string.sub(headers["Content-Type"], 1, 16) != "application/json" then
if (string.sub(headers["Content-Type"], 1, 16) != "application/json") then
gmInte.log("HTTP Failed: Invalid Content-Type", true) gmInte.log("HTTP Failed: Invalid Content-Type", true)
return failed(code, body) return failed(code, body)
end end
body = util.JSONToTable(body || "{}") body = util.JSONToTable(body || "{}")
if code < 200 || code >= 300 then
if (code < 200 || code >= 300) then
gmInte.log("HTTP Failed: Invalid Status Code", true) gmInte.log("HTTP Failed: Invalid Status Code", true)
return failed(code, body) return failed(code, body)
end end
@ -85,10 +72,6 @@ function gmInte.http.requestAPI(params)
}) })
end end
//
// HTTP Methods
//
function gmInte.http.get(endpoint, onSuccess, onFailed) function gmInte.http.get(endpoint, onSuccess, onFailed)
gmInte.http.requestAPI({ gmInte.http.requestAPI({
["endpoint"] = endpoint, ["endpoint"] = endpoint,

View File

@ -1,59 +1,50 @@
//
// Functions
//
// Log
function gmInte.log(msg, debug) function gmInte.log(msg, debug)
if (debug && !gmInte.config.debug) then return end if debug && !gmInte.config.debug then return end
print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] " .. msg) print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] " .. msg)
end end
// Log Error // Log Error
function gmInte.logError(msg, debug) function gmInte.logError(msg, debug)
if (debug && !gmInte.config.debug) then return end if debug && !gmInte.config.debug then return end
print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] [ERROR] " .. msg) print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] [ERROR] " .. msg)
end end
// Log Warning // Log Warning
function gmInte.logWarning(msg, debug) function gmInte.logWarning(msg, debug)
if (debug && !gmInte.config.debug) then return end if debug && !gmInte.config.debug then return end
print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] [WARNING] " .. msg) print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] [WARNING] " .. msg)
end end
// Log Hint // Log Hint
function gmInte.logHint(msg, debug) function gmInte.logHint(msg, debug)
if (debug && !gmInte.config.debug) then return end if debug && !gmInte.config.debug then return end
print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] [HINT] " .. msg) print("[" .. os.date("%Y-%m-%d %H:%M:%S") .. "] [Gmod Integration] [HINT] " .. msg)
end end
// Is Private IP // Is Private IP
function gmInte.isPrivateIP(ip) function gmInte.isPrivateIP(ip)
// detect localhost // detect localhost
if (ip == "localhost") then return true end if ip == "localhost" then return true end
// detect private IP addresses (RFC 1918) // detect private IP addresses (RFC 1918)
local parts = string.Explode(".", ip) local parts = string.Explode(".", ip)
if (parts[1] == "192" && parts[2] == "168") then return true end if parts[1] == "192" && parts[2] == "168" then return true end
if (parts[1] == "10") then return true end if parts[1] == "10" then return true end
if (parts[1] == "172" && tonumber(parts[2]) >= 16 && tonumber(parts[2]) <= 31) then return true end if parts[1] == "172" && tonumber(parts[2]) >= 16 && tonumber(parts[2]) <= 31 then return true end
if (parts[1] == "127") then return true end if parts[1] == "127" then return true end
return false return false
end end
concommand.Add("gmi_test_error", function( ply, cmd, args ) concommand.Add("gmi_test_error", function(ply, cmd, args)
print(ply, cmd) print(ply, cmd)
PrintTable(args) PrintTable(args)
if (#args == 0) then if #args == 0 then
error("This is a test error") error("This is a test error")
else else
if (args[1] == "loop") then if args[1] == "loop" then
hook.Add("Think", "gmInte:TestError:Loop", function() hook.Add("Think", "gmInte:TestError:Loop", function() error("This is a test error") end)
error("This is a test error") timer.Simple(5, function() hook.Remove("Think", "gmInte:TestError:Loop") end)
end) elseif args[1] == "crash" then
timer.Simple(5, function() while true do
hook.Remove("Think", "gmInte:TestError:Loop")
end)
elseif (args[1] == "crash") then
while (true) do
error("This is a crash error") error("This is a crash error")
end end
else else

View File

@ -1,9 +1,4 @@
//
// Meta
//
local ply = FindMetaTable("Player") local ply = FindMetaTable("Player")
function ply:gmIntGetConnectTime() function ply:gmIntGetConnectTime()
return self.gmIntTimeConnect || 0 return self.gmIntTimeConnect || 0
end end
@ -22,52 +17,38 @@ function ply:gmIntGetCustomValue(key)
end end
function ply:gmIntRemoveCustomValue(key) function ply:gmIntRemoveCustomValue(key)
if (self.gmIntCustomValues) then if self.gmIntCustomValues then self.gmIntCustomValues[key] = nil end
self.gmIntCustomValues[key] = nil
end
end end
//
// Compatibility
//
local function getCustomCompatability(ply) local function getCustomCompatability(ply)
local values = {} local values = {}
// DarkRP // DarkRP
if (DarkRP) then if DarkRP then
values.money = ply:getDarkRPVar("money") values.money = ply:getDarkRPVar("money")
values.job = ply:getDarkRPVar("job") values.job = ply:getDarkRPVar("job")
end end
// GUI Level System // GUI Level System
if (GUILevelSystem) then if GUILevelSystem then
values.level = ply:GetLevel() values.level = ply:GetLevel()
values.xp = ply:GetXP() values.xp = ply:GetXP()
end end
return values return values
end end
//
// Methods
//
local function getCustomValues(ply) local function getCustomValues(ply)
local values = {} local values = {}
// Get compatability values // Get compatability values
for key, value in pairs(getCustomCompatability(ply)) do for key, value in pairs(getCustomCompatability(ply)) do
values[key] = value values[key] = value
end end
// Get custom values or overwrite compatability values // Get custom values or overwrite compatability values
if (ply.gmIntCustomValues) then if ply.gmIntCustomValues then
for key, value in pairs(ply.gmIntCustomValues) do for key, value in pairs(ply.gmIntCustomValues) do
values[key] = value values[key] = value
end end
end end
return values return values
end end

View File

@ -5,10 +5,11 @@
Add Server: Add Server:
0. Add the bot to your guild if it's not already done: https://gmod-integration.com/invite 0. Add the bot to your guild if it's not already done: https://gmod-integration.com/invite
1. Go to our dashboard and Login with Discord: https://gmod-integration.com/login 1. Go to our dashboard and Login with Discord: https://gmod-integration.com/login you should be redirected to the dashboard
2. Go to the "Servers" page: https://gmod-integration.com/config/servers and click on "Create Server" 2. Add the bot to your guild and click on "Add to Guild" or select your guild if it's already added
3. Copy the ID and Token of your server and paste them in this file 3. Go to the "Servers" page and click on "Create Server"
4. Everything is ready, you can now restart your server 4. Copy the ID and Token of your server and paste them in this file
5 Everything is ready, you can now restart your server
To go further, you can check the documentation: https://docs.gmod-integration.com To go further, you can check the documentation: https://docs.gmod-integration.com
@ -17,43 +18,22 @@
IF ANY PROBLEM OCCURS, GO TO OUR WEBSITE AND FOLLOW THE INSTRUCTIONS: IF ANY PROBLEM OCCURS, GO TO OUR WEBSITE AND FOLLOW THE INSTRUCTIONS:
https://gmod-integration.com/emergency https://gmod-integration.com/emergency
*/ */
//
// General
//
// API Connection // API Connection
gmInte.config.id = "" // Server ID gmInte.config.id = "" // Server ID
gmInte.config.token = "" // Server Token gmInte.config.token = "" // Server Token
gmInte.config.websocketFQDN = "ws.gmod-integration.com" // The FQDN of the websocket server gmInte.config.websocketFQDN = "ws.gmod-integration.com" // The FQDN of the websocket server
gmInte.config.apiFQDN = "api.gmod-integration.com" // The FQDN of the API server gmInte.config.apiFQDN = "api.gmod-integration.com" // The FQDN of the API server
// Other // Other
gmInte.config.forcePlayerLink = false // If true, the addon will force the players to link their discord account to their steam account before playing gmInte.config.forcePlayerLink = false // If true, the addon will force the players to link their discord account to their steam account before playing
gmInte.config.supportLink = "" // The link of your support (shown when a player do not have the requiments to join the server) gmInte.config.supportLink = "" // The link of your support (shown when a player do not have the requiments to join the server)
gmInte.config.maintenance = false // If true, the addon will only allow the players with the "gmod-integration.maintenance" permission to join the server gmInte.config.maintenance = false // If true, the addon will only allow the players with the "gmod-integration.maintenance" permission to join the server
//
// Syncronization
//
// Punishment // Punishment
gmInte.config.syncBan = true // If true, the addon will sync gmod bans with discord bans (and vice versa) gmInte.config.syncBan = true // If true, the addon will sync gmod bans with discord bans (and vice versa)
gmInte.config.syncTimeout = false // If true, the addon will sync gmod timeouts with discord timeouts (and vice versa) gmInte.config.syncTimeout = false // If true, the addon will sync gmod timeouts with discord timeouts (and vice versa)
gmInte.config.syncKick = false // If true, the addon will sync gmod kicks with discord kicks (and vice versa) gmInte.config.syncKick = false // If true, the addon will sync gmod kicks with discord kicks (and vice versa)
// Ban // Ban
gmInte.config.filterOnBan = true // If true, the addon will filter the players according to their ban status gmInte.config.filterOnBan = true // If true, the addon will filter the players according to their ban status
//
// Materials // Materials
//
gmInte.config.redownloadMaterials = false // If true, the addon will redownload the materials of the addon (useful if you have a problem with the materials) gmInte.config.redownloadMaterials = false // If true, the addon will redownload the materials of the addon (useful if you have a problem with the materials)
//
// Debug & Development // Debug & Development
//
gmInte.config.debug = false // If true, the addon will show debug informations in the console gmInte.config.debug = false // If true, the addon will show debug informations in the console
gmInte.config.devInstance = false // If true, the addon will use the development instance of API and Websocket