local AdminPanel local EditGroupTools local RetrieveRestrictedTool local RetrieveBlockedModels local BlockedLists = {} local CatsOpened = {} local ShowBlockedModels FPP = FPP or {} FPP.Groups = {} FPP.GroupMembers = {} net.Receive("FPP_Settings_Update", function() local skipK, skipS, value = net.ReadUInt(8), net.ReadUInt(8), net.ReadDouble() local K, S = 0, 0 FPP.ForAllSettings(function(k, s) K = K + 1 if K ~= skipK then return true end K, S = K - 1, S + 1 if S ~= skipS then return end FPP.Settings[k][s] = value end) end) net.Receive("FPP_Settings", function() FPP.ForAllSettings(function(k, s, v) FPP.Settings[k][s] = net.ReadDouble() end) end) local canEditSettings = false local canCleanup = false local function updatePrivs() CAMI.PlayerHasAccess(LocalPlayer(), "FPP_Settings", function(b, _) canEditSettings = b end) CAMI.PlayerHasAccess(LocalPlayer(), "FPP_Cleanup", function(b, _) canCleanup = b end) end hook.Add("InitPostEntity", "FPP_Menu", updatePrivs) local function nickSortedPlayers() local plys = player.GetAll() table.sort(plys, function(a,b) return a:Nick() < b:Nick() end) return plys end function FPP.AdminMenu(Panel) updatePrivs() AdminPanel = Panel AdminPanel:SetSize(100, 400) AdminPanel:Clear(true) AdminPanel.contents = AdminPanel.contents or vgui.Create("DListLayout") AdminPanel.contents:Clear() if not canEditSettings then AdminPanel.contents:Add(Label("You are not a superadmin\nThe changes you make will not have any effect.")) local AmAdmin = AdminPanel.contents:Add("DButton") AmAdmin:SetText("Unlock buttons anyway") AmAdmin:SetTooltip("If you're REALLY not an admin it won't work") function AmAdmin:DoClick() AmAdmin:SetText("Buttons unlocked") AmAdmin:SetTooltip("The changes you make now DO have effect unless you're really not an admin") canEditSettings = true end end local function MakeOption(Name) local cat = AdminPanel.contents:Add("DCollapsibleCategory") cat:SetLabel(Name) cat:SetExpanded(CatsOpened[Name]) cat.oldtoggle = cat.Toggle function cat:Toggle() self:oldtoggle() CatsOpened[Name] = cat:GetExpanded() AdminPanel:Toggle() timer.Simple(0, function() AdminPanel:Toggle() end) end local pan = vgui.Create("DListLayout") cat:SetContents(pan) return cat, pan end local function addchk(label, command, plist) local box = plist:Add("DCheckBoxLabel") box:SetText(label) box:SetDark(true) box:SetValue(tobool(FPP.Settings[command[1]][command[2]])) box.Button.Toggle = function() if not canEditSettings then return end--Hehe now you can't click it anymore non-admin! if box.Button:GetChecked() == nil or not box.Button:GetChecked() then box.Button:SetValue( true ) else box.Button:SetValue( false ) end local tonum = {} tonum[false] = "0" tonum[true] = "1" RunConsoleCommand("FPP_Setting", command[1], command[2], tonum[box.Button:GetChecked()]) end end local function addblock(pan, Type) local label = pan:Add("DLabel") label:SetText("\n" .. Type .. " black/whitelist entities:") label:SetTextColor(Color(0, 0, 0, 255)) label:SizeToContents() local lview = pan:Add("DListView") lview:AddColumn("Entity") BlockedLists[string.lower(Type)] = lview RunConsoleCommand("FPP_sendblocked", Type) local RemoveSelected = pan:Add("DButton") RemoveSelected:SetText("Remove Selected items from the list") RemoveSelected:SetDisabled(not canEditSettings) RemoveSelected.DoClick = function() for k, v in pairs(lview.Lines) do if v:IsLineSelected() then local text = v.text timer.Simple(k / 10, function() RunConsoleCommand("FPP_RemoveBlocked", Type, text) end) lview:RemoveLine(k) lview:SetTall(17 + #lview:GetLines() * 17) pan:InvalidateLayout() pan:GetParent():GetParent():InvalidateLayout() end end end local AddLA = pan:Add("DButton") AddLA:SetText("Add the entity you're looking at") AddLA:SetDisabled(not canEditSettings) AddLA.DoClick = function() local ent = LocalPlayer():GetEyeTraceNoCursor().Entity if not IsValid(ent) then return end for _, v in pairs(lview.Lines) do if v.text == string.lower(ent:GetClass()) then return end end RunConsoleCommand("FPP_AddBlocked", Type, ent:GetClass()) lview:AddLine(ent:GetClass()).text = ent:GetClass() lview:SetTall(17 + #lview:GetLines() * 17) pan:InvalidateLayout() pan:GetParent():GetParent():InvalidateLayout() end local AddManual = pan:Add("DButton") AddManual:SetText("Add entity manually") AddManual:SetDisabled(not canEditSettings) AddManual.DoClick = function() Derma_StringRequest("Enter entity manually", "Enter the classname of the entity you would like to add.", nil, function(a) RunConsoleCommand("FPP_AddBlocked", Type, a) end, function() end ) end end local function addsldr(max, command, text, plist, decimals) local label = plist:Add("DLabel") label:SetText(text) label:SetTextColor(Color(0, 0, 0, 255)) label:SizeToContents() local sldr = plist:Add("DNumSlider") sldr.Label:SetVisible(false) sldr:SetMinMax(0, max) decimals = decimals or 1 sldr:SetDecimals(decimals) sldr:SetDark(true) sldr:SetValue(FPP.Settings[command[1]][command[2]]) function sldr.Slider:OnMouseReleased() self:SetDragging(false) self:MouseCapture(false) if not canEditSettings then sldr:SetValue(FPP.Settings[command[1]][command[2]]) return end RunConsoleCommand("FPP_Setting", command[1], command[2], sldr:GetValue()) end function sldr.TextArea:OnEnter() if not canEditSettings then sldr:SetValue(FPP.Settings[command[1]][command[2]]) return end RunConsoleCommand("FPP_Setting", command[1], command[2], sldr:GetValue()) end local KnobMouseReleased = sldr.Slider.Knob.OnMouseReleased function sldr.Slider.Knob:OnMouseReleased(...) KnobMouseReleased(self, ...) sldr.Slider:OnMouseReleased() end end local _, general = MakeOption("General options") addchk("Freeze disconnected players's entities", {"FPP_GLOBALSETTINGS1", "freezedisconnected"}, general) addchk("Cleanup disconnected players's entities", {"FPP_GLOBALSETTINGS1", "cleanupdisconnected"}, general) addchk("Cleanup admin's entities on disconnect", {"FPP_GLOBALSETTINGS1", "cleanupadmin"}, general) addsldr(600, {"FPP_GLOBALSETTINGS1", "cleanupdisconnectedtime"}, "Deletion time", general, 0) addchk("Anti E2 mingery (mass killing with E2)", {"FPP_GLOBALSETTINGS1", "antie2minge"}, general) local delnow = general:Add("DButton") delnow:SetText("Delete disconnected players' entities") delnow:SetConsoleCommand("FPP_cleanup", "disconnected") delnow:SetDisabled(not canCleanup) local other = general:Add(Label("\nDelete player's entities:")) other:SizeToContents() other:SetTextColor(Color(0, 0, 0, 255)) local areplayers = false for _, v in ipairs(nickSortedPlayers()) do if not IsValid(v) then continue end areplayers = true local rm = general:Add("DButton") rm:SetText(v:Nick()) rm:SetConsoleCommand("FPP_Cleanup", v:UserID()) rm:SetDisabled(not canCleanup) end if not areplayers then local nope = general:Add(Label("")) nope:SizeToContents() end local _, antispam = MakeOption("Antispam options") addchk("Spam protection enabled on/off", {"FPP_ANTISPAM1", "toggle"}, antispam) addchk("Prevent spawning a prop in a prop", {"FPP_ANTISPAM1", "antispawninprop"}, antispam) addchk("Big prop spam protection", {"FPP_ANTISPAM1", "bigpropantispam"}, antispam) addsldr(10, {"FPP_ANTISPAM1", "bigpropwait"}, "Time (seconds) between spawning two big props", antispam) addsldr(10, {"FPP_ANTISPAM1", "smallpropdowngradecount"}, "Spawn delay (in fraction) to consider spam", antispam) addsldr(10, {"FPP_ANTISPAM1", "smallpropghostlimit"}, "How many props to spam before ghosting", antispam) addsldr(20, {"FPP_ANTISPAM1", "smallpropdenylimit"}, "How many props to spam before blocking", antispam) addsldr(10, {"FPP_ANTISPAM1", "duplicatorlimit"}, "How many duplications to spam before blocking", antispam) local _, physgun = MakeOption("Physgun options") addchk("Physgun protection enabled", {"FPP_PHYSGUN1", "toggle"}, physgun) addchk("Privileged users can physgun all entities", {"FPP_PHYSGUN1", "adminall"}, physgun) addchk("People can physgun world entities", {"FPP_PHYSGUN1", "worldprops"}, physgun) addchk("Admins can physgun world entities", {"FPP_PHYSGUN1", "adminworldprops"}, physgun) addchk("People can physgun blocked entities", {"FPP_PHYSGUN1", "canblocked"}, physgun) addchk("Admins can physgun blocked entities", {"FPP_PHYSGUN1", "admincanblocked"}, physgun) addchk("Physgun reload protection enabled", {"FPP_PHYSGUN1", "reloadprotection"}, physgun) addchk("The blocked list is a white list", {"FPP_PHYSGUN1", "iswhitelist"}, physgun) addblock(physgun, "Physgun1") local _, gravgun = MakeOption("Gravity gun options") addchk("Gravity gun protection enabled", {"FPP_GRAVGUN1", "toggle"}, gravgun) addchk("Privileged users can gravgun all entities", {"FPP_GRAVGUN1", "adminall"}, gravgun) addchk("People can gravgun world entities", {"FPP_GRAVGUN1", "worldprops"}, gravgun) addchk("Admins can gravgun world entities", {"FPP_GRAVGUN1", "adminworldprops"}, gravgun) addchk("People can gravgun blocked entities", {"FPP_GRAVGUN1", "canblocked"}, gravgun) addchk("Admins can gravgun blocked entities", {"FPP_GRAVGUN1", "admincanblocked"}, gravgun) addchk("People can't punt props", {"FPP_GRAVGUN1", "noshooting"}, gravgun) addchk("The blocked list is a white list", {"FPP_GRAVGUN1", "iswhitelist"}, gravgun) addblock(gravgun, "Gravgun1") local _, toolgun = MakeOption("Toolgun options") addchk("Toolgun protection enabled", {"FPP_TOOLGUN1", "toggle"}, toolgun) addchk("Admins can use tool all entities", {"FPP_TOOLGUN1", "adminall"}, toolgun) addchk("People can use tool on world entities", {"FPP_TOOLGUN1", "worldprops"}, toolgun) addchk("Admins can use tool on world entities", {"FPP_TOOLGUN1", "adminworldprops"}, toolgun) addchk("People can use tool on blocked entities", {"FPP_TOOLGUN1", "canblocked"}, toolgun) addchk("Admins can use tool on blocked entities", {"FPP_TOOLGUN1", "admincanblocked"}, toolgun) addchk("The blocked list is a white list", {"FPP_TOOLGUN1", "iswhitelist"}, toolgun) addblock(toolgun, "Toolgun1") addchk("Duplicator restriction (blocked list)", {"FPP_TOOLGUN1", "duplicatorprotect"}, toolgun) addchk("People can't duplicate weapons", {"FPP_TOOLGUN1", "duplicatenoweapons"}, toolgun) addchk("Duplicator blocked list is a white list", {"FPP_TOOLGUN1", "spawniswhitelist"}, toolgun) addchk("Admins can spawn blocked weapons", {"FPP_TOOLGUN1", "spawnadmincanweapon"}, toolgun) addchk("Admins can spawn blocked entities", {"FPP_TOOLGUN1", "spawnadmincanblocked"}, toolgun) addblock(toolgun, "Spawning1") local _, playeruse = MakeOption("Player use options") addchk("Use protection enabled", {"FPP_PLAYERUSE1", "toggle"}, playeruse) addchk("Privileged users can use all entities", {"FPP_PLAYERUSE1", "adminall"}, playeruse) addchk("People can use world entities", {"FPP_PLAYERUSE1", "worldprops"}, playeruse) addchk("Admins can use world entities", {"FPP_PLAYERUSE1", "adminworldprops"}, playeruse) addchk("People can use blocked entities", {"FPP_PLAYERUSE1", "canblocked"}, playeruse) addchk("Admins can use blocked entities", {"FPP_PLAYERUSE1", "admincanblocked"}, playeruse) addchk("The blocked list is a white list", {"FPP_PLAYERUSE1", "iswhitelist"}, playeruse) addblock(playeruse, "PlayerUse1") local _, damage = MakeOption("Entity damage options") local antiDMGLabel = Label("Prevents players from damaging other players' props") antiDMGLabel:SetTextColor(Color(0, 0, 0, 255)) damage:Add(antiDMGLabel) addchk("Damage protection enabled", {"FPP_ENTITYDAMAGE1", "toggle"}, damage) addchk("Protect against damage by props", {"FPP_ENTITYDAMAGE1", "protectpropdamage"}, damage) addchk("Privileged users can damage all entities", {"FPP_ENTITYDAMAGE1", "adminall"}, damage) addchk("People can damage world entities", {"FPP_ENTITYDAMAGE1", "worldprops"}, damage) addchk("Admins can damage world entities", {"FPP_ENTITYDAMAGE1", "adminworldprops"}, damage) addchk("People can damage blocked entities", {"FPP_ENTITYDAMAGE1", "canblocked"}, damage) addchk("Admins can damage blocked entities", {"FPP_ENTITYDAMAGE1", "admincanblocked"}, damage) addchk("The blocked list is a white list", {"FPP_ENTITYDAMAGE1", "iswhitelist"}, damage) addblock(damage, "EntityDamage1") local _, blockedmodels = MakeOption("Blocked models options") local BlockedModelsLabel = blockedmodels:Add("DLabel") BlockedModelsLabel:SetText("\nTo add a model in the blocked models list:\nOpen the spawn menu, right click a prop and\nadd it to the blocked list") BlockedModelsLabel:SetTextColor(Color(0, 0, 0, 255)) BlockedModelsLabel:SizeToContents() addchk("Blocked models enabled", {"FPP_BLOCKMODELSETTINGS1", "toggle"}, blockedmodels) addchk("Apply to props only", {"FPP_BLOCKMODELSETTINGS1", "propsonly"}, blockedmodels) addchk("The blocked models list is a white list", {"FPP_BLOCKMODELSETTINGS1", "iswhitelist"}, blockedmodels) local BlockedModelsAddLA = blockedmodels:Add("DButton") BlockedModelsAddLA:SetText("Add model of entity you're looking at") function BlockedModelsAddLA:DoClick() if not IsValid(LocalPlayer():GetEyeTraceNoCursor().Entity) then return end RunConsoleCommand("FPP_AddBlockedModel", LocalPlayer():GetEyeTraceNoCursor().Entity:GetModel(), LocalPlayer():GetEyeTraceNoCursor().Entity:EntIndex()) end local BlockedModelsList = blockedmodels:Add("DButton") BlockedModelsList:SetText("Show blocked models") BlockedModelsList:SetTooltip("If there are no models in the list THIS BUTTON WON'T DO ANYTHING") function BlockedModelsList:DoClick() RunConsoleCommand("FPP_sendblockedmodels") local frame = vgui.Create("DFrame") frame:MakePopup() frame:SetVisible(true) frame:SetSize(math.Min(1280, ScrW() - 100), math.Min(720, ScrH() - 100)) frame:Center() frame:SetTitle(((tobool(FPP.Settings.FPP_BLOCKMODELSETTINGS1.iswhitelist) and "Allowed") or "Blocked") .. " models list") function frame:Close() ShowBlockedModels = nil self:Remove() end local Explanation = vgui.Create("DLabel", frame) Explanation:SetPos(5, 25) Explanation:SetText([[This is the list of props that are currently in the Blocked/Allowed props list. If this is a whitelist (set in settings), only the entities with the models in this list can be spawned If it's a blacklist, people will be able to spawn any model except for the ones in this list. To remove a model from the list, click the model in this list and click remove. To add a model to this list: - open your spawn menu (Q by default) - find the model in the props list - right click it - click "Add to blocked models"]]) Explanation:SizeToContents() frame.pan = vgui.Create("DPanelList", frame) frame.pan:SetPos(5, 160) frame.pan:SetSize(frame:GetWide() - 10, frame:GetTall() - 165) frame.pan:EnableHorizontal(true) frame.pan:EnableVerticalScrollbar(true) frame.pan:SetSpacing(0) frame.pan:SetPadding(4) frame.pan:SetAutoSize(false) ShowBlockedModels = frame end local _, ToolRestrict = MakeOption("Tool restriction") --spawnmenu.GetTools() FPP.DtreeToolRestrict = ToolRestrict:Add(IsValid(FPP.DtreeToolRestrict) and FPP.DtreeToolRestrict or "DTree") FPP.multirestricttoollist = ToolRestrict:Add(IsValid(FPP.multirestricttoollist) and FPP.multirestricttoollist or "DListView") FPP.DtreeToolRestrict:SetVisible(true) FPP.DtreeToolRestrict:SetSize(0, 300) FPP.SELECTEDRESTRICTNODE = FPP.SELECTEDRESTRICTNODE or "weld" if not FPP.DtreeToolRestrict.Items then local nodeClick = function(self) FPP.SELECTEDRESTRICTNODE = self.Tool for k, v in pairs(weapons.Get("gmod_tool").Tool) do if not v.Mode or v.Mode ~= FPP.SELECTEDRESTRICTNODE then continue end --Add to DListView for a, b in pairs(FPP.multirestricttoollist:GetLines()) do if b.Columns[1].Value == k then return end end FPP.multirestricttoollist:AddLine(k) return end end FPP.DtreeToolRestrict.Items = true for a, b in pairs(spawnmenu.GetTools()) do for c, d in pairs(spawnmenu.GetTools()[a].Items) do local addnodes = {} for _, f in pairs(spawnmenu.GetTools()[a].Items[c]) do if istable(f) and string.find(f.Command or "", "gmod_tool") then table.insert(addnodes, {f.Text, f.ItemName}) end end if #addnodes == 0 then continue end local node1 = FPP.DtreeToolRestrict:AddNode(d.ItemName) for _, f in pairs(addnodes) do local node2 = node1:AddNode(f[1]) node2.Icon:SetImage("gui/silkicons/wrench") node2.Tool = f[2] node2.DoClick = nodeClick end end end end local SingleEditTool = ToolRestrict:Add("DButton") SingleEditTool:SetText("Edit/view selected tool restrictions") SingleEditTool:SetTooltip("Edit or view the restrictions of the selected tool!") SingleEditTool.DoClick = function() for k, v in pairs(weapons.Get("gmod_tool").Tool) do if v.Mode and v.Mode == FPP.SELECTEDRESTRICTNODE then RunConsoleCommand("FPP_SendRestrictTool", k) return end end SingleEditTool:SetText("No tool selected!") timer.Simple(1, function() if IsValid(SingleEditTool) then SingleEditTool:SetText("Edit/view selected tool's restrictions") end end) end local multiToolEditLabel = Label("\nMultiple tool editor.\nAdd tools in this list by clicking on them,\nthen click \"Edit multiple tools\"\nto edit multiple tools at once!") multiToolEditLabel:SetTextColor(Color(0, 0, 0, 255)) local EditToolListLabel = ToolRestrict:Add(multiToolEditLabel) EditToolListLabel:SizeToContents() if #FPP.multirestricttoollist.Columns ~= 1 then FPP.multirestricttoollist:AddColumn("Tool names") end FPP.multirestricttoollist:SetTall(150) function FPP.multirestricttoollist:OnClickLine(line) line:SetSelected(true) FPP.multirestricttoollist:RemoveLine(FPP.multirestricttoollist:GetSelectedLine()) end local StartEditMultiTool = ToolRestrict:Add("DButton") StartEditMultiTool:SetText("Edit multiple tools") StartEditMultiTool:SetTooltip("Start editing the tools in above list!") StartEditMultiTool:SetDisabled(not canEditSettings) StartEditMultiTool.DoClick = function() local lines = FPP.multirestricttoollist:GetLines() local EditTable = {} if #lines > 0 then for _, v in ipairs(lines) do table.insert(EditTable, v.Columns[1].Value) end RetrieveRestrictedTool(EditTable) return end StartEditMultiTool:SetText("List is empty!") timer.Simple(1, function() if IsValid(StartEditMultiTool) then StartEditMultiTool:SetText("Edit multiple tools") end end) end local _, GroupRestrict = MakeOption("Group tool restriction") local pressLoadFirstLabel = Label("Press \"Load groups and members\" first!") pressLoadFirstLabel:SetTextColor(Color(0, 0, 0, 255)) local PressLoadFirst = GroupRestrict:Add(pressLoadFirstLabel) local membersLabel = Label("Group Members: NOTE: People who have the\nusergroup that matches with this group\nare automatically in this group!") membersLabel:SizeToContents() membersLabel:SetTextColor(Color(0, 0, 0, 255)) GroupRestrict:Add(membersLabel) local LoadGroups = GroupRestrict:Add("DButton") LoadGroups:SetText("Load groups and members") LoadGroups.DoClick = function() RunConsoleCommand("FPP_SendGroups") RunConsoleCommand("FPP_SendGroupMembers") PressLoadFirst:SetText("Groups loaded!") end local ChkAllowDefault local GroupList = GroupRestrict:Add("DListView") GroupList:AddColumn("Group names") GroupList:SetSize(0, 100) function GroupList:OnClickLine(line) self:ClearSelection() line:SetSelected(true) ChkAllowDefault:SetValue(FPP.Groups[GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()].allowdefault) end ChkAllowDefault = GroupRestrict:Add("DCheckBoxLabel") ChkAllowDefault:SetText("Allow all tools by default") ChkAllowDefault:SetDark(true) ChkAllowDefault:SetTooltip([[Ticked: All tools are allowed, EXCEPT for the tools in the tool list Unticked: NO tools will be allowed, EXCEPT for the tools in the tool list]]) if GroupList:GetSelectedLine() and FPP.Groups[GroupList:GetSelectedLine().Columns[1]:GetValue()] then ChkAllowDefault:SetValue(FPP.Groups[GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()].allowdefault) end ChkAllowDefault.Button.Toggle = function() local line = GroupList:GetSelectedLine() if not line then return end local value = 0 if not ChkAllowDefault.Button:GetChecked() then value = 1 end local lineObj = GroupList:GetLine(line) RunConsoleCommand("FPP_ChangeGroupStatus", lineObj.Columns[1]:GetValue(), value) ChkAllowDefault.Button:SetValue(not ChkAllowDefault.Button:GetChecked()) end local AddGroupBtn = GroupRestrict:Add("DButton") AddGroupBtn:SetText("Add a group") AddGroupBtn.DoClick = function() Derma_StringRequest("Name of the group", "What will be the name of the group?\nNOTE: YOU WILL NOT BE ABLE TO CHANGE THIS AFTERWARDS", "", function(text) RunConsoleCommand("FPP_AddGroup", text) end) end local RemGroupBtn = GroupRestrict:Add("DButton") RemGroupBtn:SetText("Remove selected group") RemGroupBtn.DoClick = function() if not GroupList:GetLine(GroupList:GetSelectedLine()) or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue() then LocalPlayer():ChatPrint("No item selected!") return end RunConsoleCommand("FPP_RemoveGroup", GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()) GroupList:RemoveLine(GroupList:GetSelectedLine()) PressLoadFirst:SetText("List might be corrupted, reload is recommended") end local EditGroupBtn = GroupRestrict:Add("DButton") EditGroupBtn:SetText("Edit selected group's tools") EditGroupBtn.DoClick = function() if not GroupList:GetLine(GroupList:GetSelectedLine()) or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue() then LocalPlayer():ChatPrint("No item selected!") return end EditGroupTools(GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()) end local groupMemLabel = Label("Group Members:") groupMemLabel:SetTextColor(Color(0, 0, 0, 255)) GroupRestrict:Add(groupMemLabel) local GroupMembers = GroupRestrict:Add("DListView") GroupMembers:AddColumn("SteamID") GroupMembers:AddColumn("Name") GroupMembers:AddColumn("Member of") GroupMembers:SetSize(0, 150) local AddPerson = GroupRestrict:Add("DButton") AddPerson:SetText("Change group of this person to selected") AddPerson.DoClick = function() if not GroupList:GetLine(GroupList:GetSelectedLine()) or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue() then LocalPlayer():ChatPrint("No item selected!") return end for k, v in pairs(GroupMembers:GetSelected()) do timer.Simple(k / 10, function() RunConsoleCommand("FPP_SetPlayerGroup", v.Columns[1]:GetValue(), GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()) end) end end local AddPersonManual = GroupRestrict:Add("DButton") AddPersonManual:SetText("Add person/SteamID to selected group") AddPersonManual.DoClick = function() if not GroupList:GetLine(GroupList:GetSelectedLine()) or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns or not GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue() then LocalPlayer():ChatPrint("No item selected!") return end local menu = DermaMenu() menu:SetPos(gui.MouseX(), gui.MouseY()) for _, b in ipairs(player.GetAll()) do if not IsValid(b) then continue end menu:AddOption(b:Nick(), function() RunConsoleCommand("FPP_SetPlayerGroup", b:UserID(), GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()) PressLoadFirst:SetText("List might be corrupted, reload is recommended") end) end menu:AddOption("other...", function() Derma_StringRequest("Enter steam ID", "Enter the Steam ID of the person you would like to add to this group.", "", function(text) RunConsoleCommand("FPP_SetPlayerGroup", text, GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()) end) end) menu:Open() end local function RetrieveGroups(len) FPP.Groups = net.ReadTable() GroupList:Clear() for k, _ in pairs(FPP.Groups) do GroupList:AddLine(k) end GroupList:SelectFirstItem() if #FPP.Groups == 0 then return end ChkAllowDefault:SetValue(FPP.Groups[GroupList:GetLine(GroupList:GetSelectedLine()).Columns[1]:GetValue()].allowdefault) end net.Receive("FPP_Groups", RetrieveGroups) local function RetrieveGroupMembers(len) FPP.GroupMembers = net.ReadTable() GroupMembers:Clear() for k, v in pairs(FPP.GroupMembers) do local name = "Unknown" for _, ply in ipairs(player.GetAll()) do if ply:SteamID() == k then name = ply:Nick() break end end GroupMembers:AddLine(k, name, v) end GroupMembers:SelectFirstItem() end net.Receive("FPP_GroupMembers", RetrieveGroupMembers) local lbl = Label("\nFalco's Prop Protection\nMade by Falco A.K.A. FPtje") lbl:SizeToContents() lbl:SetTextColor(Color(0, 0, 0, 255)) AdminPanel.contents:Add(lbl) AdminPanel:SetContents(AdminPanel.contents) AdminPanel:Dock(FILL) end RetrieveBlockedModels = function(len) if not ShowBlockedModels then return end local data = net.ReadData(len) local models = string.Explode('\0', util.Decompress(data)) for _, model in pairs(models) do local Icon = vgui.Create("SpawnIcon", ShowBlockedModels.pan) Icon:SetModel(model, 1) Icon:SetSize(64, 64) Icon.DoClick = function() local menu = DermaMenu() menu:AddOption("Remove from FPP blocked models list", function() -- I use a DMenu so people don't accidentally click the wrong icon and go FFFUUU RunConsoleCommand("FPP_RemoveBlockedModel", model) Icon:Remove() ShowBlockedModels.pan:InvalidateLayout() end) menu:Open() end ShowBlockedModels.pan:AddItem(Icon) end end net.Receive("FPP_BlockedModels", RetrieveBlockedModels) RetrieveRestrictedTool = function(um) local tool, admin, Teams = um, 0, {}--Settings when it's not a usermessage if not istable(um) then tool = net.ReadString() admin = net.ReadUInt(2) local teamCount = net.ReadUInt(10) for i = 1, teamCount do Teams[net.ReadUInt(10)] = true end end local frame = vgui.Create("DFrame") if istable(tool) then frame:SetTitle("Edit multiple tools' restrictions") else frame:SetTitle("Edit/view " .. tool .. " restrictions") end frame:MakePopup() frame:SetVisible( true ) frame:SetSize(250, 400) frame:Center() local pan = vgui.Create("DPanelList", frame) pan:SetPos(10, 30) pan:SetSize(230, 1) pan:SetSpacing(5) pan:EnableHorizontal(false) pan:EnableVerticalScrollbar(true) pan:SetAutoSize(true) local adminsCHKboxes = {} adminsCHKboxes[1] = vgui.Create("DCheckBoxLabel") adminsCHKboxes[1]:SetText("for everyone") adminsCHKboxes[1].GoodValue = 0 if admin == 0 then adminsCHKboxes[1].Button:SetValue(1) end pan:AddItem(adminsCHKboxes[1]) adminsCHKboxes[2] = vgui.Create("DCheckBoxLabel") adminsCHKboxes[2]:SetText("Admin only") adminsCHKboxes[2].GoodValue = 1 if admin == 1 then adminsCHKboxes[2].Button:SetValue(1) end pan:AddItem(adminsCHKboxes[2]) adminsCHKboxes[3] = vgui.Create("DCheckBoxLabel") adminsCHKboxes[3]:SetText("Superadmin only") adminsCHKboxes[3].GoodValue = 2 if admin == 2 then adminsCHKboxes[3].Button:SetValue(1) end pan:AddItem(adminsCHKboxes[3]) for k in pairs(adminsCHKboxes) do adminsCHKboxes[k].Button.Toggle = function() if adminsCHKboxes[k].Button:GetChecked() then return false -- You can't turn a checkbox off end for a in pairs(adminsCHKboxes) do adminsCHKboxes[a].Button:SetValue(false) end adminsCHKboxes[k].Button:SetValue(true) if not istable(tool) then RunConsoleCommand("FPP_restricttool", tool, "admin", adminsCHKboxes[k].GoodValue) else local i = 0 for _, b in pairs(tool) do i = i + 1 timer.Simple(i / 10, function() -- Timer to prevent lag of executing multiple commands at the same time. RunConsoleCommand("FPP_restricttool", b, "admin", adminsCHKboxes[k].GoodValue) end) end end end end local RestrictPlayerButton = vgui.Create("DButton", frame) RestrictPlayerButton:SetPos(10, #adminsCHKboxes * 20 + 35) RestrictPlayerButton:SetSize(230, 20) RestrictPlayerButton:SetText("Restrict per player") RestrictPlayerButton:SetTooltip[[Default: reset their privileges and let them use this/these tool(s) like anyone else Allow: Allow them to use this tool no matter what team/admin access the tool is restricted to Disallow: Disallow them to use this tool no matter what team/admin access the tool is restricted to]] RestrictPlayerButton.DoClick = function(self) local menu = DermaMenu(self) menu:SetPos(gui.MouseX(), gui.MouseY()) for _, v in ipairs(player.GetAll()) do if not IsValid(v) then continue end local submenu = menu:AddSubMenu(v:Nick()) submenu:AddOption( "Default", function() if not istable(tool) then RunConsoleCommand("FPP_restricttoolplayer", tool, v:UserID(), 2) return end for a, b in pairs(tool) do timer.Simple(a / 10, function() RunConsoleCommand("FPP_restricttoolplayer", b, v:UserID(), 2) end) end end) submenu:AddOption( "Allow", function() if not istable(tool) then RunConsoleCommand("FPP_restricttoolplayer", tool, v:UserID(), 1) return end for a, b in pairs(tool) do timer.Simple(a / 10, function() RunConsoleCommand("FPP_restricttoolplayer", b, v:UserID(), 1) end) end end) submenu:AddOption( "Disallow", function() if not istable(tool) then RunConsoleCommand("FPP_restricttoolplayer", tool, v:UserID(), 0) end for a, b in pairs(tool) do timer.Simple(a / 10, function() RunConsoleCommand("FPP_restricttoolplayer", b, v:UserID(), 0) end) end end) end menu:Open() end local Tpan = vgui.Create("DPanelList", frame) local count = #adminsCHKboxes Tpan:SetPos(10, count * 20 + 65) Tpan:SetSize(230, 325 - count * 20) Tpan:SetSpacing(5) Tpan:EnableHorizontal(false) Tpan:EnableVerticalScrollbar(true) for k, v in pairs(team.GetAllTeams()) do local chkbx = vgui.Create("DCheckBoxLabel") chkbx:SetText(v.Name) chkbx:SetDark(true) chkbx.Team = k chkbx.Button:SetValue(Teams[k]) chkbx.Button.Toggle = function() if chkbx.Button:GetChecked() == nil or not chkbx.Button:GetChecked() then chkbx.Button:SetValue(true) else chkbx.Button:SetValue(false) end local tonum = {} tonum[false] = "0" tonum[true] = "1" if not istable(tool) then RunConsoleCommand("FPP_restricttool", tool, "team", chkbx.Team, tonum[chkbx.Button:GetChecked()] ) else for a, b in pairs(tool) do timer.Simple(a / 10, function() RunConsoleCommand("FPP_restricttool", b, "team", chkbx.Team, tonum[chkbx.Button:GetChecked()]) end) end end end Tpan:AddItem(chkbx) end end net.Receive("FPP_RestrictedToolList", RetrieveRestrictedTool) EditGroupTools = function(groupname) if not FPP.Groups[groupname] then return end local tools = FPP.Groups[groupname].tools local frame = vgui.Create("DFrame") frame:SetTitle("Edit tools of " .. groupname) frame:MakePopup() frame:SetVisible( true ) frame:SetSize(640, 480) frame:Center() local GroupTools = vgui.Create("DListView", frame) GroupTools:SetPos(340, 25) GroupTools:SetSize(295, 450) GroupTools:AddColumn("Tools currently in " .. groupname) for _, v in pairs(tools or {}) do GroupTools:AddLine(v) end local SelectTool = Label("Select a tool or a folder", frame) SelectTool:SetPos(5, 25) SelectTool:SizeToContents() local ToolList = vgui.Create("DTree", frame) ToolList:SetPos(5, 45) ToolList:SetSize(300, 430) for a in pairs(spawnmenu.GetTools()) do for c,d in pairs(spawnmenu.GetTools()[a].Items) do local addnodes = {} for g, h in pairs(weapons.Get("gmod_tool").Tool) do if h.Category and h.Category == d.ItemName then table.insert(addnodes, {h.Name, g}) end end if #addnodes ~= 0 then local node1 = ToolList:AddNode(d.ItemName) node1.Tool = d.ItemName for _, f in pairs(addnodes) do local node2 = node1:AddNode(f[1]) node2.Icon:SetImage("icon16/wrench.png") node2.Tool = f[2] end end end end local AddTool = vgui.Create("DButton", frame) AddTool:SetPos(310, 45) AddTool:SetSize(25, 25) AddTool:SetText(">") AddTool.DoClick = function() if not ToolList.m_pSelectedItem then return end local SelectedTool = string.lower(ToolList.m_pSelectedItem.Tool) if not ToolList.m_pSelectedItem.ChildNodes then -- if it's not a folder for _, v in pairs(GroupTools:GetLines()) do if v.Columns[1]:GetValue() == SelectedTool then return end end RunConsoleCommand("FPP_AddGroupTool", groupname, SelectedTool) GroupTools:AddLine(SelectedTool) else--if it's a folder: for k, v in pairs(ToolList.m_pSelectedItem.ChildNodes:GetChildren()) do local found = false for _, b in pairs(GroupTools:GetLines()) do if b.Columns[1]:GetValue() == string.lower(v.Tool) then found = true break end end if not found then GroupTools:AddLine(string.lower(v.Tool)) timer.Simple(k / 10, function() RunConsoleCommand("FPP_AddGroupTool", groupname, v.Tool) end) end end end end local RemTool = vgui.Create("DButton", frame) RemTool:SetPos(310, 75) RemTool:SetSize(25, 25) RemTool:SetText("<") RemTool.DoClick = function() for k, v in pairs(GroupTools:GetSelected()) do local toolname = v.Columns[1]:GetValue() timer.Simple(k / 10, function() RunConsoleCommand("FPP_RemoveGroupTool", groupname, toolname) end) GroupTools:RemoveLine(v.m_iID) end end end local function retrieveblocked(um) local Type = string.lower(um:ReadString()) if not BlockedLists[Type] then return end local text = um:ReadString() local line = BlockedLists[Type]:AddLine(text) line.text = text BlockedLists[Type]:SetTall(18 + #BlockedLists[Type]:GetLines() * 17) end usermessage.Hook("FPP_blockedlist", retrieveblocked) local BuddiesPanel function FPP.BuddiesMenu(Panel) BuddiesPanel = BuddiesPanel or Panel if not IsValid(BuddiesPanel) then return end Panel:ClearControls() BuddiesPanel:Clear() Panel:AddControl("Label", {Text = "\nBuddies menu\nNote: Your buddies are saved and will work in all servers with FPP\nThe buddies list includes players that aren't here\n\nYour buddies:"}) local BuddiesList = vgui.Create("DListView") BuddiesList:AddColumn("Steam ID") BuddiesList:AddColumn("Name") BuddiesList:SetTall(150) BuddiesList:SetMultiSelect(false) BuddiesPanel:AddPanel(BuddiesList) for k, v in SortedPairsByMemberValue(FPP.Buddies, "name", false) do BuddiesList:AddLine(k, v.name) end BuddiesList:SelectFirstItem() local remove = vgui.Create("DButton") remove:SetText("Remove selected buddy") remove.DoClick = function() local line = BuddiesList:GetLine(BuddiesList:GetSelectedLine()) -- Select the only selected line if not line then return end FPP.SaveBuddy(line.Columns[1]:GetValue(), line.Columns[2]:GetValue(), "remove") FPP.BuddiesMenu(BuddiesPanel) -- Restart the entire menu end BuddiesPanel:AddPanel(remove) local edit = vgui.Create("DButton") edit:SetText("Edit selected buddy") edit.DoClick = function() local line = BuddiesList:GetLine(BuddiesList:GetSelectedLine()) -- Select the only selected line if not line then return end local tmp = FPP.Buddies[line.Columns[1]:GetValue()] if not tmp then return end local data = {tmp.physgun, tmp.gravgun, tmp.toolgun, tmp.playeruse, tmp.entitydamage} FPP.SetBuddyMenu(line.Columns[1]:GetValue(), line.Columns[2]:GetValue(), data) end BuddiesPanel:AddPanel(edit) local AddManual = vgui.Create("DButton") AddManual:SetText("Add steamID manually") AddManual.DoClick = function() Derma_StringRequest("Add buddy manually", "Please enter the SteamID of the player you want to add in your buddies list", "", function(ID) Derma_StringRequest("Name of buddy", "What is the name of this buddy? (You can enter any name, it will change the next time you meet in a server with FPP)", "", function(Name) FPP.SetBuddyMenu(ID, Name) end) end) end BuddiesPanel:AddPanel(AddManual) Panel:AddControl("Label", {Text = "\nAdd buddy:"}) local AvailablePlayers = false for _, v in SortedPairs(player.GetAll(), function(a, b) return a:Nick() > b:Nick() end) do if not IsValid(v) then continue end local cantadd = false if v == LocalPlayer() then cantadd = true end for a in pairs(FPP.Buddies) do if a == v:SteamID() then cantadd = true break end end if not cantadd then local add = vgui.Create("DButton") add:SetText(v:Nick()) add.DoClick = function() FPP.SetBuddyMenu(v:SteamID(), v:Nick()) end BuddiesPanel:AddPanel(add) AvailablePlayers = true end end if not AvailablePlayers then Panel:AddControl("Label", {Text = ""}) end end function FPP.SetBuddyMenu(SteamID, Name, data) local frame = vgui.Create("DFrame") frame:SetTitle(Name) frame:MakePopup() frame:SetVisible( true ) frame:SetSize(150, 130) frame:Center() local count = 1.5 local function AddChk(name, Type, value) local box = vgui.Create("DCheckBoxLabel", frame) box:SetText(name .. " buddy") box:SetDark(true) box:SetPos(10, count * 20) count = count + 1 box:SetValue(tobool(value)) box.Button.Toggle = function() if box.Button:GetChecked() == nil or not box.Button:GetChecked() then box.Button:SetValue( true ) else box.Button:SetValue( false ) end local tonum = {} tonum[false] = 0 tonum[true] = 1 FPP.SaveBuddy(SteamID, Name, Type, tonum[box.Button:GetChecked()]) FPP.BuddiesMenu(BuddiesPanel) -- Restart the entire menu end box:SizeToContents() end data = data or {0,0,0,0,0} AddChk("Physgun", "physgun", data[1]) AddChk("Gravgun", "gravgun", data[2]) AddChk("Toolgun", "toolgun", data[3]) AddChk("Use", "playeruse", data[4]) AddChk("Entity damage", "entitydamage", data[5]) end local PrivateSettings = { ["touch my own entities"] = "OwnProps", ["touch world entities"] = "WorldProps", ["touch other people's entities"] = "OtherPlayerProps", ["touch blocked entities"] = "BlockedProps", ["see the owners of props"] = "HideOwner" } local privateSettingVars = {} for _, v in pairs(PrivateSettings) do privateSettingVars[v] = CreateClientConVar("FPP_PrivateSettings_" .. v, 0, true, true) end CreateClientConVar("cl_pickupplayers", 1, true, true) function FPP.getPrivateSetting(setting) return privateSettingVars[setting]:GetBool() end local PrivateSettingsPanel function FPP.PrivateSettings(Panel) PrivateSettingsPanel = PrivateSettingsPanel or Panel Panel:ClearControls() PrivateSettingsPanel:Clear() Panel:AddControl("Label", {Text = "\nPrivate settings menu\nUse to set settings that override server settings\n\nThese settings can only restrict you further.\n"}) for k, v in pairs(PrivateSettings) do local box = vgui.Create("DCheckBoxLabel") box:SetText("I don't want to " .. k) box:SetValue(GetConVar("FPP_PrivateSettings_" .. v):GetBool()) box:SetDark(true) box.Button.Toggle = function(self) RunConsoleCommand("FPP_PrivateSettings_" .. v, self:GetChecked() and "0" or "1") self:SetValue(not self:GetChecked()) RunConsoleCommand("_FPP_RefreshPrivatePlayerSettings") end box:SizeToContents() Panel:AddItem(box) end Panel:AddControl("CheckBox", {Label = "I want to pick up players", Command = "cl_pickupplayers"}) local fallbackChoice = Panel:ComboBox("Fallback player") fallbackChoice:AddChoice("None", -1, true) for _, v in ipairs(player.GetAll()) do if v == LocalPlayer() then continue end fallbackChoice:AddChoice(v:Nick(), v:UserID(), PrivateSettingsPanel.FallbackSelected == v:UserID()) end fallbackChoice.OnSelect = function(_, _, nick, uid) RunConsoleCommand("FPP_FallbackOwner", uid) PrivateSettingsPanel.FallbackSelected = uid end end local function makeMenus() spawnmenu.AddToolMenuOption( "Utilities", "Falco's prop protection", "Falco's prop protection admin settings", "Admin settings", "", "", FPP.AdminMenu) spawnmenu.AddToolMenuOption( "Utilities", "Falco's prop protection", "Falco's prop protection buddies", "Buddies", "", "", FPP.BuddiesMenu) spawnmenu.AddToolMenuOption( "Utilities", "Falco's prop protection", "Falco's prop protection Private settings", "Private Settings", "", "", FPP.PrivateSettings) end hook.Add("PopulateToolMenu", "FPPMenus", makeMenus) local function UpdateMenus() if IsValid(AdminPanel) then FPP.AdminMenu(AdminPanel) end if IsValid(BuddiesPanel) then FPP.BuddiesMenu(BuddiesPanel) end if IsValid(PrivateSettingsPanel) then FPP.PrivateSettings(PrivateSettingsPanel) end end hook.Add("SpawnMenuOpen", "FPPMenus", UpdateMenus) function FPP.SharedMenu(um) local ent = um:ReadEntity() local frame = vgui.Create("DFrame") if not IsValid(ent) then frame:Close() return end frame:SetTitle("Share " .. ent:GetClass()) frame:MakePopup() frame:SetVisible( true ) local count = 1.5 local row = 1 local function AddChk(name, Type, value) local box = vgui.Create("DCheckBoxLabel", frame) if isstring(name) then box:SetText(name .. " share this entity") elseif name:IsPlayer() and name:IsValid() then box:SetText(name:Nick() .. " can touch this") else return end if count * 20 - (row - 1) * ScrH() > ScrH() - 30 - (row - 1) * 50 then row = row + 1 end box:SetPos(10 + (row - 1) * 155, count * 20 - (row - 1) * ScrH() + (row - 1) * 40) count = count + 1 box:SetValue(value) box.Button.Toggle = function() if not IsValid(ent) then frame:Close() return end if box.Button:GetChecked() == nil or not box.Button:GetChecked() then box.Button:SetValue( true ) else box.Button:SetValue( false ) end local tonum = {} tonum[false] = "0" tonum[true] = "1" RunConsoleCommand("FPP_ShareProp", ent:EntIndex(), Type, tonum[box.Button:GetChecked()]) end box:SizeToContents() end AddChk("Physgun", "SharePhysgun1", um:ReadBool()) AddChk("Gravgun", "ShareGravgun1", um:ReadBool()) AddChk("Use", "SharePlayerUse1", um:ReadBool()) AddChk("Damage", "ShareEntityDamage1", um:ReadBool()) AddChk("Toolgun", "ShareToolgun1", um:ReadBool()) local long = um:ReadLong() local SharedWith = {} if long > 0 then for i = 1, long do table.insert(SharedWith, um:ReadEntity()) end end if player.GetCount() ~= 1 then count = count + 1 end for _, v in ipairs(player.GetAll()) do if IsValid(v) and v ~= LocalPlayer() then local IsShared = false if table.HasValue(SharedWith, v) then IsShared = true end AddChk(v, v:UserID(), IsShared) end end local height = count * 20 if row > 1 then height = ScrH() - 20 end frame:SetSize(math.Min(math.Max(165 + (row - 1) * 165, 165), ScrW()), height) frame:Center() end usermessage.Hook("FPP_ShareSettings", FPP.SharedMenu) properties.Add("addFPPBlocked", { MenuLabel = "Add to FPP blocked models", Order = 2001, MenuIcon = "icon16/cross.png", Filter = function(self, ent, ply) if not IsValid(ent) or ent:IsPlayer() then return false end return ply:IsSuperAdmin() end, Action = function(self, ent) if not IsValid(ent) then return end RunConsoleCommand("FPP_AddBlockedModel", ent:GetModel(), ent:EntIndex()) end }) properties.Add("removeFPPBlocked", { MenuLabel = "Remove from FPP blocked models", Order = 2002, MenuIcon = "icon16/tick.png", Filter = function(self, ent, ply) if not IsValid(ent) or ent:IsPlayer() then return false end return ply:IsSuperAdmin() end, Action = function(self, ent) if not IsValid(ent) then return end RunConsoleCommand("FPP_RemoveBlockedModel", ent:GetModel(), ent:EntIndex()) end })