Initial commit
This commit is contained in:
88
gamemodes/darkrp/gamemode/modules/fadmin/cl_fadmin.lua
Normal file
88
gamemodes/darkrp/gamemode/modules/fadmin/cl_fadmin.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
local function IncludeFolder(fol)
|
||||
fol = string.lower(fol)
|
||||
local _, folders = file.Find(fol .. "*", "LUA")
|
||||
|
||||
for _, folder in SortedPairs(folders, true) do
|
||||
if folder ~= "." and folder ~= ".." then
|
||||
for _, File in SortedPairs(file.Find(fol .. folder .. "/sh_*.lua", "LUA"), true) do
|
||||
include(fol .. folder .. "/" .. File)
|
||||
end
|
||||
|
||||
for _, File in SortedPairs(file.Find(fol .. folder .. "/cl_*.lua", "LUA"), true) do
|
||||
include(fol .. folder .. "/" .. File)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
IncludeFolder(GM.FolderName .. "/gamemode/modules/fadmin/fadmin/")
|
||||
IncludeFolder(GM.FolderName .. "/gamemode/modules/fadmin/fadmin/playeractions/")
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
FAdmin global settings
|
||||
---------------------------------------------------------------------------]]
|
||||
net.Receive("FAdmin_GlobalSetting", function(len)
|
||||
local setting, value = net.ReadString(), net.ReadType(net.ReadUInt(8))
|
||||
|
||||
FAdmin.GlobalSetting = FAdmin.GlobalSetting or {}
|
||||
FAdmin.GlobalSetting[setting] = value
|
||||
end)
|
||||
|
||||
net.Receive("FAdmin_PlayerSetting", function(len)
|
||||
local uid, setting, value = net.ReadUInt(16), net.ReadString(), net.ReadType(net.ReadUInt(8))
|
||||
|
||||
FAdmin.PlayerSettings = FAdmin.PlayerSettings or {}
|
||||
FAdmin.PlayerSettings[uid] = FAdmin.PlayerSettings[uid] or {}
|
||||
FAdmin.PlayerSettings[uid][setting] = value
|
||||
end)
|
||||
|
||||
timer.Create("FAdmin_CleanPlayerSettings", 300, 0, function()
|
||||
if not FAdmin.PlayerSettings then return end
|
||||
|
||||
-- find highest userID
|
||||
local max = math.huge
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if IsValid(v) and v:UserID() > max then max = v:UserID() end
|
||||
end
|
||||
|
||||
-- Anything lower than the maximal UserID can be culled
|
||||
-- This prevents data from joining players from being removed
|
||||
-- New players always get a strictly higher UserID than any player before them
|
||||
for uid in pairs(FAdmin.PlayerSettings) do
|
||||
if IsValid(Player(uid)) or uid > max then continue end
|
||||
|
||||
FAdmin.PlayerSettings[uid] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
local plyMeta = FindMetaTable("Player")
|
||||
|
||||
function plyMeta:FAdmin_GetGlobal(setting)
|
||||
local uid = self:UserID()
|
||||
return FAdmin.PlayerSettings and FAdmin.PlayerSettings[uid] and FAdmin.PlayerSettings[uid][setting] or nil
|
||||
end
|
||||
|
||||
net.Receive("FAdmin_GlobalPlayerSettings", function(len)
|
||||
local globalCount = net.ReadUInt(8)
|
||||
|
||||
FAdmin.GlobalSetting = FAdmin.GlobalSetting or {}
|
||||
|
||||
for i = 1, globalCount do
|
||||
FAdmin.GlobalSetting[net.ReadString()] = net.ReadType(net.ReadUInt(8))
|
||||
end
|
||||
|
||||
local plyCount = net.ReadUInt(8)
|
||||
FAdmin.PlayerSettings = FAdmin.PlayerSettings or {}
|
||||
|
||||
for i = 1, plyCount do
|
||||
local uid = net.ReadUInt(16)
|
||||
local count = net.ReadUInt(8)
|
||||
|
||||
FAdmin.PlayerSettings[uid] = FAdmin.PlayerSettings[uid] or {}
|
||||
|
||||
for j = 1, count do
|
||||
FAdmin.PlayerSettings[uid][net.ReadString()] = net.ReadType(net.ReadUInt(8))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
if not FAdmin or not FAdmin.StartHooks then return end
|
||||
FAdmin.StartHooks["DarkRP"] = function()
|
||||
-- DarkRP information:
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Money", function(ply) if LocalPlayer():IsAdmin() then return DarkRP.formatMoney(ply:getDarkRPVar("money")) end end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Steam name", function(ply) return ply:SteamName() end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Wanted", function(ply) if ply:getDarkRPVar("wanted") then return tostring(ply:getDarkRPVar("wantedReason") or "N/A") end end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Community link", function(ply) return FAdmin.SteamToProfile(ply) end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Rank", function(ply)
|
||||
if FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "SeeAdmins") then
|
||||
return ply:GetUserGroup()
|
||||
end
|
||||
end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Wanted reason", function(ply)
|
||||
if ply:isWanted() and LocalPlayer():isCP() then
|
||||
return ply:getWantedReason()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Warrant
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Warrant", "fadmin/icons/message", Color(0, 0, 200, 255),
|
||||
function(ply) return LocalPlayer():isCP() end,
|
||||
function(ply, button)
|
||||
Derma_StringRequest("Warrant reason", "Enter the reason for the warrant", "", function(Reason)
|
||||
RunConsoleCommand("darkrp", "warrant", ply:SteamID(), Reason)
|
||||
end)
|
||||
end)
|
||||
|
||||
--wanted
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
return ((ply:getDarkRPVar("wanted") and "Unw") or "W") .. "anted"
|
||||
end,
|
||||
function(ply) return "fadmin/icons/jail", ply:getDarkRPVar("wanted") and "fadmin/icons/disable" end,
|
||||
Color(0, 0, 200, 255),
|
||||
function(ply) return LocalPlayer():isCP() end,
|
||||
function(ply, button)
|
||||
if not ply:getDarkRPVar("wanted") then
|
||||
Derma_StringRequest("wanted reason", "Enter the reason to arrest this player", "", function(Reason)
|
||||
RunConsoleCommand("darkrp", "wanted", ply:SteamID(), Reason)
|
||||
end)
|
||||
else
|
||||
RunConsoleCommand("darkrp", "unwanted", ply:UserID())
|
||||
end
|
||||
end)
|
||||
|
||||
--Teamban
|
||||
local function teamban(ply, button)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Jobs:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
menu:AddPanel(Title)
|
||||
|
||||
local command = "teamban"
|
||||
local uid = ply:UserID()
|
||||
for k, v in SortedPairsByMemberValue(RPExtraTeams, "name") do
|
||||
local submenu = menu:AddSubMenu(v.name)
|
||||
submenu:AddOption("2 minutes", function() RunConsoleCommand("darkrp", command, uid, k, 120) end)
|
||||
submenu:AddOption("Half an hour", function() RunConsoleCommand("darkrp", command, uid, k, 1800) end)
|
||||
submenu:AddOption("An hour", function() RunConsoleCommand("darkrp", command, uid, k, 3600) end)
|
||||
submenu:AddOption("Until restart", function() RunConsoleCommand("darkrp", command, uid, k, 0) end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Ban from job", "fadmin/icons/changeteam", Color(200, 0, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "DarkRP_AdminCommands", ply) end, teamban)
|
||||
|
||||
local function teamunban(ply, button)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Jobs:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
menu:AddPanel(Title)
|
||||
|
||||
local command = "teamunban"
|
||||
local uid = ply:UserID()
|
||||
for k, v in SortedPairsByMemberValue(RPExtraTeams, "name") do
|
||||
menu:AddOption(v.name, function() RunConsoleCommand("darkrp", command, uid, k) end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Unban from job", function() return "fadmin/icons/changeteam", "fadmin/icons/disable" end, Color(200, 0, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "DarkRP_AdminCommands", ply) end, teamunban)
|
||||
end
|
||||
@@ -0,0 +1,262 @@
|
||||
local ContinueNewGroup
|
||||
local EditGroups
|
||||
|
||||
local function RetrievePRIVS(len)
|
||||
FAdmin.Access.Groups = net.ReadTable()
|
||||
|
||||
for k, v in pairs(FAdmin.Access.Groups) do
|
||||
if CAMI.GetUsergroup(k) then continue end
|
||||
|
||||
CAMI.RegisterUsergroup({
|
||||
Name = k,
|
||||
Inherits = FAdmin.Access.ADMIN[v.ADMIN]
|
||||
}, "FAdmin")
|
||||
end
|
||||
|
||||
-- Remove any groups that are removed from FAdmin from CAMI.
|
||||
for k in pairs(CAMI.GetUsergroups()) do
|
||||
if FAdmin.Access.Groups[k] then continue end
|
||||
|
||||
CAMI.UnregisterUsergroup(k, "FAdmin")
|
||||
end
|
||||
end
|
||||
net.Receive("FADMIN_SendGroups", RetrievePRIVS)
|
||||
|
||||
local function addPriv(um)
|
||||
local group = um:ReadString()
|
||||
FAdmin.Access.Groups[group] = FAdmin.Access.Groups[group] or {}
|
||||
FAdmin.Access.Groups[group].PRIVS[um:ReadString()] = true
|
||||
end
|
||||
usermessage.Hook("FAdmin_AddPriv", addPriv)
|
||||
|
||||
local function removePriv(um)
|
||||
FAdmin.Access.Groups[um:ReadString()].PRIVS[um:ReadString()] = nil
|
||||
end
|
||||
usermessage.Hook("FAdmin_RemovePriv", removePriv)
|
||||
|
||||
local function addGroupUI(ply, func)
|
||||
Derma_StringRequest("Set name",
|
||||
"What will be the name of the new group?",
|
||||
"",
|
||||
function(text)
|
||||
if text == "" then return end
|
||||
Derma_Query("On what access will this team be based? (the new group will inherit all the privileges from the group)", "Admin access",
|
||||
"user", function() ContinueNewGroup(ply, text, 0, func) end,
|
||||
"admin", function() ContinueNewGroup(ply, text, 1, func) end,
|
||||
"superadmin", function() ContinueNewGroup(ply, text, 2, func) end)
|
||||
end)
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["1SetAccess"] = function() -- 1 in hook name so it will be executed first.
|
||||
FAdmin.Commands.AddCommand("setaccess", nil, "<Player>", "<Group name>", "[new group based on (number)]", "[new group privileges]")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Set access", "fadmin/icons/access", Color(155, 0, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "SetAccess") or LocalPlayer():IsSuperAdmin() end, function(ply)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Set access:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
|
||||
menu:AddPanel(Title)
|
||||
|
||||
for k in SortedPairsByMemberValue(FAdmin.Access.Groups, "ADMIN", true) do
|
||||
menu:AddOption(k, function()
|
||||
if not IsValid(ply) then return end
|
||||
RunConsoleCommand("_FAdmin", "setaccess", ply:UserID(), k)
|
||||
end)
|
||||
end
|
||||
|
||||
menu:AddOption("New...", function() addGroupUI(ply) end)
|
||||
menu:Open()
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddPlayerAction("Edit groups", "fadmin/icons/access", Color(0, 155, 0, 255), function() return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "ManageGroups") or FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "ManagePrivileges") end, EditGroups)
|
||||
|
||||
-- Admin immunity
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting(function()
|
||||
return (FAdmin.GlobalSetting.Immunity and "Disable" or "Enable") .. " Admin immunity"
|
||||
end,
|
||||
function()
|
||||
return "fadmin/icons/access", FAdmin.GlobalSetting.Immunity and "fadmin/icons/disable"
|
||||
end, Color(0, 0, 155, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "ManageGroups") end, function(button)
|
||||
button:SetImage2((not FAdmin.GlobalSetting.Immunity and "fadmin/icons/disable") or "null")
|
||||
button:SetText((not FAdmin.GlobalSetting.Immunity and "Disable" or "Enable") .. " Admin immunity")
|
||||
button:GetParent():InvalidateLayout()
|
||||
|
||||
RunConsoleCommand("_Fadmin", "immunity", (FAdmin.GlobalSetting.Immunity and 0) or 1)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
ContinueNewGroup = function(ply, name, admin_access, func)
|
||||
if IsValid(ply) then
|
||||
RunConsoleCommand("_FAdmin", "setaccess", ply:UserID(), name, admin_access)
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "AddGroup", name, admin_access)
|
||||
end
|
||||
|
||||
if func then
|
||||
func(name, admin_access)
|
||||
end
|
||||
end
|
||||
|
||||
EditGroups = function()
|
||||
local frame, SelectedGroup, AddGroup, RemGroup, Privileges, SelectedPrivs, AddPriv, RemPriv, lblImmunity, nmbrImmunity
|
||||
|
||||
frame = vgui.Create("DFrame")
|
||||
frame:SetTitle("Create, edit and remove groups")
|
||||
frame:MakePopup()
|
||||
frame:SetVisible(true)
|
||||
frame:SetSize(640, 480)
|
||||
frame:Center()
|
||||
|
||||
SelectedGroup = vgui.Create("DComboBox", frame)
|
||||
SelectedGroup:SetPos(5, 30)
|
||||
SelectedGroup:SetWidth(145)
|
||||
|
||||
for _, v in pairs(FAdmin.Access.Groups) do
|
||||
v.immunity = v.immunity or 0
|
||||
end
|
||||
for k in SortedPairsByMemberValue(FAdmin.Access.Groups, "immunity", true) do
|
||||
SelectedGroup:AddChoice(k)
|
||||
end
|
||||
|
||||
AddGroup = vgui.Create("DButton", frame)
|
||||
AddGroup:SetPos(155, 30)
|
||||
AddGroup:SetSize(60, 22)
|
||||
AddGroup:SetText("Add Group")
|
||||
AddGroup.DoClick = function()
|
||||
addGroupUI(nil, function(name, admin, privs)
|
||||
SelectedGroup:AddChoice(name)
|
||||
SelectedGroup:SetValue(name)
|
||||
RemGroup:SetDisabled(false)
|
||||
|
||||
Privileges:Clear()
|
||||
SelectedPrivs:Clear()
|
||||
nmbrImmunity:SetText(FAdmin.Access.Groups[FAdmin.Access.ADMIN[admin + 1]].immunity)
|
||||
nmbrImmunity:SetDisabled(false)
|
||||
nmbrImmunity:SetEditable(true)
|
||||
|
||||
for priv, am in SortedPairs(FAdmin.Access.Privileges) do
|
||||
if am <= admin + 1 then
|
||||
SelectedPrivs:AddLine(priv)
|
||||
else
|
||||
Privileges:AddLine(priv)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
RemGroup = vgui.Create("DButton", frame)
|
||||
RemGroup:SetPos(220, 30)
|
||||
RemGroup:SetSize(85, 22)
|
||||
RemGroup:SetText("Remove Group")
|
||||
RemGroup.DoClick = function()
|
||||
RunConsoleCommand("_FAdmin", "RemoveGroup", SelectedGroup:GetValue())
|
||||
|
||||
for k, v in pairs(SelectedGroup.Choices) do
|
||||
if v ~= SelectedGroup:GetValue() then continue end
|
||||
|
||||
SelectedGroup.Choices[k] = nil
|
||||
break
|
||||
end
|
||||
table.ClearKeys(SelectedGroup.Choices)
|
||||
|
||||
SelectedGroup:SetValue("user")
|
||||
SelectedGroup:OnSelect(1, "user")
|
||||
end
|
||||
|
||||
Privileges = vgui.Create("DListView", frame)
|
||||
Privileges:SetPos(5, 55)
|
||||
Privileges:SetSize(300, 420)
|
||||
Privileges:AddColumn("Available privileges")
|
||||
|
||||
SelectedPrivs = vgui.Create("DListView", frame)
|
||||
SelectedPrivs:SetPos(340, 55)
|
||||
SelectedPrivs:SetSize(295, 420)
|
||||
SelectedPrivs:AddColumn("Selected Privileges")
|
||||
|
||||
function SelectedGroup:OnSelect(index, value, data)
|
||||
if not FAdmin.Access.Groups[value] then return end
|
||||
|
||||
RemGroup:SetDisabled(false)
|
||||
if table.HasValue(FAdmin.Access.ADMIN, value) then
|
||||
RemGroup:SetDisabled(true)
|
||||
end
|
||||
|
||||
Privileges:Clear()
|
||||
SelectedPrivs:Clear()
|
||||
|
||||
for priv, _ in SortedPairs(FAdmin.Access.Privileges) do
|
||||
if FAdmin.Access.Groups[value].PRIVS[priv] then
|
||||
SelectedPrivs:AddLine(priv)
|
||||
else
|
||||
Privileges:AddLine(priv)
|
||||
end
|
||||
end
|
||||
|
||||
if nmbrImmunity then
|
||||
nmbrImmunity:SetText(FAdmin.Access.Groups[value].immunity or "")
|
||||
if table.HasValue({"superadmin", "admin", "user", "noaccess"}, string.lower(value)) then
|
||||
nmbrImmunity:SetDisabled(true)
|
||||
nmbrImmunity:SetEditable(false)
|
||||
else
|
||||
nmbrImmunity:SetDisabled(false)
|
||||
nmbrImmunity:SetEditable(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
SelectedGroup:SetValue("user")
|
||||
SelectedGroup:OnSelect(1, "user")
|
||||
|
||||
AddPriv = vgui.Create("DButton", frame)
|
||||
AddPriv:SetPos(310, 55)
|
||||
AddPriv:SetSize(25, 25)
|
||||
AddPriv:SetText(">")
|
||||
AddPriv.DoClick = function()
|
||||
for _, v in ipairs(Privileges:GetSelected()) do
|
||||
local priv = v.Columns[1]:GetValue()
|
||||
RunConsoleCommand("FAdmin", "AddPrivilege", SelectedGroup:GetValue(), priv)
|
||||
SelectedPrivs:AddLine(priv)
|
||||
Privileges:RemoveLine(v.m_iID)
|
||||
end
|
||||
end
|
||||
|
||||
RemPriv = vgui.Create("DButton", frame)
|
||||
RemPriv:SetPos(310, 85)
|
||||
RemPriv:SetSize(25, 25)
|
||||
RemPriv:SetText("<")
|
||||
RemPriv.DoClick = function()
|
||||
for _, v in ipairs(SelectedPrivs:GetSelected()) do
|
||||
local priv = v.Columns[1]:GetValue()
|
||||
if SelectedGroup:GetValue() == LocalPlayer():GetUserGroup() and priv == "ManagePrivileges" then
|
||||
return Derma_Message("You shouldn't be removing ManagePrivileges. It will make you unable to edit the groups. This is preventing you from locking yourself out of the system.", "Clever move.")
|
||||
end
|
||||
RunConsoleCommand("FAdmin", "RemovePrivilege", SelectedGroup:GetValue(), priv)
|
||||
Privileges:AddLine(priv)
|
||||
SelectedPrivs:RemoveLine(v.m_iID)
|
||||
end
|
||||
end
|
||||
|
||||
lblImmunity = vgui.Create("DLabel", frame)
|
||||
lblImmunity:SetPos(340, 30)
|
||||
lblImmunity:SetText("Immunity number (higher is more immune)")
|
||||
lblImmunity:SizeToContents()
|
||||
|
||||
nmbrImmunity = vgui.Create("DTextEntry", frame)
|
||||
nmbrImmunity:SetPos(545, 28)
|
||||
nmbrImmunity:SetWide(90)
|
||||
nmbrImmunity:SetNumeric(true)
|
||||
nmbrImmunity:SetText(FAdmin.Access.Groups.user.immunity)
|
||||
nmbrImmunity:SetDisabled(true)
|
||||
nmbrImmunity:SetEditable(false)
|
||||
nmbrImmunity.OnEnter = function(self) RunConsoleCommand("FAdmin", "SetImmunity", SelectedGroup:GetValue(), self:GetValue()) end
|
||||
end
|
||||
@@ -0,0 +1,273 @@
|
||||
CreateConVar("_FAdmin_immunity", 1, {FCVAR_GAMEDLL, FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_SERVER_CAN_EXECUTE})
|
||||
|
||||
FAdmin.Access = FAdmin.Access or {}
|
||||
FAdmin.Access.ADMIN = {"user", "admin", "superadmin"}
|
||||
FAdmin.Access.ADMIN[0] = "user"
|
||||
|
||||
FAdmin.Access.Groups = FAdmin.Access.Groups or {}
|
||||
FAdmin.Access.Privileges = FAdmin.Access.Privileges or {}
|
||||
|
||||
function FAdmin.Access.AddGroup(name, admin_access --[[0 = not admin, 1 = admin, 2 = superadmin]], privs, immunity, fromCAMI, CAMIsrc)
|
||||
FAdmin.Access.Groups[name] = FAdmin.Access.Groups[name] or {ADMIN = admin_access, PRIVS = privs or {}, immunity = immunity}
|
||||
|
||||
--Make sure things that come from CAMI come with a CAMIsrc
|
||||
assert((fromCAMI and CAMIsrc ~= nil) or ((not fromCAMI) and CAMIsrc == nil))
|
||||
--If the CAMIsrc is a string, save it, otherwise save an empty string
|
||||
if not isstring(CAMIsrc) then
|
||||
CAMIsrc = ""
|
||||
end
|
||||
|
||||
-- Register custom usergroups with CAMI
|
||||
if name ~= "user" and name ~= "admin" and name ~= "superadmin" and not fromCAMI then
|
||||
CAMI.RegisterUsergroup({
|
||||
Name = name,
|
||||
Inherits = FAdmin.Access.ADMIN[admin_access]
|
||||
}, "FAdmin")
|
||||
end
|
||||
|
||||
-- Add newly created privileges on server reload
|
||||
for p, _ in pairs(privs or {}) do
|
||||
FAdmin.Access.Groups[name].PRIVS[p] = true
|
||||
end
|
||||
|
||||
if not SERVER then return end
|
||||
|
||||
MySQLite.queryValue("SELECT COUNT(*) FROM FADMIN_GROUPS WHERE NAME = " .. MySQLite.SQLStr(name) .. ";", function(val)
|
||||
if tonumber(val or 0) > 0 then return end
|
||||
|
||||
MySQLite.query("REPLACE INTO FADMIN_GROUPS VALUES(" .. MySQLite.SQLStr(name) .. ", " .. tonumber(admin_access) .. ");", function()
|
||||
for priv, _ in pairs(privs or {}) do
|
||||
MySQLite.query("REPLACE INTO FADMIN_PRIVILEGES VALUES(" .. MySQLite.SQLStr(name) .. ", " .. MySQLite.SQLStr(priv) .. ");")
|
||||
end
|
||||
if fromCAMI then
|
||||
MySQLite.query("REPLACE INTO FADMIN_GROUPS_SRC VALUES(" .. MySQLite.SQLStr(name) .. ", " .. MySQLite.SQLStr(CAMIsrc) .. ");")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
if immunity then
|
||||
MySQLite.query("REPLACE INTO FAdmin_Immunity VALUES(" .. MySQLite.SQLStr(name) .. ", " .. tonumber(immunity) .. ");")
|
||||
end
|
||||
|
||||
if FAdmin.Access.SendGroups and privs then
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
FAdmin.Access.SendGroups(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.Access.OnUsergroupRegistered(usergroup, source)
|
||||
-- Don't re-add usergroups coming from FAdmin itself
|
||||
if source == "FAdmin" then return end
|
||||
|
||||
local inheritRoot = CAMI.InheritanceRoot(usergroup.Inherits)
|
||||
local admin_access = table.KeyFromValue(FAdmin.Access.ADMIN, inheritRoot) or 1
|
||||
|
||||
-- Add groups registered to CAMI to FAdmin. Assume privileges from either the usergroup it inherits or its inheritance root.
|
||||
-- Immunity is unknown and can be set by the user later. FAdmin immunity only applies to FAdmin anyway.
|
||||
local parent = FAdmin.Access.Groups[usergroup.Inherits] or FAdmin.Access.Groups[inheritRoot] or {}
|
||||
FAdmin.Access.AddGroup(usergroup.Name, admin_access - 1, table.Copy(parent.PRIVS) or {}, parent.immunity or 10, true, source)
|
||||
end
|
||||
|
||||
|
||||
function FAdmin.Access.OnUsergroupUnregistered(usergroup, source)
|
||||
if table.HasValue({"superadmin", "admin", "user", "noaccess"}, usergroup.Name) then return end
|
||||
|
||||
FAdmin.Access.Groups[usergroup.Name] = nil
|
||||
|
||||
if not SERVER then return end
|
||||
|
||||
MySQLite.query("DELETE FROM FADMIN_GROUPS WHERE NAME = " .. MySQLite.SQLStr(usergroup.Name) .. ";")
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
FAdmin.Access.SendGroups(v)
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.Access.RemoveGroup(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ManageGroups") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
if not FAdmin.Access.Groups[args[1]] or table.HasValue({"superadmin", "admin", "user"}, string.lower(args[1])) then return true, args[1] end
|
||||
|
||||
-- Setting a group with a higher rank than one's own
|
||||
if (not plyGroup or FAdmin.Access.Groups[args[1]].immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to remove usergroups with a higher rank than your own")
|
||||
return false
|
||||
end
|
||||
|
||||
CAMI.UnregisterUsergroup(args[1], "FAdmin")
|
||||
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Group succesfully removed")
|
||||
end
|
||||
|
||||
local PLAYER = FindMetaTable("Player")
|
||||
|
||||
local oldplyIsAdmin = PLAYER.IsAdmin
|
||||
function PLAYER:IsAdmin(...)
|
||||
local usergroup = self:GetUserGroup()
|
||||
|
||||
if not FAdmin or not FAdmin.Access or not FAdmin.Access.Groups or not FAdmin.Access.Groups[usergroup] then return oldplyIsAdmin(self, ...) or game.SinglePlayer() end
|
||||
|
||||
if (FAdmin.Access.Groups[usergroup] and FAdmin.Access.Groups[usergroup].ADMIN >= 1 --[[1 = admin]]) or (self.IsListenServerHost and self:IsListenServerHost()) then
|
||||
return true
|
||||
end
|
||||
|
||||
if CLIENT and tonumber(self:FAdmin_GetGlobal("FAdmin_admin")) and self:FAdmin_GetGlobal("FAdmin_admin") >= 1 then return true end
|
||||
|
||||
return oldplyIsAdmin(self, ...) or game.SinglePlayer()
|
||||
end
|
||||
|
||||
local oldplyIsSuperAdmin = PLAYER.IsSuperAdmin
|
||||
function PLAYER:IsSuperAdmin(...)
|
||||
local usergroup = self:GetUserGroup()
|
||||
if not FAdmin or not FAdmin.Access or not FAdmin.Access.Groups or not FAdmin.Access.Groups[usergroup] then return oldplyIsSuperAdmin(self, ...) or game.SinglePlayer() end
|
||||
if (FAdmin.Access.Groups[usergroup] and FAdmin.Access.Groups[usergroup].ADMIN >= 2 --[[2 = superadmin]]) or (self.IsListenServerHost and self:IsListenServerHost()) then
|
||||
return true
|
||||
end
|
||||
if CLIENT and tonumber(self:FAdmin_GetGlobal("FAdmin_admin")) and self:FAdmin_GetGlobal("FAdmin_admin") >= 2 then return true end
|
||||
return oldplyIsSuperAdmin(self, ...) or game.SinglePlayer()
|
||||
end
|
||||
|
||||
--Privileges
|
||||
function FAdmin.Access.AddPrivilege(Name, admin_access)
|
||||
FAdmin.Access.Privileges[Name] = admin_access
|
||||
end
|
||||
|
||||
hook.Add("CAMI.OnPrivilegeRegistered", "FAdmin", function(privilege)
|
||||
FAdmin.Access.AddPrivilege(privilege.Name, table.KeyFromValue(FAdmin.Access.ADMIN, CAMI.InheritanceRoot(privilege.MinAccess)) or 3)
|
||||
|
||||
-- Register privilege and add to respective usergroups
|
||||
if SERVER then FAdmin.Access.RegisterCAMIPrivilege(privilege) end
|
||||
end)
|
||||
|
||||
for _, camipriv in pairs(CAMI.GetPrivileges()) do
|
||||
FAdmin.Access.AddPrivilege(camipriv.Name, table.KeyFromValue(FAdmin.Access.ADMIN, CAMI.InheritanceRoot(camipriv.MinAccess)) or 3)
|
||||
-- Register if the database has already loaded
|
||||
if SERVER and FAdmin.Access.RegisterCAMIPrivilege then FAdmin.Access.RegisterCAMIPrivilege(camipriv) end
|
||||
end
|
||||
|
||||
hook.Add("CAMI.OnPrivilegeUnregistered", "FAdmin", function(privilege)
|
||||
FAdmin.Access.Privileges[privilege.Name] = nil
|
||||
end)
|
||||
|
||||
function FAdmin.Access.PlayerIsHost(ply)
|
||||
return ply:EntIndex() == 0 or game.SinglePlayer() or (ply.IsListenServerHost and ply:IsListenServerHost())
|
||||
end
|
||||
|
||||
function FAdmin.Access.PlayerHasPrivilege(ply, priv, target, ignoreImmunity)
|
||||
-- This is the server console
|
||||
if FAdmin.Access.PlayerIsHost(ply) then return true end
|
||||
-- Privilege does not exist
|
||||
if not FAdmin.Access.Privileges[priv] then return ply:IsAdmin() end
|
||||
|
||||
local Usergroup = ply:GetUserGroup()
|
||||
|
||||
local canTarget = hook.Call("FAdmin_CanTarget", nil, ply, priv, target)
|
||||
if canTarget ~= nil then
|
||||
return canTarget
|
||||
end
|
||||
|
||||
if FAdmin.GlobalSetting.Immunity and
|
||||
not ignoreImmunity and
|
||||
not isstring(target) and IsValid(target) and target ~= ply and
|
||||
FAdmin.Access.Groups[Usergroup] and FAdmin.Access.Groups[target:GetUserGroup()] and
|
||||
FAdmin.Access.Groups[Usergroup].immunity and FAdmin.Access.Groups[target:GetUserGroup()].immunity and
|
||||
FAdmin.Access.Groups[target:GetUserGroup()].immunity >= FAdmin.Access.Groups[Usergroup].immunity then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Defer answer when usergroup is unknown
|
||||
if not FAdmin.Access.Groups[Usergroup] then return end
|
||||
|
||||
if FAdmin.Access.Groups[Usergroup].PRIVS[priv] then
|
||||
return true
|
||||
end
|
||||
|
||||
if CLIENT and ply.FADMIN_PRIVS and ply.FADMIN_PRIVS[priv] then return true end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
hook.Add("CAMI.PlayerHasAccess", "FAdmin", function(actor, privilegeName, callback, target, extraInfo)
|
||||
-- FAdmin doesn't know. Defer answer.
|
||||
if not FAdmin.Access.Privileges[privilegeName] then return end
|
||||
|
||||
local res = FAdmin.Access.PlayerHasPrivilege(actor, privilegeName, target, extraInfo and extraInfo.IgnoreImmunity)
|
||||
|
||||
-- Defer again
|
||||
if res == nil then return end
|
||||
|
||||
-- Publish the answer
|
||||
callback(res, "FAdmin")
|
||||
|
||||
-- FAdmin knows the answer. Prevent other hooks from running.
|
||||
return true
|
||||
end)
|
||||
|
||||
hook.Add("CAMI.SteamIDHasAccess", "FAdmin", function(actorSteam, privilegeName, callback, targetSteam, extraInfo)
|
||||
-- The client just doesn't know
|
||||
if CLIENT then return end
|
||||
|
||||
if not targetSteam or extraInfo and extraInfo.IgnoreImmunity then
|
||||
MySQLite.query(string.format(
|
||||
[[SELECT COUNT(*) AS c
|
||||
FROM FAdmin_PlayerGroup l
|
||||
JOIN FADMIN_PRIVILEGES r ON l.groupname = r.NAME
|
||||
WHERE l.steamid = %s AND r.PRIVILEGE = %s]],
|
||||
MySQLite.SQLStr(actorSteam),
|
||||
MySQLite.SQLStr(privilegeName)
|
||||
), function(res) callback(tonumber(res[1].c) > 0) end)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
MySQLite.query(string.format(
|
||||
[[SELECT ll.i AND rr.c AS res
|
||||
FROM (SELECT li.immunity >= ri.immunity AS i
|
||||
FROM FAdmin_PlayerGroup lg
|
||||
JOIN FAdmin_Immunity li ON lg.groupname = li.groupname
|
||||
JOIN FAdmin_PlayerGroup rg
|
||||
JOIN FAdmin_Immunity ri ON rg.groupname = ri.groupname
|
||||
WHERE lg.steamid = %s AND rg.steamid = %s) AS ll
|
||||
JOIN (SELECT COUNT(*) AS c
|
||||
FROM FAdmin_PlayerGroup l
|
||||
JOIN FADMIN_PRIVILEGES r ON l.groupname = r.NAME
|
||||
WHERE l.steamid = %s AND r.PRIVILEGE = %s) AS rr]],
|
||||
MySQLite.SQLStr(actorSteam),
|
||||
MySQLite.SQLStr(targetSteam),
|
||||
MySQLite.SQLStr(actorSteam),
|
||||
MySQLite.SQLStr(privilegeName)
|
||||
), function(res) callback(res and res[1] and tobool(res[1].res) or false) end)
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
FAdmin.StartHooks["AccessFunctions"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "setaccess",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " set the usergroup of ", "targets", " to ", "extraInfo.1"},
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(i) net.WriteString(i[1]) end,
|
||||
readExtraInfo = function() return {net.ReadString()} end,
|
||||
extraInfoColors = {Color(255, 102, 0)}
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("SetAccess", 3) -- AddPrivilege is shared, run on both client and server
|
||||
FAdmin.Access.AddPrivilege("ManagePrivileges", 3)
|
||||
FAdmin.Access.AddPrivilege("ManageGroups", 3)
|
||||
FAdmin.Access.AddPrivilege("SeeAdmins", 1)
|
||||
FAdmin.Commands.AddCommand("RemoveGroup", FAdmin.Access.RemoveGroup)
|
||||
|
||||
FAdmin.Commands.AddCommand("Admins", function(ply)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "SeeAdmins") then return false end
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
ply:PrintMessage(HUD_PRINTCONSOLE, v:Nick() .. "\t|\t" .. v:GetUserGroup())
|
||||
end
|
||||
return true
|
||||
end
|
||||
)
|
||||
end
|
||||
@@ -0,0 +1,449 @@
|
||||
--Immunity
|
||||
cvars.AddChangeCallback("_FAdmin_immunity", function(Cvar, Previous, New)
|
||||
FAdmin.SetGlobalSetting("Immunity", (tonumber(New) == 1 and true) or false)
|
||||
FAdmin.SaveSetting("_FAdmin_immunity", tonumber(New))
|
||||
end)
|
||||
|
||||
hook.Add("DatabaseInitialized", "InitializeFAdminGroups", function()
|
||||
MySQLite.query("CREATE TABLE IF NOT EXISTS FADMIN_GROUPS(NAME VARCHAR(40) NOT NULL PRIMARY KEY, ADMIN_ACCESS INTEGER NOT NULL);")
|
||||
MySQLite.query("CREATE TABLE IF NOT EXISTS FAdmin_PlayerGroup(steamid VARCHAR(40) NOT NULL, groupname VARCHAR(40) NOT NULL, PRIMARY KEY(steamid));")
|
||||
MySQLite.query("CREATE TABLE IF NOT EXISTS FAdmin_Immunity(groupname VARCHAR(40) NOT NULL, immunity INTEGER NOT NULL, PRIMARY KEY(groupname));")
|
||||
MySQLite.query("CREATE TABLE IF NOT EXISTS FAdmin_CAMIPrivileges(privname VARCHAR(255) NOT NULL PRIMARY KEY);")
|
||||
MySQLite.query("CREATE TABLE IF NOT EXISTS FADMIN_GROUPS_SRC(NAME VARCHAR(40) NOT NULL PRIMARY KEY REFERENCES FADMIN_GROUPS(NAME) ON DELETE CASCADE, SRC VARCHAR(40));")
|
||||
MySQLite.query([[CREATE TABLE IF NOT EXISTS FADMIN_PRIVILEGES(
|
||||
NAME VARCHAR(40),
|
||||
PRIVILEGE VARCHAR(100),
|
||||
PRIMARY KEY(NAME, PRIVILEGE),
|
||||
FOREIGN KEY(NAME) REFERENCES FADMIN_GROUPS(NAME)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
);]], function()
|
||||
|
||||
-- Remove SetAccess workaround
|
||||
MySQLite.query([[DELETE FROM FADMIN_PRIVILEGES WHERE NAME = "user" AND PRIVILEGE = "SetAccess";]])
|
||||
|
||||
MySQLite.query("SELECT g.NAME, g.ADMIN_ACCESS, p.PRIVILEGE, i.immunity, s.src FROM FADMIN_GROUPS g LEFT OUTER JOIN FADMIN_PRIVILEGES p ON g.NAME = p.NAME LEFT OUTER JOIN FAdmin_Immunity i ON g.NAME = i.groupname LEFT OUTER JOIN FADMIN_GROUPS_SRC s ON g.NAME = s.NAME;", function(data)
|
||||
if not data then return end
|
||||
|
||||
for _, v in pairs(data) do
|
||||
FAdmin.Access.Groups[v.NAME] = FAdmin.Access.Groups[v.NAME] or
|
||||
{ADMIN = tonumber(v.ADMIN_ACCESS), PRIVS = {}}
|
||||
|
||||
if v.PRIVILEGE and v.PRIVILEGE ~= "NULL" then
|
||||
FAdmin.Access.Groups[v.NAME].PRIVS[v.PRIVILEGE] = true
|
||||
end
|
||||
|
||||
if v.immunity and v.immunity ~= "NULL" then
|
||||
FAdmin.Access.Groups[v.NAME].immunity = tonumber(v.immunity)
|
||||
end
|
||||
|
||||
if CAMI.GetUsergroup(v.NAME) then continue end
|
||||
|
||||
CAMI.RegisterUsergroup({
|
||||
Name = v.NAME,
|
||||
Inherits = FAdmin.Access.ADMIN[v.ADMIN_ACCESS] or "user"
|
||||
}, v.SRC)
|
||||
end
|
||||
|
||||
-- Send groups to early joiners and listen server hosts
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
FAdmin.Access.SendGroups(v)
|
||||
end
|
||||
|
||||
-- See if there are any CAMI usergroups that FAdmin doesn't know about yet.
|
||||
-- FAdmin doesn't start listening immediately because the database might not have initialised.
|
||||
-- Besides, other admin mods might add usergroups before FAdmin's Lua files are even run
|
||||
for _, v in pairs(CAMI.GetUsergroups()) do
|
||||
if FAdmin.Access.Groups[v.Name] then continue end
|
||||
|
||||
FAdmin.Access.OnUsergroupRegistered(v,"")
|
||||
end
|
||||
|
||||
-- Start listening for CAMI usergroup registrations.
|
||||
hook.Add("CAMI.OnUsergroupRegistered", "FAdmin", FAdmin.Access.OnUsergroupRegistered)
|
||||
hook.Add("CAMI.OnUsergroupUnregistered", "FAdmin", FAdmin.Access.OnUsergroupUnregistered)
|
||||
|
||||
FAdmin.Access.RegisterCAMIPrivileges()
|
||||
end)
|
||||
|
||||
local function createGroups(privs)
|
||||
FAdmin.Access.AddGroup("superadmin", 2, privs.superadmin, 100)
|
||||
FAdmin.Access.AddGroup("admin", 1, privs.admin, 50)
|
||||
FAdmin.Access.AddGroup("user", 0, privs.user, 10)
|
||||
FAdmin.Access.AddGroup("noaccess", 0, privs.noaccess, 0)
|
||||
end
|
||||
|
||||
MySQLite.query("SELECT DISTINCT PRIVILEGE FROM FADMIN_PRIVILEGES;", function(privTbl)
|
||||
local privs = {}
|
||||
local hasPrivs = {"noaccess", "user", "admin", "superadmin"}
|
||||
|
||||
-- No privileges registered to anyone. Reset everything
|
||||
if not privTbl or table.IsEmpty(privTbl) then
|
||||
for priv, access in pairs(FAdmin.Access.Privileges) do
|
||||
for i = access + 1, #hasPrivs, 1 do
|
||||
privs[hasPrivs[i]] = privs[hasPrivs[i]] or {}
|
||||
privs[hasPrivs[i]][priv] = true
|
||||
end
|
||||
end
|
||||
|
||||
createGroups(privs)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- Check for newly created privileges and assign them to the default usergroups
|
||||
-- No privilege can be revoke from every group
|
||||
local privSet = {}
|
||||
for _, priv in ipairs(privTbl) do
|
||||
privSet[priv.PRIVILEGE] = true
|
||||
end
|
||||
|
||||
for priv, access in pairs(FAdmin.Access.Privileges) do
|
||||
if privSet[priv] then continue end
|
||||
|
||||
for i = access + 1, #hasPrivs do
|
||||
MySQLite.query(("REPLACE INTO FADMIN_PRIVILEGES VALUES(%s, %s);"):format(MySQLite.SQLStr(hasPrivs[i]), MySQLite.SQLStr(priv)))
|
||||
end
|
||||
end
|
||||
|
||||
createGroups(privs)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Assign a privilege to its respective usergroups when they are seen for the first time
|
||||
function FAdmin.Access.RegisterCAMIPrivilege(priv)
|
||||
-- Privileges haven't been loaded yet or has already been seen
|
||||
if not FAdmin.CAMIPrivs or FAdmin.CAMIPrivs[priv.Name] then return end
|
||||
|
||||
FAdmin.CAMIPrivs[priv.Name] = true
|
||||
|
||||
for groupName, groupdata in pairs(FAdmin.Access.Groups) do
|
||||
if FAdmin.Access.Privileges[priv.Name] - 1 > groupdata.ADMIN then continue end
|
||||
groupdata.PRIVS[priv.Name] = true
|
||||
|
||||
MySQLite.query(string.format([[REPLACE INTO FADMIN_PRIVILEGES VALUES(%s, %s);]], MySQLite.SQLStr(groupName), MySQLite.SQLStr(priv.Name)))
|
||||
end
|
||||
|
||||
MySQLite.query(string.format([[REPLACE INTO FAdmin_CAMIPrivileges VALUES(%s);]], MySQLite.SQLStr(priv.Name)))
|
||||
end
|
||||
|
||||
-- Assign privileges to their respective usergroups when they are seen for the first time
|
||||
function FAdmin.Access.RegisterCAMIPrivileges()
|
||||
MySQLite.query([[SELECT privname FROM FAdmin_CAMIPrivileges]], function(data)
|
||||
FAdmin.CAMIPrivs = {}
|
||||
|
||||
for _, row in ipairs(data or {}) do
|
||||
FAdmin.CAMIPrivs[row.privname] = true
|
||||
end
|
||||
|
||||
|
||||
for privName, _ in pairs(CAMI.GetPrivileges()) do
|
||||
if FAdmin.CAMIPrivs[privName] then continue end
|
||||
FAdmin.CAMIPrivs[privName] = true
|
||||
|
||||
for groupName, groupdata in pairs(FAdmin.Access.Groups) do
|
||||
if FAdmin.Access.Privileges[privName] - 1 > groupdata.ADMIN then continue end
|
||||
groupdata.PRIVS[privName] = true
|
||||
|
||||
MySQLite.query(string.format([[REPLACE INTO FADMIN_PRIVILEGES VALUES(%s, %s);]], MySQLite.SQLStr(groupName), MySQLite.SQLStr(privName)))
|
||||
end
|
||||
|
||||
MySQLite.query(string.format([[REPLACE INTO FAdmin_CAMIPrivileges VALUES(%s);]], MySQLite.SQLStr(privName)))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function FAdmin.Access.PlayerSetGroup(ply, group)
|
||||
if not FAdmin.Access.Groups[group] then return end
|
||||
ply = isstring(ply) and FAdmin.FindPlayer(ply) and FAdmin.FindPlayer(ply)[1] or ply
|
||||
|
||||
if not isstring(ply) and IsValid(ply) then
|
||||
ply:SetUserGroup(group)
|
||||
end
|
||||
end
|
||||
|
||||
hook.Remove("PlayerInitialSpawn", "PlayerAuthSpawn") -- Remove Garry's usergroup setter.
|
||||
|
||||
-- Update the database only when an end users indicates that a player's usergroup is to be changed.
|
||||
hook.Add("CAMI.PlayerUsergroupChanged", "FAdmin", function(ply, old, new, source)
|
||||
MySQLite.query("REPLACE INTO FAdmin_PlayerGroup VALUES(" .. MySQLite.SQLStr(ply:SteamID()) .. ", " .. MySQLite.SQLStr(new) .. ");")
|
||||
end)
|
||||
|
||||
hook.Add("CAMI.SteamIDUsergroupChanged", "FAdmin", function(steamId, old, new, source)
|
||||
MySQLite.query("REPLACE INTO FAdmin_PlayerGroup VALUES(" .. MySQLite.SQLStr(steamId) .. ", " .. MySQLite.SQLStr(new) .. ");")
|
||||
end)
|
||||
|
||||
function FAdmin.Access.SetRoot(ply, cmd, args) -- FAdmin setroot player. Sets the player to superadmin
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "SetAccess") then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "No access!")
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Please use RCon to set yourself to superadmin if you are the owner of the server")
|
||||
return false
|
||||
end
|
||||
|
||||
local group = FAdmin.Access.Groups["superadmin"]
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
-- Setting a group with a higher rank than one's own
|
||||
if (not plyGroup or group.immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to assign anyone a usergroup with a higher rank than your own")
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Please use RCon to set yourself to superadmin if you are the owner of the server")
|
||||
return false
|
||||
end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not IsValid(target) then continue end
|
||||
|
||||
local target_previous_group = target:GetUserGroup()
|
||||
FAdmin.Access.PlayerSetGroup(target, "superadmin")
|
||||
|
||||
-- An end user changed the usergroup. Register with CAMI
|
||||
CAMI.SignalUserGroupChanged(target, target_previous_group, "superadmin", "FAdmin")
|
||||
|
||||
FAdmin.Messages.SendMessage(ply, 2, "User set to superadmin!")
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("setaccess", ply, targets, {"superadmin"})
|
||||
return true, targets, "superadmin"
|
||||
end
|
||||
|
||||
-- AddGroup <Groupname> <Adminstatus> <Privileges>
|
||||
local function AddGroup(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ManageGroups") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
local admin = tonumber(args[2])
|
||||
if not args[1] or not admin then FAdmin.Messages.SendMessage(ply, 5, "Incorrect arguments!") return false end
|
||||
local privs = {}
|
||||
|
||||
for priv, am in SortedPairs(FAdmin.Access.Privileges) do
|
||||
-- The user cannot create groups with privileges they don't have
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, priv) then continue end
|
||||
if am <= admin + 1 then privs[priv] = true end
|
||||
end
|
||||
|
||||
local immunity = FAdmin.Access.Groups[FAdmin.Access.ADMIN[admin + 1]].immunity
|
||||
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
if (not plyGroup or immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to create usergroups with a higher rank than your own")
|
||||
return false
|
||||
end
|
||||
|
||||
FAdmin.Access.AddGroup(args[1], admin, privs, immunity) -- Add new group
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Group created")
|
||||
FAdmin.Access.SendGroups()
|
||||
|
||||
return true, args[1]
|
||||
end
|
||||
|
||||
local function AddPrivilege(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ManagePrivileges") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local group, priv = args[1], args[2]
|
||||
|
||||
if not FAdmin.Access.Groups[group] or not FAdmin.Access.Privileges[priv] then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Invalid arguments")
|
||||
return false
|
||||
end
|
||||
|
||||
-- The player cannot add privileges that they themselves do not have
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, priv) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to assign privileges that you don't have yourself")
|
||||
return false
|
||||
end
|
||||
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
-- Setting a group with a higher rank than one's own
|
||||
if (not plyGroup or FAdmin.Access.Groups[group].immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to manage the privileges of a usergroup with a higher rank than your own")
|
||||
return false
|
||||
end
|
||||
|
||||
FAdmin.Access.Groups[group].PRIVS[priv] = true
|
||||
|
||||
MySQLite.query("REPLACE INTO FADMIN_PRIVILEGES VALUES(" .. MySQLite.SQLStr(group) .. ", " .. MySQLite.SQLStr(priv) .. ");")
|
||||
SendUserMessage("FAdmin_AddPriv", player.GetAll(), group, priv)
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Privilege Added!")
|
||||
|
||||
return true, group, priv
|
||||
end
|
||||
|
||||
local function RemovePrivilege(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ManagePrivileges") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local group, priv = args[1], args[2]
|
||||
if not FAdmin.Access.Groups[group] or not FAdmin.Access.Privileges[priv] then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Invalid arguments")
|
||||
return false
|
||||
end
|
||||
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
-- Setting a group with a higher rank than one's own
|
||||
if (not plyGroup or FAdmin.Access.Groups[group].immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to manage the privileges of a usergroup with a higher rank than your own")
|
||||
return false
|
||||
end
|
||||
|
||||
FAdmin.Access.Groups[group].PRIVS[priv] = nil
|
||||
|
||||
MySQLite.query("DELETE FROM FADMIN_PRIVILEGES WHERE NAME = " .. MySQLite.SQLStr(group) .. " AND PRIVILEGE = " .. MySQLite.SQLStr(priv) .. ";")
|
||||
SendUserMessage("FAdmin_RemovePriv", player.GetAll(), group, priv)
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Privilege Removed!")
|
||||
|
||||
return true, group, priv
|
||||
end
|
||||
|
||||
function FAdmin.Access.SendGroups(ply)
|
||||
if not FAdmin.Access.Groups then return end
|
||||
|
||||
net.Start("FADMIN_SendGroups")
|
||||
net.WriteTable(FAdmin.Access.Groups)
|
||||
net.Send(IsValid(ply) and ply or player.GetAll())
|
||||
end
|
||||
|
||||
-- FAdmin SetAccess <player> <groupname> [new_groupadmin, new_groupprivs]
|
||||
function FAdmin.Access.SetAccess(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "SetAccess") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
local admin = tonumber(args[3])
|
||||
local group = FAdmin.Access.Groups[args[2]]
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
if not args[2] or not group and not admin then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Group not found")
|
||||
return false
|
||||
elseif args[2] and not group and admin then
|
||||
local privs = {}
|
||||
for priv, am in SortedPairs(FAdmin.Access.Privileges) do
|
||||
if am <= admin + 1 then privs[priv] = true end
|
||||
end
|
||||
|
||||
local immunity = FAdmin.Access.Groups[FAdmin.Access.ADMIN[admin + 1]].immunity
|
||||
-- Creating and setting a group with a higher rank than one's own
|
||||
if (not plyGroup or immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to assign anyone a usergroup with a higher rank than your own")
|
||||
return false
|
||||
end
|
||||
|
||||
FAdmin.Access.AddGroup(args[2], tonumber(args[3]), privs, immunity) -- Add new group
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Group created")
|
||||
FAdmin.Access.SendGroups()
|
||||
end
|
||||
|
||||
-- Setting a group with a higher rank than one's own
|
||||
if group and (not plyGroup or group.immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to assign anyone a usergroup with a higher rank than your own")
|
||||
return false
|
||||
end
|
||||
|
||||
if not targets and (string.find(args[1], "^STEAM_[0-9]:[01]:[0-9]+$") or args[1] == "BOT" or (string.find(args[1], "STEAM_") and #args == 6)) then
|
||||
local target, groupname = args[1], args[2]
|
||||
-- The console splits arguments on colons. Very annoying.
|
||||
if args[1] == "STEAM_0" then
|
||||
target = table.concat(args, "", 1, 5)
|
||||
groupname = args[6]
|
||||
end
|
||||
FAdmin.Access.PlayerSetGroup(target, groupname)
|
||||
|
||||
MySQLite.queryValue(string.format("SELECT groupname FROM FAdmin_PlayerGroup WHERE steamid = %s", MySQLite.SQLStr(target)), function(val)
|
||||
CAMI.SignalSteamIDUserGroupChanged(target, val or "user", groupname, "FAdmin")
|
||||
end)
|
||||
FAdmin.Messages.SendMessage(ply, 4, "User access set!")
|
||||
return true, target, groupname
|
||||
elseif not targets then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not IsValid(target) then continue end
|
||||
|
||||
local target_previous_group = target:GetUserGroup()
|
||||
FAdmin.Access.PlayerSetGroup(target, args[2])
|
||||
|
||||
-- An end user changed the usergroup. Register with CAMI
|
||||
CAMI.SignalUserGroupChanged(target, target_previous_group, args[2], "FAdmin")
|
||||
end
|
||||
|
||||
FAdmin.Messages.SendMessage(ply, 4, "User access set!")
|
||||
FAdmin.Messages.FireNotification("setaccess", ply, targets, {args[2]})
|
||||
return true, targets, args[2]
|
||||
end
|
||||
|
||||
--hooks and stuff
|
||||
|
||||
hook.Add("PlayerInitialSpawn", "FAdmin_SetAccess", function(ply)
|
||||
MySQLite.queryValue("SELECT groupname FROM FAdmin_PlayerGroup WHERE steamid = " .. MySQLite.SQLStr(ply:SteamID()) .. ";", function(Group)
|
||||
if not Group then return end
|
||||
ply:SetUserGroup(Group)
|
||||
|
||||
if FAdmin.Access.Groups[Group] then
|
||||
ply:FAdmin_SetGlobal("FAdmin_admin", FAdmin.Access.Groups[Group].ADMIN_ACCESS)
|
||||
end
|
||||
end, function(err) ErrorNoHalt(err) MsgN() end)
|
||||
FAdmin.Access.SendGroups(ply)
|
||||
end)
|
||||
|
||||
local function toggleImmunity(ply, cmd, args)
|
||||
-- ManageGroups privilege because they can handle immunity settings
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ManageGroups") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
if not args[1] then FAdmin.Messages.SendMessage(ply, 5, "Invalid argument!") return false end
|
||||
RunConsoleCommand("_FAdmin_immunity", args[1])
|
||||
local OnOff = (tonumber(args[1]) == 1 and "on") or "off"
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), ply:Nick() .. " turned " .. OnOff .. " admin immunity!", "Admin immunity has been turned " .. OnOff, "Turned admin immunity " .. OnOff)
|
||||
|
||||
return true, OnOff
|
||||
end
|
||||
|
||||
|
||||
local function setImmunity(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ManageGroups") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
local group, immunity = args[1], tonumber(args[2])
|
||||
|
||||
if not FAdmin.Access.Groups[group] or not immunity then return false end
|
||||
|
||||
local plyGroup = FAdmin.Access.Groups[ply:EntIndex() == 0 and "superadmin" or ply:GetUserGroup()]
|
||||
|
||||
-- Setting a group with a higher rank than one's own
|
||||
if (not plyGroup or FAdmin.Access.Groups[group].immunity > plyGroup.immunity) and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to change the immunity of a group with a higher rank than your")
|
||||
return false
|
||||
end
|
||||
|
||||
if immunity > plyGroup.immunity and not FAdmin.Access.PlayerIsHost(ply) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "You're not allowed to set the immunity to any value higher than your own group's immunity")
|
||||
return false
|
||||
end
|
||||
|
||||
FAdmin.Access.Groups[group].immunity = immunity
|
||||
MySQLite.query("REPLACE INTO FAdmin_Immunity VALUES(" .. MySQLite.SQLStr(group) .. ", " .. tonumber(immunity) .. ");")
|
||||
|
||||
FAdmin.Access.SendGroups(ply)
|
||||
|
||||
return true, group, immunity
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Access"] = function() --Run all functions that depend on other plugins
|
||||
FAdmin.Commands.AddCommand("setroot", FAdmin.Access.SetRoot)
|
||||
FAdmin.Commands.AddCommand("setaccess", FAdmin.Access.SetAccess)
|
||||
|
||||
FAdmin.Commands.AddCommand("AddGroup", AddGroup)
|
||||
|
||||
FAdmin.Commands.AddCommand("AddPrivilege", AddPrivilege)
|
||||
FAdmin.Commands.AddCommand("RemovePrivilege", RemovePrivilege)
|
||||
|
||||
FAdmin.Commands.AddCommand("immunity", toggleImmunity)
|
||||
FAdmin.Commands.AddCommand("SetImmunity", setImmunity)
|
||||
|
||||
FAdmin.SetGlobalSetting("Immunity", GetConVar("_FAdmin_immunity"):GetBool())
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
net.Receive("FAdmin_ReceiveAdminMessage", function(len)
|
||||
local FromPly = net.ReadEntity()
|
||||
local Text = net.ReadString()
|
||||
local Team = FromPly:IsPlayer() and FromPly:Team() or 1
|
||||
local Nick = FromPly:IsPlayer() and FromPly:Nick() or "Console"
|
||||
local prefix = (FAdmin.Access.PlayerHasPrivilege(FromPly, "AdminChat") or FromPly:IsAdmin()) and "[Admin Chat] " or "[To admins] "
|
||||
|
||||
chat.AddNonParsedText(Color(255, 0, 0, 255), prefix, team.GetColor(Team), Nick .. ": ", color_white, Text)
|
||||
end)
|
||||
|
||||
FAdmin.StartHooks["Chatting"] = function()
|
||||
FAdmin.Commands.AddCommand("adminhelp", nil, "<text>")
|
||||
FAdmin.Commands.AddCommand("//", nil, "<text>")
|
||||
|
||||
FAdmin.Access.AddPrivilege("AdminChat", 2)
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
util.AddNetworkString("FAdmin_ReceiveAdminMessage")
|
||||
local function ToAdmins(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local text = table.concat(args, " ")
|
||||
local send = {}
|
||||
|
||||
if IsValid(ply) then table.insert(send, ply) end
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if FAdmin.Access.PlayerHasPrivilege(v, "AdminChat") or v:IsAdmin() then
|
||||
table.insert(send, v)
|
||||
end
|
||||
end
|
||||
|
||||
net.Start("FAdmin_ReceiveAdminMessage")
|
||||
net.WriteEntity(ply)
|
||||
net.WriteString(text)
|
||||
net.Send(send)
|
||||
|
||||
return true, text
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Chatting"] = function()
|
||||
FAdmin.Commands.AddCommand("adminhelp", ToAdmins)
|
||||
FAdmin.Commands.AddCommand("//", ToAdmins)
|
||||
|
||||
FAdmin.Access.AddPrivilege("AdminChat", 2)
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
local PANEL = {}
|
||||
|
||||
AccessorFunc(PANEL, "gamemodeList", "GamemodeList")
|
||||
AccessorFunc(PANEL, "mapList", "MapList")
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetMouseInputEnabled(true)
|
||||
self:SetKeyboardInputEnabled(false)
|
||||
|
||||
self:SetDeleteOnClose(false)
|
||||
|
||||
self:SetTitle("Change level")
|
||||
self:SetSize(630, ScrH() * 0.8)
|
||||
|
||||
self.gamemodeList = {}
|
||||
self.mapList = {}
|
||||
|
||||
self.catList = vgui.Create("DCategoryList", self)
|
||||
self.catList:Dock(FILL)
|
||||
|
||||
self.topPanel = vgui.Create("DPanel", self)
|
||||
self.topPanel:SetPaintBackground(false)
|
||||
self.topPanel:DockMargin(0, 0, 0, 4)
|
||||
self.topPanel:Dock(TOP)
|
||||
self.gmLabel = vgui.Create("DLabel", self.topPanel)
|
||||
self.gmLabel:SetText("Gamemode:")
|
||||
self.gmLabel:Dock(LEFT)
|
||||
self.gmComboBox = vgui.Create("DComboBox", self.topPanel)
|
||||
self.gmComboBox:Dock(FILL)
|
||||
self.gmComboBox:SetValue("(current)")
|
||||
|
||||
self.bottomPanel = vgui.Create("DPanel", self)
|
||||
self.bottomPanel:SetPaintBackground(false)
|
||||
self.bottomPanel:DockMargin(0, 4, 0, 0)
|
||||
self.bottomPanel:Dock(BOTTOM)
|
||||
self.changeButton = vgui.Create("DButton", self.bottomPanel)
|
||||
self.changeButton:SetText("Change level")
|
||||
self.changeButton:Dock(RIGHT)
|
||||
self.changeButton:SetWidth(100)
|
||||
self.changeButton:SetEnabled(false)
|
||||
self.changeButton.DoClick = function()
|
||||
if not IsValid(self.selectedIconPanel) then return end
|
||||
local _,gmName = self.gmComboBox:GetSelected()
|
||||
local mapName = self.selectedIconPanel:GetText()
|
||||
RunConsoleCommand("_FAdmin", "Changelevel", gmName and gmName or mapName, gmName and mapName)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Refresh()
|
||||
for _, gmInfo in ipairs(self:GetGamemodeList()) do
|
||||
self.gmComboBox:AddChoice(gmInfo.title, gmInfo.name)
|
||||
end
|
||||
self.gmComboBox:SetValue("(current)")
|
||||
|
||||
for catName, maps in pairs(self:GetMapList()) do
|
||||
local cat = self.catList:Add(catName)
|
||||
local iconLayout = vgui.Create("DIconLayout")
|
||||
iconLayout:SetSpaceX(5)
|
||||
iconLayout:SetSpaceY(5)
|
||||
for _, map in ipairs(maps) do
|
||||
local icon = iconLayout:Add("FAdmin_MapIcon")
|
||||
icon:SetText(map)
|
||||
icon:SetDark(true)
|
||||
local mat = Material("maps/thumb/" .. map .. ".png")
|
||||
if mat:IsError() then mat = Material("maps/thumb/noicon.png") end
|
||||
icon:SetMaterial(mat)
|
||||
local onToggled = icon.OnToggled
|
||||
icon.OnToggled = function(iconSelf, selected)
|
||||
onToggled(iconSelf, selected)
|
||||
if IsValid(self.selectedIconPanel) then
|
||||
if selected and self.selectedIconPanel ~= iconSelf then
|
||||
self.selectedIconPanel:Toggle()
|
||||
elseif not selected and self.selectedIconPanel == iconSelf then
|
||||
self.selectedIconPanel = nil
|
||||
self.changeButton:SetEnabled(false)
|
||||
return
|
||||
end
|
||||
end
|
||||
self.selectedIconPanel = iconSelf
|
||||
self.changeButton:SetEnabled(true)
|
||||
end
|
||||
end
|
||||
cat:SetContents(iconLayout)
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("FAdmin_Changelevel", PANEL, "DFrame")
|
||||
@@ -0,0 +1,46 @@
|
||||
local mapList = {}
|
||||
local gamemodeList = {}
|
||||
net.Receive("FAdmin_ChangelevelInfo", function(len)
|
||||
mapList = {}
|
||||
local mapLen = net.ReadUInt(16)
|
||||
|
||||
for i = 1, mapLen, 1 do
|
||||
local cat = net.ReadString()
|
||||
mapList[cat] = {}
|
||||
local catLen = net.ReadUInt(16)
|
||||
|
||||
for j = 1, catLen, 1 do
|
||||
mapList[cat][j] = net.ReadString()
|
||||
end
|
||||
end
|
||||
|
||||
gamemodeList = {}
|
||||
local gmLen = net.ReadUInt(16)
|
||||
|
||||
for i = 1, gmLen, 1 do
|
||||
gamemodeList[i] = {
|
||||
name = net.ReadString(),
|
||||
title = net.ReadString()
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
local Changelevel
|
||||
FAdmin.StartHooks["ChangeLevel"] = function()
|
||||
FAdmin.Access.AddPrivilege("changelevel", 2)
|
||||
FAdmin.Commands.AddCommand("changelevel", "[gamemode]", "<map>")
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerAction("Changelevel", "icon16/world.png", Color(155, 0, 0, 255), function() return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "changelevel") end,
|
||||
function(ply, button)
|
||||
local refresh = not Changelevel or table.Count(Changelevel:GetMapList()) ~= table.Count(mapList)
|
||||
Changelevel = Changelevel or vgui.Create("FAdmin_Changelevel")
|
||||
if refresh then
|
||||
Changelevel:SetGamemodeList(gamemodeList)
|
||||
Changelevel:SetMapList(mapList)
|
||||
Changelevel:Refresh()
|
||||
end
|
||||
Changelevel:SetVisible(true)
|
||||
Changelevel:Center()
|
||||
Changelevel:MakePopup()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,43 @@
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.BaseClass.Init(self)
|
||||
self:SetPaintBackground(true)
|
||||
self:SetIsToggle(true)
|
||||
self:SetSize(96, 110)
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
if self.m_bToggle then
|
||||
surface.SetDrawColor(255, 155, 20, 255)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:UpdateColours(skin)
|
||||
return self:SetTextStyleColor(skin.Colours.Button.Normal)
|
||||
end
|
||||
|
||||
function PANEL:OnToggled(selected)
|
||||
self:InvalidateLayout(true)
|
||||
end
|
||||
|
||||
function PANEL:OnMousePressed(code)
|
||||
DButton.OnMousePressed(self, code)
|
||||
end
|
||||
|
||||
function PANEL:OnMouseReleased(code)
|
||||
DButton.OnMouseReleased(self, code)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.m_Image:SetPos(0, 0)
|
||||
local w,h = self:GetSize()
|
||||
h = h - 14
|
||||
self.m_Image:SetSize(w, h)
|
||||
self:SetTextInset(5, w / 2)
|
||||
DLabel.PerformLayout(self)
|
||||
end
|
||||
|
||||
vgui.Register("FAdmin_MapIcon", PANEL, "DImageButton")
|
||||
@@ -0,0 +1,266 @@
|
||||
util.AddNetworkString("FAdmin_ChangelevelInfo")
|
||||
|
||||
local function ChangeLevel(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "changelevel") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local map = args[2] or args[1] -- Changelevel gamemode map OR changelevel map
|
||||
local gameMode = args[2] and args[1]
|
||||
|
||||
if gameMode then
|
||||
RunConsoleCommand("gamemode", gameMode)
|
||||
end
|
||||
|
||||
RunConsoleCommand("changelevel", map)
|
||||
|
||||
return true, map, gameMode
|
||||
end
|
||||
|
||||
local mapNames = {}
|
||||
local mapPatterns = {}
|
||||
|
||||
local ignorePatterns = {
|
||||
"^asi-", "^background", "^c[%d]m", "^devtest", "^ep1_background", "^ep2_background", "^mp_coop_", "^sp_a", "^styleguide"
|
||||
}
|
||||
|
||||
local ignoreMaps = {
|
||||
-- Prefixes
|
||||
["ddd_"] = true,
|
||||
["sdk_"] = true,
|
||||
["test_"] = true,
|
||||
["vst_"] = true,
|
||||
-- Maps
|
||||
["c4a1y"] = true,
|
||||
["cp_docks"] = true,
|
||||
["cp_parkour"] = true,
|
||||
["cp_sequence"] = true,
|
||||
["cp_terrace"] = true,
|
||||
["cp_test"] = true,
|
||||
["credits"] = true,
|
||||
["curling_stadium"] = true,
|
||||
["d2_coast_02"] = true,
|
||||
["d3_c17_02_camera"] = true,
|
||||
["duel_"] = true,
|
||||
["e1912"] = true,
|
||||
["ep1_citadel_00_demo"] = true,
|
||||
["ffa_community"] = true,
|
||||
["free_"] = true,
|
||||
["intro"] = true,
|
||||
["lobby"] = true,
|
||||
["practice_box"] = true,
|
||||
["test"] = true,
|
||||
["tut_training"] = true,
|
||||
["tutorial_standards"] = true,
|
||||
["tutorial_standards_vs"] = true
|
||||
}
|
||||
|
||||
hook.Add("PlayerInitialSpawn", "FAdmin_ChangelevelInfo", function(ply)
|
||||
local mapList = {}
|
||||
local maps = file.Find("maps/*.bsp", "GAME")
|
||||
|
||||
for _, v in ipairs(maps) do
|
||||
local name = string.lower(string.gsub(v, "%.bsp$", ""))
|
||||
if ignoreMaps[name] then continue end
|
||||
|
||||
local prefix = string.match(name, "^(.-_)")
|
||||
if ignoreMaps[prefix] then continue end
|
||||
|
||||
for _, ignore in ipairs(ignorePatterns) do
|
||||
if string.find(name, ignore) then
|
||||
goto mapContinue
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if the map has a simple name or prefix
|
||||
local mapCategory = mapNames[name] or mapNames[prefix]
|
||||
|
||||
-- Check if the map has an embedded prefix, or is TTT/Sandbox
|
||||
if not mapCategory then
|
||||
for pattern, category in pairs(mapPatterns) do
|
||||
if string.find(name, pattern) then
|
||||
mapCategory = category
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Throw all uncategorized maps into Other
|
||||
mapCategory = mapCategory or "Other"
|
||||
-- Don't show CS:GO maps
|
||||
if mapCategory == "Counter-Strike" and not file.Exists("maps/" .. name .. ".bsp", "cstrike") then
|
||||
continue
|
||||
end
|
||||
|
||||
if not mapList[mapCategory] then
|
||||
mapList[mapCategory] = {}
|
||||
end
|
||||
|
||||
table.insert(mapList[mapCategory], name)
|
||||
::mapContinue::
|
||||
end
|
||||
|
||||
local gamemodeList = engine.GetGamemodes()
|
||||
net.Start("FAdmin_ChangelevelInfo")
|
||||
net.WriteUInt(table.Count(mapList), 16) -- 65536 should be enough
|
||||
for cat, mps in pairs(mapList) do
|
||||
net.WriteString(cat)
|
||||
net.WriteUInt(#mps, 16)
|
||||
for _, map in pairs(mps) do
|
||||
net.WriteString(map)
|
||||
end
|
||||
end
|
||||
net.WriteUInt(#gamemodeList, 16)
|
||||
for _, gmInfo in ipairs(gamemodeList) do
|
||||
net.WriteString(gmInfo.name)
|
||||
net.WriteString(gmInfo.title)
|
||||
end
|
||||
net.Send(ply)
|
||||
end)
|
||||
|
||||
FAdmin.StartHooks["ChangeLevel"] = function()
|
||||
FAdmin.Commands.AddCommand("changelevel", ChangeLevel)
|
||||
|
||||
FAdmin.Access.AddPrivilege("changelevel", 2)
|
||||
|
||||
mapNames = {}
|
||||
mapPatterns = {}
|
||||
|
||||
mapNames["aoc_"] = "Age of Chivalry"
|
||||
|
||||
mapNames["ar_"] = "Counter-Strike"
|
||||
mapNames["cs_"] = "Counter-Strike"
|
||||
mapNames["de_"] = "Counter-Strike"
|
||||
mapNames["es_"] = "Counter-Strike"
|
||||
mapNames["fy_"] = "Counter-Strike"
|
||||
mapNames["gd_"] = "Counter-Strike"
|
||||
mapNames["training1"] = "Counter-Strike"
|
||||
|
||||
mapNames["dod_"] = "Day Of Defeat"
|
||||
|
||||
mapNames["de_dam"] = "DIPRIP"
|
||||
mapNames["dm_city"] = "DIPRIP"
|
||||
mapNames["dm_refinery"] = "DIPRIP"
|
||||
mapNames["dm_supermarket"] = "DIPRIP"
|
||||
mapNames["dm_village"] = "DIPRIP"
|
||||
mapNames["ur_city"] = "DIPRIP"
|
||||
mapNames["ur_refinery"] = "DIPRIP"
|
||||
mapNames["ur_supermarket"] = "DIPRIP"
|
||||
mapNames["ur_village"] = "DIPRIP"
|
||||
|
||||
mapNames["dys_"] = "Dystopia"
|
||||
mapNames["pb_dojo"] = "Dystopia"
|
||||
mapNames["pb_rooftop"] = "Dystopia"
|
||||
mapNames["pb_round"] = "Dystopia"
|
||||
mapNames["pb_urbandome"] = "Dystopia"
|
||||
mapNames["sav_dojo6"] = "Dystopia"
|
||||
mapNames["varena"] = "Dystopia"
|
||||
|
||||
mapNames["d1_"] = "Half-Life 2"
|
||||
mapNames["d2_"] = "Half-Life 2"
|
||||
mapNames["d3_"] = "Half-Life 2"
|
||||
|
||||
mapNames["dm_"] = "Half-Life 2: Deathmatch"
|
||||
mapNames["halls3"] = "Half-Life 2: Deathmatch"
|
||||
|
||||
mapNames["ep1_"] = "Half-Life 2: Episode 1"
|
||||
mapNames["ep2_"] = "Half-Life 2: Episode 2"
|
||||
mapNames["ep3_"] = "Half-Life 2: Episode 3"
|
||||
|
||||
mapNames["d2_lostcoast"] = "Half-Life 2: Lost Coast"
|
||||
|
||||
mapPatterns["^c[%d]a"] = "Half-Life"
|
||||
mapPatterns["^t0a"] = "Half-Life"
|
||||
|
||||
mapNames["boot_camp"] = "Half-Life Deathmatch"
|
||||
mapNames["bounce"] = "Half-Life Deathmatch"
|
||||
mapNames["crossfire"] = "Half-Life Deathmatch"
|
||||
mapNames["datacore"] = "Half-Life Deathmatch"
|
||||
mapNames["frenzy"] = "Half-Life Deathmatch"
|
||||
mapNames["lambda_bunker"] = "Half-Life Deathmatch"
|
||||
mapNames["rapidcore"] = "Half-Life Deathmatch"
|
||||
mapNames["snarkpit"] = "Half-Life Deathmatch"
|
||||
mapNames["stalkyard"] = "Half-Life Deathmatch"
|
||||
mapNames["subtransit"] = "Half-Life Deathmatch"
|
||||
mapNames["undertow"] = "Half-Life Deathmatch"
|
||||
|
||||
mapNames["ins_"] = "Insurgency"
|
||||
|
||||
mapNames["l4d_"] = "Left 4 Dead"
|
||||
|
||||
mapNames["clocktower"] = "Nuclear Dawn"
|
||||
mapNames["coast"] = "Nuclear Dawn"
|
||||
mapNames["downtown"] = "Nuclear Dawn"
|
||||
mapNames["gate"] = "Nuclear Dawn"
|
||||
mapNames["hydro"] = "Nuclear Dawn"
|
||||
mapNames["metro"] = "Nuclear Dawn"
|
||||
mapNames["metro_training"] = "Nuclear Dawn"
|
||||
mapNames["oasis"] = "Nuclear Dawn"
|
||||
mapNames["oilfield"] = "Nuclear Dawn"
|
||||
mapNames["silo"] = "Nuclear Dawn"
|
||||
mapNames["sk_metro"] = "Nuclear Dawn"
|
||||
mapNames["training"] = "Nuclear Dawn"
|
||||
|
||||
mapNames["bt_"] = "Pirates, Vikings, & Knights II"
|
||||
mapNames["lts_"] = "Pirates, Vikings, & Knights II"
|
||||
mapNames["te_"] = "Pirates, Vikings, & Knights II"
|
||||
mapNames["tw_"] = "Pirates, Vikings, & Knights II"
|
||||
|
||||
mapNames["escape_"] = "Portal"
|
||||
mapNames["testchmb_"] = "Portal"
|
||||
|
||||
mapNames["achievement_"] = "Team Fortress 2"
|
||||
mapNames["arena_"] = "Team Fortress 2"
|
||||
mapNames["cp_"] = "Team Fortress 2"
|
||||
mapNames["ctf_"] = "Team Fortress 2"
|
||||
mapNames["itemtest"] = "Team Fortress 2"
|
||||
mapNames["koth_"] = "Team Fortress 2"
|
||||
mapNames["mvm_"] = "Team Fortress 2"
|
||||
mapNames["pl_"] = "Team Fortress 2"
|
||||
mapNames["plr_"] = "Team Fortress 2"
|
||||
mapNames["rd_"] = "Team Fortress 2"
|
||||
mapNames["pd_"] = "Team Fortress 2"
|
||||
mapNames["sd_"] = "Team Fortress 2"
|
||||
mapNames["tc_"] = "Team Fortress 2"
|
||||
mapNames["tr_"] = "Team Fortress 2"
|
||||
mapNames["trade_"] = "Team Fortress 2"
|
||||
mapNames["pass_"] = "Team Fortress 2"
|
||||
|
||||
mapNames["zpa_"] = "Zombie Panic! Source"
|
||||
mapNames["zpl_"] = "Zombie Panic! Source"
|
||||
mapNames["zpo_"] = "Zombie Panic! Source"
|
||||
mapNames["zps_"] = "Zombie Panic! Source"
|
||||
|
||||
mapNames["bhop_"] = "Bunny Hop"
|
||||
mapNames["cinema_"] = "Cinema"
|
||||
mapNames["theater_"] = "Cinema"
|
||||
mapNames["xc_"] = "Climb"
|
||||
mapNames["deathrun_"] = "Deathrun"
|
||||
mapNames["dr_"] = "Deathrun"
|
||||
mapNames["fm_"] = "Flood"
|
||||
mapNames["gmt_"] = "GMod Tower"
|
||||
mapNames["gg_"] = "Gun Game"
|
||||
mapNames["scoutzknivez"] = "Gun Game"
|
||||
mapNames["ba_"] = "Jailbreak"
|
||||
mapNames["jail_"] = "Jailbreak"
|
||||
mapNames["jb_"] = "Jailbreak"
|
||||
mapNames["mg_"] = "Minigames"
|
||||
mapNames["pw_"] = "Pirate Ship Wars"
|
||||
mapNames["ph_"] = "Prop Hunt"
|
||||
mapNames["rp_"] = "Roleplay"
|
||||
mapNames["slb_"] = "Sled Build"
|
||||
mapNames["sb_"] = "Spacebuild"
|
||||
mapNames["slender_"] = "Stop it Slender"
|
||||
mapNames["gms_"] = "Stranded"
|
||||
mapNames["surf_"] = "Surf"
|
||||
mapNames["ts_"] = "The Stalker"
|
||||
mapNames["zm_"] = "Zombie Survival"
|
||||
mapNames["zombiesurvival_"] = "Zombie Survival"
|
||||
mapNames["zs_"] = "Zombie Survival"
|
||||
|
||||
for _, gm in ipairs(engine.GetGamemodes()) do
|
||||
if gm.maps ~= "" then
|
||||
for _, pattern in ipairs(string.Split(gm.maps, "|")) do
|
||||
-- When in doubt, just try to match it with string.find later
|
||||
mapPatterns[string.lower(pattern)] = gm.title or "Unnammed Gamemode"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
local function SortedPairsByFunction(Table, Sorted, SortDown)
|
||||
local CopyTable = {}
|
||||
for _, v in pairs(Table) do
|
||||
table.insert(CopyTable, {NAME = tostring(v:Nick()), PLY = v})
|
||||
end
|
||||
table.SortByMember(CopyTable, "NAME", SortDown)
|
||||
|
||||
local SortedTable = {}
|
||||
for _, v in ipairs(CopyTable) do
|
||||
if not IsValid(v.PLY) or not v.PLY[Sorted] then continue end
|
||||
local SortBy = (Sorted ~= "Team" and v.PLY[Sorted](v.PLY)) or (v.PLY:getDarkRPVar("job") or team.GetName(v.PLY[Sorted](v.PLY)))
|
||||
SortedTable[SortBy] = SortedTable[SortBy] or {}
|
||||
table.insert(SortedTable[SortBy], v.PLY)
|
||||
end
|
||||
|
||||
local SecondSort = {}
|
||||
for _, v in SortedPairs(SortedTable, SortDown) do
|
||||
table.insert(SecondSort, v)
|
||||
end
|
||||
|
||||
CopyTable = {}
|
||||
for _, v in ipairs(SecondSort) do
|
||||
for _, b in pairs(v) do
|
||||
table.insert(CopyTable, b)
|
||||
end
|
||||
end
|
||||
|
||||
return ipairs(CopyTable)
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Main.PlayerListView(Sorted, SortDown)
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:Clear(true)
|
||||
for _, ply in SortedPairsByFunction(player.GetAll(), Sorted, SortDown) do
|
||||
local Row = vgui.Create("FadminPlayerRow")
|
||||
Row:SetPlayer(ply)
|
||||
Row:Dock(TOP)
|
||||
Row:InvalidateLayout()
|
||||
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:AddItem(Row)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,308 @@
|
||||
FAdmin.PlayerIcon = {}
|
||||
FAdmin.PlayerIcon.RightClickOptions = {}
|
||||
|
||||
function FAdmin.PlayerIcon.AddRightClickOption(name, func)
|
||||
FAdmin.PlayerIcon.RightClickOptions[name] = func
|
||||
end
|
||||
|
||||
-- FAdminPanelList
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.Padding = 5
|
||||
end
|
||||
|
||||
function PANEL:SizeToContents()
|
||||
local w, h = self:GetSize()
|
||||
|
||||
-- Fix size of w to have the same size as the scoreboard
|
||||
w = math.Clamp(w, ScrW() * 0.9, ScrW() * 0.9)
|
||||
h = math.Min(h, ScrH() * 0.95)
|
||||
|
||||
-- It fucks up when there's only one icon in
|
||||
if #self:GetChildren() == 1 then
|
||||
h = math.Max(0, 120)
|
||||
end
|
||||
|
||||
self:SetSize(w, h)
|
||||
self:PerformLayout()
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
end
|
||||
|
||||
derma.DefineControl("FAdminPanelList", "DPanellist adapted for FAdmin", PANEL, "DPanelList")
|
||||
|
||||
-- FAdminPlayerCatagoryHeader
|
||||
local PANEL2 = {}
|
||||
|
||||
function PANEL2:PerformLayout()
|
||||
self:SetFont("Trebuchet24")
|
||||
end
|
||||
|
||||
derma.DefineControl("FAdminPlayerCatagoryHeader", "DCatagoryCollapse header adapted for FAdmin", PANEL2, "DCategoryHeader")
|
||||
|
||||
-- FAdminPlayerCatagory
|
||||
local PANEL3 = {}
|
||||
|
||||
function PANEL3:Init()
|
||||
if self.Header then
|
||||
self.Header:Remove() -- the old header is still there don't ask me why
|
||||
end
|
||||
self.Header = vgui.Create("FAdminPlayerCatagoryHeader", self)
|
||||
self.Header:SetSize(20, 25)
|
||||
self:SetPadding(5)
|
||||
self.Header:Dock(TOP)
|
||||
|
||||
self:SetExpanded(true)
|
||||
self:SetMouseInputEnabled(true)
|
||||
|
||||
self:SetAnimTime(0.2)
|
||||
self.animSlide = Derma_Anim("Anim", self, self.AnimSlide)
|
||||
|
||||
self:SetPaintBackgroundEnabled(true)
|
||||
|
||||
end
|
||||
|
||||
function PANEL3:Paint()
|
||||
if self.CatagoryColor then
|
||||
draw.RoundedBox(4, 0, 0, self:GetWide(), self.Header:GetTall(), self.CatagoryColor)
|
||||
end
|
||||
end
|
||||
|
||||
derma.DefineControl("FAdminPlayerCatagory", "DCatagoryCollapse adapted for FAdmin", PANEL3, "DCollapsibleCategory")
|
||||
|
||||
-- FAdmin player row (from the sandbox player row)
|
||||
PANEL = {}
|
||||
|
||||
local PlayerRowSize = CreateClientConVar("FAdmin_PlayerRowSize", 30, true, false)
|
||||
function PANEL:Init()
|
||||
self.Size = PlayerRowSize:GetInt()
|
||||
|
||||
self.lblName = vgui.Create("DLabel", self)
|
||||
self.lblFrags = vgui.Create("DLabel", self)
|
||||
self.lblTeam = vgui.Create("DLabel", self)
|
||||
self.lblDeaths = vgui.Create("DLabel", self)
|
||||
self.lblPing = vgui.Create("DLabel", self)
|
||||
self.lblWanted = vgui.Create("DLabel", self)
|
||||
|
||||
-- If you don't do this it'll block your clicks
|
||||
self.lblName:SetMouseInputEnabled(false)
|
||||
self.lblTeam:SetMouseInputEnabled(false)
|
||||
self.lblFrags:SetMouseInputEnabled(false)
|
||||
self.lblDeaths:SetMouseInputEnabled(false)
|
||||
self.lblPing:SetMouseInputEnabled(false)
|
||||
self.lblWanted:SetMouseInputEnabled(false)
|
||||
|
||||
self.lblName:SetColor(Color(255,255,255,200))
|
||||
self.lblTeam:SetColor(Color(255,255,255,200))
|
||||
self.lblFrags:SetColor(Color(255,255,255,200))
|
||||
self.lblDeaths:SetColor(Color(255,255,255,200))
|
||||
self.lblPing:SetColor(Color(255,255,255,200))
|
||||
self.lblWanted:SetColor(Color(255,255,255,200))
|
||||
|
||||
self.imgAvatar = vgui.Create("AvatarImage", self)
|
||||
|
||||
self:SetCursor("hand")
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
if not IsValid(self.Player) then return end
|
||||
|
||||
self.Size = PlayerRowSize:GetInt()
|
||||
self.imgAvatar:SetSize(self.Size - 4, self.Size - 4)
|
||||
|
||||
local color = Color(100, 150, 245, 255)
|
||||
|
||||
|
||||
if GAMEMODE.Name == "Sandbox" then
|
||||
color = Color(100, 150, 245, 255)
|
||||
if self.Player:Team() == TEAM_CONNECTING then
|
||||
color = Color(200, 120, 50, 255)
|
||||
elseif self.Player:IsAdmin() then
|
||||
color = Color(30, 200, 50, 255)
|
||||
end
|
||||
|
||||
if self.Player:GetFriendStatus() == "friend" then
|
||||
color = Color(236, 181, 113, 255)
|
||||
end
|
||||
else
|
||||
color = team.GetColor(self.Player:Team())
|
||||
end
|
||||
|
||||
local hooks = hook.GetTable().FAdmin_PlayerRowColour
|
||||
if hooks then
|
||||
for _, v in pairs(hooks) do
|
||||
color = (v and v(self.Player, color)) or color
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
draw.RoundedBox(4, 0, 0, self:GetWide(), self.Size, color)
|
||||
|
||||
surface.SetTexture(0)
|
||||
if self.Player == LocalPlayer() or self.Player:GetFriendStatus() == "friend" then
|
||||
surface.SetDrawColor(255, 255, 255, 50 + math.sin(RealTime() * 2) * 50)
|
||||
end
|
||||
surface.DrawTexturedRect(0, 0, self:GetWide(), self.Size)
|
||||
return true
|
||||
end
|
||||
|
||||
function PANEL:SetPlayer(ply)
|
||||
self.Player = ply
|
||||
|
||||
self.imgAvatar:SetPlayer(ply)
|
||||
|
||||
self:UpdatePlayerData()
|
||||
end
|
||||
|
||||
function PANEL:UpdatePlayerData()
|
||||
if not self.Player then return end
|
||||
if not self.Player:IsValid() then return end
|
||||
|
||||
self.lblName:SetText(DarkRP.deLocalise(self.Player:Nick()))
|
||||
self.lblTeam:SetText((self.Player.DarkRPVars and DarkRP.deLocalise(self.Player:getDarkRPVar("job") or "")) or team.GetName(self.Player:Team()))
|
||||
self.lblTeam:SizeToContents()
|
||||
self.lblFrags:SetText(self.Player:Frags())
|
||||
self.lblDeaths:SetText(self.Player:Deaths())
|
||||
self.lblPing:SetText(self.Player:Ping())
|
||||
self.lblWanted:SetText(self.Player:isWanted() and DarkRP.getPhrase("Wanted_text") or "")
|
||||
end
|
||||
|
||||
function PANEL:ApplySchemeSettings()
|
||||
self.lblName:SetFont("ScoreboardPlayerNameBig")
|
||||
self.lblTeam:SetFont("ScoreboardPlayerNameBig")
|
||||
self.lblFrags:SetFont("ScoreboardPlayerName")
|
||||
self.lblDeaths:SetFont("ScoreboardPlayerName")
|
||||
self.lblPing:SetFont("ScoreboardPlayerName")
|
||||
self.lblWanted:SetFont("ScoreboardPlayerNameBig")
|
||||
|
||||
self.lblName:SetFGColor(color_white)
|
||||
self.lblTeam:SetFGColor(color_white)
|
||||
self.lblFrags:SetFGColor(color_white)
|
||||
self.lblDeaths:SetFGColor(color_white)
|
||||
self.lblPing:SetFGColor(color_white)
|
||||
self.lblWanted:SetFGColor(color_white)
|
||||
end
|
||||
|
||||
function PANEL:DoClick(x, y)
|
||||
if not IsValid(self.Player) then self:Remove() return end
|
||||
FAdmin.ScoreBoard.ChangeView("Player", self.Player)
|
||||
end
|
||||
|
||||
function PANEL:DoRightClick()
|
||||
if table.IsEmpty(FAdmin.PlayerIcon.RightClickOptions) then return end
|
||||
local menu = DermaMenu()
|
||||
|
||||
menu:SetPos(gui.MouseX(), gui.MouseY())
|
||||
|
||||
for Name, func in SortedPairs(FAdmin.PlayerIcon.RightClickOptions) do
|
||||
menu:AddOption(Name, function() if IsValid(self.Player) then func(self.Player, self) end end)
|
||||
end
|
||||
|
||||
menu:Open()
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
if not self.PlayerUpdate or self.PlayerUpdate < CurTime() then
|
||||
self.PlayerUpdate = CurTime() + 0.5
|
||||
self:UpdatePlayerData()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.imgAvatar:SetPos(2, 2)
|
||||
self.imgAvatar:SetSize(32, 32)
|
||||
|
||||
self:SetSize(self:GetWide(), self.Size)
|
||||
|
||||
self.lblName:SizeToContents()
|
||||
self.lblName:SetPos(24, 2)
|
||||
self.lblName:MoveRightOf(self.imgAvatar, 8)
|
||||
|
||||
local COLUMN_SIZE = 75
|
||||
|
||||
self.lblPing:SetPos(self:GetWide() - COLUMN_SIZE * 0.4, 0)
|
||||
self.lblDeaths:SetPos(self:GetWide() - COLUMN_SIZE * 1.4, 0)
|
||||
self.lblFrags:SetPos(self:GetWide() - COLUMN_SIZE * 2.4, 0)
|
||||
|
||||
self.lblTeam:SetPos(self:GetWide() / 2 - (0.5 * self.lblTeam:GetWide()))
|
||||
|
||||
self.lblWanted:SizeToContents()
|
||||
self.lblWanted:SetPos(math.floor(self:GetWide() / 4), 2)
|
||||
end
|
||||
vgui.Register("FadminPlayerRow", PANEL, "Button")
|
||||
|
||||
-- FAdminActionButton
|
||||
local PANEL6 = {}
|
||||
|
||||
function PANEL6:Init()
|
||||
self:SetDrawBackground(false)
|
||||
self:SetDrawBorder(false)
|
||||
self:SetStretchToFit(false)
|
||||
self:SetSize(120, 40)
|
||||
|
||||
self.TextLabel = vgui.Create("DLabel", self)
|
||||
self.TextLabel:SetColor(Color(200,200,200,200))
|
||||
self.TextLabel:SetFont("Roboto20")
|
||||
|
||||
self.m_Image2 = vgui.Create("DImage", self)
|
||||
|
||||
self.BorderColor = Color(190,40,0,255)
|
||||
end
|
||||
|
||||
function PANEL6:SetText(text)
|
||||
self.TextLabel:SetText(text)
|
||||
self.TextLabel:SizeToContents()
|
||||
|
||||
self:SetWide(self.TextLabel:GetWide() + 44)
|
||||
end
|
||||
|
||||
function PANEL6:PerformLayout()
|
||||
self.m_Image:SetSize(32,32)
|
||||
self.m_Image:SetPos(4,4)
|
||||
|
||||
self.m_Image2:SetSize(32, 32)
|
||||
self.m_Image2:SetPos(4,4)
|
||||
|
||||
self.TextLabel:SetPos(38, 8)
|
||||
end
|
||||
|
||||
function PANEL6:SetImage2(Mat, bckp)
|
||||
self.m_Image2:SetImage(Mat, bckp)
|
||||
end
|
||||
|
||||
function PANEL6:SetBorderColor(Col)
|
||||
self.BorderColor = Col or Color(190,40,0,255)
|
||||
end
|
||||
|
||||
function PANEL6:Paint()
|
||||
local BorderColor = self.BorderColor
|
||||
if self.Hovered then
|
||||
BorderColor = Color(math.Min(BorderColor.r + 40, 255), math.Min(BorderColor.g + 40, 255), math.Min(BorderColor.b + 40, 255), BorderColor.a)
|
||||
end
|
||||
if self.Depressed then
|
||||
BorderColor = color_transparent
|
||||
end
|
||||
draw.RoundedBox(4, 0, 0, self:GetWide(), self:GetTall(), BorderColor)
|
||||
draw.RoundedBox(4, 2, 2, self:GetWide() - 4, self:GetTall() - 4, Color(40, 40, 40, 255))
|
||||
end
|
||||
|
||||
function PANEL6:OnMousePressed(mouse)
|
||||
if self:GetDisabled() then return end
|
||||
|
||||
self.m_Image:SetSize(24,24)
|
||||
self.m_Image:SetPos(8,8)
|
||||
self.Depressed = true
|
||||
end
|
||||
|
||||
function PANEL6:OnMouseReleased(mouse)
|
||||
if self:GetDisabled() then return end
|
||||
|
||||
self.m_Image:SetSize(32,32)
|
||||
self.m_Image:SetPos(4,4)
|
||||
self.Depressed = false
|
||||
self:DoClick()
|
||||
end
|
||||
|
||||
derma.DefineControl("FAdminActionButton", "Button for doing actions", PANEL6, "DImageButton")
|
||||
@@ -0,0 +1,146 @@
|
||||
local OverrideScoreboard = CreateClientConVar("FAdmin_OverrideScoreboard", 0, true, false) -- Set if it's a scoreboard or not
|
||||
|
||||
function FAdmin.ScoreBoard.ChangeView(newView, ...)
|
||||
if FAdmin.ScoreBoard.CurrentView == newView or not FAdmin.ScoreBoard.Visible then return end
|
||||
|
||||
for _, v in pairs(FAdmin.ScoreBoard[FAdmin.ScoreBoard.CurrentView].Controls) do
|
||||
v:SetVisible(false)
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.CurrentView = newView
|
||||
FAdmin.ScoreBoard[newView].Show(...)
|
||||
FAdmin.ScoreBoard.ChangeGmodLogo(FAdmin.ScoreBoard[newView].Logo)
|
||||
|
||||
FAdmin.ScoreBoard.Controls.BackButton = FAdmin.ScoreBoard.Controls.BackButton or vgui.Create("DButton")
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetVisible(true)
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetPos(FAdmin.ScoreBoard.X, FAdmin.ScoreBoard.Y)
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetText("")
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetTooltip("Click me to go back!")
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetCursor("hand")
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetSize(100,90)
|
||||
FAdmin.ScoreBoard.Controls.BackButton:SetZPos(999)
|
||||
|
||||
function FAdmin.ScoreBoard.Controls.BackButton:DoClick()
|
||||
FAdmin.ScoreBoard.ChangeView("Main")
|
||||
end
|
||||
FAdmin.ScoreBoard.Controls.BackButton.Paint = function() end
|
||||
end
|
||||
|
||||
--"fadmin/back", gui/gmod_tool
|
||||
local GmodLogo, TempGmodLogo, GmodLogoColor = surface.GetTextureID("gui/gmod_logo"), surface.GetTextureID("gui/gmod_logo"), color_white
|
||||
function FAdmin.ScoreBoard.ChangeGmodLogo(new)
|
||||
if surface.GetTextureID(new) == TempGmodLogo then return end
|
||||
TempGmodLogo = surface.GetTextureID(new)
|
||||
for i = 0, 0.5, 0.01 do
|
||||
timer.Simple(i, function() GmodLogoColor = Color(255,255,255,GmodLogoColor.a-5.1) end)
|
||||
end
|
||||
timer.Simple(0.5, function() GmodLogo = surface.GetTextureID(new) end)
|
||||
for i = 0.5, 1, 0.01 do
|
||||
timer.Simple(i, function()
|
||||
GmodLogoColor = Color(255, 255, 255, GmodLogoColor.a + 5.1)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Background()
|
||||
surface.SetDrawColor(0,0,0,200)
|
||||
surface.DrawRect(FAdmin.ScoreBoard.X, FAdmin.ScoreBoard.Y, FAdmin.ScoreBoard.Width, FAdmin.ScoreBoard.Height)
|
||||
|
||||
surface.SetTexture(GmodLogo)
|
||||
surface.SetDrawColor(255,255,255,GmodLogoColor.a)
|
||||
surface.DrawTexturedRect(FAdmin.ScoreBoard.X - 20, FAdmin.ScoreBoard.Y, 128, 128)
|
||||
end
|
||||
|
||||
|
||||
function FAdmin.ScoreBoard.DrawScoreBoard()
|
||||
if (input.IsMouseDown(MOUSE_4) or input.IsKeyDown(KEY_BACKSPACE)) and not FAdmin.ScoreBoard.DontGoBack then
|
||||
FAdmin.ScoreBoard.ChangeView("Main")
|
||||
elseif FAdmin.ScoreBoard.DontGoBack then
|
||||
FAdmin.ScoreBoard.DontGoBack = input.IsMouseDown(MOUSE_4) or input.IsKeyDown(KEY_BACKSPACE)
|
||||
end
|
||||
FAdmin.ScoreBoard.Background()
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.ShowScoreBoard()
|
||||
FAdmin.ScoreBoard.Visible = true
|
||||
FAdmin.ScoreBoard.DontGoBack = input.IsMouseDown(MOUSE_4) or input.IsKeyDown(KEY_BACKSPACE)
|
||||
|
||||
FAdmin.ScoreBoard.Controls.Hostname = FAdmin.ScoreBoard.Controls.Hostname or vgui.Create("DLabel")
|
||||
FAdmin.ScoreBoard.Controls.Hostname:SetText(DarkRP.deLocalise(GetHostName()))
|
||||
FAdmin.ScoreBoard.Controls.Hostname:SetFont("ScoreboardHeader")
|
||||
FAdmin.ScoreBoard.Controls.Hostname:SetColor(Color(200,200,200,200))
|
||||
FAdmin.ScoreBoard.Controls.Hostname:SetPos(FAdmin.ScoreBoard.X + 90, FAdmin.ScoreBoard.Y + 20)
|
||||
FAdmin.ScoreBoard.Controls.Hostname:SizeToContents()
|
||||
FAdmin.ScoreBoard.Controls.Hostname:SetVisible(true)
|
||||
|
||||
FAdmin.ScoreBoard.Controls.Description = FAdmin.ScoreBoard.Controls.Description or vgui.Create("DLabel")
|
||||
FAdmin.ScoreBoard.Controls.Description:SetText(string.format("%s\n%s", GAMEMODE.Name, GAMEMODE.Author))
|
||||
FAdmin.ScoreBoard.Controls.Description:SetFont("ScoreboardSubtitle")
|
||||
FAdmin.ScoreBoard.Controls.Description:SetColor(Color(200,200,200,200))
|
||||
FAdmin.ScoreBoard.Controls.Description:SetPos(FAdmin.ScoreBoard.X + 90, FAdmin.ScoreBoard.Y + 50)
|
||||
FAdmin.ScoreBoard.Controls.Description:SizeToContents()
|
||||
if FAdmin.ScoreBoard.X + FAdmin.ScoreBoard.Width / 9.5 + FAdmin.ScoreBoard.Controls.Description:GetWide() > FAdmin.ScoreBoard.Width - 150 then
|
||||
FAdmin.ScoreBoard.Controls.Description:SetFont("Trebuchet18")
|
||||
FAdmin.ScoreBoard.Controls.Description:SetPos(FAdmin.ScoreBoard.X + 90, FAdmin.ScoreBoard.Y + 50)
|
||||
end
|
||||
FAdmin.ScoreBoard.Controls.Description:SetVisible(true)
|
||||
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel = FAdmin.ScoreBoard.Controls.ServerSettingsLabel or vgui.Create("DLabel")
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel:SetFont("ScoreboardSubtitle")
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel:SetText("Server settings")
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel:SetColor(Color(200,200,200,200))
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel:SizeToContents()
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel:SetPos(FAdmin.ScoreBoard.Width-150, FAdmin.ScoreBoard.Y + 68)
|
||||
FAdmin.ScoreBoard.Controls.ServerSettingsLabel:SetVisible(true)
|
||||
|
||||
FAdmin.ScoreBoard.Controls.ServerSettings = FAdmin.ScoreBoard.Controls.ServerSettings or vgui.Create("DImageButton")
|
||||
FAdmin.ScoreBoard.Controls.ServerSettings:SetMaterial("vgui/gmod_tool")
|
||||
FAdmin.ScoreBoard.Controls.ServerSettings:SetPos(FAdmin.ScoreBoard.Width-200, FAdmin.ScoreBoard.Y - 20)
|
||||
FAdmin.ScoreBoard.Controls.ServerSettings:SizeToContents()
|
||||
FAdmin.ScoreBoard.Controls.ServerSettings:SetVisible(true)
|
||||
|
||||
function FAdmin.ScoreBoard.Controls.ServerSettings:DoClick()
|
||||
FAdmin.ScoreBoard.ChangeView("Server")
|
||||
end
|
||||
|
||||
if FAdmin.ScoreBoard.Controls.BackButton then FAdmin.ScoreBoard.Controls.BackButton:SetVisible(true) end
|
||||
|
||||
FAdmin.ScoreBoard[FAdmin.ScoreBoard.CurrentView].Show()
|
||||
|
||||
gui.EnableScreenClicker(true)
|
||||
hook.Add("HUDPaint", "FAdmin_ScoreBoard", FAdmin.ScoreBoard.DrawScoreBoard)
|
||||
hook.Call("FAdmin_ShowFAdminMenu")
|
||||
return true
|
||||
end
|
||||
concommand.Add("+FAdmin_menu", FAdmin.ScoreBoard.ShowScoreBoard)
|
||||
|
||||
hook.Add("ScoreboardShow", "FAdmin_scoreboard", function()
|
||||
if FAdmin.GlobalSetting.FAdmin or OverrideScoreboard:GetBool() then -- Don't show scoreboard when FAdmin is not installed on server
|
||||
return FAdmin.ScoreBoard.ShowScoreBoard()
|
||||
end
|
||||
end)
|
||||
|
||||
function FAdmin.ScoreBoard.HideScoreBoard()
|
||||
if not FAdmin.GlobalSetting.FAdmin then return end
|
||||
FAdmin.ScoreBoard.Visible = false
|
||||
CloseDermaMenus()
|
||||
|
||||
gui.EnableScreenClicker(false)
|
||||
hook.Remove("HUDPaint", "FAdmin_ScoreBoard")
|
||||
|
||||
for _, v in pairs(FAdmin.ScoreBoard[FAdmin.ScoreBoard.CurrentView].Controls) do
|
||||
v:SetVisible(false)
|
||||
end
|
||||
|
||||
for _, v in pairs(FAdmin.ScoreBoard.Controls) do
|
||||
v:SetVisible(false)
|
||||
end
|
||||
return true
|
||||
end
|
||||
concommand.Add("-FAdmin_menu", FAdmin.ScoreBoard.HideScoreBoard)
|
||||
|
||||
hook.Add("ScoreboardHide", "FAdmin_scoreboard", function()
|
||||
if FAdmin.GlobalSetting.FAdmin or OverrideScoreboard:GetBool() then -- Don't show scoreboard when FAdmin is not installed on server
|
||||
return FAdmin.ScoreBoard.HideScoreBoard()
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,110 @@
|
||||
local Sorted, SortDown = CreateClientConVar("FAdmin_SortPlayerList", "Team", true), CreateClientConVar("FAdmin_SortPlayerListDown", 1, true)
|
||||
local allowedSorts = {
|
||||
["Name"] = true,
|
||||
["Team"] = true,
|
||||
["Frags"] = true,
|
||||
["Deaths"] = true,
|
||||
["Ping"] = true
|
||||
}
|
||||
|
||||
function FAdmin.ScoreBoard.Main.Show()
|
||||
local Sort = {}
|
||||
local ScreenWidth, ScreenHeight = ScrW(), ScrH()
|
||||
|
||||
FAdmin.ScoreBoard.X = ScreenWidth * 0.05
|
||||
FAdmin.ScoreBoard.Y = ScreenHeight * 0.025
|
||||
FAdmin.ScoreBoard.Width = ScreenWidth * 0.9
|
||||
FAdmin.ScoreBoard.Height = ScreenHeight * 0.95
|
||||
|
||||
FAdmin.ScoreBoard.ChangeView("Main")
|
||||
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList = FAdmin.ScoreBoard.Main.Controls.FAdminPanelList or vgui.Create("DPanelList")
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:SetVisible(true)
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:Clear(true)
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList.Padding = 3
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:EnableVerticalScrollbar(true)
|
||||
|
||||
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:Clear(true)
|
||||
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:SetPos(FAdmin.ScoreBoard.X + 20, FAdmin.ScoreBoard.Y + 90 + 30 + 20)
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:SetSize(FAdmin.ScoreBoard.Width - 40, FAdmin.ScoreBoard.Height - 90 - 30 - 20 - 20)
|
||||
|
||||
Sort.Name = Sort.Name or vgui.Create("DLabel")
|
||||
Sort.Name:SetText("Sort by: Name")
|
||||
Sort.Name:SetPos(FAdmin.ScoreBoard.X + 20, FAdmin.ScoreBoard.Y + 90 + 30)
|
||||
Sort.Name.Type = "Name"
|
||||
Sort.Name:SetVisible(true)
|
||||
|
||||
Sort.Team = Sort.Team or vgui.Create("DLabel")
|
||||
Sort.Team:SetText("Team")
|
||||
Sort.Team:SetPos(ScreenWidth * 0.5 - 30, FAdmin.ScoreBoard.Y + 90 + 30)
|
||||
Sort.Team.Type = "Team"
|
||||
Sort.Team:SetVisible(true)
|
||||
|
||||
Sort.Frags = Sort.Frags or vgui.Create("DLabel")
|
||||
Sort.Frags:SetText("Kills")
|
||||
Sort.Frags:SetPos(FAdmin.ScoreBoard.X + FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:GetWide() - 200, FAdmin.ScoreBoard.Y + 90 + 30)
|
||||
Sort.Frags.Type = "Frags"
|
||||
Sort.Frags:SetVisible(true)
|
||||
|
||||
Sort.Deaths = Sort.Deaths or vgui.Create("DLabel")
|
||||
Sort.Deaths:SetText("Deaths")
|
||||
Sort.Deaths:SetPos(FAdmin.ScoreBoard.X + FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:GetWide() - 140, FAdmin.ScoreBoard.Y + 90 + 30)
|
||||
Sort.Deaths.Type = "Deaths"
|
||||
Sort.Deaths:SetVisible(true)
|
||||
|
||||
Sort.Ping = Sort.Ping or vgui.Create("DLabel")
|
||||
Sort.Ping:SetText("Ping")
|
||||
Sort.Ping:SetPos(FAdmin.ScoreBoard.X + FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:GetWide() - 50, FAdmin.ScoreBoard.Y + 90 + 30)
|
||||
Sort.Ping.Type = "Ping"
|
||||
Sort.Ping:SetVisible(true)
|
||||
|
||||
local sortBy = Sorted:GetString()
|
||||
sortBy = allowedSorts[sortBy] and sortBy or "Team"
|
||||
|
||||
FAdmin.ScoreBoard.Main.PlayerListView(sortBy, SortDown:GetBool())
|
||||
|
||||
for _, v in pairs(Sort) do
|
||||
v:SetFont("Trebuchet20")
|
||||
v:SizeToContents()
|
||||
|
||||
local X, Y = v:GetPos()
|
||||
|
||||
v.BtnSort = vgui.Create("DButton")
|
||||
v.BtnSort:SetText("")
|
||||
v.BtnSort.Type = "Down"
|
||||
v.BtnSort.Paint = function(panel, w, h) derma.SkinHook("Paint", "ButtonDown", panel, w, h) end
|
||||
v.BtnSort:SetSkin(GAMEMODE.Config.DarkRPSkin)
|
||||
if Sorted:GetString() == v.Type then
|
||||
v.BtnSort.Depressed = true
|
||||
v.BtnSort.Type = (SortDown:GetBool() and "Down") or "Up"
|
||||
end
|
||||
v.BtnSort:SetSize(16, 16)
|
||||
v.BtnSort:SetPos(X + v:GetWide() + 5, Y + 4)
|
||||
function v.BtnSort.DoClick()
|
||||
for _, b in pairs(Sort) do
|
||||
b.BtnSort.Depressed = b.BtnSort == v.BtnSort
|
||||
end
|
||||
v.BtnSort.Type = (v.BtnSort.Type == "Down" and "Up") or "Down"
|
||||
v.BtnSort.Paint = function(panel, w, h)
|
||||
derma.SkinHook("Paint", "Button" .. v.BtnSort.Type, panel, w, h)
|
||||
end
|
||||
|
||||
RunConsoleCommand("FAdmin_SortPlayerList", v.Type)
|
||||
RunConsoleCommand("FAdmin_SortPlayerListDown", (v.BtnSort.Type == "Down" and "1") or "0")
|
||||
FAdmin.ScoreBoard.Main.Controls.FAdminPanelList:Clear(true)
|
||||
FAdmin.ScoreBoard.Main.PlayerListView(v.Type, v.BtnSort.Type == "Down")
|
||||
end
|
||||
table.insert(FAdmin.ScoreBoard.Main.Controls, v) -- Add them to the table so they get removed when you close the scoreboard
|
||||
table.insert(FAdmin.ScoreBoard.Main.Controls, v.BtnSort)
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Main.AddPlayerRightClick(Name, func)
|
||||
FAdmin.PlayerIcon.RightClickOptions[Name] = func
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["CopySteamID"] = function()
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Copy SteamID", function(ply) SetClipboardText(ply:SteamID()) end)
|
||||
end
|
||||
@@ -0,0 +1,181 @@
|
||||
FAdmin.ScoreBoard.Player.Information = {}
|
||||
FAdmin.ScoreBoard.Player.ActionButtons = {}
|
||||
|
||||
function FAdmin.ScoreBoard.Player.Show(ply)
|
||||
ply = ply or FAdmin.ScoreBoard.Player.Player
|
||||
FAdmin.ScoreBoard.Player.Player = ply
|
||||
|
||||
if not IsValid(ply) or not IsValid(FAdmin.ScoreBoard.Player.Player) then FAdmin.ScoreBoard.ChangeView("Main") return end
|
||||
|
||||
local ScreenHeight = ScrH()
|
||||
|
||||
FAdmin.ScoreBoard.Player.Controls.AvatarBackground = vgui.Create("AvatarImage")
|
||||
FAdmin.ScoreBoard.Player.Controls.AvatarBackground:SetPos(FAdmin.ScoreBoard.X + 20, FAdmin.ScoreBoard.Y + 100)
|
||||
FAdmin.ScoreBoard.Player.Controls.AvatarBackground:SetSize(184, 184)
|
||||
FAdmin.ScoreBoard.Player.Controls.AvatarBackground:SetPlayer(ply, 184)
|
||||
FAdmin.ScoreBoard.Player.Controls.AvatarBackground:SetVisible(true)
|
||||
|
||||
FAdmin.ScoreBoard.Player.InfoPanels = FAdmin.ScoreBoard.Player.InfoPanels or {}
|
||||
for k, v in pairs(FAdmin.ScoreBoard.Player.InfoPanels) do
|
||||
if IsValid(v) then
|
||||
v:Remove()
|
||||
FAdmin.ScoreBoard.Player.InfoPanels[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(FAdmin.ScoreBoard.Player.Controls.InfoPanel1) then
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1:Remove()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1 = vgui.Create("DListLayout")
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1:SetPos(FAdmin.ScoreBoard.X + 20, FAdmin.ScoreBoard.Y + 100 + 184 + 5 --[[ + Avatar size]])
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1:SetSize(184, ScreenHeight * 0.1 + 2)
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1:SetVisible(true)
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1:Clear(true)
|
||||
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel2 = FAdmin.ScoreBoard.Player.Controls.InfoPanel2 or vgui.Create("FAdminPanelList")
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel2:SetPos(FAdmin.ScoreBoard.X + 25 + 184 --[[+ Avatar]], FAdmin.ScoreBoard.Y + 100)
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel2:SetSize(FAdmin.ScoreBoard.Width - 184 - 30 - 10, 184 + 5 + ScreenHeight * 0.1 + 2)
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel2:SetVisible(true)
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel2:Clear(true)
|
||||
|
||||
local function AddInfoPanel()
|
||||
local pan = FAdmin.ScoreBoard.Player.Controls.InfoPanel2:Add("DListLayout")
|
||||
pan:SetSize(1, FAdmin.ScoreBoard.Player.Controls.InfoPanel2:GetTall())
|
||||
|
||||
table.insert(FAdmin.ScoreBoard.Player.InfoPanels, pan)
|
||||
return pan
|
||||
end
|
||||
|
||||
local SelectedPanel = AddInfoPanel() -- Make first panel to put the first things in
|
||||
|
||||
for k, v in pairs(FAdmin.ScoreBoard.Player.Information) do
|
||||
SelectedPanel:Dock(LEFT)
|
||||
local Value = v.func(FAdmin.ScoreBoard.Player.Player)
|
||||
--if not Value or Value == "" then return --[[ Value = "N/A" ]] end
|
||||
if Value and Value ~= "" then
|
||||
|
||||
local Text = vgui.Create("DLabel")
|
||||
Text:Dock(LEFT)
|
||||
Text:SetFont("TabLarge")
|
||||
Text:SetText(v.name .. ": " .. Value)
|
||||
Text:SizeToContents()
|
||||
Text:SetColor(Color(200,200,200,200))
|
||||
Text:SetTooltip("Click to copy " .. v.name .. " to clipboard")
|
||||
Text:SetMouseInputEnabled(true)
|
||||
|
||||
function Text:OnMousePressed(mcode)
|
||||
self:SetTooltip(v.name .. " copied to clipboard!")
|
||||
ChangeTooltip(self)
|
||||
SetClipboardText(Value)
|
||||
self:SetTooltip("Click to copy " .. v.name .. " to clipboard")
|
||||
end
|
||||
|
||||
timer.Create("FAdmin_Scoreboard_text_update_" .. v.name, 1, 0, function()
|
||||
if not IsValid(ply) or not IsValid(FAdmin.ScoreBoard.Player.Player) or not IsValid(Text) then
|
||||
timer.Remove("FAdmin_Scoreboard_text_update_" .. v.name)
|
||||
if FAdmin.ScoreBoard.Visible and (not IsValid(ply) or not IsValid(FAdmin.ScoreBoard.Player.Player)) then FAdmin.ScoreBoard.ChangeView("Main") end
|
||||
return
|
||||
end
|
||||
Value = v.func(FAdmin.ScoreBoard.Player.Player)
|
||||
if not Value or Value == "" then Value = "N/A" end
|
||||
Text:SetText(v.name .. ": " .. Value)
|
||||
end)
|
||||
|
||||
if (#FAdmin.ScoreBoard.Player.Controls.InfoPanel1:GetChildren() * 17 + 17) <= FAdmin.ScoreBoard.Player.Controls.InfoPanel1:GetTall() and not v.NewPanel then
|
||||
FAdmin.ScoreBoard.Player.Controls.InfoPanel1:Add(Text)
|
||||
else
|
||||
if #SelectedPanel:GetChildren() * 17 + 17 >= SelectedPanel:GetTall() or v.NewPanel then
|
||||
SelectedPanel = AddInfoPanel() -- Add new panel if the last one is full
|
||||
end
|
||||
SelectedPanel:Add(Text)
|
||||
if Text:GetWide() > SelectedPanel:GetWide() then
|
||||
SelectedPanel:SetWide(Text:GetWide() + 40)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local CatColor = team.GetColor(ply:Team())
|
||||
if GAMEMODE.Name == "Sandbox" then
|
||||
CatColor = Color(100, 150, 245, 255)
|
||||
if ply:Team() == TEAM_CONNECTING then
|
||||
CatColor = Color(200, 120, 50, 255)
|
||||
elseif ply:IsAdmin() then
|
||||
CatColor = Color(30, 200, 50, 255)
|
||||
end
|
||||
|
||||
if ply:GetFriendStatus() == "friend" then
|
||||
CatColor = Color(236, 181, 113, 255)
|
||||
end
|
||||
end
|
||||
CatColor = hook.Run("FAdmin_PlayerRowColour", ply, CatColor) or CatColor
|
||||
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonCat = FAdmin.ScoreBoard.Player.Controls.ButtonCat or vgui.Create("FAdminPlayerCatagory")
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonCat:SetLabel(" Player options!")
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonCat.CatagoryColor = CatColor
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonCat:SetSize(FAdmin.ScoreBoard.Width - 40, 100)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonCat:SetPos(FAdmin.ScoreBoard.X + 20, FAdmin.ScoreBoard.Y + 100 + FAdmin.ScoreBoard.Player.Controls.InfoPanel2:GetTall() + 5)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonCat:SetVisible(true)
|
||||
|
||||
function FAdmin.ScoreBoard.Player.Controls.ButtonCat:Toggle()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel = FAdmin.ScoreBoard.Player.Controls.ButtonPanel or vgui.Create("FAdminPanelList", FAdmin.ScoreBoard.Player.Controls.ButtonCat)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:SetSpacing(5)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:EnableHorizontal(true)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:EnableVerticalScrollbar(true)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:SizeToContents()
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:SetVisible(true)
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:SetSize(0, (ScreenHeight - FAdmin.ScoreBoard.Y - 40) - (FAdmin.ScoreBoard.Y + 100 + FAdmin.ScoreBoard.Player.Controls.InfoPanel2:GetTall() + 5))
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:Clear()
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:DockMargin(5, 5, 5, 5)
|
||||
|
||||
for _, v in ipairs(FAdmin.ScoreBoard.Player.ActionButtons) do
|
||||
if v.Visible == true or (isfunction(v.Visible) and v.Visible(FAdmin.ScoreBoard.Player.Player) == true) then
|
||||
local ActionButton = vgui.Create("FAdminActionButton")
|
||||
local imageType = TypeID(v.Image)
|
||||
if imageType == TYPE_STRING then
|
||||
ActionButton:SetImage(v.Image or "icon16/exclamation")
|
||||
elseif imageType == TYPE_TABLE then
|
||||
ActionButton:SetImage(v.Image[1])
|
||||
if v.Image[2] then ActionButton:SetImage2(v.Image[2]) end
|
||||
elseif imageType == TYPE_FUNCTION then
|
||||
local img1, img2 = v.Image(ply)
|
||||
ActionButton:SetImage(img1)
|
||||
if img2 then ActionButton:SetImage2(img2) end
|
||||
else
|
||||
ActionButton:SetImage("icon16/exclamation")
|
||||
end
|
||||
local name = v.Name
|
||||
if isfunction(name) then name = name(FAdmin.ScoreBoard.Player.Player) end
|
||||
ActionButton:SetText(DarkRP.deLocalise(name))
|
||||
ActionButton:SetBorderColor(v.color)
|
||||
|
||||
function ActionButton:DoClick()
|
||||
if not IsValid(FAdmin.ScoreBoard.Player.Player) then return end
|
||||
return v.Action(FAdmin.ScoreBoard.Player.Player, self)
|
||||
end
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:AddItem(ActionButton)
|
||||
if v.OnButtonCreated then
|
||||
v.OnButtonCreated(FAdmin.ScoreBoard.Player.Player, ActionButton)
|
||||
end
|
||||
end
|
||||
end
|
||||
FAdmin.ScoreBoard.Player.Controls.ButtonPanel:Dock(TOP)
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Player:AddInformation(name, func, ForceNewPanel) -- ForeNewPanel is to start a new column
|
||||
table.insert(FAdmin.ScoreBoard.Player.Information, {name = name, func = func, NewPanel = ForceNewPanel})
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Player:AddActionButton(Name, Image, color, Visible, Action, OnButtonCreated)
|
||||
table.insert(FAdmin.ScoreBoard.Player.ActionButtons, {Name = Name, Image = Image, color = color, Visible = Visible, Action = Action, OnButtonCreated = OnButtonCreated})
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Name", function(ply) return ply:Nick() end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Kills", function(ply) return ply:Frags() end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Deaths", function(ply) return ply:Deaths() end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Health", function(ply) return ply:Health() end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("Ping", function(ply) return ply:Ping() end)
|
||||
FAdmin.ScoreBoard.Player:AddInformation("SteamID", function(ply) return ply:SteamID() end, true)
|
||||
@@ -0,0 +1,227 @@
|
||||
FAdmin.ScoreBoard.Server.Information = {} -- Compatibility for autoreload
|
||||
FAdmin.ScoreBoard.Server.ActionButtons = {} -- Refresh server buttons when reloading gamemode
|
||||
|
||||
local function MakeServerOptions()
|
||||
local _, YPos, Width = 20, FAdmin.ScoreBoard.Y + 120 + FAdmin.ScoreBoard.Height / 5 + 20, (FAdmin.ScoreBoard.Width - 40) / 3
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat = FAdmin.ScoreBoard.Server.Controls.ServerActionsCat or vgui.Create("FAdminPlayerCatagory")
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat:SetLabel(" Server Actions")
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat.CatagoryColor = Color(155, 0, 0, 255)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat:SetSize(Width-5, FAdmin.ScoreBoard.Height - 20 - YPos)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat:SetPos(FAdmin.ScoreBoard.X + 20, YPos)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat:SetVisible(true)
|
||||
function FAdmin.ScoreBoard.Server.Controls.ServerActionsCat:Toggle()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActions = FAdmin.ScoreBoard.Server.Controls.ServerActions or vgui.Create("FAdminPanelList")
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActionsCat:SetContents(FAdmin.ScoreBoard.Server.Controls.ServerActions)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerActions:SetTall(FAdmin.ScoreBoard.Height - 20 - YPos)
|
||||
for k, v in ipairs(FAdmin.ScoreBoard.Server.Controls.ServerActions:GetChildren()) do
|
||||
if k == 1 then continue end
|
||||
v:Remove()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat = FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat or vgui.Create("FAdminPlayerCatagory")
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat:SetLabel(" Player Actions")
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat.CatagoryColor = Color(0, 155, 0, 255)
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat:SetSize(Width-5, FAdmin.ScoreBoard.Height - 20 - YPos)
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat:SetPos(FAdmin.ScoreBoard.X + 20 + Width, YPos)
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat:SetVisible(true)
|
||||
function FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat:Toggle()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActions = FAdmin.ScoreBoard.Server.Controls.PlayerActions or vgui.Create("FAdminPanelList")
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActionsCat:SetContents(FAdmin.ScoreBoard.Server.Controls.PlayerActions)
|
||||
FAdmin.ScoreBoard.Server.Controls.PlayerActions:SetTall(FAdmin.ScoreBoard.Height - 20 - YPos)
|
||||
for k, v in ipairs(FAdmin.ScoreBoard.Server.Controls.PlayerActions:GetChildren()) do
|
||||
if k == 1 then continue end
|
||||
v:Remove()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat = FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat or vgui.Create("FAdminPlayerCatagory")
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat:SetLabel(" Server Settings")
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat.CatagoryColor = Color(0, 0, 155, 255)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat:SetSize(Width-5, FAdmin.ScoreBoard.Height - 20 - YPos)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat:SetPos(FAdmin.ScoreBoard.X + 20 + Width * 2, YPos)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat:SetVisible(true)
|
||||
function FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat:Toggle()
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettings = FAdmin.ScoreBoard.Server.Controls.ServerSettings or vgui.Create("FAdminPanelList")
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettingsCat:SetContents(FAdmin.ScoreBoard.Server.Controls.ServerSettings)
|
||||
FAdmin.ScoreBoard.Server.Controls.ServerSettings:SetTall(FAdmin.ScoreBoard.Height - 20 - YPos)
|
||||
for k, v in ipairs(FAdmin.ScoreBoard.Server.Controls.ServerSettings:GetChildren()) do
|
||||
if k == 1 then continue end
|
||||
v:Remove()
|
||||
end
|
||||
|
||||
for k, v in ipairs(FAdmin.ScoreBoard.Server.ActionButtons) do
|
||||
local visible = v.Visible == true or (isfunction(v.Visible) and v.Visible(LocalPlayer()) == true)
|
||||
|
||||
local ActionButton = vgui.Create("FAdminActionButton")
|
||||
local imageType = TypeID(v.Image)
|
||||
if imageType == TYPE_STRING then
|
||||
ActionButton:SetImage(v.Image or "icon16/exclamation")
|
||||
elseif imageType == TYPE_TABLE then
|
||||
ActionButton:SetImage(v.Image[1])
|
||||
if v.Image[2] then ActionButton:SetImage2(v.Image[2]) end
|
||||
elseif imageType == TYPE_FUNCTION then
|
||||
local img1, img2 = v.Image()
|
||||
ActionButton:SetImage(img1)
|
||||
if img2 then ActionButton:SetImage2(img2) end
|
||||
else
|
||||
ActionButton:SetImage("icon16/exclamation")
|
||||
end
|
||||
local name = v.Name
|
||||
if isfunction(name) then name = name() end
|
||||
ActionButton:SetText(DarkRP.deLocalise(name))
|
||||
ActionButton:SetBorderColor(visible and v.color or Color(120, 120, 120))
|
||||
ActionButton:SetDisabled(not visible)
|
||||
ActionButton:Dock(TOP)
|
||||
|
||||
function ActionButton:DoClick()
|
||||
return v.Action(self)
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server.Controls[v.TYPE]:Add(ActionButton)
|
||||
if v.OnButtonCreated then
|
||||
v.OnButtonCreated(ActionButton)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Server:AddServerAction(Name, Image, color, Visible, Action, OnButtonCreated)
|
||||
table.insert(FAdmin.ScoreBoard.Server.ActionButtons, {TYPE = "ServerActions", Name = Name, Image = Image, color = color, Visible = Visible, Action = Action, OnButtonCreated = OnButtonCreated})
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Server:AddPlayerAction(Name, Image, color, Visible, Action, OnButtonCreated)
|
||||
table.insert(FAdmin.ScoreBoard.Server.ActionButtons, {TYPE = "PlayerActions", Name = Name, Image = Image, color = color, Visible = Visible, Action = Action, OnButtonCreated = OnButtonCreated})
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Server:AddServerSetting(Name, Image, color, Visible, Action, OnButtonCreated)
|
||||
table.insert(FAdmin.ScoreBoard.Server.ActionButtons, {TYPE = "ServerSettings", Name = Name, Image = Image, color = color, Visible = Visible, Action = Action, OnButtonCreated = OnButtonCreated})
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Server.Show(ply)
|
||||
FAdmin.ScoreBoard.Server.InfoPanels = FAdmin.ScoreBoard.Server.InfoPanels or {}
|
||||
for k, v in pairs(FAdmin.ScoreBoard.Server.InfoPanels) do
|
||||
if IsValid(v) then
|
||||
v:Remove()
|
||||
FAdmin.ScoreBoard.Server.InfoPanels[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(FAdmin.ScoreBoard.Server.Controls.InfoPanel) then
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel:Remove()
|
||||
end
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel = vgui.Create("FAdminPanelList")
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel:SetPos(FAdmin.ScoreBoard.X + 20, FAdmin.ScoreBoard.Y + 120)
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel:SetSize(FAdmin.ScoreBoard.Width - 40, FAdmin.ScoreBoard.Height / 5)
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel:SetVisible(true)
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel:Clear(true)
|
||||
|
||||
local function AddInfoPanel()
|
||||
local pan = vgui.Create("FAdminPanelList")
|
||||
pan:SetSize(1, FAdmin.ScoreBoard.Server.Controls.InfoPanel:GetTall())
|
||||
pan:Dock(LEFT)
|
||||
FAdmin.ScoreBoard.Server.Controls.InfoPanel:Add(pan)
|
||||
|
||||
table.insert(FAdmin.ScoreBoard.Server.InfoPanels, pan)
|
||||
return pan
|
||||
end
|
||||
|
||||
local SelectedPanel = AddInfoPanel() -- Make first panel to put the first things in
|
||||
|
||||
for _, v in pairs(FAdmin.ScoreBoard.Server.Information) do
|
||||
local Text = vgui.Create("DLabel")
|
||||
Text:SetFont("TabLarge")
|
||||
Text:SetColor(Color(255,255,255,200))
|
||||
Text:Dock(TOP)
|
||||
Text.Func = v.Func
|
||||
|
||||
local EndText
|
||||
local function RefreshText()
|
||||
local Value = v.func()
|
||||
|
||||
if not Value or Value == "" then
|
||||
Value = "N/A"
|
||||
end
|
||||
|
||||
EndText = v.name .. ": " .. Value
|
||||
local strLen = string.len(EndText)
|
||||
|
||||
if strLen > 40 then
|
||||
local NewValue = string.sub(EndText, 1, 40)
|
||||
|
||||
for i = 40, strLen, 34 do
|
||||
NewValue = NewValue .. "\n " .. string.sub(EndText, i + 1, i + 34)
|
||||
end
|
||||
|
||||
EndText = NewValue
|
||||
else
|
||||
local MaxWidth = 240
|
||||
surface.SetFont("TabLarge")
|
||||
local TextWidth = surface.GetTextSize(v.name .. ": " .. Value)
|
||||
|
||||
if TextWidth <= MaxWidth then
|
||||
local SpacesAmount = (MaxWidth - TextWidth) / 3
|
||||
local Spaces = ""
|
||||
|
||||
for i = 1, SpacesAmount, 1 do
|
||||
Spaces = Spaces .. " "
|
||||
end
|
||||
|
||||
EndText = v.name .. ":" .. Spaces .. Value
|
||||
end
|
||||
end
|
||||
|
||||
Text:SetText(DarkRP.deLocalise(EndText))
|
||||
Text:SizeToContents()
|
||||
Text:SetTooltip("Click to copy " .. v.name .. " to clipboard")
|
||||
Text:SetMouseInputEnabled(true)
|
||||
end
|
||||
|
||||
RefreshText()
|
||||
|
||||
function Text:OnMousePressed(mcode)
|
||||
self:SetTooltip(v.name .. " copied to clipboard!")
|
||||
ChangeTooltip(self)
|
||||
SetClipboardText(v.func() or "")
|
||||
self:SetTooltip("Click to copy " .. v.name .. " to clipboard")
|
||||
end
|
||||
|
||||
timer.Create("FAdmin_Scoreboard_text_update_" .. v.name, 1, 0, function()
|
||||
if not IsValid(Text) then
|
||||
timer.Remove("FAdmin_Scoreboard_text_update_" .. v.name)
|
||||
FAdmin.ScoreBoard.ChangeView("Main")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
RefreshText()
|
||||
end)
|
||||
|
||||
if #SelectedPanel:GetChildren() * 17 + 17 >= SelectedPanel:GetTall() or v.NewPanel then
|
||||
SelectedPanel = AddInfoPanel()
|
||||
end
|
||||
-- Add new panel if the last one is full
|
||||
SelectedPanel:Add(Text)
|
||||
if Text:GetWide() > SelectedPanel:GetWide() then
|
||||
SelectedPanel:SetWide(Text:GetWide() + 40)
|
||||
end
|
||||
end
|
||||
|
||||
MakeServerOptions()
|
||||
end
|
||||
|
||||
function FAdmin.ScoreBoard.Server:AddInformation(name, func, ForceNewPanel) -- ForeNewPanel is to start a new column
|
||||
table.insert(FAdmin.ScoreBoard.Server.Information, {name = name, func = func, NewPanel = ForceNewPanel})
|
||||
end
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddInformation("Hostname", GetHostName)
|
||||
FAdmin.ScoreBoard.Server:AddInformation("Gamemode", function() return GAMEMODE.Name end)
|
||||
FAdmin.ScoreBoard.Server:AddInformation("Author", function() return GAMEMODE.Author end)
|
||||
FAdmin.ScoreBoard.Server:AddInformation("Map", game.GetMap)
|
||||
FAdmin.ScoreBoard.Server:AddInformation("Players", function() return player.GetCount() .. "/" .. game.MaxPlayers() end)
|
||||
FAdmin.ScoreBoard.Server:AddInformation("Ping", function() return LocalPlayer():Ping() end)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
FAdmin.ScoreBoard = FAdmin.ScoreBoard or {}
|
||||
|
||||
local ScreenWidth, ScreenHeight = ScrW(), ScrH()
|
||||
|
||||
FAdmin.ScoreBoard.X = ScreenWidth * 0.05
|
||||
FAdmin.ScoreBoard.Y = ScreenHeight * 0.025
|
||||
FAdmin.ScoreBoard.Width = ScreenWidth * 0.9
|
||||
FAdmin.ScoreBoard.Height = ScreenHeight * 0.95
|
||||
|
||||
FAdmin.ScoreBoard.Controls = FAdmin.ScoreBoard.Controls or {}
|
||||
FAdmin.ScoreBoard.CurrentView = "Main"
|
||||
|
||||
FAdmin.ScoreBoard.Main = FAdmin.ScoreBoard.Main or {}
|
||||
FAdmin.ScoreBoard.Main.Controls = FAdmin.ScoreBoard.Main.Controls or {}
|
||||
FAdmin.ScoreBoard.Main.Logo = "gui/gmod_logo"
|
||||
|
||||
FAdmin.ScoreBoard.Player = FAdmin.ScoreBoard.Player or {}
|
||||
FAdmin.ScoreBoard.Player.Controls = FAdmin.ScoreBoard.Player.Controls or {}
|
||||
FAdmin.ScoreBoard.Player.Player = NULL
|
||||
FAdmin.ScoreBoard.Player.Logo = "fadmin/back"
|
||||
|
||||
FAdmin.ScoreBoard.Server = FAdmin.ScoreBoard.Server or {}
|
||||
FAdmin.ScoreBoard.Server.Controls = FAdmin.ScoreBoard.Server.Controls or {}
|
||||
FAdmin.ScoreBoard.Server.Logo = "fadmin/back"
|
||||
@@ -0,0 +1,53 @@
|
||||
--[[---------------------------------------------------------------------------
|
||||
Common times for several punishment actions
|
||||
---------------------------------------------------------------------------]]
|
||||
FAdmin.PlayerActions.commonTimes = {}
|
||||
FAdmin.PlayerActions.commonTimes[0] = "indefinitely"
|
||||
FAdmin.PlayerActions.commonTimes[10] = "10 seconds"
|
||||
FAdmin.PlayerActions.commonTimes[30] = "30 seconds"
|
||||
FAdmin.PlayerActions.commonTimes[60] = "1 minute"
|
||||
FAdmin.PlayerActions.commonTimes[300] = "5 minutes"
|
||||
FAdmin.PlayerActions.commonTimes[600] = "10 minutes"
|
||||
|
||||
function FAdmin.PlayerActions.addTimeSubmenu(menu, submenuText, submenuClick, submenuItemClick)
|
||||
local SubMenu = menu:AddSubMenu(submenuText, submenuClick)
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
SubMenu:AddPanel(Padding)
|
||||
|
||||
local SubMenuTitle = vgui.Create("DLabel")
|
||||
SubMenuTitle:SetText(" Time:\n")
|
||||
SubMenuTitle:SetFont("UiBold")
|
||||
SubMenuTitle:SizeToContents()
|
||||
SubMenuTitle:SetTextColor(color_black)
|
||||
|
||||
SubMenu:AddPanel(SubMenuTitle)
|
||||
|
||||
for secs, Time in SortedPairs(FAdmin.PlayerActions.commonTimes) do
|
||||
SubMenu:AddOption(Time, function() submenuItemClick(secs) end)
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.PlayerActions.addTimeMenu(ItemClick)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Time:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
|
||||
menu:AddPanel(Title)
|
||||
|
||||
for secs, Time in SortedPairs(FAdmin.PlayerActions.commonTimes) do
|
||||
menu:AddOption(Time, function() ItemClick(secs) end)
|
||||
end
|
||||
menu:Open()
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
FAdmin.StartHooks["CleanUp"] = function()
|
||||
FAdmin.Access.AddPrivilege("CleanUp", 2)
|
||||
FAdmin.Commands.AddCommand("ClearDecals", nil)
|
||||
FAdmin.Commands.AddCommand("StopSounds", nil)
|
||||
FAdmin.Commands.AddCommand("CleanUp", nil)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerAction("Clear decals", "fadmin/icons/cleanup", Color(155, 0, 0, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "CleanUp") end, function(ply, button)
|
||||
RunConsoleCommand("_FAdmin", "ClearDecals")
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerAction("Stop all sounds", "fadmin/icons/cleanup", Color(155, 0, 0, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "CleanUp") end, function(ply, button)
|
||||
RunConsoleCommand("_FAdmin", "StopSounds")
|
||||
end)
|
||||
|
||||
usermessage.Hook("FAdmin_StopSounds", function()
|
||||
RunConsoleCommand("stopsound") -- bypass for ConCommand blocking it
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerAction("Clean up server", "fadmin/icons/cleanup", Color(155, 0, 0, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "CleanUp") end, function(ply, button)
|
||||
RunConsoleCommand("_FAdmin", "CleanUp")
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
local function ClearDecals(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "CleanUp") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
v:ConCommand("r_cleardecals")
|
||||
end
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), "You have removed all decals. NOTE: this does NOT make the server ANY less laggy!", "All decals have been removed. NOTE: this does NOT make the server ANY less laggy!", "Removed all decals.")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function StopSounds(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "CleanUp") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
umsg.Start("FAdmin_StopSounds")
|
||||
umsg.End()
|
||||
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), "You have stopped all sounds", "All sounds have been stopped", "Stopped all sounds")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function CleanUp(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "CleanUp") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
game.CleanUpMap()
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), "You have cleaned up the map", "The map has been cleaned up", "Cleaned up the map")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["CleanUp"] = function()
|
||||
FAdmin.Commands.AddCommand("ClearDecals", ClearDecals)
|
||||
FAdmin.Commands.AddCommand("StopSounds", StopSounds)
|
||||
FAdmin.Commands.AddCommand("CleanUp", CleanUp)
|
||||
|
||||
local oldCleanup = concommand.GetTable()["gmod_admin_cleanup"]
|
||||
concommand.Add("gmod_admin_cleanup", function(ply, cmd, args)
|
||||
if args[1] then return oldCleanup(ply, cmd, args) end
|
||||
return CleanUp(ply, cmd, args)
|
||||
end)
|
||||
|
||||
FAdmin.Access.AddPrivilege("CleanUp", 2)
|
||||
end
|
||||
@@ -0,0 +1,109 @@
|
||||
local Options = {}
|
||||
local targets
|
||||
local colorBackground = Color(0, 0, 0, 200)
|
||||
local colorHighlight = Color(255, 125, 0, 200)
|
||||
hook.Add("ChatTextChanged", "FAdmin_Chat_autocomplete", function(text)
|
||||
if not FAdmin.GlobalSetting.FAdmin then return end
|
||||
Options = {}
|
||||
local prefix = GetGlobalString("FAdmin_commandprefix")
|
||||
prefix = prefix ~= '' and prefix or '/'
|
||||
|
||||
if string.sub(text, 1, 1) ~= prefix then targets = nil return end
|
||||
|
||||
local TExplode = string.Explode(" ", string.sub(text, 2))
|
||||
if not TExplode[1] then return end
|
||||
local Command = string.lower(TExplode[1])
|
||||
local Args = table.Copy(TExplode)
|
||||
Args[1] = nil
|
||||
Args = table.ClearKeys(Args)
|
||||
|
||||
|
||||
local optionsCount = 0
|
||||
for k, v in pairs(FAdmin.Commands.List) do
|
||||
if string.find(string.lower(k), Command, 1, true) ~= 1 then continue end
|
||||
|
||||
Options[prefix .. k] = table.Copy(v.ExtraArgs)
|
||||
|
||||
optionsCount = optionsCount + 1
|
||||
end
|
||||
|
||||
local ChatBoxPosX, ChatBoxPosY = chat.GetChatBoxPos()
|
||||
local ChatBoxWidth = chat.GetChatBoxSize() -- Don't need height
|
||||
local DidMakeShorter = false
|
||||
table.sort(Options)
|
||||
local i = 1
|
||||
for k in pairs(Options) do
|
||||
local Pos = ChatBoxPosY + i * 24
|
||||
if Pos + 24 > ScrH() then
|
||||
Options[k] = nil
|
||||
DidMakeShorter = true
|
||||
optionsCount = optionsCount - 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
-- Player arguments
|
||||
local firstVal = table.GetFirstValue(Options)
|
||||
if optionsCount == 1 and firstVal[#Args] and string.match(firstVal[#Args], ".Player.") then
|
||||
local players = {}
|
||||
|
||||
for _, v in ipairs(FAdmin.FindPlayer(Args[#Args]) or {}) do
|
||||
if not IsValid(v) then continue end
|
||||
table.insert(players, v:Nick())
|
||||
end
|
||||
|
||||
targets = table.concat(players, ", ")
|
||||
end
|
||||
|
||||
local xPos = ChatBoxPosX + ChatBoxWidth + 2
|
||||
hook.Add("HUDPaint", "FAdmin_Chat_autocomplete", function()
|
||||
local j = 0
|
||||
for option, args in pairs(Options) do
|
||||
draw.WordBox(4, xPos, ChatBoxPosY + j * 24, option, "UiBold", colorBackground, color_white)
|
||||
|
||||
for k, arg in pairs(args) do
|
||||
draw.WordBox(4, xPos + k * 130, ChatBoxPosY + j * 24, arg, "UiBold", colorBackground, color_white)
|
||||
end
|
||||
|
||||
j = j + 1
|
||||
end
|
||||
|
||||
if targets then
|
||||
draw.WordBox(4, xPos, ChatBoxPosY + j * 24, "Targets: " .. targets, "UiBold", colorHighlight, color_white)
|
||||
end
|
||||
|
||||
if DidMakeShorter then
|
||||
draw.WordBox(4, xPos, ChatBoxPosY + j * 24, "...", "UiBold", colorBackground, color_white)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
hook.Add("FinishChat", "FAdmin_Chat_autocomplete", function() hook.Remove("HUDPaint", "FAdmin_Chat_autocomplete") end)
|
||||
|
||||
local plyIndex = 1
|
||||
|
||||
hook.Add("OnChatTab", "FAdmin_Chat_autocomplete", function(text)
|
||||
if not FAdmin.GlobalSetting.FAdmin then return end
|
||||
|
||||
for command in pairs(Options) do
|
||||
if string.find(text, " ") == nil then
|
||||
return string.sub(command, 1, string.find(command, " "))
|
||||
elseif string.find(text, " ") then
|
||||
plyIndex = plyIndex + 1
|
||||
|
||||
if plyIndex > player.GetCount() then
|
||||
plyIndex = 1
|
||||
end
|
||||
|
||||
return string.sub(command, 1, string.find(command, " ")) .. " " .. string.sub(player.GetAll()[plyIndex]:Nick(), 1, string.find(player.GetAll()[plyIndex]:Nick(), " "))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
FAdmin.StartHooks["Chatcommands"] = function()
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting("Set FAdmin's chat command prefix", "fadmin/icons/message", Color(0, 0, 155, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "ServerSetting") end, function()
|
||||
local prefix = GetGlobalString("FAdmin_commandprefix")
|
||||
prefix = prefix ~= '' and prefix or '/'
|
||||
Derma_StringRequest("Set chat command prefix", "Make sure it's only one character!", prefix, fp{RunConsoleCommand, "_Fadmin", "CommandPrefix"})
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
local function AutoComplete(command, args)
|
||||
local autocomplete = {}
|
||||
args = string.Explode(" ", args)
|
||||
table.remove(args, 1) --Remove the first space
|
||||
if args[1] == "" then
|
||||
for k in pairs(FAdmin.Commands.List) do
|
||||
table.insert(autocomplete, command .. " " .. k)
|
||||
end
|
||||
elseif not args[2] or args[3] then
|
||||
for k, v in pairs(FAdmin.Commands.List) do
|
||||
if string.sub(k, 1, string.len(args[1])) == args[1] then
|
||||
local ExtraArgs = table.concat(v.ExtraArgs, " ")
|
||||
table.insert(autocomplete, command .. " " .. k .. " " .. ExtraArgs)
|
||||
end
|
||||
end
|
||||
elseif not args[3] and FAdmin.Commands.List[string.lower(args[1])] and FAdmin.Commands.List[string.lower(args[1])].ExtraArgs[1] == "<Player>" then
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if args[2] == "" or table.HasValue(FAdmin.FindPlayer(args[2]) or {}, v) then
|
||||
table.insert(autocomplete, command .. " " .. args[1] .. " " .. v:Nick())
|
||||
end
|
||||
end
|
||||
end
|
||||
table.sort(autocomplete)
|
||||
return autocomplete
|
||||
end
|
||||
concommand.Add("FAdmin", function(ply, cmd, args)
|
||||
RunConsoleCommand("_" .. cmd, unpack(args))
|
||||
end, AutoComplete)
|
||||
@@ -0,0 +1,6 @@
|
||||
FAdmin.Commands = {}
|
||||
FAdmin.Commands.List = {}
|
||||
|
||||
function FAdmin.Commands.AddCommand(name, callback, ...)
|
||||
FAdmin.Commands.List[string.lower(name)] = {callback = callback, ExtraArgs = {...}}
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
local convar = CreateConVar("FAdmin_commandprefix", "/", {FCVAR_SERVER_CAN_EXECUTE})
|
||||
|
||||
SetGlobalString("FAdmin_commandprefix", convar:GetString())
|
||||
|
||||
cvars.AddChangeCallback("FAdmin_commandprefix", function()
|
||||
SetGlobalString("FAdmin_commandprefix", convar:GetString())
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSay", "FAdminChatCommands", function(ply, text, Team, dead)
|
||||
local prefix = convar:GetString()
|
||||
|
||||
if string.sub(text, 1, 1) ~= prefix then return end
|
||||
|
||||
local TExplode = string.Explode(" ", string.sub(text, 2))
|
||||
if not TExplode then return end
|
||||
|
||||
for k, v in ipairs(TExplode) do
|
||||
if string.sub(v, -1) == "," and TExplode[k + 1] then
|
||||
TExplode[k] = (TExplode[k] or "") .. (TExplode[k + 1] or "")
|
||||
table.remove(TExplode, k + 1)
|
||||
end
|
||||
end
|
||||
table.ClearKeys(TExplode, false)
|
||||
|
||||
local Command = string.lower(TExplode[1])
|
||||
local Args = table.Copy(TExplode)
|
||||
Args[1] = nil
|
||||
Args = table.ClearKeys(Args)
|
||||
if FAdmin.Commands.List[Command] then
|
||||
local res = {FAdmin.Commands.List[Command].callback(ply, Command, Args)}
|
||||
hook.Call("FAdmin_OnCommandExecuted", nil, ply, Command, Args, res)
|
||||
return ""
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
FAdmin.StartHooks["Chatcommands"] = function()
|
||||
convar = convar or GetConVar("FAdmin_commandprefix")
|
||||
|
||||
FAdmin.Commands.AddCommand("CommandPrefix", function(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ServerSetting") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] or string.len(args[1]) ~= 1 then return end
|
||||
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), ply:Nick() .. " set FAdmin's chat command prefix to " .. args[1], "FAdmin's chat command prefix has been set to " .. args[1], "Chat command prefix set to" .. args[1])
|
||||
|
||||
RunConsoleCommand("FAdmin_commandprefix", args[1])
|
||||
|
||||
FAdmin.SaveSetting("FAdmin_commandprefix", args[1])
|
||||
|
||||
return true
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
local function concommand_executed(ply, cmd, args)
|
||||
if not args[1] then return end
|
||||
local name = string.lower(args[1])
|
||||
|
||||
if not name or not FAdmin.Commands.List[name] then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Command does not exist!")
|
||||
return
|
||||
end
|
||||
|
||||
local args2 = args
|
||||
table.remove(args2, 1)
|
||||
for k, v in pairs(args2) do
|
||||
if string.sub(v, -1) == "," and args2[k + 1] then
|
||||
args2[k] = args2[k] .. args2[k + 1]
|
||||
table.remove(args2, k + 1)
|
||||
end
|
||||
end
|
||||
table.ClearKeys(args2)
|
||||
local res = {FAdmin.Commands.List[name].callback(ply, name, args2)}
|
||||
hook.Call("FAdmin_OnCommandExecuted", nil, ply, name, args2, res)
|
||||
end
|
||||
|
||||
local function AutoComplete(command, ...)
|
||||
local autocomplete = {}
|
||||
local args = string.Explode(" ", ...)
|
||||
table.remove(args, 1) --Remove the first space
|
||||
if args[1] == "" then
|
||||
for k in pairs(FAdmin.Commands.List) do
|
||||
table.insert(autocomplete, command .. " " .. k)
|
||||
end
|
||||
elseif not args[2] then
|
||||
for k in pairs(FAdmin.Commands.List) do
|
||||
if string.sub(k, 1, string.len(args[1])) == args[1] then
|
||||
table.insert(autocomplete, command .. " " .. k)
|
||||
end
|
||||
end
|
||||
end
|
||||
table.sort(autocomplete)
|
||||
return autocomplete
|
||||
end
|
||||
concommand.Add("_FAdmin", concommand_executed, AutoComplete)
|
||||
concommand.Add("FAdmin", concommand_executed, AutoComplete)
|
||||
|
||||
-- DO NOT EDIT THIS, NO MATTER HOW MUCH YOU'VE EDITED FADMIN IT DOESN'T GIVE YOU ANY RIGHT TO CHANGE CREDITS AND/OR REMOVE THE AUTHOR
|
||||
FAdmin.Commands.AddCommand("FAdminCredits", function(ply, cmd, args)
|
||||
if ply:SteamID() == "STEAM_0:0:8944068" and args[1] then
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or (#targets == 1 and not IsValid(targets[1])) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) then
|
||||
concommand_executed(target, "FAdmin", {"FAdminCredits"})
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Credits sent!")
|
||||
return true
|
||||
end
|
||||
FAdmin.Messages.SendMessage(ply, 2, "FAdmin by (FPtje) Falco, STEAM_0:0:8944068")
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if v:SteamID() == "STEAM_0:0:8944068" then
|
||||
FAdmin.Messages.SendMessage(ply, 4, "(FPtje) Falco is in the server at this moment")
|
||||
return true
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.SendMessage(ply, 5, "(FPtje) Falco is NOT in the server at this moment")
|
||||
|
||||
return true
|
||||
end)
|
||||
@@ -0,0 +1,17 @@
|
||||
local logging = CreateConVar("FAdmin_logging", 1, {FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE})
|
||||
|
||||
if SERVER then return end
|
||||
FAdmin.StartHooks["Logging"] = function()
|
||||
FAdmin.Access.AddPrivilege("Logging", 3)
|
||||
FAdmin.Commands.AddCommand("Logging", nil)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting(function() return (logging:GetBool() and "Disable" or "Enable") .. " Logging" end,
|
||||
function() return "fadmin/icons/message", logging:GetBool() and "fadmin/icons/disable" end,
|
||||
Color(0, 0, 155, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "Logging") end, function(button)
|
||||
button:SetImage2((not logging:GetBool() and "fadmin/icons/disable") or "null")
|
||||
button:SetText((not logging:GetBool() and "Disable" or "Enable") .. " Logging")
|
||||
button:GetParent():InvalidateLayout()
|
||||
|
||||
RunConsoleCommand("_Fadmin", "Logging", logging:GetBool() and 0 or 1)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,161 @@
|
||||
local logging
|
||||
FAdmin.StartHooks["Logging"] = function()
|
||||
FAdmin.Access.AddPrivilege("Logging", 3)
|
||||
FAdmin.Commands.AddCommand("Logging", function(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Logging") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not tonumber(args[1]) then return end
|
||||
|
||||
local OnOff = (tobool(tonumber(args[1])) and "on") or "off"
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), ply:Nick() .. " turned logging " .. OnOff, "Logging has been turned " .. OnOff, "Turned logging " .. OnOff)
|
||||
|
||||
RunConsoleCommand("FAdmin_logging", args[1])
|
||||
|
||||
FAdmin.SaveSetting("FAdmin_logging", args[1])
|
||||
|
||||
return true, OnOff
|
||||
end)
|
||||
logging = GetConVar("FAdmin_logging")
|
||||
end
|
||||
|
||||
function FAdmin.Log(text)
|
||||
if not text or text == "" then return end
|
||||
if not logging or not logging:GetBool() then return end
|
||||
|
||||
ServerLog("[FAdmin] " .. text .. "\n")
|
||||
end
|
||||
|
||||
hook.Add("PlayerGiveSWEP", "FAdmin_Log", function(ply, class)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Gave themself a " .. (class or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnedSENT", "FAdmin_Log", function(ply, ent)
|
||||
if not IsValid(ply) or not ply:IsPlayer() or not IsValid(ent) then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (ent:GetClass() or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnSWEP", "FAdmin_Log", function(ply, class)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (class or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnedProp", "FAdmin_Log", function(ply, model, ent)
|
||||
if not IsValid(ply) or not ply:IsPlayer() or not IsValid(ent) then return end
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if v:IsAdmin() then
|
||||
v:PrintMessage(HUD_PRINTCONSOLE, ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (model or "Unknown"))
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (model or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnedNPC", "FAdmin_Log", function(ply, ent)
|
||||
if not IsValid(ply) or not ply:IsPlayer() or not IsValid(ent) then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (ent:GetClass() or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnedVehicle", "FAdmin_Log", function(ply, ent)
|
||||
if not IsValid(ply) or not ply:IsPlayer() or not IsValid(ent) then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (ent:GetClass() or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnedEffect", "FAdmin_Log", function(ply, model, ent)
|
||||
if not IsValid(ply) or not ply:IsPlayer() or not model then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (model or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnedRagdoll", "FAdmin_Log", function(ply, model, ent)
|
||||
if not IsValid(ply) or not ply:IsPlayer() or not IsValid(ent) then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned a " .. (model or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("CanTool", "FAdmin_Log", function(ply, tr, toolclass)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Attempted to use tool " .. (toolclass or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("PlayerLeaveVehicle", "FAdmin_Log", function(ply, vehicle)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") exited a " .. (IsValid(vehicle) and vehicle:GetClass() or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("OnNPCKilled", "FAdmin_Log", function(NPC, Killer, Weapon)
|
||||
if not IsValid(NPC) then return end
|
||||
FAdmin.Log(NPC:GetClass() .. " was killed by " .. (IsValid(Killer) and (Killer:IsPlayer() and Killer:Nick() or Killer:GetClass()) or "Unknown") .. " with a " .. (IsValid(Weapon) and Weapon:GetClass() or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("OnPlayerChangedTeam", "FAdmin_Log", function(ply, oldteam, newteam)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") changed from " .. team.GetName(oldteam) .. " to " .. team.GetName(newteam))
|
||||
end)
|
||||
|
||||
hook.Add("WeaponEquip", "FAdmin_Log", function(weapon)
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(weapon) then return end
|
||||
local ply = weapon:GetOwner()
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Attempted to pick up a " .. weapon:GetClass())
|
||||
end)
|
||||
end)
|
||||
|
||||
hook.Add("PlayerDeath", "FAdmin_Log", function(ply, inflictor, Killer)
|
||||
local Nick = IsValid(ply) and ply:Nick() or "N/A"
|
||||
local SteamID = IsValid(ply) and ply:SteamID() or "N/A"
|
||||
local KillerName = IsValid(Killer) and (Killer:IsPlayer() and Killer:Nick() or Killer:GetClass()) or "N/A"
|
||||
local InflictorName = IsValid(inflictor) and inflictor:GetClass() or "N/A"
|
||||
|
||||
FAdmin.Log(Nick .. " (" .. SteamID .. ") Got killed by " .. KillerName .. " with a " .. InflictorName)
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSilentDeath", "FAdmin_Log", function(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Got killed silently")
|
||||
end)
|
||||
|
||||
hook.Add("PlayerDisconnected", "FAdmin_Log", function(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Disconnected")
|
||||
end)
|
||||
|
||||
hook.Add("PlayerInitialSpawn", "FAdmin_Log", function(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned for the first time")
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawn", "FAdmin_Log", function(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Spawned")
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpray", "FAdmin_Log", function(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Sprayed his spray")
|
||||
end)
|
||||
|
||||
hook.Add("PlayerEnteredVehicle", "FAdmin_Log", function(ply, vehicle)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Entered " .. (IsValid(vehicle) and vehicle:GetClass() or "Unknown"))
|
||||
end)
|
||||
|
||||
hook.Add("EntityRemoved", "FAdmin_Log", function(ent)
|
||||
if IsValid(ent) and ent:GetClass() == "prop_physics" then
|
||||
FAdmin.Log(ent:GetClass() .. "(" .. (ent:GetModel() or "<no model>") .. ") Got removed")
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerAuthed", "FAdmin_Log", function(ply, SteamID, _)
|
||||
if not IsValid(ply) then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. (SteamID or "Unknown Steam ID") .. ") is Authed")
|
||||
end)
|
||||
|
||||
hook.Add("PlayerNoClip", "FAdmin_Log", function(ply)
|
||||
if not IsValid(ply) or not ply:IsPlayer() then return end
|
||||
FAdmin.Log(ply:Nick() .. " (" .. ply:SteamID() .. ") Attempted to switch noclip")
|
||||
end)
|
||||
|
||||
hook.Add("ShutDown", "FAdmin_Log", function()
|
||||
FAdmin.shuttingDown = true
|
||||
FAdmin.Log("Server succesfully shut down.")
|
||||
end)
|
||||
@@ -0,0 +1,189 @@
|
||||
local showChat = CreateClientConVar("FAdmin_ShowChatNotifications", 1, true, false)
|
||||
|
||||
local HUDNote_c = 0
|
||||
local HUDNote_i = 1
|
||||
local HUDNotes = {}
|
||||
|
||||
--Notify ripped off the Sandbox notify, changed to my likings
|
||||
function FAdmin.Messages.AddMessage(MsgType, Message)
|
||||
local tab = {}
|
||||
tab.text = Message
|
||||
tab.recv = SysTime()
|
||||
tab.velx = 0
|
||||
tab.vely = -5
|
||||
surface.SetFont("GModNotify")
|
||||
local w, _ = surface.GetTextSize(Message)
|
||||
tab.x = ScrW() / 2 + w * 0.5 + (ScrW() / 20)
|
||||
tab.y = ScrH()
|
||||
tab.a = 255
|
||||
local MsgTypeNames = {"ERROR", "NOTIFY", "QUESTION", "GOOD", "BAD"}
|
||||
if not MsgTypeNames[MsgType] then return end
|
||||
tab.col = FAdmin.Messages.MsgTypes[MsgTypeNames[MsgType]].COLOR
|
||||
|
||||
table.insert(HUDNotes, tab)
|
||||
|
||||
HUDNote_c = HUDNote_c + 1
|
||||
HUDNote_i = HUDNote_i + 1
|
||||
|
||||
LocalPlayer():EmitSound("npc/turret_floor/click1.wav", 30, 100)
|
||||
end
|
||||
|
||||
usermessage.Hook("FAdmin_SendMessage", function(u) FAdmin.Messages.AddMessage(u:ReadShort(), u:ReadString()) end)
|
||||
|
||||
|
||||
local function DrawNotice(k, v, i)
|
||||
local H = ScrH() / 1024
|
||||
local x = v.x - 75 * H
|
||||
local y = v.y - 27
|
||||
surface.SetFont("GModNotify")
|
||||
local w, h = surface.GetTextSize(v.text)
|
||||
h = h + 16
|
||||
local col = v.col
|
||||
|
||||
draw.RoundedBox(4, x - w - h + 24, y - 8, w + h - 16, h, col)
|
||||
-- Draw Icon
|
||||
surface.SetDrawColor(255, 255, 255, v.a)
|
||||
|
||||
draw.DrawNonParsedSimpleText(v.text, "GModNotify", x + 1, y + 1, Color(0, 0, 0, v.a * 0.8), TEXT_ALIGN_RIGHT)
|
||||
draw.DrawNonParsedSimpleText(v.text, "GModNotify", x - 1, y - 1, Color(0, 0, 0, v.a * 0.5), TEXT_ALIGN_RIGHT)
|
||||
draw.DrawNonParsedSimpleText(v.text, "GModNotify", x + 1, y - 1, Color(0, 0, 0, v.a * 0.6), TEXT_ALIGN_RIGHT)
|
||||
draw.DrawNonParsedSimpleText(v.text, "GModNotify", x - 1, y + 1, Color(0, 0, 0, v.a * 0.6), TEXT_ALIGN_RIGHT)
|
||||
draw.DrawNonParsedSimpleText(v.text, "GModNotify", x, y, Color(255, 255, 255, v.a), TEXT_ALIGN_RIGHT)
|
||||
local ideal_y = ScrH() - (HUDNote_c - i) * h
|
||||
local ideal_x = ScrW() / 2 + w * 0.5 + (ScrW() / 20)
|
||||
local timeleft = 6 - (SysTime() - v.recv)
|
||||
|
||||
-- Cartoon style about to go thing
|
||||
if (timeleft < 0.8) then
|
||||
ideal_x = ScrW() / 2 + w * 0.5 + 200
|
||||
end
|
||||
|
||||
-- Gone!
|
||||
if (timeleft < 0.5) then
|
||||
ideal_y = ScrH() + 50
|
||||
end
|
||||
|
||||
local spd = RealFrameTime() * 15
|
||||
v.y = v.y + v.vely * spd
|
||||
v.x = v.x + v.velx * spd
|
||||
local dist = ideal_y - v.y
|
||||
v.vely = v.vely + dist * spd * 1
|
||||
|
||||
if (math.abs(dist) < 2 and math.abs(v.vely) < 0.1) then
|
||||
v.vely = 0
|
||||
end
|
||||
|
||||
dist = ideal_x - v.x
|
||||
v.velx = v.velx + dist * spd * 1
|
||||
|
||||
if math.abs(dist) < 2 and math.abs(v.velx) < 0.1 then
|
||||
v.velx = 0
|
||||
end
|
||||
|
||||
-- Friction.. kind of FPS independant.
|
||||
v.velx = v.velx * (0.95 - RealFrameTime() * 8)
|
||||
v.vely = v.vely * (0.95 - RealFrameTime() * 8)
|
||||
end
|
||||
|
||||
local function HUDPaint()
|
||||
if not HUDNotes then return end
|
||||
local i = 0
|
||||
|
||||
for k, v in ipairs(HUDNotes) do
|
||||
if v ~= 0 then
|
||||
i = i + 1
|
||||
DrawNotice(k, v, i)
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in ipairs(HUDNotes) do
|
||||
if v ~= 0 and v.recv + 6 < SysTime() then
|
||||
HUDNotes[k] = 0
|
||||
HUDNote_c = HUDNote_c - 1
|
||||
|
||||
if HUDNote_c == 0 then
|
||||
HUDNotes = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("HUDPaint", "FAdmin_MessagePaint", HUDPaint)
|
||||
|
||||
local function ConsoleMessage(um)
|
||||
MsgC(Color(255, 0, 0, 255), "(FAdmin) ", Color(200, 0, 200, 255), um:ReadString() .. "\n")
|
||||
end
|
||||
usermessage.Hook("FAdmin_ConsoleMessage", ConsoleMessage)
|
||||
|
||||
|
||||
local red = Color(255, 0, 0)
|
||||
local white = Color(190, 190, 190)
|
||||
local brown = Color(102, 51, 0)
|
||||
local blue = Color(102, 0, 255)
|
||||
|
||||
-- Inserts the instigator into a notification message
|
||||
local function insertInstigator(res, instigator, _)
|
||||
table.insert(res, brown)
|
||||
table.insert(res, FAdmin.PlayerName(instigator))
|
||||
end
|
||||
|
||||
-- Inserts the targets into the notification message
|
||||
local function insertTargets(res, _, targets)
|
||||
table.insert(res, blue)
|
||||
table.insert(res, FAdmin.TargetsToString(targets))
|
||||
end
|
||||
|
||||
local modMessage = {
|
||||
instigator = insertInstigator,
|
||||
you = function(res) table.insert(res, brown) table.insert(res, "you") end,
|
||||
targets = insertTargets,
|
||||
}
|
||||
local function showNotification(notification, instigator, targets, extraInfo)
|
||||
local res = {red, "[", white, "FAdmin", red, "] "}
|
||||
|
||||
for _, text in pairs(notification.message) do
|
||||
if modMessage[text] then modMessage[text](res, instigator, targets) continue end
|
||||
|
||||
if string.sub(text, 1, 10) == "extraInfo." then
|
||||
local id = tonumber(string.sub(text, 11))
|
||||
|
||||
table.insert(res, notification.extraInfoColors and notification.extraInfoColors[id] or white)
|
||||
table.insert(res, extraInfo[id])
|
||||
continue
|
||||
end
|
||||
|
||||
table.insert(res, white)
|
||||
table.insert(res, text)
|
||||
end
|
||||
|
||||
if showChat:GetBool() then
|
||||
chat.AddText(unpack(res))
|
||||
else
|
||||
local msgTbl = {}
|
||||
for i = 8, #res, 2 do table.insert(msgTbl, res[i]) end
|
||||
|
||||
FAdmin.Messages.AddMessage(FAdmin.Messages.MsgTypesByName[notification.msgType], table.concat(msgTbl, ""))
|
||||
|
||||
MsgC(unpack(res))
|
||||
Msg("\n")
|
||||
end
|
||||
end
|
||||
|
||||
local function receiveNotification()
|
||||
local id = net.ReadUInt(16)
|
||||
local notification = FAdmin.Notifications[id]
|
||||
local instigator = net.ReadEntity()
|
||||
|
||||
local targets = {}
|
||||
|
||||
if notification.hasTarget then
|
||||
local targetCount = net.ReadUInt(8)
|
||||
for i = 1, targetCount do
|
||||
table.insert(targets, net.ReadEntity())
|
||||
end
|
||||
end
|
||||
|
||||
local extraInfo = notification.readExtraInfo and notification.readExtraInfo()
|
||||
|
||||
showNotification(notification, instigator, targets, extraInfo)
|
||||
end
|
||||
net.Receive("FAdmin_Notification", receiveNotification)
|
||||
@@ -0,0 +1,135 @@
|
||||
FAdmin.Messages = {}
|
||||
|
||||
FAdmin.Messages.MsgTypes = {
|
||||
ERROR = {TEXTURE = "icon16/exclamation.png", COLOR = Color(255,180,0,80)},
|
||||
NOTIFY = {TEXTURE = "vgui/notices/error", COLOR = Color(255,255,0,80)},
|
||||
QUESTION = {TEXTURE = "vgui/notices/hint", COLOR = Color(0,0,255,80)},
|
||||
GOOD = {TEXTURE = "icon16/tick.png", COLOR = Color(0,255,0,80)},
|
||||
BAD = {TEXTURE = "icon16/cross.png", COLOR = Color(255,0,0,80)}
|
||||
}
|
||||
FAdmin.Messages.MsgTypesByName = {
|
||||
ERROR = 1,
|
||||
NOTIFY = 2,
|
||||
QUESTION = 3,
|
||||
GOOD = 4,
|
||||
BAD = 5,
|
||||
}
|
||||
|
||||
function FAdmin.PlayerName(ply)
|
||||
if CLIENT and ply == LocalPlayer() then return "you" end
|
||||
|
||||
if isstring(ply) then return ply end
|
||||
|
||||
return isentity(ply) and (ply:EntIndex() == 0 and "Console" or ply:Nick()) or "unknown"
|
||||
end
|
||||
|
||||
function FAdmin.TargetsToString(targets)
|
||||
if not istable(targets) then
|
||||
return FAdmin.PlayerName(targets)
|
||||
end
|
||||
|
||||
local targetCount = #targets
|
||||
if targetCount == 0 then
|
||||
return "no one"
|
||||
end
|
||||
|
||||
if targetCount == player.GetCount() and targetCount ~= 1 then
|
||||
return "everyone"
|
||||
end
|
||||
|
||||
targets = table.Copy(targets)
|
||||
local names = fn.Map(FAdmin.PlayerName, targets)
|
||||
|
||||
if #names == 1 then
|
||||
return names[1]
|
||||
end
|
||||
|
||||
return table.concat(names, ", ", 1, #names - 1) .. " and " .. names[#names]
|
||||
end
|
||||
|
||||
FAdmin.Notifications = {}
|
||||
|
||||
local validNotification = tc.checkTable{
|
||||
-- A name to identify the notification by
|
||||
name =
|
||||
tc.addHint(
|
||||
isstring,
|
||||
"The name must be a string!"
|
||||
),
|
||||
|
||||
-- Whether the notification applies to some kind of target
|
||||
hasTarget =
|
||||
tc.addHint(
|
||||
tc.optional(isbool),
|
||||
"hasTarget must either be true, false or nil!"
|
||||
),
|
||||
|
||||
-- Who receives the notification. Can be either one of the list or a function that returns a table of players
|
||||
receivers =
|
||||
tc.addHint(
|
||||
fn.FOr{tc.client, isfunction, tc.oneOf{"everyone", "admins", "superadmins", "self", "targets", "involved", "involved+admins", "involved+superadmins"}},
|
||||
"receivers must either be a function returning a table of players or one of 'admins', 'superadmins', 'everyone', 'self', 'targets', 'involved', 'involved+admins', 'involved+superadmins'"
|
||||
),
|
||||
|
||||
-- A table containing the message in parts. There are special strings
|
||||
message =
|
||||
tc.addHint(
|
||||
tc.tableOf(isstring),
|
||||
"The message field must be a table of strings! with special strings 'targets', 'you', 'instigator', 'extraInfo.#', with # a number."
|
||||
),
|
||||
|
||||
-- The message type when chat notifications are disabled. NOTIFY by default
|
||||
msgType =
|
||||
tc.default(
|
||||
"NOTIFY",
|
||||
tc.addHint(
|
||||
tc.oneOf{"ERROR", "NOTIFY", "QUESTION", "GOOD", "BAD"}, "msgType must be one of 'ERROR', 'NOTIFY', 'QUESTION', 'GOOD', 'BAD'"
|
||||
)
|
||||
),
|
||||
|
||||
-- A function that writes extra data in the net message
|
||||
writeExtraInfo =
|
||||
tc.addHint(
|
||||
tc.optional(isfunction),
|
||||
"writeExtraInfo must be a function"
|
||||
),
|
||||
|
||||
-- A function that reads the written data, formats it and puts it in a table
|
||||
readExtraInfo =
|
||||
tc.addHint(
|
||||
tc.optional(isfunction),
|
||||
"writeExtraInfo must be a function"
|
||||
),
|
||||
|
||||
-- When using extra information, this table contains the colours of the extraInfo messages
|
||||
extraInfoColors =
|
||||
tc.addHint(
|
||||
tc.optional(tc.tableOf(tc.iscolor)),
|
||||
"extraInfoColors must be a table of colours!"
|
||||
),
|
||||
|
||||
-- Whether the notification is to be logged to console
|
||||
logging =
|
||||
tc.default(true,
|
||||
tc.addHint(
|
||||
isbool,
|
||||
"logging must be a boolean!"
|
||||
)
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
FAdmin.NotificationNames = {}
|
||||
|
||||
function FAdmin.Messages.RegisterNotification(tbl)
|
||||
local correct, err = validNotification(tbl)
|
||||
|
||||
if not correct then
|
||||
error(string.format("Incorrect notification format for notification '%s'!\n\n%s", istable(tbl) and tbl.name or "unknown", err), 2)
|
||||
end
|
||||
|
||||
local key = table.insert(FAdmin.Notifications, tbl)
|
||||
FAdmin.NotificationNames[tbl.name] = key
|
||||
|
||||
return key
|
||||
end
|
||||
@@ -0,0 +1,137 @@
|
||||
util.AddNetworkString("FAdmin_Notification")
|
||||
|
||||
function FAdmin.Messages.SendMessage(ply, MsgType, text)
|
||||
if ply:EntIndex() == 0 then
|
||||
ServerLog("FAdmin: " .. text .. "\n")
|
||||
print("FAdmin: " .. text)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
umsg.Start("FAdmin_SendMessage", ply)
|
||||
umsg.Short(MsgType)
|
||||
umsg.String(text)
|
||||
umsg.End()
|
||||
ply:PrintMessage(HUD_PRINTCONSOLE, text)
|
||||
end
|
||||
|
||||
function FAdmin.Messages.SendMessageAll(text, MsgType)
|
||||
FAdmin.Log("FAdmin message to everyone: " .. text)
|
||||
umsg.Start("FAdmin_SendMessage")
|
||||
umsg.Short(MsgType)
|
||||
umsg.String(text)
|
||||
umsg.End()
|
||||
|
||||
for _, ply in ipairs(player.GetAll()) do
|
||||
ply:PrintMessage(HUD_PRINTCONSOLE, text)
|
||||
end
|
||||
end
|
||||
|
||||
function FAdmin.Messages.ConsoleNotify(ply, message)
|
||||
umsg.Start("FAdmin_ConsoleMessage", ply)
|
||||
umsg.String(message)
|
||||
umsg.End()
|
||||
end
|
||||
|
||||
function FAdmin.Messages.ActionMessage(ply, target, messageToPly, MessageToTarget, LogMSG)
|
||||
if not target then return end
|
||||
local Targets = (target.IsPlayer and target:IsPlayer() and target:Nick()) or ""
|
||||
|
||||
local plyNick = IsValid(ply) and ply:IsPlayer() and ply:Nick() or "Console"
|
||||
local plySteamID = IsValid(ply) and ply:IsPlayer() and ply:SteamID() or "Console"
|
||||
local bad = false
|
||||
|
||||
if ply ~= target then
|
||||
if istable(target) then
|
||||
if table.IsEmpty(target) then Targets = "no one" bad = true end
|
||||
for k, v in ipairs(target) do
|
||||
local suffix = ((k == #target-1) and " and ") or (k ~= #target and ", ") or ""
|
||||
local Name = (v == ply and "yourself") or v:Nick()
|
||||
|
||||
if v ~= ply then FAdmin.Messages.SendMessage(v, 2, string.format(MessageToTarget, plyNick)) end
|
||||
Targets = Targets .. Name .. suffix
|
||||
end
|
||||
else
|
||||
FAdmin.Messages.SendMessage(target, 2, string.format(MessageToTarget, plyNick))
|
||||
end
|
||||
|
||||
FAdmin.Messages.SendMessage(ply, bad and 1 or 4, string.format(messageToPly, Targets))
|
||||
|
||||
else
|
||||
FAdmin.Messages.SendMessage(ply, bad and 1 or 4, string.format(messageToPly, "yourself"))
|
||||
end
|
||||
|
||||
local action = plyNick .. " (" .. plySteamID .. ") " .. string.format(LogMSG, Targets:gsub("yourself", "themselves"))
|
||||
FAdmin.Log("FAdmin Action: " .. action)
|
||||
|
||||
local haspriv = fn.Partial(fn.Flip(FAdmin.Access.PlayerHasPrivilege), "SeeAdmins")
|
||||
local plys = fn.Filter(haspriv, player.GetAll())
|
||||
if table.IsEmpty(plys) then return end
|
||||
FAdmin.Messages.ConsoleNotify(plys, action)
|
||||
end
|
||||
|
||||
|
||||
local function logNotification(notification, instigator, targets, extraInfo)
|
||||
local msgs = table.Copy(notification.message)
|
||||
|
||||
local function replace(val)
|
||||
if val == "instigator" then return FAdmin.PlayerName(instigator) end
|
||||
if val == "targets" then return FAdmin.TargetsToString(targets) end
|
||||
if string.sub(val, 1, 10) == "extraInfo." then return tostring(extraInfo[tonumber(string.sub(val, 11))]) end
|
||||
|
||||
return val
|
||||
end
|
||||
|
||||
fn.Map(replace, msgs)
|
||||
|
||||
FAdmin.Log(table.concat(msgs))
|
||||
end
|
||||
|
||||
local receiversToPlayers -- allows usage of variable inside
|
||||
receiversToPlayers = {
|
||||
everyone = player.GetAll,
|
||||
admins = function() return table.ClearKeys(fn.Filter(tc.player.IsAdmin, player.GetAll())) end,
|
||||
superadmins = function() return table.ClearKeys(fn.Filter(tc.player.IsSuperAdmin, player.GetAll())) end,
|
||||
self = fn.Id,
|
||||
targets = function(_, t) return t end,
|
||||
involved = function(i, t) local res = table.Copy(istable(t) and t or {t}) table.insert(res, i) return res end,
|
||||
["involved+admins"] = function(i, t) return table.Add(receiversToPlayers.admins(i, t), receiversToPlayers.involved(i, t)) end,
|
||||
["involved+superadmins"] = function(i, t) return table.Add(receiversToPlayers.superadmins(i, t), receiversToPlayers.involved(i, t)) end,
|
||||
}
|
||||
function FAdmin.Messages.FireNotification(name, instigator, targets, extraInfo)
|
||||
local notId = FAdmin.NotificationNames[name]
|
||||
|
||||
if not notId then
|
||||
error(string.format("Notification '%s' does not exist!", name), 2)
|
||||
end
|
||||
|
||||
local notification = FAdmin.Notifications[notId]
|
||||
local receivers = receiversToPlayers[notification.receivers]
|
||||
receivers = receivers and receivers(instigator, targets) or notification.receivers(instigator, targets)
|
||||
|
||||
local targetCount = istable(targets) and #targets or not IsValid(targets) and 0 or 1
|
||||
|
||||
net.Start("FAdmin_Notification")
|
||||
net.WriteUInt(notId, 16)
|
||||
|
||||
net.WriteEntity(instigator)
|
||||
|
||||
if notification.hasTarget then
|
||||
net.WriteUInt(targetCount, 8)
|
||||
|
||||
if istable(targets) then
|
||||
for _, t in ipairs(targets) do
|
||||
net.WriteEntity(t)
|
||||
end
|
||||
else
|
||||
net.WriteEntity(targets)
|
||||
end
|
||||
end
|
||||
|
||||
if notification.writeExtraInfo then notification.writeExtraInfo(extraInfo) end
|
||||
net.Send(receivers)
|
||||
|
||||
if notification.logging then
|
||||
logNotification(notification, instigator, targets, extraInfo)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
local MOTDPage = CreateConVar("_FAdmin_MOTDPage", "default", {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_SERVER_CAN_EXECUTE})
|
||||
|
||||
if CLIENT then -- I can't be bothered to make a cl_init when there's a shared file with just one line in it.
|
||||
FAdmin.StartHooks["MOTD"] = function()
|
||||
FAdmin.ScoreBoard.Server:AddServerAction("Place MOTD", "fadmin/icons/motd", Color(155, 0, 0, 255), function(ply) return ply:IsSuperAdmin() end, function()
|
||||
RunConsoleCommand("_FAdmin", "CreateMOTD")
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting("Set MOTD page", "fadmin/icons/motd", Color(0, 0, 155, 255), function(ply) return ply:IsSuperAdmin() end, function()
|
||||
local Window = vgui.Create("DFrame")
|
||||
Window:SetTitle("Set MOTD page")
|
||||
Window:SetDraggable(false)
|
||||
Window:ShowCloseButton(false)
|
||||
Window:SetBackgroundBlur(true)
|
||||
Window:SetDrawOnTop(true)
|
||||
|
||||
local InnerPanel = vgui.Create("DPanel", Window)
|
||||
InnerPanel:SetPaintBackground(false) -- clear background
|
||||
|
||||
local Text = vgui.Create("DLabel", InnerPanel)
|
||||
Text:SetText("Set the MOTD page. Click default to reset the MOTD to default.")
|
||||
Text:SizeToContents()
|
||||
Text:SetContentAlignment(5)
|
||||
Text:SetTextColor(color_white)
|
||||
|
||||
local TextEntry = vgui.Create("DTextEntry", InnerPanel)
|
||||
TextEntry:SetText(MOTDPage:GetString())
|
||||
TextEntry.OnEnter = function() Window:Close() RunConsoleCommand("_FAdmin", "motdpage", TextEntry:GetValue()) end
|
||||
function TextEntry:OnFocusChanged(changed)
|
||||
self:RequestFocus()
|
||||
self:SelectAllText(true)
|
||||
end
|
||||
|
||||
local ButtonPanel = vgui.Create("DPanel", Window)
|
||||
ButtonPanel:SetPaintBackground(false) -- clear background
|
||||
ButtonPanel:SetTall(30)
|
||||
|
||||
local Button = vgui.Create("DButton", ButtonPanel)
|
||||
Button:SetText("OK")
|
||||
Button:SizeToContents()
|
||||
Button:SetTall(20)
|
||||
Button:SetWide(Button:GetWide() + 20)
|
||||
Button:SetPos(5, 5)
|
||||
|
||||
Button.DoClick = function()
|
||||
Window:Close()
|
||||
RunConsoleCommand("_FAdmin", "motdpage", TextEntry:GetValue())
|
||||
end
|
||||
|
||||
local ButtonDefault = vgui.Create("DButton", ButtonPanel)
|
||||
ButtonDefault:SetText("Default")
|
||||
ButtonDefault:SizeToContents()
|
||||
ButtonDefault:SetTall(20)
|
||||
ButtonDefault:SetWide(Button:GetWide() + 20)
|
||||
ButtonDefault:SetPos(5, 5)
|
||||
ButtonDefault.DoClick = function() Window:Close() RunConsoleCommand("_FAdmin", "motdpage", "default") end
|
||||
ButtonDefault:MoveRightOf(Button, 5)
|
||||
|
||||
local ButtonCancel = vgui.Create("DButton", ButtonPanel)
|
||||
ButtonCancel:SetText("Cancel")
|
||||
ButtonCancel:SizeToContents()
|
||||
ButtonCancel:SetTall(20)
|
||||
ButtonCancel:SetWide(Button:GetWide() + 20)
|
||||
ButtonCancel:SetPos(5, 5)
|
||||
ButtonCancel.DoClick = function() Window:Close() end
|
||||
ButtonCancel:MoveRightOf(ButtonDefault, 5)
|
||||
|
||||
ButtonPanel:SetWide(Button:GetWide() + 5 + ButtonCancel:GetWide() + 10 + ButtonDefault:GetWide() + 5)
|
||||
|
||||
local w, h = Text:GetSize()
|
||||
w = math.max(w, 400)
|
||||
Window:SetSize(w + 50, h + 25 + 75 + 10)
|
||||
Window:Center()
|
||||
InnerPanel:StretchToParent(5, 25, 5, 45)
|
||||
Text:StretchToParent(5, 5, 5, 35)
|
||||
TextEntry:StretchToParent(5, nil, 5, nil)
|
||||
TextEntry:AlignBottom(5)
|
||||
TextEntry:RequestFocus()
|
||||
ButtonPanel:CenterHorizontal()
|
||||
ButtonPanel:AlignBottom(8)
|
||||
Window:MakePopup()
|
||||
Window:DoModal()
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
FAdmin.MOTD = {}
|
||||
local MOTDPage
|
||||
|
||||
sql.Query([[CREATE TABLE IF NOT EXISTS FADMIN_MOTD(
|
||||
'map' TEXT NOT NULL PRIMARY KEY,
|
||||
x INTEGER NOT NULL,
|
||||
y INTEGER NOT NULL,
|
||||
z INTEGER NOT NULL,
|
||||
pitch INTEGER NOT NULL,
|
||||
yaw INTEGER NOT NULL,
|
||||
roll INTEGER NOT NULL
|
||||
);]])
|
||||
|
||||
local MOTD = sql.Query("SELECT * FROM FADMIN_MOTD WHERE LOWER(map) = " .. MySQLite.SQLStr(string.lower(game.GetMap())) .. ";")
|
||||
|
||||
hook.Add("InitPostEntity", "PlaceMOTD", function()
|
||||
if not MOTD or (not MOTD[1] and not MOTD["1"]) then return end
|
||||
MOTD = MOTD[1] or MOTD["1"]
|
||||
|
||||
local ent = ents.Create("fadmin_motd")
|
||||
ent:SetPos(Vector(MOTD.x, MOTD.y, MOTD.z))
|
||||
ent:SetAngles(Angle(MOTD.pitch % 360, MOTD.yaw % 360, MOTD.roll % 360))
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
if file.Exists("FAdmin/CurMOTDPage.txt", "DATA") and file.Read("FAdmin/CurMOTDPage.txt", "DATA") ~= "" then
|
||||
game.ConsoleCommand("_FAdmin_MOTDPage \"" .. file.Read("FAdmin/CurMOTDPage.txt", "DATA") .. "\"\n")
|
||||
end
|
||||
end)
|
||||
|
||||
function FAdmin.MOTD.SaveMOTD(ent, ply)
|
||||
local pos = ent:GetPos()
|
||||
local ang = ent:GetAngles()
|
||||
|
||||
local map, x, y, z, pitch, yaw, roll =
|
||||
string.lower(game.GetMap()),
|
||||
pos.x, pos.y, pos.z,
|
||||
ang.p, ang.y, ang.r
|
||||
if MOTD then
|
||||
sql.Query([[UPDATE FADMIN_MOTD SET ]]
|
||||
.. "x = " .. MySQLite.SQLStr(x) .. ", "
|
||||
.. "y = " .. MySQLite.SQLStr(y) .. ", "
|
||||
.. "z = " .. MySQLite.SQLStr(z) .. ", "
|
||||
.. "pitch = " .. MySQLite.SQLStr(pitch) .. ", "
|
||||
.. "yaw = " .. MySQLite.SQLStr(yaw) .. ", "
|
||||
.. "roll = " .. MySQLite.SQLStr(roll)
|
||||
.. " WHERE map = " .. MySQLite.SQLStr(map) .. ";")
|
||||
else
|
||||
sql.Query([[INSERT INTO FADMIN_MOTD VALUES(]]
|
||||
.. MySQLite.SQLStr(map) .. ", "
|
||||
.. MySQLite.SQLStr(x) .. ", "
|
||||
.. MySQLite.SQLStr(y) .. ", "
|
||||
.. MySQLite.SQLStr(z) .. ", "
|
||||
.. MySQLite.SQLStr(pitch) .. ", "
|
||||
.. MySQLite.SQLStr(yaw) .. ", "
|
||||
.. MySQLite.SQLStr(roll)
|
||||
.. ");")
|
||||
end
|
||||
FAdmin.Messages.SendMessage(ply, 4, "MOTD position saved!")
|
||||
end
|
||||
|
||||
function FAdmin.MOTD.RemoveMOTD(ent, ply)
|
||||
sql.Query("DELETE FROM FADMIN_MOTD WHERE map = " .. MySQLite.SQLStr(string.lower(game.GetMap())) .. ";")
|
||||
FAdmin.Messages.SendMessage(ply, 4, "MOTD removed!")
|
||||
end
|
||||
|
||||
function FAdmin.MOTD.SetMOTDPage(ply, cmd, args)
|
||||
if not args[1] then
|
||||
FAdmin.Messages.SendMessage(ply, 4, "MOTD is set to: " .. MOTDPage:GetString())
|
||||
return false
|
||||
end
|
||||
if ply:EntIndex() ~= 0 and (not ply.IsSuperAdmin or not ply:IsSuperAdmin()) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
RunConsoleCommand("_FAdmin_MOTDPage", args[1])
|
||||
file.Write("FAdmin/CurMOTDPage.txt", args[1])
|
||||
|
||||
return true, args[1]
|
||||
end
|
||||
|
||||
local function CreateMOTD(ply)
|
||||
if IsValid(ply) and not ply:IsSuperAdmin() then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
local MOTDEnt = ents.Create("fadmin_motd")
|
||||
MOTDEnt:SpawnFunction(ply, ply:GetEyeTrace())
|
||||
|
||||
return true, MOTDEnt
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["MOTD"] = function()
|
||||
MOTDPage = GetConVar("_FAdmin_MOTDPage")
|
||||
FAdmin.Commands.AddCommand("MOTDPage", FAdmin.MOTD.SetMOTDPage)
|
||||
FAdmin.Commands.AddCommand("CreateMOTD", CreateMOTD)
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
local AdminsCanPickUpPlayers = CreateConVar("AdminsCanPickUpPlayers", 1, {FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE})
|
||||
local PlayersCanPickUpPlayers = CreateConVar("PlayersCanPickUpPlayers", 0, {FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE})
|
||||
|
||||
FAdmin.StartHooks["PickUpPlayers"] = function()
|
||||
FAdmin.Access.AddPrivilege("PickUpPlayers", 2)
|
||||
FAdmin.ScoreBoard.Server:AddPlayerAction(function() return (AdminsCanPickUpPlayers:GetBool() and "Disable" or "Enable") .. " Admin>Player pickup" end,
|
||||
function() return "fadmin/icons/pickup", AdminsCanPickUpPlayers:GetBool() and "fadmin/icons/disable" end, Color(0, 155, 0, 255), function(ply) return ply:IsSuperAdmin() end, function(button)
|
||||
button:SetImage2((not AdminsCanPickUpPlayers:GetBool() and "fadmin/icons/disable") or "null")
|
||||
button:SetText((not AdminsCanPickUpPlayers:GetBool() and "Disable" or "Enable") .. " Admin>Player pickup")
|
||||
button:GetParent():InvalidateLayout()
|
||||
RunConsoleCommand("_FAdmin", "AdminsCanPickUpPlayers", AdminsCanPickUpPlayers:GetBool() and "0" or "1")
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddPlayerAction(function() return (PlayersCanPickUpPlayers:GetBool() and "Disable" or "Enable") .. " Player>Player pickup" end,
|
||||
function() return "fadmin/icons/pickup", PlayersCanPickUpPlayers:GetBool() and "fadmin/icons/disable" end, Color(0, 155, 0, 255), function(ply) return ply:IsSuperAdmin() end, function(button)
|
||||
button:SetImage2((not PlayersCanPickUpPlayers:GetBool() and "fadmin/icons/disable") or "null")
|
||||
button:SetText((not PlayersCanPickUpPlayers:GetBool() and "Disable" or "Enable") .. " Player>Player pickup")
|
||||
button:GetParent():InvalidateLayout()
|
||||
RunConsoleCommand("_FAdmin", "PlayersCanPickUpPlayers", PlayersCanPickUpPlayers:GetBool() and "0" or "1")
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
local AdminsCanPickUpPlayers = CreateConVar("AdminsCanPickUpPlayers", 1, {FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE})
|
||||
local PlayersCanPickUpPlayers = CreateConVar("PlayersCanPickUpPlayers", 0, {FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE})
|
||||
|
||||
hook.Add("PhysgunPickup", "FAdmin_PickUpPlayers", function(ply, ent)
|
||||
if not IsValid(ent) or not ent:IsPlayer() then return end
|
||||
|
||||
if PlayersCanPickUpPlayers:GetBool() or AdminsCanPickUpPlayers:GetBool() and
|
||||
FAdmin.Access.PlayerHasPrivilege(ply, "PickUpPlayers", ent) and tobool(ply:GetInfo("cl_pickupplayers")) then
|
||||
ent:SetMoveType(MOVETYPE_NONE)
|
||||
ent:Freeze(true)
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PhysgunDrop", "FAdmin_PickUpPlayers", function(ply, ent)
|
||||
if IsValid(ent) and ent:IsPlayer() then
|
||||
ent:SetMoveType(MOVETYPE_WALK)
|
||||
ent:Freeze(false)
|
||||
end
|
||||
end)
|
||||
|
||||
local function ChangeAdmin(ply, cmd, args)
|
||||
if not ply:IsSuperAdmin() then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
|
||||
local Value = tonumber(args[1])
|
||||
if Value ~= 1 and Value ~= 0 then return false end
|
||||
RunConsoleCommand("AdminsCanPickUpPlayers", Value)
|
||||
|
||||
FAdmin.SaveSetting("AdminsCanPickUpPlayers", Value)
|
||||
|
||||
local OnOff = (tobool(Value) and "on") or "off"
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), ply:Nick() .. " turned Admin>Player pickup " .. OnOff, "Admin>Player pickup has been turned " .. OnOff, "Turned Admin>Player pickup " .. OnOff)
|
||||
|
||||
return true, OnOff
|
||||
end
|
||||
|
||||
local function ChangeUser(ply, cmd, args)
|
||||
if not ply:IsSuperAdmin() then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
|
||||
local Value = tonumber(args[1])
|
||||
if Value ~= 1 and Value ~= 0 then return false end
|
||||
RunConsoleCommand("PlayersCanPickUpPlayers", Value)
|
||||
|
||||
FAdmin.SaveSetting("PlayersCanPickUpPlayers", Value)
|
||||
|
||||
local OnOff = (tobool(Value) and "on") or "off"
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), ply:Nick() .. " turned Player>Player pickup " .. OnOff, "Player>Player pickup has been turned " .. OnOff, "Turned Player>Player pickup " .. OnOff)
|
||||
|
||||
return true, OnOff
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["PickUpPlayers"] = function()
|
||||
FAdmin.Access.AddPrivilege("PickUpPlayers", 2)
|
||||
FAdmin.Commands.AddCommand("AdminsCanPickUpPlayers", ChangeAdmin)
|
||||
FAdmin.Commands.AddCommand("PlayersCanPickUpPlayers", ChangeUser)
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
FAdmin.StartHooks["zzSetTeam"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "setteam",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " set the team of ", "targets", " to ", "extraInfo.1"},
|
||||
readExtraInfo = function()
|
||||
return {team.GetName(net.ReadUInt(16))}
|
||||
end,
|
||||
extraInfoColors = {Color(255, 102, 0)}
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("SetTeam", 2)
|
||||
FAdmin.Commands.AddCommand("SetTeam", nil, "<Player>", "<Team>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Set team", "fadmin/icons/changeteam", Color(0, 200, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "SetTeam", ply) end, function(ply, button)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Teams:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
|
||||
menu:AddPanel(Title)
|
||||
for k, v in SortedPairsByMemberValue(team.GetAllTeams(), "Name") do
|
||||
local uid = ply:UserID()
|
||||
menu:AddOption(v.Name, function() RunConsoleCommand("_FAdmin", "setteam", uid, k) end)
|
||||
end
|
||||
menu:Open()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
local function checkDarkRP(ply, target, t)
|
||||
if not DarkRP then return true end
|
||||
|
||||
local TEAM = RPExtraTeams[t]
|
||||
if not TEAM then return true end
|
||||
|
||||
if TEAM.customCheck then
|
||||
local ret = TEAM.customCheck(target)
|
||||
if ret ~= nil and not (ply:IsAdmin() and GAMEMODE.Config.adminBypassJobRestrictions) then return ret end
|
||||
end
|
||||
|
||||
local hookValue = hook.Call("playerCanChangeTeam", nil, target, t, true)
|
||||
if hookValue == false then return false end
|
||||
|
||||
local a = TEAM.admin
|
||||
if a > 0 and not target:IsAdmin()
|
||||
or a > 1 and not target:IsSuperAdmin()
|
||||
then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function SetTeam(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local targetsSet = {}
|
||||
for k, v in pairs(team.GetAllTeams()) do
|
||||
if k == tonumber(args[2]) or string.lower(v.Name) == string.lower(args[2] or "") then
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "SetTeam", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
local setTeam = target.changeTeam or target.SetTeam -- DarkRP compatibility
|
||||
if IsValid(target) and checkDarkRP(ply, target, k) then
|
||||
setTeam(target, k, true)
|
||||
table.insert(targetsSet, target)
|
||||
end
|
||||
end
|
||||
|
||||
if not table.IsEmpty(targetsSet) then
|
||||
FAdmin.Messages.FireNotification("setteam", ply, targetsSet, {k})
|
||||
else
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Could not set team")
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["zzSetTeam"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "setteam",
|
||||
hasTarget = true,
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
message = {"instigator", " set the team of ", "targets", " to ", "extraInfo.1"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("SetTeam", SetTeam)
|
||||
|
||||
FAdmin.Access.AddPrivilege("SetTeam", 2)
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
FAdmin.StartHooks["Chatmute"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "chatmute",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " chat muted ", "targets", " ", "extraInfo.1"},
|
||||
readExtraInfo = function()
|
||||
local time = net.ReadUInt(16)
|
||||
|
||||
return {time == 0 and FAdmin.PlayerActions.commonTimes[time] or string.format("for %s", FAdmin.PlayerActions.commonTimes[time] or (time .. " seconds"))}
|
||||
end
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "chatunmute",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " chat unmuted ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Chatmute", 2)
|
||||
FAdmin.Commands.AddCommand("Chatmute", nil, "<Player>")
|
||||
FAdmin.Commands.AddCommand("UnChatmute", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_chatmuted") then return "Unmute chat" end
|
||||
return "Mute chat"
|
||||
end, function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_chatmuted") then return "fadmin/icons/chatmute" end
|
||||
return "fadmin/icons/chatmute", "fadmin/icons/disable"
|
||||
end, Color(255, 130, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Chatmute", ply) end, function(ply, button)
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_chatmuted") then
|
||||
FAdmin.PlayerActions.addTimeMenu(function(secs)
|
||||
RunConsoleCommand("_FAdmin", "chatmute", ply:UserID(), secs)
|
||||
button:SetImage2("null")
|
||||
button:SetText("Unmute chat")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "UnChatmute", ply:UserID())
|
||||
end
|
||||
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Mute chat")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
local function MuteChat(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1]) or {}
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local time = tonumber(args[2] or 0)
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Chatmute", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and not target:FAdmin_GetGlobal("FAdmin_chatmuted") then
|
||||
target:FAdmin_SetGlobal("FAdmin_chatmuted", true)
|
||||
|
||||
if time == 0 then continue end
|
||||
|
||||
timer.Simple(time, function()
|
||||
if not IsValid(target) or not target:FAdmin_GetGlobal("FAdmin_chatmuted") then return false end
|
||||
target:FAdmin_SetGlobal("FAdmin_chatmuted", false)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("chatmute", ply, targets, {time})
|
||||
|
||||
return true, targets, time
|
||||
end
|
||||
|
||||
local function UnMuteChat(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Chatmute", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and target:FAdmin_GetGlobal("FAdmin_chatmuted") then
|
||||
target:FAdmin_SetGlobal("FAdmin_chatmuted", false)
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.FireNotification("chatunmute", ply, targets)
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Chatmute"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "chatmute",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
message = {"instigator", " chat muted ", "targets", " ", "extraInfo.1"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "chatunmute",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
message = {"instigator", " chat unmuted ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("Chatmute", MuteChat)
|
||||
FAdmin.Commands.AddCommand("UnChatmute", UnMuteChat)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Chatmute", 2)
|
||||
end
|
||||
|
||||
hook.Add("PlayerSay", "FAdmin_Chatmute", function(ply, text, Team, dead)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_chatmuted") then return "" end
|
||||
end)
|
||||
@@ -0,0 +1,26 @@
|
||||
FAdmin.StartHooks["zz_Cloak"] = function()
|
||||
FAdmin.Access.AddPrivilege("Cloak", 2)
|
||||
FAdmin.Commands.AddCommand("Cloak", nil, "<Player>")
|
||||
FAdmin.Commands.AddCommand("Uncloak", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_cloaked") then return "Uncloak" end
|
||||
return "Cloak"
|
||||
end, function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_cloaked") then return "fadmin/icons/cloak", "fadmin/icons/disable" end
|
||||
return "fadmin/icons/cloak"
|
||||
end, Color(0, 200, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Cloak", ply) end, function(ply, button)
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_cloaked") then
|
||||
RunConsoleCommand("_FAdmin", "Cloak", ply:UserID())
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "Uncloak", ply:UserID())
|
||||
end
|
||||
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_cloaked") then button:SetImage2("fadmin/icons/disable") button:SetText("Uncloak") button:GetParent():InvalidateLayout() return end
|
||||
button:SetImage2("null")
|
||||
button:SetText("Cloak")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
local CloakThink
|
||||
|
||||
local function Cloak(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1]) or {ply}
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Cloak", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and not target:FAdmin_GetGlobal("FAdmin_cloaked") then
|
||||
target:FAdmin_SetGlobal("FAdmin_cloaked", true)
|
||||
target:SetNoDraw(true)
|
||||
for _, v in ipairs(target:GetWeapons()) do
|
||||
v:SetNoDraw(true)
|
||||
end
|
||||
|
||||
for _, v in ipairs(ents.FindByClass("physgun_beam")) do
|
||||
if v:GetParent() == target then
|
||||
v:SetNoDraw(true)
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("Think", "FAdmin_Cloak", CloakThink)
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.ActionMessage(ply, targets, "You have cloaked %s", "You were cloaked by %s", "Cloaked %s")
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
local function UnCloak(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1]) or {ply}
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Cloak", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and target:FAdmin_GetGlobal("FAdmin_cloaked") then
|
||||
target:FAdmin_SetGlobal("FAdmin_cloaked", false)
|
||||
|
||||
target:SetNoDraw(false)
|
||||
|
||||
for _, v in ipairs(target:GetWeapons()) do
|
||||
v:SetNoDraw(false)
|
||||
end
|
||||
|
||||
for _, v in ipairs(ents.FindByClass("physgun_beam")) do
|
||||
if v:GetParent() == target then
|
||||
v:SetNoDraw(false)
|
||||
end
|
||||
end
|
||||
|
||||
target.FAdmin_CloakWeapon = nil
|
||||
|
||||
local RemoveThink = true
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if v:FAdmin_GetGlobal("FAdmin_cloaked") then
|
||||
RemoveThink = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if RemoveThink then hook.Remove("Think", "FAdmin_Cloak") end
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.ActionMessage(ply, targets, "You have uncloaked %s", "You were uncloaked by %s", "Uncloaked %s")
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Cloak"] = function()
|
||||
FAdmin.Commands.AddCommand("Cloak", Cloak)
|
||||
FAdmin.Commands.AddCommand("Uncloak", UnCloak)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Cloak", 2)
|
||||
end
|
||||
|
||||
function CloakThink()
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
local ActiveWeapon = v:GetActiveWeapon()
|
||||
if v:FAdmin_GetGlobal("FAdmin_cloaked") and ActiveWeapon:IsValid() and ActiveWeapon ~= v.FAdmin_CloakWeapon then
|
||||
v.FAdmin_CloakWeapon = ActiveWeapon
|
||||
ActiveWeapon:SetNoDraw(true)
|
||||
|
||||
if ActiveWeapon:GetClass() == "weapon_physgun" then
|
||||
for a,b in ipairs(ents.FindByClass("physgun_beam")) do
|
||||
if b:GetParent() == v then
|
||||
b:SetNoDraw(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
FAdmin.StartHooks["Freeze"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "freeze",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " froze ", "targets", " ", "extraInfo.1"},
|
||||
readExtraInfo = function()
|
||||
local time = net.ReadUInt(16)
|
||||
|
||||
return {time == 0 and FAdmin.PlayerActions.commonTimes[time] or string.format("for %s", FAdmin.PlayerActions.commonTimes[time] or (time .. " seconds"))}
|
||||
end
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unfreeze",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " unfroze ", "targets"},
|
||||
}
|
||||
|
||||
|
||||
FAdmin.Access.AddPrivilege("Freeze", 2)
|
||||
FAdmin.Commands.AddCommand("freeze", nil, "<Player>")
|
||||
FAdmin.Commands.AddCommand("unfreeze", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_frozen") then return "Unfreeze" end
|
||||
return "Freeze"
|
||||
end, function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_frozen") then return "fadmin/icons/freeze", "fadmin/icons/disable" end
|
||||
return "fadmin/icons/freeze"
|
||||
end, Color(255, 130, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Freeze", ply) end, function(ply, button)
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_frozen") then
|
||||
FAdmin.PlayerActions.addTimeMenu(function(secs)
|
||||
RunConsoleCommand("_FAdmin", "freeze", ply:UserID(), secs)
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Unfreeze")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "unfreeze", ply:UserID())
|
||||
end
|
||||
|
||||
button:SetImage2("null")
|
||||
button:SetText("Freeze")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
local function Freeze(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local time = tonumber(args[2]) or 0
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Freeze", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and not target:FAdmin_GetGlobal("FAdmin_frozen") then
|
||||
target:FAdmin_SetGlobal("FAdmin_frozen", true)
|
||||
target:Lock()
|
||||
|
||||
if time == 0 then continue end
|
||||
|
||||
timer.Simple(time, function()
|
||||
if not IsValid(target) or not target:FAdmin_GetGlobal("FAdmin_frozen") then return end
|
||||
target:FAdmin_SetGlobal("FAdmin_frozen", false)
|
||||
target:UnLock()
|
||||
end)
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.FireNotification("freeze", ply, targets, {time})
|
||||
|
||||
return true, targets, time
|
||||
end
|
||||
|
||||
local function Unfreeze(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Freeze", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and target:FAdmin_GetGlobal("FAdmin_frozen") then
|
||||
target:FAdmin_SetGlobal("FAdmin_frozen", false)
|
||||
target:UnLock()
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("unfreeze", ply, targets)
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Freeze"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "freeze",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
message = {"instigator", " froze ", "targets", " ", "extraInfo.1"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unfreeze",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
message = {"instigator", " unfroze ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("freeze", Freeze)
|
||||
FAdmin.Commands.AddCommand("unfreeze", Unfreeze)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Freeze", 2)
|
||||
end
|
||||
|
||||
local disallow = function(ply) if ply:FAdmin_GetGlobal("FAdmin_frozen") then return false end end
|
||||
|
||||
hook.Add("PlayerSpawnObject", "FAdmin_jail", disallow)
|
||||
hook.Add("CanPlayerSuicide", "FAdmin_jail", disallow)
|
||||
@@ -0,0 +1,164 @@
|
||||
-- Controls for the give weapons menu. These are litterally copied and edited from the garry's mod code.
|
||||
-- Remaking them in case the gamemode is not derived from sandbox
|
||||
-- Copying from garry's mod code because I'm lazy and because it looks good.
|
||||
|
||||
|
||||
-- Weapon icon:
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetSize(83, 83)
|
||||
|
||||
self.Label = vgui.Create("DLabel", self)
|
||||
|
||||
self:SetKeepAspect(true)
|
||||
self:SetDrawBorder(true)
|
||||
self.m_Image:SetPaintedManually(true)
|
||||
end
|
||||
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.Label:SizeToContents()
|
||||
self.Label:SetFont("TabLarge")
|
||||
self.Label:SetTextColor(color_white)
|
||||
self.Label:SetContentAlignment(5)
|
||||
self.Label:SetWide(self:GetWide())
|
||||
self.Label:AlignBottom(2)
|
||||
|
||||
DImageButton.PerformLayout(self)
|
||||
|
||||
if self.imgAdmin then
|
||||
self.imgAdmin:SizeToContents()
|
||||
self.imgAdmin:AlignTop(4)
|
||||
self.imgAdmin:AlignRight(4)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:CreateAdminIcon()
|
||||
self.imgAdmin = vgui.Create("DImage", self)
|
||||
self.imgAdmin:SetImage("icon16/shield.png") -- SilkIcons are now merged into GMOD as materials/icon16
|
||||
self.imgAdmin:SetTooltip("#Admin Only")
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
local w, h = self:GetSize()
|
||||
self.m_Image:Paint()
|
||||
|
||||
surface.SetDrawColor(30, 30, 30, 200)
|
||||
surface.DrawRect(0, h - 16, w, 16)
|
||||
end
|
||||
|
||||
function PANEL:Setup(NiceName, SpawnName, IconMaterial, AdminOnly, Parent, IsAmmo)
|
||||
self.Label:SetText(DarkRP.deLocalise(NiceName))
|
||||
|
||||
self.DoClick = function() Parent:DoGiveWeapon(SpawnName, IsAmmo) end
|
||||
self.DoRightClick = function() end
|
||||
|
||||
if not IconMaterial then
|
||||
IconMaterial = "VGUI/entities/" .. SpawnName
|
||||
end
|
||||
|
||||
self:SetOnViewMaterial(IconMaterial, "vgui/swepicon")
|
||||
|
||||
if AdminOnly then self:CreateAdminIcon() end
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
local WeaponIcon = vgui.RegisterTable(PANEL, "DImageButton")
|
||||
|
||||
-- Full panel:
|
||||
local PANEL2 = {}
|
||||
|
||||
function PANEL2:Init()
|
||||
self.PanelList = vgui.Create("DPanelList", self)
|
||||
self.PanelList:SetPadding(4)
|
||||
self.PanelList:SetSpacing(2)
|
||||
self.PanelList:EnableVerticalScrollbar(true)
|
||||
end
|
||||
|
||||
function PANEL2:BuildList()
|
||||
self.PanelList:Clear()
|
||||
|
||||
if not self.HideAmmo then
|
||||
local AmmoCat = vgui.Create("DCollapsibleCategory", self)
|
||||
self.PanelList:AddItem(AmmoCat)
|
||||
AmmoCat:SetLabel("Give ammo")
|
||||
|
||||
local AmmoPan = vgui.Create("DPanelList")
|
||||
AmmoCat:SetContents(AmmoPan)
|
||||
AmmoPan:EnableHorizontal(true)
|
||||
AmmoPan:SetPaintBackground(false)
|
||||
AmmoPan:SetSpacing(2)
|
||||
AmmoPan:SetPadding(2)
|
||||
AmmoPan:SetAutoSize(true)
|
||||
|
||||
for k in SortedPairs(FAdmin.AmmoTypes) do
|
||||
local Icon = vgui.CreateFromTable(WeaponIcon, self)
|
||||
Icon:Setup(k, k, "spawnicons/models/items/boxmrounds60x60.png", false, self, true) -- Gets created clientside by GMOD when someone is after that model, or trying to buy ammo.
|
||||
AmmoPan:AddItem(Icon)
|
||||
end
|
||||
end
|
||||
|
||||
local Weapons = weapons.GetList()
|
||||
local Categorised = {}
|
||||
|
||||
Categorised["Half-life 2"] = {}
|
||||
for k, weapon in pairs(FAdmin.HL2Guns) do
|
||||
table.insert(Categorised["Half-life 2"], {PrintName = k, ClassName = weapon, Spawnable = true,
|
||||
Author = "Half-life 2",
|
||||
Contact = "gaben@valvesoftware.com",
|
||||
Instructions = "Shoot!"})
|
||||
end
|
||||
|
||||
for k, weapon in pairs(Weapons) do
|
||||
weapon = weapons.Get(weapon.ClassName)
|
||||
Weapons[k] = weapon
|
||||
weapon.Category = weapon.Category or "Other"
|
||||
|
||||
if not weapon.Spawnable and not weapon.AdminSpawnable then
|
||||
Weapons[k] = nil
|
||||
else
|
||||
Categorised[weapon.Category] = Categorised[weapon.Category] or {}
|
||||
table.insert(Categorised[weapon.Category], weapon)
|
||||
Weapons[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
Weapons = nil
|
||||
|
||||
for CategoryName, v in SortedPairs(Categorised) do
|
||||
local Category = vgui.Create("DCollapsibleCategory", self)
|
||||
self.PanelList:AddItem(Category)
|
||||
Category:SetLabel(CategoryName)
|
||||
Category:SetCookieName("WeaponSpawn." .. CategoryName)
|
||||
|
||||
local Content = vgui.Create("DPanelList")
|
||||
Category:SetContents(Content)
|
||||
Content:EnableHorizontal(true)
|
||||
Content:SetPaintBackground(false)
|
||||
Content:SetSpacing(2)
|
||||
Content:SetPadding(2)
|
||||
Content:SetAutoSize(true)
|
||||
|
||||
for _, WeaponTable in SortedPairsByMemberValue(v, "PrintName") do
|
||||
local Icon = vgui.CreateFromTable(WeaponIcon, self)
|
||||
Icon:Setup(WeaponTable.PrintName or WeaponTable.ClassName, WeaponTable.ClassName, WeaponTable.SpawnMenuIcon, WeaponTable.AdminSpawnable and not WeaponTable.Spawnable, self)
|
||||
|
||||
local Tooltip = Format("Name: %s", WeaponTable.PrintName)
|
||||
if WeaponTable.Author ~= "" then Tooltip = Format("%s\nAuthor: %s", Tooltip, WeaponTable.Author) end
|
||||
if WeaponTable.Contact ~= "" then Tooltip = Format("%s\nContact: %s", Tooltip, WeaponTable.Contact) end
|
||||
if WeaponTable.Instructions ~= "" then Tooltip = Format("%s\n\n%s", Tooltip, WeaponTable.Instructions) end
|
||||
|
||||
Icon:SetTooltip(Tooltip)
|
||||
Content:AddItem(Icon)
|
||||
end
|
||||
end
|
||||
self.PanelList:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL2:PerformLayout()
|
||||
self.PanelList:StretchToParent(0, 0, 0, 0)
|
||||
end
|
||||
|
||||
derma.DefineControl("FAdmin_weaponPanel", "Weapon panel for giving weapons in FAdmin", PANEL2, "Panel")
|
||||
@@ -0,0 +1,31 @@
|
||||
local function GiveWeaponGui(ply)
|
||||
local frame = vgui.Create("DFrame")
|
||||
frame:SetTitle("Give weapon")
|
||||
frame:SetSize(ScrW() / 2, ScrH() - 50)
|
||||
frame:Center()
|
||||
frame:SetVisible(true)
|
||||
frame:MakePopup()
|
||||
|
||||
local WeaponMenu = vgui.Create("FAdmin_weaponPanel", frame)
|
||||
WeaponMenu:StretchToParent(0,25,0,0)
|
||||
|
||||
function WeaponMenu:DoGiveWeapon(SpawnName, IsAmmo)
|
||||
if not ply:IsValid() then return end
|
||||
local giveWhat = (IsAmmo and "ammo") or "weapon"
|
||||
|
||||
RunConsoleCommand("FAdmin", "give" .. giveWhat, ply:UserID(), SpawnName)
|
||||
end
|
||||
|
||||
WeaponMenu:BuildList()
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["GiveWeapons"] = function()
|
||||
FAdmin.Access.AddPrivilege("giveweapon", 2)
|
||||
FAdmin.Commands.AddCommand("giveweapon", nil, "<Player>", "<weapon>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Give weapon(s)", "fadmin/icons/weapon", Color(255, 130, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "giveweapon") end, function(ply, button)
|
||||
GiveWeaponGui(ply)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
FAdmin.HL2Guns = {
|
||||
Crowbar = "weapon_crowbar",
|
||||
Gravgun = "weapon_gravgun",
|
||||
Physgun = "weapon_physgun",
|
||||
Stunstick = "weapon_stunstick",
|
||||
Pistol = "weapon_pistol",
|
||||
["357"] = "weapon_357",
|
||||
Smg1 = "weapon_smg1",
|
||||
Ar2 = "weapon_ar2",
|
||||
Shotgun = "weapon_shotgun",
|
||||
Crossbow = "weapon_crossbow",
|
||||
Grenade = "weapon_frag",
|
||||
RPG = "weapon_rpg",
|
||||
["S.L.A.M."] = "weapon_SLAM",
|
||||
Camera = "gmod_camera",
|
||||
Toolgun = "gmod_tool"
|
||||
}
|
||||
|
||||
FAdmin.AmmoTypes = {
|
||||
AR2 = 30,
|
||||
AR2AltFire = 3,
|
||||
pistol = 180,
|
||||
smg1 = 45,
|
||||
["357"] = 6,
|
||||
XBowBolt = 3,
|
||||
Buckshot = 6,
|
||||
RPG_Round = 3,
|
||||
SMG1_Grenade = 1,
|
||||
Grenade = 3,
|
||||
slam = 1
|
||||
}
|
||||
|
||||
FAdmin.StartHooks["GivingWeapons"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "giveweapon",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " gave ", "extraInfo.1", " to ", "targets"},
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(i) net.WriteString(i[1]) end,
|
||||
readExtraInfo = function()
|
||||
return {net.ReadString()}
|
||||
end,
|
||||
extraInfoColors = {Color(255, 102, 0)}
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "giveammo",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " gave ", "extraInfo.1", " ", "extraInfo.2", " ammo to ", "targets"},
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 32) net.WriteString(info[2]) end,
|
||||
readExtraInfo = function()
|
||||
return {tostring(net.ReadUInt(32)), net.ReadString()}
|
||||
end,
|
||||
extraInfoColors = {Color(255, 102, 0), Color(255, 102, 153)}
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
local function GiveWeapon(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "giveweapon") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[2] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local weapon = weapons.GetStored(args[2])
|
||||
if table.HasValue(FAdmin.HL2Guns, args[2]) then weapon = args[2]
|
||||
elseif weapon and weapon.ClassName then weapon = weapon.ClassName end
|
||||
|
||||
if not weapon then return false end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) then
|
||||
target:Give(weapon)
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.ActionMessage(ply, targets, "You gave %s a " .. weapon, "%s gave you a " .. weapon, "Gave %s a " .. weapon)
|
||||
FAdmin.Messages.FireNotification("giveweapon", ply, targets, {weapon})
|
||||
|
||||
return true, targets, weapon
|
||||
end
|
||||
|
||||
local function GiveAmmo(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "giveweapon") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[2] or not FAdmin.AmmoTypes[args[2]] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local ammo = args[2]
|
||||
local amount = tonumber(args[3]) or FAdmin.AmmoTypes[args[2]]
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) then
|
||||
target:GiveAmmo(amount, ammo)
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("giveammo", ply, targets, {amount, ammo})
|
||||
|
||||
return true, targets, ammo, amount
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["GiveWeapons"] = function()
|
||||
FAdmin.Commands.AddCommand("giveweapon", GiveWeapon)
|
||||
FAdmin.Commands.AddCommand("giveammo", GiveAmmo)
|
||||
|
||||
FAdmin.Access.AddPrivilege("giveweapon", 3)
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
FAdmin.StartHooks["God"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "god",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " enabled godmode for ", "targets"},
|
||||
receivers = "everyone",
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "ungod",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " disabled godmode for ", "targets"},
|
||||
receivers = "everyone",
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("God", 2)
|
||||
FAdmin.Commands.AddCommand("god", nil, "<Player>")
|
||||
FAdmin.Commands.AddCommand("ungod", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_godded") then return "Ungod" end
|
||||
return "God"
|
||||
end, function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_godded") then return "fadmin/icons/god", "fadmin/icons/disable" end
|
||||
return "fadmin/icons/god"
|
||||
end, Color(255, 130, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "God") end, function(ply, button)
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_godded") then
|
||||
RunConsoleCommand("_FAdmin", "god", ply:UserID())
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "ungod", ply:UserID())
|
||||
end
|
||||
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_godded") then button:SetImage2("fadmin/icons/disable") button:SetText("Ungod") button:GetParent():InvalidateLayout() return end
|
||||
button:SetImage2("null")
|
||||
button:SetText("God")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
local function God(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "God") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) and not target:FAdmin_GetGlobal("FAdmin_godded") then
|
||||
target:FAdmin_SetGlobal("FAdmin_godded", true)
|
||||
target:GodEnable()
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.FireNotification("god", ply, targets)
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
local function Ungod(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "God") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) and target:FAdmin_GetGlobal("FAdmin_godded") then
|
||||
target:FAdmin_SetGlobal("FAdmin_godded", false)
|
||||
target:GodDisable()
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.FireNotification("ungod", ply, targets)
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["God"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "god",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " enabled godmode for ", "targets"},
|
||||
receivers = "everyone",
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "ungod",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " disabled godmode for ", "targets"},
|
||||
receivers = "everyone",
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("God", God)
|
||||
FAdmin.Commands.AddCommand("Ungod", Ungod)
|
||||
|
||||
FAdmin.Access.AddPrivilege("God", 2)
|
||||
end
|
||||
|
||||
hook.Add("PlayerSpawn", "FAdmin_God", function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_godded") then
|
||||
ply:GodEnable()
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,31 @@
|
||||
FAdmin.StartHooks["Health"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "sethealth",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " set the health of ", "targets", " to ", "extraInfo.1"},
|
||||
readExtraInfo = function() return {tostring(net.ReadUInt(16))} end
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("SetHealth", 2)
|
||||
FAdmin.Commands.AddCommand("hp", nil, "<Player>", "<health>")
|
||||
FAdmin.Commands.AddCommand("SetHealth", nil, "[Player]", "<health>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Set health", "icon16/heart.png", Color(255, 130, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "SetHealth", ply) end,
|
||||
function(ply, button)
|
||||
--Do nothing when the button has been clicked
|
||||
end,
|
||||
function(ply, button) -- Create the Wang when the mouse is pressed
|
||||
button.OnMousePressed = function()
|
||||
local window = Derma_StringRequest("Select health", "What do you want the health of the person to be?", "",
|
||||
function(text)
|
||||
local health = DarkRP.toInt(text or 100) or 100
|
||||
RunConsoleCommand("_fadmin", "SetHealth", ply:UserID(), health)
|
||||
end
|
||||
)
|
||||
|
||||
-- The user is usually holding tab when clicking health, so fix the focus
|
||||
window:RequestFocus()
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
local function SetHealth(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local Health = tonumber(args[2] or 100)
|
||||
if not Health then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
targets = {ply}
|
||||
Health = math.floor(tonumber(args[1] or 100) or 100)
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "SetHealth", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) then
|
||||
target:SetHealth(Health)
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("sethealth", ply, targets, {Health})
|
||||
|
||||
return true, targets, Health
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Health"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "sethealth",
|
||||
hasTarget = true,
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
message = {"instigator", " set the health of ", "targets", " to ", "extraInfo.1"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("SetHealth", SetHealth)
|
||||
FAdmin.Commands.AddCommand("hp", SetHealth)
|
||||
|
||||
FAdmin.Access.AddPrivilege("SetHealth", 2)
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
FAdmin.StartHooks["Ignite"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "ignite",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " ignited ", "targets", " ", "extraInfo.1"},
|
||||
readExtraInfo = function()
|
||||
local time = net.ReadUInt(16)
|
||||
return {time == 0 and FAdmin.PlayerActions.commonTimes[time] or string.format("for %s", FAdmin.PlayerActions.commonTimes[time] or (time .. " seconds"))}
|
||||
end
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unignite",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " unignited ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Ignite", 2)
|
||||
FAdmin.Commands.AddCommand("Ignite", nil, "<Player>", "[time]")
|
||||
FAdmin.Commands.AddCommand("unignite", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply) return (ply:FAdmin_GetGlobal("FAdmin_ignited") and "Extinguish") or "Ignite" end,
|
||||
function(ply) local disabled = (ply:FAdmin_GetGlobal("FAdmin_ignited") and "fadmin/icons/disable") or nil return "fadmin/icons/ignite", disabled end,
|
||||
Color(255, 130, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Ignite", ply) end,
|
||||
function(ply, button)
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_ignited") then
|
||||
RunConsoleCommand("_FAdmin", "ignite", ply:UserID())
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Extinguish")
|
||||
button:GetParent():InvalidateLayout()
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "unignite", ply:UserID())
|
||||
button:SetImage2("null")
|
||||
button:SetText("Ignite")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
local function Ignite(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local time = tonumber(args[2]) or 10
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Ignite", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) then
|
||||
target:Ignite(time, 0)
|
||||
target:FAdmin_SetGlobal("FAdmin_ignited", true)
|
||||
|
||||
timer.Simple(time, function()
|
||||
if IsValid(target) then target:FAdmin_SetGlobal("FAdmin_ignited", false) end
|
||||
end)
|
||||
end
|
||||
end
|
||||
FAdmin.Messages.FireNotification("ignite", ply, targets, {time})
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
local function UnIgnite(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Ignite") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) then
|
||||
target:Extinguish()
|
||||
|
||||
target:FAdmin_SetGlobal("FAdmin_ignited", false)
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("unignite", ply, targets)
|
||||
return true, targets
|
||||
end
|
||||
|
||||
|
||||
FAdmin.StartHooks["Ignite"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "ignite",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
message = {"instigator", " ignited ", "targets", " ", "extraInfo.1"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unignite",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " unignited ", "targets"},
|
||||
receivers = "involved+admins",
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("Ignite", Ignite)
|
||||
FAdmin.Commands.AddCommand("Unignite", UnIgnite)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Ignite", 2)
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
FAdmin.StartHooks["Jail"] = function()
|
||||
FAdmin.Access.AddPrivilege("Jail", 2)
|
||||
FAdmin.Commands.AddCommand("Jail", nil, "<Player>", "[Small/Normal/Big]", "[Time]")
|
||||
FAdmin.Commands.AddCommand("UnJail", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Jail/Unjail", function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
RunConsoleCommand("_FAdmin", "unjail", ply:UserID())
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "jail", ply:UserID())
|
||||
end
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then return "Unjail" end
|
||||
return "Jail"
|
||||
end,
|
||||
function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then return "fadmin/icons/jail", "fadmin/icons/disable" end
|
||||
return "fadmin/icons/jail"
|
||||
end,
|
||||
Color(255, 130, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Jail", ply) end,
|
||||
function(ply, button)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then RunConsoleCommand("_FAdmin", "unjail", ply:UserID()) button:SetImage2("null") button:SetText("Jail") button:GetParent():InvalidateLayout() return end
|
||||
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Jail Type:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
|
||||
menu:AddPanel(Title)
|
||||
|
||||
for k, v in ipairs(FAdmin.PlayerActions.JailTypes) do
|
||||
if v == "Unjail" then continue end
|
||||
FAdmin.PlayerActions.addTimeSubmenu(menu, v .. " jail",
|
||||
function()
|
||||
RunConsoleCommand("_FAdmin", "Jail", ply:UserID(), k)
|
||||
button:SetText("Unjail") button:GetParent():InvalidateLayout()
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
end,
|
||||
function(secs)
|
||||
RunConsoleCommand("_FAdmin", "Jail", ply:UserID(), k, secs)
|
||||
button:SetText("Unjail")
|
||||
button:GetParent():InvalidateLayout()
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
menu:Open()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
FAdmin.PlayerActions.JailTypes = {}
|
||||
FAdmin.PlayerActions.JailTypes[1] = "Small"
|
||||
FAdmin.PlayerActions.JailTypes[2] = "Normal"
|
||||
FAdmin.PlayerActions.JailTypes[3] = "Big"
|
||||
FAdmin.PlayerActions.JailTypes[4] = "Unjail"
|
||||
|
||||
hook.Add("CanTool", "FAdmin_jailed", function(ply) -- shared so it doesn't look like you can use tool
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerNoClip", "FAdmin_jail", function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
FAdmin.StartHooks["Jailing"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "jail",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " jailed ", "targets", " ", "extraInfo.1"},
|
||||
receivers = "involved+admins",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
readExtraInfo = function()
|
||||
local time = net.ReadUInt(16)
|
||||
return {time == 0 and FAdmin.PlayerActions.commonTimes[time] or string.format("for %s", FAdmin.PlayerActions.commonTimes[time] or (time .. " seconds"))}
|
||||
end
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unjail",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " unjailed ", "targets"},
|
||||
receivers = "involved+admins",
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,167 @@
|
||||
local function createJailTimer(target, jailTime)
|
||||
if jailTime == 0 then return end
|
||||
|
||||
timer.Create("FAdmin_jail" .. target:UserID(), jailTime, 1, function()
|
||||
if not IsValid(target) then return end
|
||||
if not target:FAdmin_GetGlobal("fadmin_jailed") then return end
|
||||
timer.Remove("FAdmin_jail_watch" .. target:UserID())
|
||||
target:FAdmin_SetGlobal("fadmin_jailed", false)
|
||||
|
||||
for k in pairs(target.FAdminJailProps) do
|
||||
if not IsValid(k) then continue end
|
||||
k:SetCanRemove(true)
|
||||
k:Remove()
|
||||
end
|
||||
|
||||
target.FAdminJailProps = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local function Jail(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local JailType = FAdmin.PlayerActions.JailTypes[tonumber(args[2])] or args[2] or FAdmin.PlayerActions.JailTypes[2]
|
||||
JailType = string.lower(JailType)
|
||||
local JailTime = tonumber(args[3]) or 0
|
||||
local time = ""
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not IsValid(target) then continue end
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Jail", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local jailDistance
|
||||
|
||||
ply:ExitVehicle()
|
||||
|
||||
local JailProps = {}
|
||||
if JailType == "unjail" or string.lower(cmd) == "unjail" then
|
||||
if target.FAdminJailProps then
|
||||
for k in pairs(target.FAdminJailProps) do
|
||||
if not IsValid(k) then continue end
|
||||
k:SetCanRemove(true)
|
||||
k:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
target.FAdminJailProps = nil
|
||||
timer.Remove("FAdmin_jail" .. target:UserID())
|
||||
timer.Remove("FAdmin_jail_watch" .. target:UserID())
|
||||
target:FAdmin_SetGlobal("fadmin_jailed", false)
|
||||
elseif JailType == "small" then
|
||||
jailDistance = 50
|
||||
table.insert(JailProps, {pos = Vector(0,0,58), ang = Angle(0,0,0), model = "models/props_wasteland/laundry_dryer001.mdl"})
|
||||
elseif JailType == "normal" then
|
||||
jailDistance = 70
|
||||
table.insert(JailProps, {pos = Vector(0,0,-5), ang = Angle(90,0,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(0,0,97), ang = Angle(90,0,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
|
||||
table.insert(JailProps, {pos = Vector(21,31,46), ang = Angle(0,90,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(21,-31,46), ang = Angle(0,90,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(-21,31,46), ang = Angle(0,90,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(-21,-31,46), ang = Angle(0,90,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
|
||||
table.insert(JailProps, {pos = Vector(-52,0,46), ang = Angle(0,0,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(52,0,46), ang = Angle(0,0,0), model = "models/props_building_details/Storefront_Template001a_Bars.mdl"})
|
||||
|
||||
elseif JailType == "big" then -- Requires CSS but it's really funny
|
||||
jailDistance = 80
|
||||
table.insert(JailProps, {pos = Vector(0,0,-5), ang = Angle(0,0,0), model = "models/props/cs_havana/gazebo.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(70,0,50), ang = Angle(0,0,0), model = "models/props_borealis/borealis_door001a.mdl"})
|
||||
|
||||
table.insert(JailProps, {pos = Vector(-70,0,100), ang = Angle(0,0,90), model = "models/props_lab/lockerdoorleft.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(-35,-55,100), ang = Angle(0,60,90), model = "models/props_lab/lockerdoorleft.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(-35,55,100), ang = Angle(0,300,90), model = "models/props_lab/lockerdoorleft.mdl"})
|
||||
|
||||
table.insert(JailProps, {pos = Vector(35,-55,100), ang = Angle(0,300,90), model = "models/props_lab/lockerdoorleft.mdl"})
|
||||
table.insert(JailProps, {pos = Vector(35,55,100), ang = Angle(0,240,90), model = "models/props_lab/lockerdoorleft.mdl"})
|
||||
else
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Bad arguments")
|
||||
return
|
||||
end
|
||||
if not target:FAdmin_GetGlobal("fadmin_jailed") and JailType ~= "unjail" and string.lower(cmd) ~= "unjail" then
|
||||
target:SetMoveType(MOVETYPE_WALK)
|
||||
|
||||
target:FAdmin_SetGlobal("fadmin_jailed", true)
|
||||
target.FAdminJailPos = target:GetPos()
|
||||
target.FAdminJailProps = {}
|
||||
|
||||
for _, v in ipairs(JailProps) do
|
||||
local JailProp = ents.Create("fadmin_jail")
|
||||
JailProp:SetPos(target.FAdminJailPos + v.pos)
|
||||
JailProp:SetAngles(v.ang)
|
||||
JailProp:SetModel(v.model)
|
||||
JailProp:Spawn()
|
||||
JailProp:Activate()
|
||||
|
||||
JailProp.target = target
|
||||
JailProp.targetPos = target.FAdminJailPos
|
||||
target.FAdminJailProps[JailProp] = true
|
||||
end
|
||||
|
||||
createJailTimer(target, JailTime)
|
||||
|
||||
jailDistance = jailDistance * jailDistance
|
||||
local userid = target:UserID()
|
||||
timer.Create("FAdmin_jail_watch" .. target:UserID(), 1, 0, function()
|
||||
if not IsValid(target) then
|
||||
timer.Remove("FAdmin_jail_watch" .. userid)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if target:GetPos():DistToSqr(target.FAdminJailPos) > jailDistance then
|
||||
target:SetPos(target.FAdminJailPos)
|
||||
end
|
||||
end)
|
||||
|
||||
time = "for " .. JailTime .. " seconds"
|
||||
if JailTime == 0 then time = "indefinitely" end
|
||||
end
|
||||
end
|
||||
|
||||
if JailType == "unjail" or string.lower(cmd) == "unjail" then
|
||||
FAdmin.Messages.FireNotification("unjail", ply, targets)
|
||||
else
|
||||
FAdmin.Messages.FireNotification("jail", ply, targets, {JailTime})
|
||||
end
|
||||
|
||||
return true, targets, JailType, time
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Jail"] = function()
|
||||
FAdmin.Commands.AddCommand("Jail", Jail)
|
||||
FAdmin.Commands.AddCommand("UnJail", Jail)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Jail", 2)
|
||||
end
|
||||
|
||||
hook.Add("PlayerSpawn", "FAdmin_jail", function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
timer.Simple(0.1, function() if IsValid(ply) then ply:SetPos(ply.FAdminJailPos) end end)
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerSpawnObject", "FAdmin_jailed", function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("CanPlayerEnterVehicle", "FAdmin_jailed", function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
--Kill stupid addons that does not call CanPlayerEnterVehicle (like Sit Anywhere script)
|
||||
hook.Add("PlayerEnteredVehicle", "FAdmin_jailed", function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_jailed") then
|
||||
ply:ExitVehicle()
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,377 @@
|
||||
--[[
|
||||
WHEN GETTING KICKED
|
||||
]]
|
||||
local KickText = ""
|
||||
usermessage.Hook("FAdmin_kick_start", function()
|
||||
hook.Add("HUDPaint", "FAdmin_kick", function()
|
||||
draw.RoundedBox(0,0,0, ScrW(), ScrH(), Color(0,0,0,255))
|
||||
draw.DrawNonParsedText("You are getting kicked\nReason: " .. KickText .. "\nLeaving voluntarily is also an option.", "HUDNumber5", ScrW() / 2, ScrH() / 2, Color(255, 0, 0, 255), TEXT_ALIGN_CENTER)
|
||||
end)
|
||||
end)
|
||||
|
||||
usermessage.Hook("FAdmin_kick_cancel", function()
|
||||
hook.Remove("HUDPaint", "FAdmin_kick")
|
||||
FAdmin.Messages.AddMessage(4, "Kick was canceled by admin")
|
||||
end)
|
||||
|
||||
usermessage.Hook("FAdmin_kick_update", function(um)
|
||||
KickText = um:ReadString()
|
||||
end)
|
||||
|
||||
local BanText = "No reason"
|
||||
local BanTimeText = "permanent"
|
||||
|
||||
usermessage.Hook("FAdmin_ban_start", function()
|
||||
hook.Add("HUDPaint", "FAdmin_ban", function()
|
||||
draw.RoundedBox(0,0,0, ScrW(), ScrH(), Color(0,0,0,255))
|
||||
draw.DrawNonParsedText("You are getting banned\nReason: " .. BanText .. "\nTime: " .. " " .. BanTimeText .. "\nLeaving voluntarily or rejoining will not prevent banning.", "HUDNumber5", ScrW() / 2, ScrH() / 2, Color(0, 0, 255, 255), TEXT_ALIGN_CENTER)
|
||||
end)
|
||||
end)
|
||||
|
||||
usermessage.Hook("FAdmin_ban_cancel", function()
|
||||
hook.Remove("HUDPaint", "FAdmin_ban")
|
||||
FAdmin.Messages.AddMessage(4, "Ban was canceled by admin")
|
||||
end)
|
||||
|
||||
usermessage.Hook("FAdmin_ban_update", function(um)
|
||||
BanTimeText = FAdmin.PlayerActions.ConvertBanTime(um:ReadLong())
|
||||
BanText = um:ReadString()
|
||||
end)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Show the window for banning
|
||||
---------------------------------------------------------------------------]]
|
||||
local function showBanWindow(SteamID, NICK, time, reason)
|
||||
local BanTime = time or 60
|
||||
NICK = NICK or ""
|
||||
reason = reason or "No reason"
|
||||
local M,H,D,W,Y = BanTime % 60,
|
||||
math.floor(BanTime / 60) % 24,
|
||||
math.floor(BanTime / 1440) % 7,
|
||||
math.floor(BanTime / 10080) % 53,
|
||||
math.floor(BanTime / 525948)
|
||||
|
||||
RunConsoleCommand("_FAdmin", "ban", SteamID, "start")
|
||||
|
||||
local Window = vgui.Create("DFrame")
|
||||
Window:SetTitle("Ban Details")
|
||||
Window:SetDraggable(false)
|
||||
Window:ShowCloseButton(false)
|
||||
Window:SetBackgroundBlur(true)
|
||||
Window:SetDrawOnTop(true)
|
||||
|
||||
local InnerPanel = vgui.Create("DPanel", Window)
|
||||
InnerPanel:SetPaintBackground(false)
|
||||
|
||||
local Text = vgui.Create("DLabel", InnerPanel)
|
||||
Text:SetText("Ban " .. NICK .. "")
|
||||
Text:SizeToContents()
|
||||
Text:SetContentAlignment(5)
|
||||
|
||||
|
||||
local TimePanel = vgui.Create("DPanel", Window)
|
||||
TimePanel:SetPaintBackground(false)
|
||||
|
||||
local TextEntry = vgui.Create("DTextEntry", TimePanel)
|
||||
function TextEntry:OnTextChanged()
|
||||
RunConsoleCommand("_FAdmin", "ban", SteamID, "update", BanTime, self:GetValue())
|
||||
end
|
||||
TextEntry:SetText(DarkRP.deLocalise(reason))
|
||||
TextEntry.OnEnter = function() Window:Close() RunConsoleCommand("_FAdmin", "ban", SteamID, "execute", BanTime, TextEntry:GetValue()) end
|
||||
function TextEntry:OnFocusChanged(changed)
|
||||
self:RequestFocus()
|
||||
self:SelectAllText(true)
|
||||
end
|
||||
|
||||
local Minutes = vgui.Create("DNumberWang", TimePanel)
|
||||
Minutes:SetMinMax(0, 59)
|
||||
Minutes:SetDecimals(0)
|
||||
Minutes:SetValue(M)
|
||||
|
||||
local Hours = vgui.Create("DNumberWang", TimePanel)
|
||||
Hours:SetMinMax(0, 23)
|
||||
Hours:SetValue(H)
|
||||
Hours:SetDecimals(0)
|
||||
|
||||
local Days = vgui.Create("DNumberWang", TimePanel)
|
||||
Days:SetMinMax(0, 6)
|
||||
Days:SetValue(D)
|
||||
Days:SetDecimals(0)
|
||||
|
||||
local Weeks = vgui.Create("DNumberWang", TimePanel)
|
||||
Weeks:SetMinMax(0, 53)
|
||||
Weeks:SetValue(W)
|
||||
Weeks:SetDecimals(0)
|
||||
|
||||
local Years = vgui.Create("DNumberWang", TimePanel)
|
||||
Years:SetMinMax(0, 3)
|
||||
Years:SetValue(Y)
|
||||
Years:SetDecimals(0)
|
||||
|
||||
local MinLabel, HourLabel, DayLabel, WeekLabel, YearLabel = vgui.Create("DLabel", TimePanel), vgui.Create("DLabel", TimePanel),
|
||||
vgui.Create("DLabel", TimePanel), vgui.Create("DLabel", TimePanel), vgui.Create("DLabel", TimePanel)
|
||||
MinLabel:SetText("Minutes:")
|
||||
HourLabel:SetText("Hours:")
|
||||
DayLabel:SetText("Days:")
|
||||
WeekLabel:SetText("Weeks:")
|
||||
YearLabel:SetText("Years:")
|
||||
|
||||
|
||||
MinLabel:SetPos(370, 0)
|
||||
HourLabel:SetPos(280, 0)
|
||||
DayLabel:SetPos(190, 0)
|
||||
WeekLabel:SetPos(100, 0)
|
||||
YearLabel:SetPos(10, 0)
|
||||
|
||||
local function update()
|
||||
BanTime = M + H * 60 + D * 1440 + W * 10080 + Y * 525948
|
||||
RunConsoleCommand("_FAdmin", "ban", SteamID, "update", BanTime, TextEntry:GetValue())
|
||||
end
|
||||
|
||||
function Minutes:OnValueChanged(val) if val == M then return end M = val update() end
|
||||
function Hours:OnValueChanged(val) if val == H then return end H = val update() end
|
||||
function Days:OnValueChanged(val) if val == D then return end D = val update() end
|
||||
function Weeks:OnValueChanged(val) if val == W then return end W = val update() end
|
||||
function Years:OnValueChanged(val) if val == Y then return end Y = val update() end
|
||||
|
||||
local ButtonPanel = vgui.Create("DPanel", Window)
|
||||
ButtonPanel:SetTall(25)
|
||||
ButtonPanel:SetPaintBackground(false)
|
||||
|
||||
local Button = vgui.Create("DButton", ButtonPanel)
|
||||
Button:SetText("OK")
|
||||
Button:SizeToContents()
|
||||
Button:SetTall(20)
|
||||
Button:SetWide(Button:GetWide() + 20)
|
||||
Button:SetPos(5, 3)
|
||||
Button.DoClick = function()
|
||||
Window:Close()
|
||||
M, H, D, W, Y = Minutes:GetValue(), Hours:GetValue(), Days:GetValue(), Weeks:GetValue(), Years:GetValue()
|
||||
update()
|
||||
RunConsoleCommand("_FAdmin", "ban", SteamID, BanTime, (TextEntry and TextEntry:GetValue()) or "")
|
||||
end
|
||||
|
||||
local ButtonCancel = vgui.Create("DButton", ButtonPanel)
|
||||
ButtonCancel:SetText("Cancel")
|
||||
ButtonCancel:SizeToContents()
|
||||
ButtonCancel:SetTall(20)
|
||||
ButtonCancel:SetWide(Button:GetWide() + 20)
|
||||
ButtonCancel:SetPos(5, 3)
|
||||
ButtonCancel.DoClick = function() Window:Close() RunConsoleCommand("_FAdmin", "ban", SteamID, "cancel") end
|
||||
ButtonCancel:MoveRightOf(Button, 5)
|
||||
|
||||
ButtonPanel:SetWide(Button:GetWide() + 5 + ButtonCancel:GetWide() + 10)
|
||||
|
||||
Window:SetSize(450, 111 + 75 + 20)
|
||||
Window:Center()
|
||||
|
||||
InnerPanel:StretchToParent(5, 25, 5, 125)
|
||||
TimePanel:StretchToParent(5, 83, 5, 37)
|
||||
|
||||
Minutes:SetPos(370, 20)
|
||||
Hours:SetPos(280, 20)
|
||||
Days:SetPos(190, 20)
|
||||
Weeks:SetPos(100, 20)
|
||||
Years:SetPos(10, 20)
|
||||
|
||||
Text:StretchToParent(5, 5, 5, nil)
|
||||
|
||||
TextEntry:StretchToParent(5, nil, 5, nil)
|
||||
TextEntry:AlignBottom(5)
|
||||
|
||||
TextEntry:RequestFocus()
|
||||
|
||||
ButtonPanel:CenterHorizontal()
|
||||
ButtonPanel:AlignBottom(7)
|
||||
|
||||
Window:MakePopup()
|
||||
Window:DoModal()
|
||||
end
|
||||
|
||||
--[[
|
||||
ADD BUTTONS ETC. TO MENU
|
||||
]]
|
||||
FAdmin.StartHooks["CL_KickBan"] = function()
|
||||
FAdmin.Access.AddPrivilege("Kick", 2)
|
||||
FAdmin.Access.AddPrivilege("Ban", 2)
|
||||
FAdmin.Access.AddPrivilege("UnBan", 2)
|
||||
|
||||
FAdmin.Commands.AddCommand("kick", nil, "<Player>", "[Reason]")
|
||||
FAdmin.Commands.AddCommand("ban", nil, "<Player>", "<Time (minutes)>", "[Reason]")
|
||||
FAdmin.Commands.AddCommand("unban", "<SteamID>")
|
||||
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Quick Kick", function(ply, Panel)
|
||||
RunConsoleCommand("_FAdmin", "kick", ply:UserID(), "Quick kick")
|
||||
if IsValid(Panel) then Panel:Remove() end
|
||||
end)
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Ban", function(ply, Panel)
|
||||
showBanWindow(ply:SteamID(), ply:Nick())
|
||||
if IsValid(Panel) then Panel:Remove() end
|
||||
end)
|
||||
|
||||
|
||||
-- Kick button
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Kick", "fadmin/icons/kick", nil, function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Kick", ply) end, function(ply)
|
||||
if not IsValid(ply) then return end
|
||||
local UserID = ply:UserID()
|
||||
local NICK = ply:Nick()
|
||||
|
||||
RunConsoleCommand("FAdmin", "kick", UserID, "start")
|
||||
local Window = vgui.Create("DFrame")
|
||||
Window:SetTitle("Reason for kicking")
|
||||
Window:SetDraggable(false)
|
||||
Window:ShowCloseButton(false)
|
||||
Window:SetBackgroundBlur(true)
|
||||
Window:SetDrawOnTop(true)
|
||||
|
||||
local InnerPanel = vgui.Create("DPanel", Window)
|
||||
InnerPanel:SetPaintBackground(false)
|
||||
|
||||
local Text = vgui.Create("DLabel", InnerPanel)
|
||||
Text:SetText(NICK .. " knows they are getting kicked\nTake all your time entering the reason, they can't do anything anymore")
|
||||
Text:SizeToContents()
|
||||
Text:SetContentAlignment(5)
|
||||
Text:SetTextColor(color_white)
|
||||
|
||||
local TextEntry = vgui.Create("DTextEntry", InnerPanel)
|
||||
function TextEntry:OnTextChanged()
|
||||
RunConsoleCommand("_FAdmin", "kick", UserID, "update", self:GetValue())
|
||||
end
|
||||
TextEntry:SetText("Enter reason here")
|
||||
TextEntry.OnEnter = function() Window:Close() RunConsoleCommand("_FAdmin", "kick", UserID, "execute", TextEntry:GetValue()) end
|
||||
function TextEntry:OnFocusChanged(changed)
|
||||
self:RequestFocus()
|
||||
self:SelectAllText(true)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local ButtonPanel = vgui.Create("DPanel", Window)
|
||||
ButtonPanel:SetTall(30)
|
||||
ButtonPanel:SetPaintBackground(false)
|
||||
|
||||
local Button = vgui.Create("DButton", ButtonPanel)
|
||||
Button:SetText("OK")
|
||||
Button:SizeToContents()
|
||||
Button:SetTall(20)
|
||||
Button:SetWide(Button:GetWide() + 20)
|
||||
Button:SetPos(5, 5)
|
||||
Button.DoClick = function() Window:Close() RunConsoleCommand("_FAdmin", "kick", UserID, "execute", TextEntry:GetValue()) end
|
||||
|
||||
local ButtonCancel = vgui.Create("DButton", ButtonPanel)
|
||||
ButtonCancel:SetText("Cancel")
|
||||
ButtonCancel:SizeToContents()
|
||||
ButtonCancel:SetTall(20)
|
||||
ButtonCancel:SetWide(Button:GetWide() + 20)
|
||||
ButtonCancel:SetPos(5, 5)
|
||||
|
||||
ButtonCancel.DoClick = function()
|
||||
Window:Close()
|
||||
RunConsoleCommand("FAdmin", "kick", UserID, "cancel")
|
||||
end
|
||||
|
||||
ButtonCancel:MoveRightOf(Button, 5)
|
||||
ButtonPanel:SetWide(Button:GetWide() + 5 + ButtonCancel:GetWide() + 10)
|
||||
local w, h = Text:GetSize()
|
||||
w = math.max(w, 400)
|
||||
Window:SetSize(w + 50, h + 25 + 75 + 10)
|
||||
Window:Center()
|
||||
InnerPanel:StretchToParent(5, 25, 5, 45)
|
||||
Text:StretchToParent(5, 5, 5, 35)
|
||||
TextEntry:StretchToParent(5, nil, 5, nil)
|
||||
TextEntry:AlignBottom(5)
|
||||
TextEntry:RequestFocus()
|
||||
ButtonPanel:CenterHorizontal()
|
||||
ButtonPanel:AlignBottom(8)
|
||||
|
||||
Window:MakePopup()
|
||||
Window:DoModal()
|
||||
end)
|
||||
|
||||
-- Ban button
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Ban", "fadmin/icons/ban", nil, function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Ban", ply) end, function(ply)
|
||||
local SteamID = ply:SteamID()
|
||||
local NICK = ply:Nick()
|
||||
|
||||
if ply:IsBot() then SteamID = "BOT" end
|
||||
showBanWindow(SteamID, NICK)
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddPlayerAction("Unban", function() return "fadmin/icons/ban", "fadmin/icons/disable" end, Color(0, 155, 0, 255), true, function(button)
|
||||
local selectedLine
|
||||
|
||||
local Frame = vgui.Create("DFrame")
|
||||
Frame:SetSize(740, 600)
|
||||
Frame:SetTitle("Unban Details")
|
||||
Frame:SetDraggable(true)
|
||||
Frame:ShowCloseButton(true)
|
||||
Frame:SetBackgroundBlur(true)
|
||||
Frame:SetDrawOnTop(true)
|
||||
|
||||
local BanList = vgui.Create("DListView", Frame)
|
||||
BanList:StretchToParent(5, 55, 5, 5)
|
||||
BanList:AddColumn("SteamID")
|
||||
BanList:AddColumn("Name")
|
||||
BanList:AddColumn("Time")
|
||||
BanList:AddColumn("Reason")
|
||||
BanList:AddColumn("Banned by")
|
||||
BanList:AddColumn("Banned by SteamID")
|
||||
|
||||
local unban = vgui.Create("DButton", Frame)
|
||||
unban:SetText("Unban")
|
||||
unban:SetPos(695, 25)
|
||||
unban:SetSize(40, 25)
|
||||
|
||||
function unban:DoClick()
|
||||
if IsValid(selectedLine) then
|
||||
RunConsoleCommand("_FAdmin", "Unban", string.upper(selectedLine:GetValue(1)))
|
||||
BanList:RemoveLine(selectedLine:GetID())
|
||||
end
|
||||
end
|
||||
|
||||
local edit = vgui.Create("DButton", Frame)
|
||||
edit:SetText("Edit")
|
||||
edit:SetPos(650, 25)
|
||||
edit:SetSize(40, 25)
|
||||
function edit:DoClick()
|
||||
if not selectedLine then return end
|
||||
showBanWindow(selectedLine:GetValue(1), selectedLine.name, selectedLine.time > os.time() and (selectedLine.time - os.time()) / 60 or 0, selectedLine.reason)
|
||||
Frame:Close()
|
||||
end
|
||||
|
||||
local function RetrieveBans(len)
|
||||
local banCount = net.ReadUInt(32)
|
||||
|
||||
for i = 1, banCount do
|
||||
local steamid = net.ReadString()
|
||||
local time = net.ReadUInt(32)
|
||||
local name = net.ReadString()
|
||||
local reason = net.ReadString()
|
||||
local adminname = net.ReadString()
|
||||
local adminsteam = net.ReadString()
|
||||
|
||||
|
||||
local Line = BanList:AddLine(
|
||||
steamid,
|
||||
name or "N/A",
|
||||
(tonumber(time or "") and FAdmin.PlayerActions.ConvertBanTime((tonumber(time) - os.time()) / 60)) or "N/A",
|
||||
reason or "",
|
||||
adminname or "",
|
||||
adminsteam or "")
|
||||
Line.name = name
|
||||
Line.time = time
|
||||
Line.reason = reason
|
||||
|
||||
function Line:OnSelect()
|
||||
selectedLine = self
|
||||
end
|
||||
end
|
||||
end
|
||||
net.Receive("FAdmin_retrievebans", RetrieveBans)
|
||||
RunConsoleCommand("_FAdmin", "RequestBans")
|
||||
|
||||
Frame:Center()
|
||||
Frame:MakePopup()
|
||||
Frame:DoModal()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
function FAdmin.PlayerActions.ConvertBanTime(time)
|
||||
local Add = ""
|
||||
time = math.Round(time)
|
||||
|
||||
if time <= 0 then
|
||||
return "permanent"
|
||||
elseif time < 60 then
|
||||
-- minutes
|
||||
return math.ceil(time) .. " minute(s)"
|
||||
elseif time >= 60 and time < 1440 then
|
||||
-- hours
|
||||
if math.floor((time / 60 - math.floor(time / 60)) * 60) > 0 then
|
||||
Add = ", " .. FAdmin.PlayerActions.ConvertBanTime((time / 60 - math.floor(time / 60)) * 60)
|
||||
end
|
||||
|
||||
return math.floor(time / 60) .. " hour(s)" .. Add
|
||||
elseif time >= 1440 and time < 10080 then
|
||||
-- days
|
||||
if math.floor((time / 1440 - math.floor(time / 1440)) * 1440) > 0 then
|
||||
Add = ", " .. FAdmin.PlayerActions.ConvertBanTime((time / 1440 - math.floor(time / 1440)) * 1440)
|
||||
end
|
||||
|
||||
return math.floor(time / 1440) .. " day(s)" .. Add
|
||||
elseif time >= 10080 and time < 525948 then
|
||||
-- weeks
|
||||
if math.floor((time / 10080 - math.floor(time / 10080)) * 10080) > 0 then
|
||||
Add = ", " .. FAdmin.PlayerActions.ConvertBanTime((time / 10080 - math.floor(time / 10080)) * 10080)
|
||||
end
|
||||
|
||||
return math.floor(time / 10080) .. " week(s)" .. Add
|
||||
elseif time >= 525948 then
|
||||
-- years
|
||||
if math.floor((time / 525948 - math.floor(time / 525948)) * 525948) > 0 then
|
||||
Add = ", " .. FAdmin.PlayerActions.ConvertBanTime((time / 525948 - math.floor(time / 525948)) * 525948)
|
||||
end
|
||||
|
||||
return math.floor(time / 525948) .. " year(s)" .. Add
|
||||
end
|
||||
|
||||
return time
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["kickbanning"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "kick",
|
||||
hasTarget = false,
|
||||
message = {"instigator", " kicked ", "extraInfo.1", " (", "extraInfo.2", ")"},
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(info)
|
||||
net.WriteString(info[1])
|
||||
net.WriteString(info[2])
|
||||
end,
|
||||
|
||||
readExtraInfo = function()
|
||||
return {net.ReadString(), net.ReadString()}
|
||||
end,
|
||||
extraInfoColors = {Color(102, 0, 255), Color(255, 102, 0)}
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "ban",
|
||||
hasTarget = false,
|
||||
message = {"instigator", " banned ", "extraInfo.1", " for ", "extraInfo.2", " (", "extraInfo.3", ")"},
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(info)
|
||||
net.WriteString(info[1])
|
||||
|
||||
net.WriteUInt(info[2], 32)
|
||||
|
||||
net.WriteString(info[3])
|
||||
end,
|
||||
|
||||
readExtraInfo = function()
|
||||
return {net.ReadString(), FAdmin.PlayerActions.ConvertBanTime(net.ReadUInt(32)), net.ReadString()}
|
||||
end,
|
||||
|
||||
extraInfoColors = {Color(102, 0, 255), Color(255, 102, 0), Color(255, 102, 0)}
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unban",
|
||||
hasTarget = false,
|
||||
message = {"instigator", " unbanned ", "extraInfo.1", " (", "extraInfo.2", ")"},
|
||||
receivers = "everyone",
|
||||
writeExtraInfo = function(info)
|
||||
net.WriteString(info[1])
|
||||
net.WriteString(info[2])
|
||||
end,
|
||||
|
||||
readExtraInfo = function()
|
||||
return {net.ReadString(), net.ReadString()}
|
||||
end,
|
||||
|
||||
extraInfoColors = {Color(102, 0, 255), Color(255, 102, 0)}
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,328 @@
|
||||
-- Kicking
|
||||
local function Kick(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local CanKick = hook.Call("FAdmin_CanKick", nil, ply, targets)
|
||||
|
||||
if CanKick == false then return false end
|
||||
|
||||
local stage = args[2] or ""
|
||||
stage = string.lower(stage)
|
||||
local stages = {"start", "cancel", "update", "execute"}
|
||||
local Reason = (not table.HasValue(stages, stage) and table.concat(args, ' ', 2)) or table.concat(args, ' ', 3) or ply.FAdminKickReason
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Kick", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) then
|
||||
if stage == "start" then
|
||||
SendUserMessage("FAdmin_kick_start", target) -- Tell him he's getting kicked
|
||||
target:Lock() -- Make sure he can't remove the hook clientside and keep minging.
|
||||
target:KillSilent()
|
||||
elseif stage == "cancel" then
|
||||
SendUserMessage("FAdmin_kick_cancel", target) -- No I changed my mind, you can stay
|
||||
target:UnLock()
|
||||
target:Spawn()
|
||||
ply.FAdminKickReason = nil
|
||||
elseif stage == "update" then -- Update reason text
|
||||
if not args[3] then return false end
|
||||
ply.FAdminKickReason = args[3]
|
||||
SendUserMessage("FAdmin_kick_update", target, args[3])
|
||||
else
|
||||
local name = IsValid(ply) and ply:IsPlayer() and ply:Nick() or "Console"
|
||||
|
||||
Reason = Reason and string.gsub(Reason, ";", " ") or "No reason provided"
|
||||
|
||||
hook.Call("FAdmin_Kick", nil, ply, target, Reason)
|
||||
game.ConsoleCommand(string.format("kickid %s %s\n", target:UserID(), "Kicked by " .. name ..
|
||||
" (" .. Reason .. ")"))
|
||||
ply.FAdminKickReason = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if stage ~= "start" and stage ~= "cancel" and stage ~= "update" then
|
||||
FAdmin.Messages.FireNotification("kick", ply, nil, {FAdmin.TargetsToString(targets), Reason})
|
||||
end
|
||||
|
||||
return true, targets, stage, Reason
|
||||
end
|
||||
|
||||
local StartBannedUsers = {} -- Prevent rejoining before actual ban occurs
|
||||
hook.Add("PlayerAuthed", "FAdmin_LeavingBeforeBan", function(ply, SteamID, ...)
|
||||
if not StartBannedUsers[SteamID] then return end
|
||||
if not IsValid(StartBannedUsers[SteamID].author) then
|
||||
StartBannedUsers[SteamID] = nil
|
||||
return
|
||||
end
|
||||
|
||||
game.ConsoleCommand(string.format("kickid %s %s\n", ply:UserID(), "Getting banned"))
|
||||
end)
|
||||
|
||||
-- Banning
|
||||
FAdmin.BANS = FAdmin.BANS or {}
|
||||
|
||||
local function RequestBans(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "UnBan") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
net.Start("FAdmin_retrievebans")
|
||||
net.WriteUInt(table.Count(FAdmin.BANS), 32)
|
||||
|
||||
for k, v in pairs(FAdmin.BANS) do
|
||||
net.WriteString(k or "") -- SteamID
|
||||
net.WriteUInt(v.time or 0, 32)
|
||||
net.WriteString(v.name or "")
|
||||
net.WriteString(v.reason or "")
|
||||
net.WriteString(v.adminname or "")
|
||||
net.WriteString(v.adminsteam or "")
|
||||
end
|
||||
net.Send(ply)
|
||||
|
||||
return true, FAdmin.BANS
|
||||
end
|
||||
|
||||
timer.Create("FAdminCheckBans", 60, 0, function()
|
||||
for k, v in pairs(FAdmin.BANS) do
|
||||
if v.time and not isstring(v.time) and tonumber(v.time) < os.time() and v.time ~= 0 then
|
||||
FAdmin.BANS[k] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function SaveBan(SteamID, Nick, Duration, Reason, AdminName, Admin_steam)
|
||||
local StoreBans = hook.Call("FAdmin_StoreBan", nil, SteamID, Nick, Duration, Reason, AdminName, Admin_steam)
|
||||
if StoreBans == true then return end
|
||||
|
||||
if tonumber(Duration) == 0 then
|
||||
FAdmin.BANS[SteamID] = {}
|
||||
FAdmin.BANS[SteamID].time = 0
|
||||
FAdmin.BANS[SteamID].name = Nick
|
||||
FAdmin.BANS[SteamID].reason = Reason
|
||||
FAdmin.BANS[SteamID].adminname = AdminName
|
||||
FAdmin.BANS[SteamID].adminsteam = Admin_steam
|
||||
else
|
||||
FAdmin.BANS[SteamID] = {}
|
||||
FAdmin.BANS[SteamID].time = os.time() + Duration * 60 --in minutes, so *60
|
||||
FAdmin.BANS[SteamID].name = Nick
|
||||
FAdmin.BANS[SteamID].reason = Reason
|
||||
FAdmin.BANS[SteamID].adminname = AdminName
|
||||
FAdmin.BANS[SteamID].adminsteam = Admin_steam
|
||||
end
|
||||
end
|
||||
|
||||
local function Ban(ply, cmd, args)
|
||||
if not args[2] then return false end
|
||||
--start cancel update execute
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
|
||||
if not targets and string.find(args[1], "STEAM_") ~= 1 and string.find(args[2], "STEAM_") ~= 1 then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
elseif not targets and (string.find(args[1], "STEAM_") == 1 or string.find(args[2], "STEAM_") == 1) then
|
||||
targets = {(args[1] ~= "execute" and args[1]) or args[2]}
|
||||
if args[1] == "STEAM_0" then
|
||||
targets[1] = table.concat(args, "", 1, 5)
|
||||
args[1] = targets[1]
|
||||
args[2] = args[6]
|
||||
args[3] = args[7]
|
||||
targets = FAdmin.FindPlayer(targets[1]) or targets
|
||||
for i = 2, #args do
|
||||
if i >= 4 then args[i] = nil end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local CanBan = hook.Call("FAdmin_CanBan", nil, ply, targets)
|
||||
|
||||
if CanBan == false then return false end
|
||||
|
||||
local stage = string.lower(args[2])
|
||||
local stages = {"start", "cancel", "update", "execute"}
|
||||
local Reason = (not table.HasValue(stages, stage) and table.concat(args, ' ', 3)) or table.concat(args, ' ', 4) or ply.FAdminKickReason
|
||||
local time
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if (isstring(target) and not FAdmin.Access.PlayerHasPrivilege(ply, "Ban")) or
|
||||
not FAdmin.Access.PlayerHasPrivilege(ply, "Ban", target) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "No access!")
|
||||
return false
|
||||
end
|
||||
if stage == "start" and not isstring(target) and IsValid(target) then
|
||||
SendUserMessage("FAdmin_ban_start", target) -- Tell him he's getting banned
|
||||
target:Lock() -- Make sure he can't remove the hook clientside and keep minging.
|
||||
target:KillSilent()
|
||||
StartBannedUsers[target:SteamID()] = {author = ply}
|
||||
|
||||
elseif stage == "cancel" then
|
||||
if not isstring(target) and IsValid(target) then
|
||||
SendUserMessage("FAdmin_ban_cancel", target) -- No I changed my mind, you can stay
|
||||
target:UnLock()
|
||||
target:Spawn()
|
||||
StartBannedUsers[target:SteamID()] = nil
|
||||
else -- If he left and you want to cancel
|
||||
StartBannedUsers[args[1]] = nil
|
||||
end
|
||||
elseif stage == "update" then -- Update reason text
|
||||
if not args[4] or isstring(target) or not IsValid(target) then return false end
|
||||
ply.FAdminKickReason = args[4]
|
||||
umsg.Start("FAdmin_ban_update", target)
|
||||
umsg.Long(tonumber(args[3]))
|
||||
umsg.String(tostring(args[4]))
|
||||
umsg.End()
|
||||
else
|
||||
time = tonumber(args[2]) or 0
|
||||
Reason = (Reason ~= "" and Reason) or args[3] or ""
|
||||
|
||||
if stage == "execute" then
|
||||
time = tonumber(args[3]) or 60 --Default to one hour, not permanent.
|
||||
Reason = args[4] or ""
|
||||
end
|
||||
|
||||
local TimeText = FAdmin.PlayerActions.ConvertBanTime(time)
|
||||
|
||||
if not isstring(target) and IsValid(target) then
|
||||
StartBannedUsers[target:SteamID()] = nil
|
||||
local nick = ply.Nick and ply:Nick() or "console"
|
||||
SaveBan(target:SteamID(), target:Nick(), time, Reason, nick, ply.SteamID and ply:SteamID() or "Console")
|
||||
|
||||
Reason = string.gsub(Reason, ";", " ")
|
||||
target:Kick("banned by " .. nick .. " for " .. TimeText .. " (" .. Reason .. ")")
|
||||
else
|
||||
StartBannedUsers[args[1]] = nil
|
||||
|
||||
SaveBan(target, nil, time, Reason ~= "" and Reason, ply.Nick and ply:Nick() or "console", ply.SteamID and ply:SteamID() or "Console") -- Again default to one hour
|
||||
end
|
||||
ply.FAdminKickReason = nil
|
||||
end
|
||||
end
|
||||
|
||||
if stage ~= "start" and stage ~= "cancel" and stage ~= "update" then
|
||||
FAdmin.Messages.FireNotification("ban", ply, nil, {FAdmin.TargetsToString(targets), time, Reason})
|
||||
end
|
||||
|
||||
return true, targets, stage, Reason
|
||||
end
|
||||
|
||||
-- Input validation: verify that a steam id is valid
|
||||
local function isValidSteamId(steamId)
|
||||
if steamId == "STEAM_ID_PENDING" then return true end
|
||||
if steamId == "UNKNOWN" then return true end
|
||||
if string.match(steamId, "^STEAM_[0-9]:[0-9]:[0-9]+$") then return true end
|
||||
if string.match(steamId, "^[0-9]+$") then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Unbanning
|
||||
local function UnBan(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "UnBan") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
local steamID = string.upper(args[1])
|
||||
|
||||
if not isValidSteamId(steamID) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Player not found")
|
||||
return false
|
||||
end
|
||||
local nick = "Unknown"
|
||||
|
||||
hook.Call("FAdmin_UnBan", nil, ply, steamID)
|
||||
|
||||
for k, v in pairs(FAdmin.BANS) do
|
||||
if string.upper(k) == steamID then
|
||||
nick = FAdmin.BANS[k].name or nick
|
||||
FAdmin.BANS[k] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
StartBannedUsers[steamID] = nil
|
||||
|
||||
game.ConsoleCommand("removeid " .. steamID .. "\n")
|
||||
FAdmin.Messages.FireNotification("unban", ply, nil, {nick, steamID})
|
||||
|
||||
return true, steamID
|
||||
end
|
||||
|
||||
-- Commands and privileges
|
||||
FAdmin.StartHooks["KickBan"] = function()
|
||||
FAdmin.Commands.AddCommand("kick", Kick)
|
||||
FAdmin.Commands.AddCommand("ban", Ban)
|
||||
FAdmin.Commands.AddCommand("unban", UnBan)
|
||||
FAdmin.Commands.AddCommand("RequestBans", RequestBans)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Kick", 2)
|
||||
FAdmin.Access.AddPrivilege("Ban", 2)
|
||||
FAdmin.Access.AddPrivilege("UnBan", 2)
|
||||
end
|
||||
|
||||
hook.Add("DarkRPDBInitialized", "FAdmin_Retrievebans", function()
|
||||
timer.Simple(2, function()
|
||||
local RetrieveBans = hook.Call("FAdmin_RetrieveBans", nil)
|
||||
|
||||
if RetrieveBans then
|
||||
for k, v in pairs(RetrieveBans) do
|
||||
FAdmin.BANS[string.upper(k)] = v
|
||||
end
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
if file.Exists("FAdmin/Bans.txt", "DATA") then
|
||||
local bans = util.KeyValuesToTable(file.Read("FAdmin/bans.txt", "DATA") or {})
|
||||
for k, v in pairs(bans) do
|
||||
FAdmin.BANS[string.upper(k)] = v
|
||||
end
|
||||
|
||||
for k, v in pairs(FAdmin.BANS) do
|
||||
v.time = tonumber(v.time)
|
||||
if v.time and v.time < os.time() then
|
||||
FAdmin.BANS[string.upper(k)] = nil
|
||||
continue
|
||||
elseif not v.time then
|
||||
continue
|
||||
end
|
||||
|
||||
hook.Call("FAdmin_StoreBan", nil, string.upper(k), v.name, (v.time - os.time()) / 60, v.reason, v.adminname, v.adminsteam)
|
||||
end
|
||||
file.Delete("FAdmin/Bans.txt", "DATA")
|
||||
end
|
||||
end)
|
||||
|
||||
local function canJoin(steamID)
|
||||
local ban = FAdmin.BANS[string.upper(steamID)]
|
||||
|
||||
if not ban then return end
|
||||
|
||||
if ban.time ~= 0 and ban.time < os.time() then
|
||||
FAdmin.BANS[string.upper(steamID)] = nil
|
||||
return
|
||||
end
|
||||
|
||||
local timeText = FAdmin.PlayerActions.ConvertBanTime((ban.time - os.time()) / 60)
|
||||
|
||||
return false, "banned by " .. (ban.adminname or "<Unknown>") .. " for " .. timeText .. " (" .. (ban.reason or "no reason") .. ")"
|
||||
end
|
||||
hook.Add("CheckPassword", "FAdmin_Bans", fc{canJoin, util.SteamIDFrom64})
|
||||
|
||||
-- When the bans haven't loaded yet, or when the player passes
|
||||
-- CheckPassword when banned, they'll be caught on InitialSpawn
|
||||
hook.Add("PlayerInitialSpawn", "FAdmin_Bans", function(ply)
|
||||
local allowedIn, reason = canJoin(ply:SteamID())
|
||||
if allowedIn == false then
|
||||
ply:Kick(reason)
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerDisconnected", "FAdmin bans", function(ply)
|
||||
for k,v in pairs(StartBannedUsers) do
|
||||
if v.author ~= ply then continue end
|
||||
StartBannedUsers[k] = nil
|
||||
local target = player.GetBySteamID(k)
|
||||
if not IsValid(target) then continue end
|
||||
SendUserMessage("FAdmin_ban_cancel", target)
|
||||
target:UnLock()
|
||||
target:Spawn()
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,77 @@
|
||||
local function MessageGui(ply)
|
||||
if not FAdmin.Messages or not FAdmin.Messages.MsgTypes then return end
|
||||
|
||||
local frame = vgui.Create("DFrame")
|
||||
frame:SetTitle("Send message")
|
||||
frame:SetSize(350, 170)
|
||||
frame:Center()
|
||||
frame:SetVisible(true)
|
||||
frame:MakePopup()
|
||||
|
||||
local MsgType = 2
|
||||
|
||||
local i = 0
|
||||
local TypeButtons = {}
|
||||
local MsgTypeNames = {ERROR = 1, NOTIFY = 2, QUESTION = 3, GOOD = 4, BAD = 5}
|
||||
for k, v in pairs(FAdmin.Messages.MsgTypes) do
|
||||
|
||||
|
||||
local MsgTypeButton = vgui.Create("DCheckBox", frame)
|
||||
MsgTypeButton:SetPos(20 + i * 64, 46)
|
||||
if k == "NOTIFY" then MsgTypeButton:SetValue(true) end
|
||||
|
||||
function MsgTypeButton:DoClick()
|
||||
for _, B in pairs(TypeButtons) do B:SetValue(false) end
|
||||
|
||||
self:SetValue(true)
|
||||
MsgType = MsgTypeNames[k]
|
||||
end
|
||||
|
||||
local Icon = vgui.Create("DImageButton", frame)
|
||||
Icon:SetImage(v.TEXTURE)
|
||||
Icon:SetPos(20 + i * 64 + 16, 30)
|
||||
Icon:SetSize(32, 32)
|
||||
function Icon:DoClick()
|
||||
for _, B in pairs(TypeButtons) do B:SetValue(false) end
|
||||
MsgTypeButton:SetValue(true)
|
||||
MsgType = MsgTypeNames[k]
|
||||
end
|
||||
|
||||
table.insert(TypeButtons, MsgTypeButton)
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
local OK = vgui.Create("DButton", frame)
|
||||
local TextBox = vgui.Create("DTextEntry", frame)
|
||||
TextBox:SetPos(20, 100)
|
||||
TextBox:StretchToParent(20, nil, 20, nil)
|
||||
TextBox:RequestFocus()
|
||||
function TextBox:Think() -- Most people are holding tab when they open this window. Get focus back!
|
||||
TextBox.InTab = TextBox.InTab or input.IsKeyDown(KEY_TAB)
|
||||
if TextBox.InTab and not input.IsKeyDown(KEY_TAB) then self:RequestFocus() end
|
||||
end
|
||||
function TextBox:OnEnter()
|
||||
OK:DoClick()
|
||||
end
|
||||
|
||||
OK:SetSize(100, 20)
|
||||
OK:SetText("OK")
|
||||
OK:AlignRight(20)
|
||||
OK:AlignBottom(20)
|
||||
function OK:DoClick()
|
||||
frame:Close()
|
||||
if not IsValid(ply) then return end
|
||||
RunConsoleCommand("_FAdmin", "Message", ply:SteamID(), MsgType, TextBox:GetValue())
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["zzSendMessage"] = function()
|
||||
FAdmin.Access.AddPrivilege("Message", 1)
|
||||
FAdmin.Commands.AddCommand("Message", nil, "<Player>", "[type]", "<text>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Send message", "fadmin/icons/message", Color(0, 200, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Message") and not ply:IsBot() end, function(ply, button)
|
||||
MessageGui(ply)
|
||||
end
|
||||
)
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
local function DoMessage(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Message") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[2] then return false end
|
||||
|
||||
ply.FAdmin_LastMessageTime = ply.FAdmin_LastMessageTime or CurTime() - 2
|
||||
if ply.FAdmin_LastMessageTime > (CurTime() - 2) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Wait before sending a new message")
|
||||
return false
|
||||
end
|
||||
|
||||
ply.FAdmin_LastMessageTime = CurTime()
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) or not args[3] then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
local MsgType = tonumber(args[2]) or 2
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) then
|
||||
FAdmin.Messages.SendMessage(target, MsgType, ply:Nick() .. ": " .. args[3])
|
||||
end
|
||||
end
|
||||
|
||||
if ply ~= targets[1] then
|
||||
FAdmin.Messages.SendMessage(ply, MsgType, ply:Nick() .. ": " .. args[3])
|
||||
end
|
||||
|
||||
return true, targets, MsgType, args[3]
|
||||
end
|
||||
|
||||
|
||||
FAdmin.StartHooks["DoMessage"] = function()
|
||||
FAdmin.Commands.AddCommand("Message", DoMessage)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Message", 1) -- Anyone can send messages. Why not?
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
local sbox_noclip = GetConVar("sbox_noclip")
|
||||
|
||||
local function EnableDisableNoclip(ply)
|
||||
return ply:FAdmin_GetGlobal("FADmin_CanNoclip") or
|
||||
((FAdmin.Access.PlayerHasPrivilege(ply, "Noclip") or sbox_noclip:GetBool())
|
||||
and not ply:FAdmin_GetGlobal("FADmin_DisableNoclip"))
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["zz_Noclip"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "noclipenable",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " enabled noclip for ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "noclipdisable",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " disabled noclip for ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Noclip", 2)
|
||||
FAdmin.Access.AddPrivilege("SetNoclip", 2)
|
||||
|
||||
FAdmin.Commands.AddCommand("SetNoclip", nil, "<Player>", "<Toggle 1/0>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if EnableDisableNoclip(ply) then
|
||||
return "Disable noclip"
|
||||
end
|
||||
return "Enable noclip"
|
||||
end, function(ply) return "fadmin/icons/noclip", EnableDisableNoclip(ply) and "fadmin/icons/disable" end, Color(0, 200, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "SetNoclip") end, function(ply, button)
|
||||
if EnableDisableNoclip(ply) then
|
||||
RunConsoleCommand("_FAdmin", "SetNoclip", ply:UserID(), 0)
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "SetNoclip", ply:UserID(), 1)
|
||||
end
|
||||
|
||||
if EnableDisableNoclip(ply) then
|
||||
button:SetText("Enable noclip")
|
||||
button:SetImage2("null")
|
||||
button:GetParent():InvalidateLayout()
|
||||
return
|
||||
end
|
||||
button:SetText("Disable noclip")
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
local sbox_noclip = GetConVar("sbox_noclip")
|
||||
|
||||
local function sendNoclipMessage(ply)
|
||||
if not SERVER or ply.FADmin_HasGotNoclipMessage then return end
|
||||
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Noclip allowed")
|
||||
ply.FADmin_HasGotNoclipMessage = true
|
||||
end
|
||||
|
||||
hook.Add("PlayerNoClip", "FAdmin_noclip", function(ply)
|
||||
if ply:FAdmin_GetGlobal("FADmin_DisableNoclip") then
|
||||
if SERVER then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "Noclip disallowed!")
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- No further judgement when sbox_noclip is on
|
||||
if sbox_noclip:GetBool() then return end
|
||||
|
||||
if ply:FAdmin_GetGlobal("FADmin_CanNoclip") then
|
||||
sendNoclipMessage(ply)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if not ply:Alive() then return end
|
||||
|
||||
-- Has privilege
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Noclip") then return end
|
||||
|
||||
-- Disallow if other hooks say no
|
||||
for k, v in pairs(hook.GetTable().PlayerNoClip) do
|
||||
if k == "FAdmin_noclip" then continue end
|
||||
if v(ply) == false then return false end
|
||||
end
|
||||
|
||||
sendNoclipMessage(ply)
|
||||
|
||||
return true
|
||||
end)
|
||||
@@ -0,0 +1,60 @@
|
||||
local function SetNoclip(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "SetNoclip") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
local Toggle = tobool(tonumber(args[2])) or false
|
||||
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) then
|
||||
if Toggle then
|
||||
target:FAdmin_SetGlobal("FADmin_CanNoclip", true)
|
||||
target:FAdmin_SetGlobal("FADmin_DisableNoclip", false)
|
||||
|
||||
if not FAdmin.Access.PlayerHasPrivilege(target, "Noclip") then
|
||||
FAdmin.Messages.SendMessage(ply, 3, "This is not permanent! Make it permanent with a custom group in SetAccess!")
|
||||
end
|
||||
else
|
||||
target:FAdmin_SetGlobal("FADmin_CanNoclip", false)
|
||||
target:FAdmin_SetGlobal("FADmin_DisableNoclip", true)
|
||||
|
||||
if target:GetMoveType() == MOVETYPE_NOCLIP then
|
||||
target:SetMoveType(MOVETYPE_WALK)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if Toggle then
|
||||
FAdmin.Messages.FireNotification("noclipenable", ply, targets)
|
||||
else
|
||||
FAdmin.Messages.FireNotification("noclipdisable", ply, targets)
|
||||
end
|
||||
|
||||
return true, targets, Toggle
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["zz_Noclip"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "noclipenable",
|
||||
hasTarget = true,
|
||||
receivers = "involved",
|
||||
message = {"instigator", " enabled noclip for ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "noclipdisable",
|
||||
hasTarget = true,
|
||||
receivers = "involved",
|
||||
message = {"instigator", " disabled noclip for ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Noclip", 2)
|
||||
FAdmin.Access.AddPrivilege("SetNoclip", 2)
|
||||
|
||||
FAdmin.Commands.AddCommand("SetNoclip", SetNoclip)
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
FAdmin.StartHooks["Ragdoll"] = function()
|
||||
FAdmin.Access.AddPrivilege("Ragdoll", 2)
|
||||
FAdmin.Commands.AddCommand("Ragdoll", nil, "<Player>", "[normal/hang/kick]")
|
||||
FAdmin.Commands.AddCommand("UnRagdoll", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_ragdolled") then return "Unragdoll" end
|
||||
return "Ragdoll"
|
||||
end,
|
||||
function(ply)
|
||||
if ply:FAdmin_GetGlobal("fadmin_ragdolled") then return "fadmin/icons/ragdoll", "fadmin/icons/disable" end
|
||||
return "fadmin/icons/ragdoll"
|
||||
end,
|
||||
Color(255, 130, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Ragdoll", ply) end,
|
||||
function(ply, button)
|
||||
if ply:FAdmin_GetGlobal("fadmin_ragdolled") then
|
||||
RunConsoleCommand("_FAdmin", "unragdoll", ply:UserID())
|
||||
button:SetImage2("null")
|
||||
button:SetText("Ragdoll")
|
||||
button:GetParent():InvalidateLayout()
|
||||
return end
|
||||
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Ragdoll Type:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
|
||||
menu:AddPanel(Title)
|
||||
|
||||
for k, v in ipairs(FAdmin.PlayerActions.RagdollTypes) do
|
||||
if v == "Unragdoll" then continue end
|
||||
FAdmin.PlayerActions.addTimeSubmenu(menu, v,
|
||||
function()
|
||||
RunConsoleCommand("_FAdmin", "Ragdoll", ply:UserID(), k)
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Unragdoll")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end,
|
||||
function(secs)
|
||||
RunConsoleCommand("_FAdmin", "Ragdoll", ply:UserID(), k, secs)
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Unragdoll")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
menu:Open()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
-- lua_Run A = Player(5):GetEyeTrace().Entity
|
||||
-- lua_run for i = 1, A:GetPhysicsObjectCount() do B = A:WorldToLocal(A:GetPhysicsObjectNum(i):GetPos()) print("Vector("..B.x..", "..B.y..", "..B.z.."),") end
|
||||
-- lua_run for i = 1, A:GetPhysicsObjectCount() do B = A:GetPhysicsObjectNum(i):GetAngle() print("Angle("..B.p..", "..B.y..", "..B.r.."),") end
|
||||
|
||||
FAdmin.PlayerActions.RagdollTypes = {
|
||||
[1] = "Normal",
|
||||
[2] = "Kick them in the nuts",
|
||||
[3] = "Hang",
|
||||
[4] = "Unragdoll"
|
||||
}
|
||||
|
||||
FAdmin.StartHooks["Ragdolling"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "ragdoll",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " ragdolled ", "targets", " ", "extraInfo.1"},
|
||||
receivers = "involved+admins",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
readExtraInfo = function()
|
||||
local time = net.ReadUInt(16)
|
||||
return {time == 0 and FAdmin.PlayerActions.commonTimes[time] or string.format("for %s", FAdmin.PlayerActions.commonTimes[time] or (time .. " seconds"))}
|
||||
end
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "unragdoll",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " unragdolled ", "targets"},
|
||||
receivers = "involved+admins",
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,333 @@
|
||||
local HangProps = {
|
||||
[1] = {model = "models/props_docks/dock02_pole02a_256.mdl", pos = Vector(100, 0, 39), ang = Angle(0,0,0)},
|
||||
[2] = {model = "models/props_docks/dock01_pole01a_128.mdl", pos = Vector(43, 0, 135), ang = Angle(0, -90, 90)}
|
||||
}
|
||||
|
||||
local VictimPos1 = {
|
||||
Vector(0.08349609375, 4.9041748046875, 10.35856628418),
|
||||
Vector(-7.62841796875, 2.5777587890625, 19.235778808594),
|
||||
Vector(7.866943359375, 3.7470703125, 19.656280517578),
|
||||
Vector(9.823974609375, 2.7562255859375, 8.1713256835938),
|
||||
Vector(10.78173828125, -0.431640625, -2.8172454833984),
|
||||
Vector(-9.223876953125, 2.2598876953125, 7.7528839111328),
|
||||
Vector(-10.81884765625, -2.521240234375, -2.6094360351563),
|
||||
Vector(-4.3515625, 0.2113037109375, -0.05419921875),
|
||||
Vector(-7.78466796875, -0.5653076171875, -17.549179077148),
|
||||
Vector(0.08544921875, 1.6834716796875, 25.412673950195),
|
||||
Vector(4.400390625, -0.2120361328125, 0.064102172851563),
|
||||
Vector(6.23095703125, -0.237548828125, -17.736618041992),
|
||||
Vector(8.871337890625, 1.25146484375, -33.981475830078),
|
||||
Vector(-9.429443359375, 2.0859375, -33.777191162109)
|
||||
}
|
||||
|
||||
local VictimAng1 = {
|
||||
Angle(-87.673042297363, -109.66005706787, 294.1647644043),
|
||||
Angle(82.838233947754, -165.22711181641, 201.99559020996),
|
||||
Angle(79.187240600586, -26.850950241089, 355.43997192383),
|
||||
Angle(73.147010803223, -73.275413513184, 310.1682434082),
|
||||
Angle(80.774833679199, -150.97926330566, 325.01263427734),
|
||||
Angle(63.71996307373, -112.01448822021, 253.77954101563),
|
||||
Angle(77.913925170898, -69.091110229492, 173.12385559082),
|
||||
Angle(78.631988525391, -167.21780395508, 216.82838439941),
|
||||
Angle(79.116714477539, 121.81723022461, 146.85758972168),
|
||||
Angle(-89.117118835449, 92.446853637695, 267.04473876953),
|
||||
Angle(83.278358459473, -2.6300358772278, 12.258254051208),
|
||||
Angle(79.429931640625, 29.419277191162, 43.093002319336),
|
||||
Angle(37.975448608398, -70.136756896973, 293.39251708984),
|
||||
Angle(42.589946746826, -95.914726257324, 258.73498535156)
|
||||
}
|
||||
|
||||
-- Kick leg = 9 and 14
|
||||
local KickerPos = {
|
||||
Vector(0.151123046875, -0.55889892578125, 12.428649902344),
|
||||
Vector(-6.949951171875, -4.727294921875, 21.128128051758),
|
||||
Vector(8.18798828125, -4.1649780273438, 20.041198730469),
|
||||
Vector(12.109619140625, 6.8145751953125, 19.155548095703),
|
||||
Vector(8.816162109375, 16.727844238281, 14.390106201172),
|
||||
Vector(-10.9814453125, -12.980773925781, 13.879943847656),
|
||||
Vector(-7.9189453125, -24.001403808594, 14.877258300781),
|
||||
Vector(-4.06396484375, 0.56243896484375, -0.14239501953125),
|
||||
Vector(-0.764404296875, 15.5107421875, -9.5738525390625),
|
||||
Vector(1.176025390625, -7.4561767578125, 26.153648376465),
|
||||
Vector(3.85009765625, -0.55645751953125, -0.035125732421875),
|
||||
Vector(5.841796875, -1.1864624023438, -17.723190307617),
|
||||
Vector(4.7431640625, 4.4840698242188, -33.206146240234),
|
||||
Vector(0.028076171875, 27.153869628906, 2.1262817382813)
|
||||
}
|
||||
|
||||
local KickerAng = {
|
||||
Angle(-72.853500366211, -77.192611694336, 258.47763061523),
|
||||
Angle(38.269737243652, -116.13293457031, 218.30332946777),
|
||||
Angle(4.3439903259277, 70.343925476074, 147.32099914551),
|
||||
Angle(24.522411346436, 108.37782287598, 157.29452514648),
|
||||
Angle(15.059949874878, 50.6491355896, 180.38879394531),
|
||||
Angle(-4.983060836792, -74.469413757324, 230.35047912598),
|
||||
Angle(1.2094515562057, -73.130561828613, 136.18098449707),
|
||||
Angle(32.704917907715, 77.20344543457, 82.96809387207),
|
||||
Angle(-45.073616027832, 86.105369567871, 82.506660461426),
|
||||
Angle(-79.46248626709, -65.311363220215, 68.129730224609),
|
||||
Angle(82.879898071289, -27.148105621338, 318.85842895508),
|
||||
Angle(69.541847229004, 100.96334838867, 80.36100769043),
|
||||
Angle(31.048385620117, -61.657707214355, 279.41061401367),
|
||||
Angle(-19.616451263428, 81.610832214355, 87.282814025879)
|
||||
}
|
||||
|
||||
local function unragdoll(target)
|
||||
timer.Remove(target:SteamID() .. "FAdminRagdoll")
|
||||
target:FAdmin_SetGlobal("fadmin_ragdolled", false)
|
||||
target:UnSpectate()
|
||||
target:Spawn()
|
||||
|
||||
if not istable(target.FAdminRagdoll) and IsValid(target.FAdminRagdoll) then
|
||||
if target.FAdminRagdoll.SetCanRemove then target.FAdminRagdoll:SetCanRemove(true) end
|
||||
target.FAdminRagdoll:Remove()
|
||||
elseif istable(target.FAdminRagdoll) then
|
||||
for _, v in pairs(target.FAdminRagdoll) do
|
||||
if not IsValid(v) then continue end
|
||||
if v.SetCanRemove then v:SetCanRemove(true) end
|
||||
v:Remove()
|
||||
end
|
||||
end
|
||||
target.FAdminRagdoll = nil
|
||||
end
|
||||
|
||||
local function ragdollKick(target)
|
||||
if istable(target.FAdminRagdoll) or IsValid(target.FAdminRagdoll) then return false end
|
||||
local doll = ents.Create("prop_ragdoll")
|
||||
|
||||
doll:SetModel(target:GetModel())
|
||||
doll:SetPos(target:GetPos())
|
||||
|
||||
doll:Spawn()
|
||||
doll:Activate()
|
||||
|
||||
-- The rotation angle (the direction the ragdoll is looking at)
|
||||
local angle = Angle(0, target:EyeAngles().y + 90, 0)
|
||||
for i = 1, doll:GetPhysicsObjectCount() do
|
||||
local phys = doll:GetPhysicsObjectNum(i)
|
||||
if phys and phys:IsValid() and VictimPos1[i] then
|
||||
phys:EnableMotion(false)
|
||||
-- Copy the vector
|
||||
local pos = Vector(VictimPos1[i].x, VictimPos1[i].y, VictimPos1[i].z)
|
||||
pos:Rotate(angle)
|
||||
|
||||
phys:SetPos(pos + doll:GetPos())
|
||||
phys:SetAngles(VictimAng1[i] + angle)
|
||||
end
|
||||
end
|
||||
|
||||
-- The kicker's position is behind the target with distance 35, translated to stand a bit higher
|
||||
local aimVec = Vector(target:GetAimVector().x, target:GetAimVector().y, 0)
|
||||
local kickerPos = target:GetPos() - aimVec * 35 + Vector(0, 0, 5)
|
||||
local Kicker = ents.Create("prop_ragdoll")
|
||||
Kicker:SetModel("models/Police.mdl")
|
||||
Kicker:SetPos(kickerPos)
|
||||
Kicker:Spawn()
|
||||
Kicker:Activate()
|
||||
|
||||
Kicker:EmitSound("npc/combine_soldier/vo/contactconfirmprosecuting.wav", 100, 100)
|
||||
|
||||
for i = 1, Kicker:GetPhysicsObjectCount() do
|
||||
local phys = Kicker:GetPhysicsObjectNum(i)
|
||||
if phys and phys:IsValid() then
|
||||
phys:EnableMotion(false)
|
||||
if i == 8 or i == 9 or i == 14 then
|
||||
phys:EnableCollisions(false)
|
||||
timer.Simple(2, function()
|
||||
if phys:IsValid() then
|
||||
phys:EnableMotion(true)
|
||||
phys:Wake()
|
||||
phys:SetVelocity(aimVec - Vector(0, 0, 1000))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local pos = Vector(KickerPos[i].x, KickerPos[i].y, KickerPos[i].z)
|
||||
pos:Rotate(angle)
|
||||
phys:SetPos(pos + Kicker:GetPos())
|
||||
phys:SetAngles(KickerAng[i] + angle)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
target:StripWeapons()
|
||||
target:Spectate(OBS_MODE_CHASE)
|
||||
target:SpectateEntity(doll)
|
||||
|
||||
target.FAdminRagdoll = doll
|
||||
|
||||
timer.Simple(2.1, function() if IsValid(doll) then
|
||||
doll:EmitSound("physics/body/body_medium_impact_hard6.wav", 100, 100)
|
||||
for i = 1, doll:GetPhysicsObjectCount() do
|
||||
local phys = doll:GetPhysicsObjectNum(i)
|
||||
if phys and phys:IsValid() then
|
||||
phys:EnableCollisions(false)
|
||||
phys:EnableMotion(true)
|
||||
phys:SetVelocity((aimVec:GetNormalized() + Vector(0, 0, 1)) * 1000)
|
||||
end
|
||||
end
|
||||
end end)
|
||||
|
||||
timer.Simple(2.2, function() if IsValid(doll) then
|
||||
for i = 1, doll:GetPhysicsObjectCount() do
|
||||
local phys = doll:GetPhysicsObjectNum(i)
|
||||
if phys and phys:IsValid() then
|
||||
phys:EnableCollisions(true)
|
||||
end
|
||||
end
|
||||
end end)
|
||||
|
||||
timer.Simple(5, function()
|
||||
if IsValid(Kicker) then
|
||||
Kicker:Remove()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function Ragdoll(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
local RagdollType = string.lower(FAdmin.PlayerActions.RagdollTypes[tonumber(args[2])] or args[2] or cmd)
|
||||
|
||||
local time = tonumber(args[3]) or 0
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Ragdoll", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not IsValid(target) then continue end
|
||||
if RagdollType == "unragdoll" or string.lower(cmd) == "unragdoll" and target:FAdmin_GetGlobal("fadmin_ragdolled") then
|
||||
unragdoll(target)
|
||||
elseif RagdollType == "normal" or RagdollType == "ragdoll" then
|
||||
if istable(target.FAdminRagdoll) or IsValid(target.FAdminRagdoll) then return false end
|
||||
local doll = ents.Create("prop_ragdoll")
|
||||
|
||||
doll:SetModel(target:GetModel())
|
||||
doll:SetPos(target:GetPos())
|
||||
doll:SetAngles(target:GetAngles())
|
||||
doll:Spawn()
|
||||
doll:Activate()
|
||||
|
||||
target:StripWeapons()
|
||||
target:Spectate(OBS_MODE_CHASE)
|
||||
target:SpectateEntity(doll)
|
||||
|
||||
target.FAdminRagdoll = doll
|
||||
elseif RagdollType == "hang" then
|
||||
if istable(target.FAdminRagdoll) or IsValid(target.FAdminRagdoll) then return false end
|
||||
target.FAdminRagdoll = {}
|
||||
|
||||
local doll = ents.Create("prop_ragdoll")
|
||||
|
||||
doll:SetModel(target:GetModel())
|
||||
doll:SetPos(target:GetPos())
|
||||
doll:SetAngles(target:GetAngles())
|
||||
doll:Spawn()
|
||||
doll:Activate()
|
||||
table.insert(target.FAdminRagdoll, doll)
|
||||
|
||||
target:StripWeapons()
|
||||
target:Spectate(OBS_MODE_CHASE)
|
||||
target:SpectateEntity(doll)
|
||||
|
||||
local HangOn
|
||||
for k,v in ipairs(HangProps) do
|
||||
local prop = ents.Create("fadmin_jail")
|
||||
prop.target = prop
|
||||
prop:SetModel(v.model)
|
||||
prop:SetPos(v.pos + target:GetPos())
|
||||
prop:SetAngles(v.ang)
|
||||
prop:Spawn()
|
||||
prop:Activate()
|
||||
|
||||
local phys = prop:GetPhysicsObject()
|
||||
if IsValid(phys) then phys:EnableMotion(false) end
|
||||
|
||||
table.insert(target.FAdminRagdoll, prop)
|
||||
HangOn = prop -- Hang on the last prop
|
||||
end
|
||||
if not HangOn then return false end
|
||||
|
||||
doll:SetPos(HangOn:GetPos() - Vector(-50,0,10))
|
||||
timer.Simple(0.2, function() constraint.Rope(doll, HangOn, 10, 0, Vector(-2.4,0,-0.6), Vector(0,0,53), 10, 40, 0, 4, "cable/rope", false) end)
|
||||
elseif string.find(RagdollType, "kick") == 1 then -- Best ragdoll mod EVER
|
||||
ragdollKick(target)
|
||||
end
|
||||
|
||||
if time ~= 0 then
|
||||
timer.Create(target:SteamID() .. "FAdminRagdoll", time, 1, function()
|
||||
if not IsValid(target) then return end
|
||||
if IsValid(target.FAdminRagdoll) then
|
||||
target:SetPos(target.FAdminRagdoll:GetPos())
|
||||
target.FAdminRagdoll:Remove()
|
||||
elseif istable(target.FAdminRagdoll) then
|
||||
for k, v in pairs(target.FAdminRagdoll) do SafeRemoveEntity(v) end
|
||||
end
|
||||
target:UnSpectate()
|
||||
target:Spawn()
|
||||
target.FAdminRagdoll = nil
|
||||
target:FAdmin_SetGlobal("fadmin_ragdolled", false)
|
||||
end)
|
||||
end
|
||||
|
||||
if RagdollType ~= "unragdoll" and string.lower(cmd) ~= "unragdoll" then
|
||||
target:FAdmin_SetGlobal("fadmin_ragdolled", true)
|
||||
end
|
||||
end
|
||||
if RagdollType == "unragdoll" or string.lower(cmd) == "unragdoll" then
|
||||
FAdmin.Messages.FireNotification("unragdoll", ply, targets)
|
||||
else
|
||||
FAdmin.Messages.FireNotification("ragdoll", ply, targets, {time})
|
||||
end
|
||||
|
||||
return true, targets, RagdollType, time
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Ragdoll"] = function()
|
||||
FAdmin.Commands.AddCommand("Ragdoll", Ragdoll)
|
||||
FAdmin.Commands.AddCommand("UnRagdoll", Ragdoll)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Ragdoll", 2)
|
||||
end
|
||||
|
||||
hook.Add("PlayerSpawnObject", "FAdmin_ragdoll", function(ply)
|
||||
if istable(ply.FAdminRagdoll) or IsValid(ply.FAdminRagdoll) then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("CanPlayerSuicide", "FAdmin_ragdoll", function(ply)
|
||||
if istable(ply.FAdminRagdoll) or IsValid(ply.FAdminRagdoll) then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerDeath", "FAdmin_ragdoll", function(ply)
|
||||
if (istable(ply.FAdminRagdoll) or IsValid(ply.FAdminRagdoll)) and IsValid(ply:GetRagdollEntity()) then
|
||||
ply:GetRagdollEntity():Remove()
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerDeathThink", "FAdmin_ragdoll", function(ply)
|
||||
if istable(ply.FAdminRagdoll) or IsValid(ply.FAdminRagdoll) then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PlayerDisconnected", "FAdmin_ragdoll", function(ply)
|
||||
if not ply.FAdminRagdoll then return end
|
||||
|
||||
if IsValid(ply.FAdminRagdoll) then
|
||||
ply.FAdminRagdoll:Remove()
|
||||
return
|
||||
end
|
||||
|
||||
if not istable(ply.FAdminRagdoll) then return end
|
||||
|
||||
for _, v in pairs(ply.FAdminRagdoll or {}) do
|
||||
if IsValid(v) then v:Remove() end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,53 @@
|
||||
local Damages = {0, 1, 10, 50, 100, 500, 9999999--[[for the 12-year-olds]]}
|
||||
local Repetitions = {[1] = "once", [5] = "5 times", [10] = "10 times", [50] = "50 times", [100] = "100 times"}
|
||||
|
||||
FAdmin.StartHooks["Slap"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "slap",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " slapped ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Slap", 2)
|
||||
FAdmin.Commands.AddCommand("Slap", nil, "<Player>", "[Amount]", "[Repetitions]")
|
||||
|
||||
-- Right click option
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Slap", function(ply)
|
||||
RunConsoleCommand("_FAdmin", "Slap", ply:UserID())
|
||||
end)
|
||||
|
||||
-- Slap option in player menu
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Slap", "fadmin/icons/slap", Color(255, 130, 0, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Slap", ply) end, function(ply)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Damage:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
menu:AddPanel(Title)
|
||||
|
||||
for _, v in ipairs(Damages) do
|
||||
local SubMenu = menu:AddSubMenu(v, function() RunConsoleCommand("_FAdmin", "slap", ply:UserID(), v) end)
|
||||
|
||||
local SubMenuTitle = vgui.Create("DLabel")
|
||||
SubMenuTitle:SetText(" " .. v .. " damage\n")
|
||||
SubMenuTitle:SetFont("UiBold")
|
||||
SubMenuTitle:SizeToContents()
|
||||
SubMenuTitle:SetTextColor(color_black)
|
||||
|
||||
SubMenu:AddPanel(SubMenuTitle)
|
||||
|
||||
for reps, Name in SortedPairs(Repetitions) do
|
||||
local uid = ply:UserID()
|
||||
SubMenu:AddOption(Name, function() RunConsoleCommand("_FAdmin", "slap", uid, v, reps) end)
|
||||
end
|
||||
end
|
||||
menu:Open()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,63 @@
|
||||
local function ExecuteSlap(target, Amount, ply)
|
||||
if not IsValid(target) or not IsValid(ply) then return end
|
||||
|
||||
local Force = Vector(math.Rand(-500, 500), math.Rand(-500, 500), math.Rand(-100, 700))
|
||||
|
||||
local DmgInfo = DamageInfo()
|
||||
DmgInfo:SetDamage(Amount)
|
||||
DmgInfo:SetDamageType(DMG_DROWN)
|
||||
DmgInfo:SetAttacker(ply)
|
||||
DmgInfo:SetDamageForce(Force)
|
||||
|
||||
target:TakeDamageInfo(DmgInfo)
|
||||
target:SetVelocity(Force)
|
||||
end
|
||||
|
||||
local function Slap(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
local Amount = DarkRP.toInt(args[2]) or 10
|
||||
local Repetitions = DarkRP.toInt(args[3])
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Slap", target) then
|
||||
FAdmin.Messages.SendMessage(ply, 5, "No access!")
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if IsValid(target) then
|
||||
if not Repetitions or Repetitions == 1 then
|
||||
ExecuteSlap(target, Amount, ply)
|
||||
else
|
||||
for i = 1, Repetitions, 1 do
|
||||
timer.Simple(i * 0.7, function()
|
||||
ExecuteSlap(target, Amount, ply)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("slap", ply, targets)
|
||||
|
||||
return true, targets, Amount, Repetitions
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Slap"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "slap",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
message = {"instigator", " slapped ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("Slap", Slap)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Slap", 2)
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
FAdmin.StartHooks["Slay"] = function()
|
||||
FAdmin.Access.AddPrivilege("Slay", 2)
|
||||
FAdmin.Commands.AddCommand("Slay", nil, "<Player>", "[Normal/Silent/Explode/Rocket]")
|
||||
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Slay", function(ply)
|
||||
RunConsoleCommand("_FAdmin", "slay", ply:UserID())
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Slay", "fadmin/icons/slay", Color(255, 130, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Slay", ply) end,
|
||||
function(ply)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Kill Type:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
menu:AddPanel(Title)
|
||||
|
||||
for k, v in ipairs(FAdmin.PlayerActions.SlayTypes) do
|
||||
local uid = ply:UserID()
|
||||
menu:AddOption(v, function()
|
||||
RunConsoleCommand("_FAdmin", "slay", uid, k)
|
||||
end)
|
||||
end
|
||||
|
||||
menu:Open()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
FAdmin.PlayerActions.SlayTypes = {}
|
||||
FAdmin.PlayerActions.SlayTypes[1] = "Normal"
|
||||
FAdmin.PlayerActions.SlayTypes[2] = "Silent"
|
||||
FAdmin.PlayerActions.SlayTypes[3] = "Explode"
|
||||
FAdmin.PlayerActions.SlayTypes[4] = "Rocket"
|
||||
|
||||
FAdmin.StartHooks["Slaying"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "slay",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " slayed ", "targets"},
|
||||
receivers = "involved+admins",
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
local function Slay(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
local SlayType = string.lower(FAdmin.PlayerActions.SlayTypes[tonumber(args[2])] or args[2] or "Normal")
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Slay", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) then
|
||||
if SlayType == "normal" then
|
||||
target:Kill()
|
||||
elseif SlayType == "silent" then
|
||||
target:KillSilent()
|
||||
elseif SlayType == "explode" then
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetStart(target:GetPos())
|
||||
effectdata:SetOrigin(target:GetPos())
|
||||
effectdata:SetScale(3)
|
||||
util.Effect("HelicopterMegaBomb", effectdata)
|
||||
target:EmitSound("ambient/explosions/explode_1.wav", 100, 100)
|
||||
target:SetVelocity(Vector(math.Rand(-500, 500), math.Rand(-500, 500), math.Rand(200, 700)))
|
||||
target:Kill()
|
||||
elseif SlayType == "rocket" then
|
||||
target:SetVelocity(Vector(0,0,1000))
|
||||
timer.Simple(1, function()
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetStart(target:GetPos())
|
||||
effectdata:SetOrigin(target:GetPos())
|
||||
effectdata:SetScale(3)
|
||||
util.Effect("HelicopterMegaBomb", effectdata)
|
||||
target:EmitSound("ambient/explosions/explode_1.wav", 100, 100)
|
||||
target:SetVelocity(Vector(math.Rand(-500, 500), math.Rand(-500, 500), math.Rand(200, 700)))
|
||||
target:Kill()
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("slay", ply, targets)
|
||||
|
||||
return true, targets, SlayType
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Slay"] = function()
|
||||
FAdmin.Commands.AddCommand("Slay", Slay)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Slay", 2)
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
FAdmin.StartHooks["StripWeapons"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "stripweapons",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " stripped the weapons of ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("StripWeapons", 2)
|
||||
FAdmin.Commands.AddCommand("StripWeapons", nil, "<Player>")
|
||||
FAdmin.Commands.AddCommand("Strip", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Strip weapons", {"fadmin/icons/weapon", "fadmin/icons/disable"}, Color(255, 130, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "StripWeapons", ply) end, function(ply, button)
|
||||
RunConsoleCommand("_FAdmin", "StripWeapons", ply:UserID())
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
local function StripWeapons(ply, cmd, args)
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "StripWeapons", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) then
|
||||
target:StripWeapons()
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("stripweapons", ply, targets)
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["StripWeapons"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "stripweapons",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
message = {"instigator", " stripped the weapons of ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("StripWeapons", StripWeapons)
|
||||
FAdmin.Commands.AddCommand("Strip", StripWeapons)
|
||||
|
||||
FAdmin.Access.AddPrivilege("StripWeapons", 2)
|
||||
end
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
FAdmin.StartHooks["zz_Teleport"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "goto",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " teleported to ", "targets"}
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "bring",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " brought ", "targets", " to them"}
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Teleport", 2)
|
||||
|
||||
FAdmin.Commands.AddCommand("Teleport", nil, "[Player]")
|
||||
FAdmin.Commands.AddCommand("TP", nil, "[Player]")
|
||||
FAdmin.Commands.AddCommand("Bring", nil, "<Player>", "[Player]")
|
||||
FAdmin.Commands.AddCommand("goto", nil, "<Player>")
|
||||
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Teleport", "fadmin/icons/teleport", Color(0, 200, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Teleport") end,
|
||||
function(ply, button)
|
||||
RunConsoleCommand("_FAdmin", "Teleport", ply:UserID())
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Goto", "fadmin/icons/teleport", Color(0, 200, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Teleport") and ply ~= LocalPlayer() end,
|
||||
function(ply, button)
|
||||
RunConsoleCommand("_FAdmin", "goto", ply:UserID())
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton("Bring", "fadmin/icons/teleport", Color(0, 200, 0, 255),
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Teleport") and ply ~= LocalPlayer() end,
|
||||
function(ply, button)
|
||||
local menu = DermaMenu()
|
||||
|
||||
local Padding = vgui.Create("DPanel")
|
||||
Padding:SetPaintBackgroundEnabled(false)
|
||||
Padding:SetSize(1,5)
|
||||
menu:AddPanel(Padding)
|
||||
|
||||
local Title = vgui.Create("DLabel")
|
||||
Title:SetText(" Bring to:\n")
|
||||
Title:SetFont("UiBold")
|
||||
Title:SizeToContents()
|
||||
Title:SetTextColor(color_black)
|
||||
|
||||
menu:AddPanel(Title)
|
||||
|
||||
local uid = ply:UserID()
|
||||
menu:AddOption("Yourself", function() RunConsoleCommand("_FAdmin", "bring", uid) end)
|
||||
for _, v in ipairs(DarkRP.nickSortedPlayers()) do
|
||||
if IsValid(v) and v ~= LocalPlayer() then
|
||||
local vUid = v:UserID()
|
||||
menu:AddOption(v:Nick(), function() RunConsoleCommand("_FAdmin", "bring", uid, vUid) end)
|
||||
end
|
||||
end
|
||||
menu:Open()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,169 @@
|
||||
local function zapEffect(target)
|
||||
local effectdata = EffectData()
|
||||
effectdata:SetStart(target:GetShootPos())
|
||||
effectdata:SetOrigin(target:GetShootPos())
|
||||
effectdata:SetScale(1)
|
||||
effectdata:SetMagnitude(1)
|
||||
effectdata:SetScale(3)
|
||||
effectdata:SetRadius(1)
|
||||
effectdata:SetEntity(target)
|
||||
for i = 1, 100, 1 do
|
||||
timer.Simple(1 / i, function()
|
||||
util.Effect("TeslaHitBoxes", effectdata, true, true)
|
||||
end)
|
||||
end
|
||||
local Zap = math.random(1,9)
|
||||
if Zap == 4 then Zap = 3 end
|
||||
target:EmitSound("ambient/energy/zap" .. Zap .. ".wav")
|
||||
end
|
||||
|
||||
local function TPToPos(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Teleport") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local x, y, z = string.match(args[1] or "", "([-0-9\\.]+),%s?([-0-9\\.]+),%s?([-0-9\\.]+)")
|
||||
local vx, vy, vz = string.match(args[2] or "", "([-0-9\\.]+),%s?([-0-9\\.]+),%s?([-0-9\\.]+)")
|
||||
local pos = Vector(tonumber(x), tonumber(y), tonumber(z))
|
||||
local vel = Vector(tonumber(vx), tonumber(vy), tonumber(vz))
|
||||
|
||||
if not args[1] or not x or not y or not z then return false end
|
||||
|
||||
ply:SetPos(pos)
|
||||
if vx and vy and vz then ply:SetVelocity(vel) end
|
||||
zapEffect(ply)
|
||||
|
||||
return true, pos, vel
|
||||
end
|
||||
|
||||
local function Teleport(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Teleport") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
targets = {ply}
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if IsValid(target) and target:Alive() then
|
||||
target:ExitVehicle()
|
||||
|
||||
local tracedata = {}
|
||||
tracedata.start = ply:GetShootPos()
|
||||
tracedata.endpos = tracedata.start + ply:GetAimVector() * 10000
|
||||
tracedata.filter = ply
|
||||
|
||||
local trace = util.TraceLine(tracedata)
|
||||
local offset = Vector(0, 0, 1)
|
||||
if trace.HitNormal ~= Vector(0, 0, 1) then
|
||||
offset = trace.HitNormal * 16
|
||||
end
|
||||
|
||||
local _, hull = ply:GetHull()
|
||||
|
||||
local InitialPosition = DarkRP.findEmptyPos(trace.HitPos + offset, {ply}, 600, 20, hull)
|
||||
target:SetPos(InitialPosition)
|
||||
|
||||
zapEffect(target)
|
||||
FAdmin.Log(string.format("FAdmin: %s (%s) teleported %s", ply:Nick(), ply:SteamID(), target:Nick()))
|
||||
end
|
||||
end
|
||||
|
||||
return true, targets, ply:GetEyeTrace().HitPos
|
||||
end
|
||||
|
||||
local function Bring(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Teleport") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
local BringTo = FAdmin.FindPlayer(args[2])
|
||||
|
||||
BringTo = (BringTo and BringTo[1]) or ply
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not IsValid(target) or target == ply then continue end
|
||||
|
||||
target:ExitVehicle()
|
||||
if not target:Alive() then target:Spawn() end
|
||||
local PHYSGUN = false
|
||||
if IsValid(target:GetActiveWeapon()) and target:GetActiveWeapon():GetClass() == "weapon_physgun" and target:KeyDown(IN_ATTACK) then
|
||||
target:ConCommand("-attack") --release the stuff he's holding :)
|
||||
target:GetActiveWeapon():Remove()
|
||||
PHYSGUN = true
|
||||
end
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(target) then return end
|
||||
local tracedata = {}
|
||||
tracedata.start = BringTo:GetShootPos()
|
||||
tracedata.endpos = tracedata.start + BringTo:GetAimVector() * 50
|
||||
tracedata.filter = BringTo
|
||||
|
||||
local trace = util.TraceLine(tracedata)
|
||||
if trace.HitPos:DistToSqr(BringTo:GetShootPos()) < 2025 then
|
||||
tracedata.endpos = tracedata.start - BringTo:GetAimVector() * 50
|
||||
trace = util.TraceLine(tracedata)
|
||||
end
|
||||
|
||||
local _, hull = target:GetHull()
|
||||
|
||||
target:SetPos(DarkRP.findEmptyPos(BringTo:GetPos(), {target}, 600, 30, hull))
|
||||
|
||||
zapEffect(target)
|
||||
|
||||
if PHYSGUN then timer.Simple(0.5, function() target:Give("weapon_physgun") target:SelectWeapon("weapon_physgun") end) end
|
||||
end)
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("bring", ply, targets)
|
||||
|
||||
return true, targets, BringTo
|
||||
end
|
||||
|
||||
local function Goto(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Teleport") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[1] then return false end
|
||||
|
||||
local target = FAdmin.FindPlayer(args[1])
|
||||
target = target and target[1]
|
||||
if not IsValid(target) then return false end
|
||||
|
||||
ply:ExitVehicle()
|
||||
if not ply:Alive() then ply:Spawn() end
|
||||
|
||||
local _, hull = ply:GetHull()
|
||||
|
||||
ply:SetPos(DarkRP.findEmptyPos(target:GetPos(), {ply}, 600, 30, hull))
|
||||
|
||||
zapEffect(ply)
|
||||
|
||||
FAdmin.Messages.FireNotification("goto", ply, target)
|
||||
|
||||
return true, target
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["zz_Teleport"] = function()
|
||||
FAdmin.Access.AddPrivilege("Teleport", 2)
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "goto",
|
||||
hasTarget = true,
|
||||
receivers = "admins",
|
||||
message = {"instigator", " teleported to ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "bring",
|
||||
hasTarget = true,
|
||||
receivers = "admins",
|
||||
message = {"instigator", " brought ", "targets", " to them"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("Teleport", Teleport)
|
||||
FAdmin.Commands.AddCommand("TP", Teleport)
|
||||
FAdmin.Commands.AddCommand("Bring", Bring)
|
||||
FAdmin.Commands.AddCommand("Goto", Goto)
|
||||
FAdmin.Commands.AddCommand("TPToPos", TPToPos)
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
hook.Add("PlayerBindPress", "FAdmin_voicemuted", function(ply, bind, pressed)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_voicemuted") and string.find(string.lower(bind), "voicerecord") then return true end
|
||||
-- The voice muting is not done clientside, this is just so people know they can't talk
|
||||
end)
|
||||
|
||||
FAdmin.StartHooks["VoiceMute"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "voicemute",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " voice muted ", "targets", " ", "extraInfo.1"},
|
||||
readExtraInfo = function()
|
||||
local time = net.ReadUInt(16)
|
||||
return {time == 0 and FAdmin.PlayerActions.commonTimes[time] or string.format("for %s", FAdmin.PlayerActions.commonTimes[time] or (time .. " seconds"))}
|
||||
end
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "voiceunmute",
|
||||
hasTarget = true,
|
||||
message = {"instigator", " voice unmuted ", "targets"}
|
||||
}
|
||||
|
||||
FAdmin.Access.AddPrivilege("Voicemute", 2)
|
||||
FAdmin.Commands.AddCommand("Voicemute", nil, "<Player>")
|
||||
FAdmin.Commands.AddCommand("UnVoicemute", nil, "<Player>")
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_voicemuted") then return "Unmute voice globally" end
|
||||
return "Mute voice globally"
|
||||
end,
|
||||
|
||||
function(ply)
|
||||
if ply:FAdmin_GetGlobal("FAdmin_voicemuted") then return "fadmin/icons/voicemute" end
|
||||
return "fadmin/icons/voicemute", "fadmin/icons/disable"
|
||||
end,
|
||||
Color(255, 130, 0, 255),
|
||||
|
||||
function(ply) return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "Voicemute", ply) end,
|
||||
function(ply, button)
|
||||
if not ply:FAdmin_GetGlobal("FAdmin_voicemuted") then
|
||||
FAdmin.PlayerActions.addTimeMenu(function(secs)
|
||||
RunConsoleCommand("_FAdmin", "Voicemute", ply:UserID(), secs)
|
||||
button:SetImage2("null")
|
||||
button:SetText("Unmute voice globally")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
else
|
||||
RunConsoleCommand("_FAdmin", "UnVoicemute", ply:UserID())
|
||||
end
|
||||
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Mute voice globally")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Player:AddActionButton(function(ply)
|
||||
return ply.FAdminMuted and "Unmute voice" or "Mute voice"
|
||||
end,
|
||||
function(ply)
|
||||
if ply.FAdminMuted then return "fadmin/icons/voicemute" end
|
||||
return "fadmin/icons/voicemute", "fadmin/icons/disable"
|
||||
end,
|
||||
Color(255, 130, 0, 255),
|
||||
|
||||
true,
|
||||
|
||||
function(ply, button)
|
||||
ply:SetMuted(not ply.FAdminMuted)
|
||||
ply.FAdminMuted = not ply.FAdminMuted
|
||||
|
||||
if ply.FAdminMuted then button:SetImage2("null") button:SetText("Unmute voice") button:GetParent():InvalidateLayout() return end
|
||||
|
||||
button:SetImage2("fadmin/icons/disable")
|
||||
button:SetText("Mute voice")
|
||||
button:GetParent():InvalidateLayout()
|
||||
end)
|
||||
|
||||
FAdmin.ScoreBoard.Main.AddPlayerRightClick("Mute/Unmute", function(ply, Panel)
|
||||
ply:SetMuted(not ply.FAdminMuted)
|
||||
ply.FAdminMuted = not ply.FAdminMuted
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
local function MuteVoice(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
local time = tonumber(args[2]) or 0
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Voicemute", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and not target:FAdmin_GetGlobal("FAdmin_voicemuted") then
|
||||
target:FAdmin_SetGlobal("FAdmin_voicemuted", true)
|
||||
|
||||
if time == 0 then continue end
|
||||
|
||||
timer.Simple(time, function()
|
||||
if not IsValid(target) or not target:FAdmin_GetGlobal("FAdmin_voicemuted") then return false end
|
||||
target:FAdmin_SetGlobal("FAdmin_voicemuted", false)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("voicemute", ply, targets, {time})
|
||||
|
||||
return true, targets, time
|
||||
end
|
||||
|
||||
local function UnMuteVoice(ply, cmd, args)
|
||||
if not args[1] then return false end
|
||||
|
||||
local targets = FAdmin.FindPlayer(args[1])
|
||||
if not targets or #targets == 1 and not IsValid(targets[1]) then
|
||||
FAdmin.Messages.SendMessage(ply, 1, "Player not found")
|
||||
return false
|
||||
end
|
||||
|
||||
for _, target in ipairs(targets) do
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Voicemute", target) then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if IsValid(target) and target:FAdmin_GetGlobal("FAdmin_voicemuted") then
|
||||
target:FAdmin_SetGlobal("FAdmin_voicemuted", false)
|
||||
end
|
||||
end
|
||||
|
||||
FAdmin.Messages.FireNotification("voiceunmute", ply, targets)
|
||||
|
||||
return true, targets
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["VoiceMute"] = function()
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "voicemute",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
writeExtraInfo = function(info) net.WriteUInt(info[1], 16) end,
|
||||
message = {"instigator", " voice muted ", "targets", " ", "extraInfo.1"},
|
||||
}
|
||||
|
||||
FAdmin.Messages.RegisterNotification{
|
||||
name = "voiceunmute",
|
||||
hasTarget = true,
|
||||
receivers = "involved+admins",
|
||||
message = {"instigator", " voice unmuted ", "targets"},
|
||||
}
|
||||
|
||||
FAdmin.Commands.AddCommand("Voicemute", MuteVoice)
|
||||
FAdmin.Commands.AddCommand("UnVoicemute", UnMuteVoice)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Voicemute", 2)
|
||||
end
|
||||
|
||||
hook.Add("PlayerCanHearPlayersVoice", "FAdmin_Voicemute", function(Listener, Talker)
|
||||
if Talker:FAdmin_GetGlobal("FAdmin_voicemuted") then return false end
|
||||
end)
|
||||
@@ -0,0 +1,10 @@
|
||||
FAdmin.StartHooks["00RCon"] = function()
|
||||
FAdmin.Access.AddPrivilege("RCon", 3)
|
||||
FAdmin.Commands.AddCommand("RCon", "<command>", "<args>")
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerAction("RCon", "fadmin/icons/rcon", Color(155, 0, 0, 255), function() return FAdmin.Access.PlayerHasPrivilege(LocalPlayer(), "RCon") end,
|
||||
function(ply, button)
|
||||
Derma_StringRequest("RCon comand", "Enter a command to be run on the server. Note: a lot of commands are blocked and they will not work!", "",
|
||||
function(text) RunConsoleCommand("_FAdmin", "RCon", unpack(string.Explode(" ", text))) end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
local function RCon(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "RCon") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
|
||||
local CommandArgs = table.Copy(args)
|
||||
CommandArgs[1] = nil
|
||||
CommandArgs = table.ClearKeys(CommandArgs)
|
||||
RunConsoleCommand(args[1], unpack(CommandArgs))
|
||||
|
||||
return true, args[1], CommandArgs
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["RCon"] = function()
|
||||
FAdmin.Commands.AddCommand("RCon", RCon)
|
||||
|
||||
FAdmin.Access.AddPrivilege("RCon", 3) -- Root only
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
local function FillMenu(menu, SpawnName, GroupName)
|
||||
menu:AddOption("unrestrict", function() RunConsoleCommand("_FAdmin", "UnRestrictWeapon", SpawnName) end)
|
||||
|
||||
menu:AddSpacer("")
|
||||
for k in SortedPairsByMemberValue(FAdmin.Access.Groups, "ADMIN", true) do
|
||||
menu:AddOption(k, function() RunConsoleCommand("_FAdmin", "RestrictWeapon", SpawnName, k) end)
|
||||
end
|
||||
end
|
||||
|
||||
local function RestrictWeaponMenu()
|
||||
local frame = vgui.Create("DFrame")
|
||||
frame:SetTitle("Restrict weapons")
|
||||
frame:SetSize(ScrW() / 2, ScrH() - 50)
|
||||
frame:Center()
|
||||
frame:SetVisible(true)
|
||||
frame:MakePopup()
|
||||
|
||||
local WeaponMenu = vgui.Create("FAdmin_weaponPanel", frame)
|
||||
WeaponMenu.HideAmmo = true
|
||||
function WeaponMenu:DoGiveWeapon(SpawnName)
|
||||
local menu = DermaMenu()
|
||||
menu:SetPos(gui.MouseX(), gui.MouseY())
|
||||
FillMenu(menu, SpawnName)
|
||||
menu:Open()
|
||||
end
|
||||
WeaponMenu:BuildList()
|
||||
WeaponMenu:StretchToParent(0,25,0,0)
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["Restrict"] = function()
|
||||
FAdmin.Access.AddPrivilege("Restrict", 3)
|
||||
FAdmin.ScoreBoard.Server:AddPlayerAction("Restrict weapons", "fadmin/icons/weapon", Color(0, 155, 0, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "Restrict") end, RestrictWeaponMenu)
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
sql.Query("CREATE TABLE IF NOT EXISTS FADMIN_RESTRICTEDENTS('TYPE' TEXT NOT NULL, 'ENTITY' TEXT NOT NULL, 'ADMIN_GROUP' TEXT NOT NULL, PRIMARY KEY(TYPE, ENTITY));")
|
||||
|
||||
local Restricted = {}
|
||||
Restricted.Weapons = {}
|
||||
|
||||
local function RetrieveRestricted()
|
||||
local Query = sql.Query("SELECT * FROM FADMIN_RESTRICTEDENTS") or {}
|
||||
for _, v in ipairs(Query) do
|
||||
if Restricted[v.TYPE] then
|
||||
Restricted[v.TYPE][v.ENTITY] = v.ADMIN_GROUP
|
||||
end
|
||||
end
|
||||
end RetrieveRestricted()
|
||||
|
||||
local function DoRestrictWeapons(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Restrict") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
local Weapon = args[1]
|
||||
local Group = args[2]
|
||||
if not Group or not FAdmin.Access.Groups[Group] or not Weapon then return false end
|
||||
if Restricted.Weapons[Weapon] then
|
||||
sql.Query("UPDATE FADMIN_RESTRICTEDENTS SET ADMIN_GROUP = " .. sql.SQLStr(Group) .. " WHERE ENTITY = " .. sql.SQLStr(Weapon) .. " AND TYPE = " .. sql.SQLStr("Weapons") .. ";")
|
||||
else
|
||||
sql.Query("INSERT INTO FADMIN_RESTRICTEDENTS VALUES(" .. sql.SQLStr("Weapons") .. ", " .. sql.SQLStr(Weapon) .. ", " .. sql.SQLStr(Group) .. ");")
|
||||
end
|
||||
Restricted.Weapons[Weapon] = Group
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Weapon restricted!")
|
||||
|
||||
return true, Weapon, Group
|
||||
end
|
||||
|
||||
local function UnRestrictWeapons(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "Restrict") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
local Weapon = args[1]
|
||||
|
||||
sql.Query("DELETE FROM FADMIN_RESTRICTEDENTS WHERE ENTITY = " .. sql.SQLStr(Weapon) .. " AND TYPE = " .. sql.SQLStr("Weapons") .. ";")
|
||||
|
||||
Restricted.Weapons[Weapon] = nil
|
||||
FAdmin.Messages.SendMessage(ply, 4, "Weapon unrestricted!")
|
||||
|
||||
return true, Weapon
|
||||
end
|
||||
|
||||
local function RestrictWeapons(ply, Weapon, WeaponTable)
|
||||
local Group = ply:GetUserGroup()
|
||||
if not FAdmin or not FAdmin.Access or not FAdmin.Access.Groups or not FAdmin.Access.Groups[Group]
|
||||
or not FAdmin.Access.Groups[Restricted.Weapons[Weapon]] then return end
|
||||
local RequiredGroup = Restricted.Weapons[Weapon]
|
||||
|
||||
if Group ~= RequiredGroup and FAdmin.Access.Groups[Group].ADMIN <= FAdmin.Access.Groups[RequiredGroup].ADMIN then return false end
|
||||
end
|
||||
hook.Add("PlayerGiveSWEP", "FAdmin_RestrictWeapons", RestrictWeapons)
|
||||
hook.Add("PlayerSpawnSWEP", "FAdmin_RestrictWeapons", RestrictWeapons)
|
||||
|
||||
FAdmin.StartHooks["Restrict"] = function()
|
||||
FAdmin.Commands.AddCommand("RestrictWeapon", DoRestrictWeapons)
|
||||
FAdmin.Commands.AddCommand("UnRestrictWeapon", UnRestrictWeapons)
|
||||
|
||||
FAdmin.Access.AddPrivilege("Restrict", 3)
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
local function SetLimits()
|
||||
local frame = vgui.Create("DFrame")
|
||||
frame:SetTitle("Set Limits")
|
||||
frame:SetSize(300, 460)
|
||||
frame:Center()
|
||||
frame:SetVisible(true)
|
||||
frame:MakePopup()
|
||||
|
||||
local PanelList = vgui.Create("DPanelList", frame)
|
||||
PanelList:StretchToParent(5, 25, 5, 5)
|
||||
PanelList:EnableVerticalScrollbar(true)
|
||||
|
||||
local Form = vgui.Create("DForm", PanelList)
|
||||
Form:SetName("")
|
||||
|
||||
local Settings = util.KeyValuesToTable(file.Read("gamemodes/sandbox/sandbox.txt", "GAME")) -- All SBox limits are in here :D
|
||||
for _, v in SortedPairs(Settings.settings or {}) do
|
||||
if v.type == "Numeric" then
|
||||
local left, _ = Form:NumberWang(v.text, nil, v.low or 0, v.high or 1000, v.decimals or 0)
|
||||
left:SetFloatValue(GetConVar(v.name):GetFloat())
|
||||
left:SetValue(GetConVar(v.name):GetFloat())
|
||||
|
||||
function left:OnValueChanged(val)
|
||||
if val == GetConVar(v.name):GetFloat() then
|
||||
return
|
||||
end
|
||||
RunConsoleCommand("_FAdmin", "ServerSetting", v.name, val)
|
||||
end
|
||||
end
|
||||
end
|
||||
PanelList:AddItem(Form)
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["ServerSettings"] = function()
|
||||
FAdmin.Access.AddPrivilege("ServerSetting", 2)
|
||||
|
||||
local sbox_godmode = GetConVar("sbox_godmode")
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting(function() return (sbox_godmode:GetBool() and "Disable" or "Enable") .. " global god mode" end,
|
||||
function() return "fadmin/icons/god", sbox_godmode:GetBool() and "fadmin/icons/disable" end,
|
||||
Color(0, 0, 155, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "ServerSetting") end, function(button)
|
||||
local val = sbox_godmode:GetBool()
|
||||
|
||||
button:SetImage2((not val and "fadmin/icons/disable") or "null")
|
||||
button:SetText((not val and "Disable" or "Enable") .. " global god mode")
|
||||
button:GetParent():InvalidateLayout()
|
||||
|
||||
RunConsoleCommand("_FAdmin", "ServerSetting", "sbox_godmode", val and 0 or 1)
|
||||
end)
|
||||
|
||||
local sbox_playershurtplayers = GetConVar("sbox_playershurtplayers")
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting(function() return (sbox_playershurtplayers:GetBool() and "Disable" or "Enable") .. " player vs player damage" end,
|
||||
function() return "fadmin/icons/weapon", sbox_playershurtplayers:GetBool() and "fadmin/icons/disable" end,
|
||||
Color(0, 0, 155, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "ServerSetting") end, function(button)
|
||||
local val = sbox_playershurtplayers:GetBool()
|
||||
|
||||
button:SetImage2(not val and "fadmin/icons/disable" or "null")
|
||||
button:SetText((not val and "Disable" or "Enable") .. " player vs player damage")
|
||||
button:GetParent():InvalidateLayout()
|
||||
|
||||
RunConsoleCommand("_FAdmin", "ServerSetting", "sbox_playershurtplayers", val and 0 or 1)
|
||||
end)
|
||||
|
||||
local sbox_noclip = GetConVar("sbox_noclip")
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting(function() return (sbox_noclip:GetBool() and "Disable" or "Enable") .. " global noclip" end,
|
||||
function() return "fadmin/icons/noclip", sbox_noclip:GetBool() and "fadmin/icons/disable" end,
|
||||
Color(0, 0, 155, 255), function(ply) return FAdmin.Access.PlayerHasPrivilege(ply, "ServerSetting") end, function(button)
|
||||
local val = sbox_noclip:GetBool()
|
||||
|
||||
button:SetImage2(not val and "fadmin/icons/disable" or "null")
|
||||
button:SetText((not val and "Disable" or "Enable") .. " global noclip")
|
||||
button:GetParent():InvalidateLayout()
|
||||
|
||||
RunConsoleCommand("_FAdmin", "ServerSetting", "sbox_noclip", val and 0 or 1)
|
||||
end)
|
||||
|
||||
|
||||
FAdmin.ScoreBoard.Server:AddServerSetting("Set server limits", "fadmin/icons/serversetting", Color(0, 0, 155, 255), true, SetLimits)
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
local Whitelist = {"sv_password"} -- Make sure people don't use FAdmin serversetting as easy RCON, only the SBOX commands are allowed
|
||||
table.insert(Whitelist, "sbox_.*")
|
||||
table.insert(Whitelist, "_FAdmin_.*")
|
||||
|
||||
sql.Query([[CREATE TABLE IF NOT EXISTS FAdmin_ServerSettings(setting STRING NOT NULL PRIMARY KEY, value STRING NOT NULL);]])
|
||||
function FAdmin.SaveSetting(var, value)
|
||||
sql.Query([[REPLACE INTO FAdmin_ServerSettings VALUES(]] .. MySQLite.SQLStr(var:lower()) .. [[, ]] .. MySQLite.SQLStr(value) .. ");")
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity", "FAdmin_Settings", function()
|
||||
local Settings = sql.Query("SELECT * FROM FAdmin_ServerSettings;") or {}
|
||||
for _, v in pairs(Settings) do
|
||||
RunConsoleCommand(v.setting, v.value)
|
||||
end
|
||||
end)
|
||||
|
||||
local function ServerSetting(ply, cmd, args)
|
||||
if not FAdmin.Access.PlayerHasPrivilege(ply, "ServerSetting") then FAdmin.Messages.SendMessage(ply, 5, "No access!") return false end
|
||||
if not args[2] then FAdmin.Messages.SendMessage(ply, 5, "Incorrect argument") return false end
|
||||
|
||||
local found = false
|
||||
for _, v in pairs(Whitelist) do
|
||||
if string.match(args[1], v) then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then return false end
|
||||
|
||||
local CommandArgs = table.Copy(args)
|
||||
CommandArgs[1] = nil
|
||||
CommandArgs = table.ClearKeys(CommandArgs)
|
||||
RunConsoleCommand(args[1], unpack(CommandArgs))
|
||||
FAdmin.SaveSetting(args[1], CommandArgs[1])
|
||||
FAdmin.Messages.ActionMessage(ply, player.GetAll(), "You have set " .. args[1] .. " to " .. unpack(CommandArgs),
|
||||
args[1] .. " was set to " .. unpack(CommandArgs), "Set " .. args[1] .. " to " .. unpack(CommandArgs))
|
||||
|
||||
return true, args[1], CommandArgs
|
||||
end
|
||||
|
||||
FAdmin.StartHooks["ServerSettings"] = function()
|
||||
FAdmin.Commands.AddCommand("ServerSetting", ServerSetting)
|
||||
|
||||
FAdmin.Access.AddPrivilege("ServerSetting", 2)
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
FAdmin = FAdmin or {}
|
||||
|
||||
FAdmin.PlayerActions = FAdmin.PlayerActions or {}
|
||||
FAdmin.StartHooks = FAdmin.StartHooks or {}
|
||||
|
||||
--[[
|
||||
|
||||
Utilities!
|
||||
|
||||
]]
|
||||
function FAdmin.FindPlayer(info)
|
||||
if not info then return nil end
|
||||
local pls = player.GetAll()
|
||||
local found = {}
|
||||
|
||||
if string.lower(info) == "*" or string.lower(info) == "<all>" then return pls end
|
||||
|
||||
local InfoPlayers = {}
|
||||
for A in string.gmatch(info .. ";", "([a-zA-Z0-9:_.]*)[;(,%s)%c]") do
|
||||
if A ~= "" then
|
||||
table.insert(InfoPlayers, A)
|
||||
end
|
||||
end
|
||||
|
||||
for _, PlayerInfo in ipairs(InfoPlayers) do
|
||||
-- Playerinfo is always to be treated as UserID when it's a number
|
||||
-- otherwise people with numbers in their names could get confused with UserID's of other players
|
||||
if tonumber(PlayerInfo) then
|
||||
if IsValid(Player(PlayerInfo)) and not found[Player(PlayerInfo)] then
|
||||
found[Player(PlayerInfo)] = true
|
||||
end
|
||||
continue
|
||||
end
|
||||
|
||||
for _, v in ipairs(pls) do
|
||||
-- Find by Steam ID
|
||||
if (PlayerInfo == v:SteamID() or v:SteamID() == "UNKNOWN") and not found[v] then
|
||||
found[v] = true
|
||||
end
|
||||
|
||||
-- Find by Partial Nick
|
||||
if string.find(string.lower(v:Nick()), string.lower(tostring(PlayerInfo)), 1, true) ~= nil and not found[v] then
|
||||
found[v] = true
|
||||
end
|
||||
|
||||
if v.SteamName and string.find(string.lower(v:SteamName()), string.lower(tostring(PlayerInfo)), 1, true) ~= nil and not found[v] then
|
||||
found[v] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local players = {}
|
||||
local empty = true
|
||||
for k in pairs(found or {}) do
|
||||
empty = false
|
||||
table.insert(players, k)
|
||||
end
|
||||
return not empty and players or nil
|
||||
end
|
||||
|
||||
function FAdmin.SteamToProfile(ply) -- Thanks decodaman
|
||||
return "https://steamcommunity.com/profiles/" .. (ply:SteamID64() or "BOT")
|
||||
end
|
||||
|
||||
--[[
|
||||
FAdmin global settings
|
||||
]]
|
||||
FAdmin.GlobalSetting = FAdmin.GlobalSetting or {}
|
||||
|
||||
|
||||
--[[Dependency solver:
|
||||
Many plugins are dependant of one another.
|
||||
To prevent plugins calling functions from other plugins that haven't been opened yet
|
||||
there will be a hook that is called when all plugins are loaded.
|
||||
This way there will be no hassle with which plugin loads first, which one next etc.
|
||||
]]
|
||||
timer.Simple(0, function()
|
||||
for k in pairs(FAdmin.StartHooks) do if not isstring(k) then FAdmin.StartHooks[k] = nil end end
|
||||
for _, v in SortedPairs(FAdmin.StartHooks) do
|
||||
v()
|
||||
end
|
||||
end)
|
||||
107
gamemodes/darkrp/gamemode/modules/fadmin/sv_fadmin.lua
Normal file
107
gamemodes/darkrp/gamemode/modules/fadmin/sv_fadmin.lua
Normal file
@@ -0,0 +1,107 @@
|
||||
util.AddNetworkString("FAdmin_retrievebans")
|
||||
util.AddNetworkString("FADMIN_SendGroups")
|
||||
util.AddNetworkString("FAdmin_GlobalSetting")
|
||||
util.AddNetworkString("FAdmin_PlayerSetting")
|
||||
util.AddNetworkString("FAdmin_GlobalPlayerSettings")
|
||||
|
||||
local SortedPairs, ipairs, pairs = SortedPairs, ipairs, pairs
|
||||
-- recursively adds everything in a directory to be downloaded by client
|
||||
local function AddDir(dir)
|
||||
local files, folders = file.Find(dir .. "/*", "GAME")
|
||||
|
||||
for _, fdir in ipairs(folders) do
|
||||
-- don't spam people with useless .svn folders
|
||||
if fdir ~= ".svn" then
|
||||
AddDir(dir .. "/" .. fdir)
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in ipairs(files) do
|
||||
resource.AddFile(dir .. "/" .. v)
|
||||
end
|
||||
end
|
||||
|
||||
AddDir("materials/fadmin")
|
||||
|
||||
local function AddCSLuaFolder(fol)
|
||||
fol = string.lower(fol)
|
||||
local _, folders = file.Find(fol .. "*", "LUA")
|
||||
|
||||
for _, folder in SortedPairs(folders, true) do
|
||||
if folder ~= "." and folder ~= ".." then
|
||||
for _, File in SortedPairs(file.Find(fol .. folder .. "/sh_*.lua", "LUA")) do
|
||||
AddCSLuaFile(fol .. folder .. "/" .. File)
|
||||
include(fol .. folder .. "/" .. File)
|
||||
end
|
||||
|
||||
for _, File in SortedPairs(file.Find(fol .. folder .. "/sv_*.lua", "LUA"), true) do
|
||||
include(fol .. folder .. "/" .. File)
|
||||
end
|
||||
|
||||
for _, File in SortedPairs(file.Find(fol .. folder .. "/cl_*.lua", "LUA"), true) do
|
||||
AddCSLuaFile(fol .. folder .. "/" .. File)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AddCSLuaFolder(GM.FolderName .. "/gamemode/modules/fadmin/fadmin/")
|
||||
AddCSLuaFolder(GM.FolderName .. "/gamemode/modules/fadmin/fadmin/playeractions/")
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
FAdmin global settings
|
||||
---------------------------------------------------------------------------]]
|
||||
function FAdmin.SetGlobalSetting(setting, value)
|
||||
if FAdmin.GlobalSetting[setting] == value then return end -- If the value didn't change, we don't need to resend it.
|
||||
FAdmin.GlobalSetting[setting] = value
|
||||
net.Start("FAdmin_GlobalSetting")
|
||||
net.WriteString(setting)
|
||||
net.WriteType(value)
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
|
||||
local plyMeta = FindMetaTable("Player")
|
||||
function plyMeta:FAdmin_SetGlobal(setting, value)
|
||||
self.GlobalSetting = self.GlobalSetting or {}
|
||||
if self.GlobalSetting[setting] == value then return end -- If the value didn't change, we don't need to resend it.
|
||||
self.GlobalSetting[setting] = value
|
||||
|
||||
net.Start("FAdmin_PlayerSetting")
|
||||
net.WriteUInt(self:UserID(), 16)
|
||||
net.WriteString(setting)
|
||||
net.WriteType(value)
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
function plyMeta:FAdmin_GetGlobal(setting)
|
||||
return self.GlobalSetting and self.GlobalSetting[setting] or nil
|
||||
end
|
||||
|
||||
hook.Add("PlayerInitialSpawn", "FAdmin_GlobalSettings", function(ply)
|
||||
-- Not optimal in efficiency, but with the amount of global settings
|
||||
-- it's not worth spending a lot of time on.
|
||||
net.Start("FAdmin_GlobalPlayerSettings")
|
||||
net.WriteUInt(table.Count(FAdmin.GlobalSetting), 8) -- assume max 255 settings
|
||||
|
||||
for k, v in pairs(FAdmin.GlobalSetting) do
|
||||
net.WriteString(k)
|
||||
net.WriteType(v)
|
||||
end
|
||||
|
||||
local tPlayers = player.GetAll()
|
||||
net.WriteUInt(#tPlayers, 8)
|
||||
for _, target in ipairs(tPlayers) do
|
||||
local targetSettings = target.GlobalSetting or {}
|
||||
|
||||
net.WriteUInt(target:UserID(), 16)
|
||||
net.WriteUInt(table.Count(targetSettings), 8)
|
||||
|
||||
for k, v in pairs(targetSettings) do
|
||||
net.WriteString(k)
|
||||
net.WriteType(v)
|
||||
end
|
||||
end
|
||||
net.Send(ply)
|
||||
end)
|
||||
FAdmin.SetGlobalSetting("FAdmin", true)
|
||||
76
gamemodes/darkrp/gamemode/modules/fadmin/sv_fadmin_sql.lua
Normal file
76
gamemodes/darkrp/gamemode/modules/fadmin/sv_fadmin_sql.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
--[[---------------------------------------------------------------------------
|
||||
Create the tables used for banning
|
||||
---------------------------------------------------------------------------]]
|
||||
hook.Add("DatabaseInitialized", "FAdmin_CreateMySQLTables", function()
|
||||
MySQLite.query("CREATE TABLE IF NOT EXISTS FAdminBans(SteamID VARCHAR(25) NOT NULL PRIMARY KEY, Nick VARCHAR(40), BanDate DATETIME, UnbanDate DATETIME, Reason VARCHAR(100), AdminName VARCHAR(40), Admin_steam VARCHAR(25));", function()
|
||||
|
||||
hook.Call("FAdmin_RetrieveBans", nil)
|
||||
end)
|
||||
end)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Store a ban in the MySQL tables
|
||||
---------------------------------------------------------------------------]]
|
||||
hook.Add("FAdmin_StoreBan", "MySQLBans", function(SteamID, Nick, Duration, Reason, AdminName, Admin_steam)
|
||||
local steam = MySQLite.SQLStr(SteamID)
|
||||
local nick = Nick and MySQLite.SQLStr(Nick) or "NULL"
|
||||
local bandate = MySQLite.isMySQL() and "NOW()" or "datetime('now')"
|
||||
local reason = Reason and MySQLite.SQLStr(Reason) or "NULL"
|
||||
local admin = AdminName and MySQLite.SQLStr(AdminName) or "NULL"
|
||||
local adminsteam = Admin_steam and MySQLite.SQLStr(Admin_steam) or "NULL"
|
||||
|
||||
local duration
|
||||
if MySQLite.isMySQL() then
|
||||
duration = Duration == 0 and "NULL" or "DATE_ADD(NOW(), INTERVAL " .. tonumber(Duration or 60) .. " MINUTE)"
|
||||
else
|
||||
duration = Duration == 0 and "NULL" or "datetime('now', '+" .. tonumber(Duration or 60) .. " minutes')"
|
||||
end
|
||||
|
||||
MySQLite.query("REPLACE INTO FAdminBans VALUES(" .. steam .. ", " .. nick .. ", " .. bandate .. ", " .. duration .. ", " .. reason .. ", " .. admin .. ", " .. adminsteam .. ");")
|
||||
end)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Unban someone
|
||||
---------------------------------------------------------------------------]]
|
||||
hook.Add("FAdmin_UnBan", "FAdmin_MySQLUnban", function(ply, steamID)
|
||||
MySQLite.query("DELETE FROM FAdminBans WHERE steamID = " .. MySQLite.SQLStr(steamID))
|
||||
end)
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Retrieve the bans from the MySQL server and put them into effect
|
||||
|
||||
Note: Must be called more than two seconds after InitPostEntity, because
|
||||
that's when the database initializes
|
||||
---------------------------------------------------------------------------]]
|
||||
hook.Add("FAdmin_RetrieveBans", "getMySQLBans", function()
|
||||
FAdmin.BANS = FAdmin.BANS or {}
|
||||
|
||||
-- Small SQLite and MySQL syntax difference
|
||||
local diffSeconds = MySQLite.isMySQL() and "TIMESTAMPDIFF(SECOND, NOW(), UnbanDate)" or
|
||||
"strftime('%s', UnbanDate) - strftime('%s','now')"
|
||||
|
||||
local now = MySQLite.isMySQL() and "NOW()" or "datetime('now')"
|
||||
|
||||
MySQLite.query("SELECT SteamID, Nick, " .. diffSeconds .. " AS duration, Reason, AdminName, Admin_steam FROM FAdminBans WHERE (UnbanDate > " .. now .. " OR UnbanDate IS NULL);", function(data)
|
||||
if not data then return end
|
||||
|
||||
for _, v in ipairs(data) do
|
||||
if tonumber(v.SteamID) or not v.SteamID then continue end
|
||||
local duration = (not v.duration or v.duration == "NULL") and 0 or (os.time() + v.duration)
|
||||
|
||||
FAdmin.BANS[string.upper(v.SteamID)] = {
|
||||
time = duration,
|
||||
name = v.Nick,
|
||||
reason = v.Reason,
|
||||
adminname = v.AdminName,
|
||||
adminsteam = v.Admin_steam
|
||||
}
|
||||
end
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if not FAdmin.BANS[string.upper(v:SteamID())] then continue end
|
||||
|
||||
v:Kick("FAdmin ban evasion")
|
||||
end
|
||||
end)
|
||||
end)
|
||||
Reference in New Issue
Block a user