mirror of
https://github.com/Nebual/NadmodPP.git
synced 2025-03-04 03:03:10 -05:00
Initial Nadmod Prop Protection commit, v1.3.1
This commit is contained in:
commit
03f088ff55
14
addon.json
Normal file
14
addon.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"title" : "Nadmod Prop Protection",
|
||||
"type" : "tool",
|
||||
"tags" : [ "build" ],
|
||||
"description": "NPP is a simple and efficient Prop Protection system. \n\n* Admins can touch all props (configurable)\n* All player spawned entities are protected by default from:\n- All Tools\n- Properties menu (right clicking props while holding C)\n- Gravity gun punt/pickup\n- Physgun pickup/reload\n* Has a friends system with cpanel that saves friends to file\n* Quick and easy buttons to cleanup either Disconnected Player's stuff or specific players, which also show the current # of entities that player owns\n* Autoclean Disconnected Player's props timer\n* Simple overlay shown on all entities shows owner, class, model, and entID\n* Freshly written for Gmod13, it includes blocking the new CanProperty (right click menu)\n* CPPI Compliant\n\nFor more information, see the Facepunch thread http://facepunch.com/showthread.php?t=1242185\nNote: Initially Protection is disabled serverwide, just tick on the Main Power Switch in the Admin CPanel and hit Apply.",
|
||||
"ignore" :
|
||||
[
|
||||
".git/*",
|
||||
"*.psd",
|
||||
"*.vcproj",
|
||||
"*.svn*",
|
||||
"*.txt"
|
||||
]
|
||||
}
|
205
lua/autorun/client/cl_nadmodpp.lua
Normal file
205
lua/autorun/client/cl_nadmodpp.lua
Normal file
@ -0,0 +1,205 @@
|
||||
-- =================================
|
||||
-- NADMOD PP - Prop Protection
|
||||
-- By Nebual@nebtown.info 2012
|
||||
-- Menus designed after SpaceTech's Simple Prop Protection
|
||||
-- =================================
|
||||
if !NADMOD then
|
||||
NADMOD = {}
|
||||
NADMOD.PropOwners = {}
|
||||
NADMOD.PPConfig = {}
|
||||
NADMOD.Friends = {}
|
||||
end
|
||||
|
||||
local Props = NADMOD.PropOwners
|
||||
net.Receive("nadmod_propowners",function(len)
|
||||
local num = net.ReadUInt(16)
|
||||
for k=1,num do
|
||||
local id,str = net.ReadUInt(16), net.ReadString()
|
||||
if str == "-" then Props[id] = nil
|
||||
elseif str == "W" then Props[id] = "World"
|
||||
elseif str == "O" then Props[id] = "Ownerless"
|
||||
else Props[id] = str
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local font = "ChatFont"
|
||||
hook.Add("HUDPaint", "NADMOD.HUDPaint", function()
|
||||
local tr = LocalPlayer():GetEyeTrace()
|
||||
if !tr.HitNonWorld then return end
|
||||
local ent = tr.Entity
|
||||
if ent:IsValid() && !ent:IsPlayer() then
|
||||
local text = "Owner: " .. (Props[ent:EntIndex()] or "N/A")
|
||||
local text2 = "'"..string.sub(table.remove(string.Explode("/", ent:GetModel() or "?")), 1,-5).."' ["..ent:EntIndex().."]"
|
||||
local text3 = ent:GetClass()
|
||||
surface.SetFont(font)
|
||||
local Width, Height = surface.GetTextSize(text)
|
||||
local w2,h2 = surface.GetTextSize(text2)
|
||||
local w3,h3 = surface.GetTextSize(text3)
|
||||
local boxHeight = Height + h2 + h3 + 16
|
||||
local boxWidth = math.Max(Width,w2,w3) + 25
|
||||
draw.RoundedBox(4, ScrW() - (boxWidth + 4), (ScrH()/2 - 200) - 16, boxWidth, boxHeight, Color(0, 0, 0, 150))
|
||||
draw.SimpleText(text, font, ScrW() - (Width / 2) - 20, ScrH()/2 - 200, Color(255, 255, 255, 255), 1, 1)
|
||||
draw.SimpleText(text2, font, ScrW() - (w2 / 2) - 20, ScrH()/2 - 200 + Height, Color(255, 255, 255, 255), 1, 1)
|
||||
draw.SimpleText(text3, font, ScrW() - (w3 / 2) - 20, ScrH()/2 - 200 + Height + h2, Color(255, 255, 255, 255), 1, 1)
|
||||
end
|
||||
end)
|
||||
|
||||
function NADMOD.CleanCLRagdolls()
|
||||
for k,v in pairs(ents.FindByClass("class C_ClientRagdoll")) do v:SetNoDraw(true) end
|
||||
for k,v in pairs(ents.FindByClass("class C_BaseAnimating")) do v:SetNoDraw(true) end
|
||||
end
|
||||
net.Receive("nadmod_cleanclragdolls", NADMOD.CleanCLRagdolls)
|
||||
|
||||
-- =============================
|
||||
-- NADMOD PP CPanels
|
||||
-- =============================
|
||||
net.Receive("nadmod_ppconfig",function(len)
|
||||
NADMOD.PPConfig = net.ReadTable()
|
||||
for k,v in pairs(NADMOD.PPConfig) do
|
||||
local val = v
|
||||
if isbool(v) then val = v and "1" or "0" end
|
||||
|
||||
CreateClientConVar("npp_"..k,val, false, false)
|
||||
RunConsoleCommand("npp_"..k,val)
|
||||
end
|
||||
NADMOD.AdminPanel(NADMOD.AdminCPanel, true)
|
||||
end)
|
||||
|
||||
concommand.Add("npp_apply",function(ply,cmd,args)
|
||||
for k,v in pairs(NADMOD.PPConfig) do
|
||||
if isbool(v) then NADMOD.PPConfig[k] = GetConVar("npp_"..k):GetBool()
|
||||
elseif isnumber(v) then NADMOD.PPConfig[k] = GetConVarNumber("npp_"..k)
|
||||
else NADMOD.PPConfig[k] = GetConVarString("npp_"..k)
|
||||
end
|
||||
end
|
||||
net.Start("nadmod_ppconfig")
|
||||
net.WriteTable(NADMOD.PPConfig)
|
||||
net.SendToServer()
|
||||
end)
|
||||
|
||||
function NADMOD.AdminPanel(Panel, runByNetReceive)
|
||||
if Panel then
|
||||
if !NADMOD.AdminCPanel then NADMOD.AdminCPanel = Panel end
|
||||
end
|
||||
if not runByNetReceive then
|
||||
RunConsoleCommand("npp_refreshconfig")
|
||||
timer.Create("NADMOD.AdminPanelCheckFail",0.75,1,function()
|
||||
Panel:ClearControls()
|
||||
Panel:Help("Waiting for the server to say you're an admin...")
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
timer.Remove("NADMOD.AdminPanelCheckFail")
|
||||
Panel:ClearControls()
|
||||
Panel:SetName("NADMOD PP Admin Panel")
|
||||
|
||||
Panel:CheckBox( "Main PP Power Switch", "npp_toggle")
|
||||
Panel:CheckBox( "Admins can touch anything", "npp_adminall")
|
||||
local use_protection = Panel:CheckBox( "Use (E) Protection", "npp_use")
|
||||
use_protection:SetToolTip("Stop nonfriends from entering vehicles, pushing buttons/doors")
|
||||
|
||||
local txt = Panel:Help("Autoclean Disconnected Players?")
|
||||
txt:SetAutoStretchVertical(false)
|
||||
txt:SetContentAlignment( TEXT_ALIGN_CENTER )
|
||||
local autoclean_admins = Panel:CheckBox( "Autoclean Admins", "npp_autocdpadmins")
|
||||
autoclean_admins:SetToolTip("Should Admin Props also be autocleaned?")
|
||||
local autoclean_timer = Panel:NumSlider("Autoclean Timer", "npp_autocdp", 0, 1200, 0 )
|
||||
autoclean_timer:SetToolTip("0 disables autocleaning")
|
||||
Panel:Button( "Apply Settings", "npp_apply")
|
||||
|
||||
local txt = Panel:Help(" Cleanup Panel")
|
||||
txt:SetContentAlignment( TEXT_ALIGN_CENTER )
|
||||
txt:SetFont("DermaDefaultBold")
|
||||
txt:SetAutoStretchVertical(false)
|
||||
|
||||
local counts = {}
|
||||
for k,v in pairs(NADMOD.PropOwners) do
|
||||
counts[v] = (counts[v] or 0) + 1
|
||||
end
|
||||
local dccount = 0
|
||||
for k,v in pairs(counts) do
|
||||
if k != "World" and k != "Ownerless" then dccount = dccount + v end
|
||||
end
|
||||
for k, ply in pairs(player.GetAll()) do
|
||||
if IsValid(ply) then
|
||||
Panel:Button( ply:Nick().." ("..(counts[ply:Nick()] or 0)..")", "nadmod_cleanupprops", ply:EntIndex() )
|
||||
dccount = dccount - (counts[ply:Nick()] or 0)
|
||||
end
|
||||
end
|
||||
|
||||
Panel:Help(""):SetAutoStretchVertical(false) -- Spacer
|
||||
Panel:Button("Cleanup Disconnected Players Props ("..dccount..")", "nadmod_cdp")
|
||||
Panel:Button("Cleanup All NPCs", "nadmod_cleanclass", "npc_*")
|
||||
Panel:Button("Cleanup All Ragdolls", "nadmod_cleanclass", "prop_ragdol*")
|
||||
Panel:Button("Cleanup Clientside Ragdolls", "nadmod_cleanclragdolls")
|
||||
Panel:Button("Cleanup World Ropes", "nadmod_cleanworldropes")
|
||||
end
|
||||
|
||||
net.Receive("nadmod_ppfriends",function(len)
|
||||
NADMOD.Friends = net.ReadTable()
|
||||
for _,tar in pairs(player.GetAll()) do
|
||||
CreateClientConVar("npp_friend_"..tar:UniqueID(),NADMOD.Friends[tar:SteamID()] and "1" or "0", false, false)
|
||||
RunConsoleCommand("npp_friend_"..tar:UniqueID(),NADMOD.Friends[tar:SteamID()] and "1" or "0")
|
||||
end
|
||||
end)
|
||||
|
||||
concommand.Add("npp_applyfriends",function(ply,cmd,args)
|
||||
for _,tar in pairs(player.GetAll()) do
|
||||
NADMOD.Friends[tar:SteamID()] = GetConVar("npp_friend_"..tar:UniqueID()):GetBool()
|
||||
end
|
||||
net.Start("nadmod_ppfriends")
|
||||
net.WriteTable(NADMOD.Friends)
|
||||
net.SendToServer()
|
||||
end)
|
||||
|
||||
function NADMOD.ClientPanel(Panel)
|
||||
RunConsoleCommand("npp_refreshfriends")
|
||||
Panel:ClearControls()
|
||||
if !NADMOD.ClientCPanel then NADMOD.ClientCPanel = Panel end
|
||||
Panel:SetName("NADMOD - Client Panel")
|
||||
|
||||
Panel:Button("Cleanup Props", "nadmod_cleanupprops")
|
||||
Panel:Button("Clear Clientside Ragdolls", "nadmod_cleanclragdolls")
|
||||
|
||||
local txt = Panel:Help(" Friends Panel")
|
||||
txt:SetContentAlignment( TEXT_ALIGN_CENTER )
|
||||
txt:SetFont("DermaDefaultBold")
|
||||
txt:SetAutoStretchVertical(false)
|
||||
|
||||
local Players = player.GetAll()
|
||||
if(table.Count(Players) == 1) then
|
||||
Panel:Help("No Other Players Are Online")
|
||||
else
|
||||
for _, tar in pairs(Players) do
|
||||
if(IsValid(tar) and tar != LocalPlayer()) then
|
||||
Panel:CheckBox(tar:Nick(), "npp_friend_"..tar:UniqueID())
|
||||
end
|
||||
end
|
||||
Panel:Button("Apply Friends", "npp_applyfriends")
|
||||
end
|
||||
end
|
||||
|
||||
function NADMOD.SpawnMenuOpen()
|
||||
if NADMOD.AdminCPanel then
|
||||
NADMOD.AdminPanel(NADMOD.AdminCPanel)
|
||||
end
|
||||
if NADMOD.ClientCPanel then
|
||||
NADMOD.ClientPanel(NADMOD.ClientCPanel)
|
||||
end
|
||||
end
|
||||
hook.Add("SpawnMenuOpen", "NADMOD.SpawnMenuOpen", NADMOD.SpawnMenuOpen)
|
||||
|
||||
function NADMOD.PopulateToolMenu()
|
||||
spawnmenu.AddToolMenuOption("Utilities", "NADMOD Prop Protection", "Admin", "Admin", "", "", NADMOD.AdminPanel)
|
||||
spawnmenu.AddToolMenuOption("Utilities", "NADMOD Prop Protection", "Client", "Client", "", "", NADMOD.ClientPanel)
|
||||
end
|
||||
hook.Add("PopulateToolMenu", "NADMOD.PopulateToolMenu", NADMOD.PopulateToolMenu)
|
||||
|
||||
net.Receive("nadmod_notify", function(len)
|
||||
local text = net.ReadString()
|
||||
notification.AddLegacy(text, NOTIFY_GENERIC, 5)
|
||||
surface.PlaySound("ambient/water/drip"..math.random(1, 4)..".wav")
|
||||
print(text)
|
||||
end)
|
561
lua/autorun/server/nadmod_pp.lua
Normal file
561
lua/autorun/server/nadmod_pp.lua
Normal file
@ -0,0 +1,561 @@
|
||||
-- Nebual 2012 (nebual@nebtown.info) presents:
|
||||
-- NADMOD Prop Protection
|
||||
-- Inspired by Spacetech's Simple Prop Protection, <3's
|
||||
-- Bugs? Feature requests? Email me or poke the Facepunch http://www.facepunch.com/showthread.php?t=1221183
|
||||
|
||||
if not NADMOD then
|
||||
-- User is running without my Admin mod NADMOD, lets just copy some required initialization stuff over here
|
||||
concommand.Add("nadmod_reload", function(ply,cmd,args)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
if args[1] == "full" then NADMOD = nil end
|
||||
include("autorun/server/nadmod_pp.lua")
|
||||
end)
|
||||
NADMOD = util.JSONToTable(file.Read("nadmod_config.txt","DATA") or "") or {Users = {}, Groups = {}, Bans = {}, PPConfig = {}}
|
||||
function NADMOD.Save()
|
||||
file.Write("nadmod_config.txt", util.TableToJSON({Users = NADMOD.Users, Groups = NADMOD.Groups, Bans = NADMOD.Bans, PPConfig = NADMOD.PPConfig}))
|
||||
end
|
||||
hook.Add("Shutdown","NADMOD.Save",NADMOD.Save)
|
||||
function NADMOD.FindPlayer(nick)
|
||||
if not nick or nick == "" then return end
|
||||
nick = string.lower(nick)
|
||||
local num = tonumber(nick)
|
||||
for _,v in pairs(player.GetAll()) do
|
||||
if string.lower(v:Nick()) == nick then return v -- Exact name match
|
||||
elseif v:UserID() == num then return v -- UserID match (from status)
|
||||
end
|
||||
end
|
||||
-- If the above two exact searches fail, try doing a partial search
|
||||
for _,v in pairs(player.GetAll()) do
|
||||
if string.find(string.lower(v:Nick()), nick) then return v end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not NADMOD.Props then
|
||||
-- NADMOD PP Initialization
|
||||
NADMOD.PPVersion = "1.3.1"
|
||||
NADMOD.Props = {} // {entid = {Ent = ent, Owner = ply, SteamID = ply:SteamID(), Name = ply:Nick() or "W" or "O"}}
|
||||
NADMOD.PropOwnersSmall = {} // A smaller buffer of PropOwner names to send to current players
|
||||
NADMOD.AutoCDPTimers = {}
|
||||
|
||||
local oldCPPI = CPPI
|
||||
CPPI = {}
|
||||
|
||||
-- Copy over default settings if they aren't present in the disk's PPConfig
|
||||
for k,v in pairs({toggle=true,use=false,adminall=true,autocdp=0,autocdpadmins=false}) do
|
||||
if NADMOD.PPConfig[k] == nil then NADMOD.PPConfig[k] = v end
|
||||
end
|
||||
|
||||
AddCSLuaFile("autorun/client/cl_nadmodpp.lua")
|
||||
util.AddNetworkString("nadmod_propowners")
|
||||
util.AddNetworkString("nadmod_ppfriends")
|
||||
util.AddNetworkString("nadmod_ppconfig")
|
||||
util.AddNetworkString("nadmod_cleanclragdolls")
|
||||
util.AddNetworkString("nadmod_notify")
|
||||
|
||||
timer.Create("WarnOtherPPs", 0, 1, function()
|
||||
//Print a harmless error if we detect other PP's active, since this often leads to confusion. NPP'll still load fine
|
||||
//Known CPPI plugins: FPP, SPP, NPP, ULX's UPS
|
||||
if not oldCPPI or (oldCPPI.GetName and oldCPPI:GetName() == "Nadmod Prop Protection") then oldCPPI = CPPI end
|
||||
if oldCPPI and (not oldCPPI.GetName or oldCPPI:GetName() ~= "Nadmod Prop Protection") then Error("NPP has detected "..(oldCPPI.GetName and oldCPPI:GetName() or "another CPPI PP").." is installed, you probably only want one PP active at a time!!\n")
|
||||
elseif PP_Settings then Error("NPP has detected Evolve's PP plugin, you probably only want one PP active at a time!!\n")
|
||||
end
|
||||
end)
|
||||
end
|
||||
local metaply = FindMetaTable("Player")
|
||||
local metaent = FindMetaTable("Entity")
|
||||
|
||||
-- Does your admin mod not seem to work with Nadmod PP? Try overriding this function!
|
||||
function NADMOD.IsPPAdmin(ply)
|
||||
if NADMOD.HasPermission then
|
||||
return NADMOD.HasPermission(ply, "PP_All")
|
||||
else
|
||||
-- If the admin mod NADMOD isn't present, just default to using IsAdmin
|
||||
return ply:IsAdmin()
|
||||
end
|
||||
end
|
||||
|
||||
function NADMOD.PPInitPlayer(ply)
|
||||
local steamid = ply:SteamID()
|
||||
for _,v in pairs(NADMOD.Props) do
|
||||
if v.SteamID == steamid then
|
||||
v.Owner = ply
|
||||
v.Ent.SPPOwner = ply
|
||||
if v.Ent.SetPlayer then v.Ent:SetPlayer(ply) end
|
||||
end
|
||||
end
|
||||
net.Start("nadmod_propowners")
|
||||
net.WriteUInt(table.Count(NADMOD.Props),16)
|
||||
for k,v in pairs(NADMOD.Props) do
|
||||
net.WriteUInt(k,16)
|
||||
net.WriteString(v.Name)
|
||||
end
|
||||
net.Send(ply)
|
||||
end
|
||||
hook.Add("PlayerInitialSpawn", "NADMOD.PPInitPlayer", NADMOD.PPInitPlayer)
|
||||
|
||||
function NADMOD.PPOwnWeapons(ply)
|
||||
timer.Create("NADMOD.PPOwnWeapons", 0.2, 1, function()
|
||||
if not IsValid(ply) then return end
|
||||
for k,v in pairs(ply:GetWeapons()) do
|
||||
if not IsValid(v) then continue end
|
||||
NADMOD.SetOwnerWorld(v)
|
||||
end
|
||||
end)
|
||||
end
|
||||
hook.Add("PlayerSpawn", "NADMOD.PPOwnWeapons", NADMOD.PPOwnWeapons)
|
||||
|
||||
function NADMOD.RefreshOwners()
|
||||
if next(NADMOD.PropOwnersSmall) then
|
||||
net.Start("nadmod_propowners")
|
||||
net.WriteUInt(table.Count(NADMOD.PropOwnersSmall),16)
|
||||
for k,v in pairs(NADMOD.PropOwnersSmall) do
|
||||
net.WriteUInt(k,16)
|
||||
net.WriteString(v)
|
||||
end
|
||||
//net.WriteTable(NADMOD.PropOwnersSmall)
|
||||
net.Broadcast()
|
||||
table.Empty(NADMOD.PropOwnersSmall)
|
||||
end
|
||||
end
|
||||
timer.Create("NADMOD.RefreshOwners", 1, 0, NADMOD.RefreshOwners)
|
||||
|
||||
function NADMOD.IsFriendProp(ply, ent)
|
||||
if IsValid(ent) && IsValid(ply) && ply:IsPlayer() && NADMOD.Props[ent:EntIndex()] then
|
||||
local ownerSteamID = NADMOD.Props[ent:EntIndex()].SteamID
|
||||
if NADMOD.Users[ownerSteamID] then
|
||||
local friends = NADMOD.Users[ownerSteamID].Friends
|
||||
return friends && friends[ply:SteamID()]
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function NADMOD.PlayerCanTouch(ply, ent)
|
||||
-- If PP is off or the ent is worldspawn, let them touch it
|
||||
if not tobool(NADMOD.PPConfig["toggle"]) or ent:IsWorld() then return true end
|
||||
|
||||
if !IsValid(ent) or !IsValid(ply) or ent:IsPlayer() or !ply:IsPlayer() then return false end
|
||||
|
||||
if not NADMOD.Props[ent:EntIndex()] then
|
||||
local class = ent:GetClass()
|
||||
if(string.find(class, "stone_") == 1 or string.find(class, "rock_") == 1 or string.find(class, "stargate_") == 0 or string.find(class, "dhd_") == 0 or class == "flag" or class == "item" or class == "predicted_viewmodel" or class == "gmod_hands" or class == "physgun_beam") then
|
||||
NADMOD.SetOwnerWorld(ent)
|
||||
elseif ent.GetPlayer and IsValid(ent:GetPlayer()) then
|
||||
NADMOD.PlayerMakePropOwner(ent:GetPlayer(), ent)
|
||||
elseif ent.GetOwner and (IsValid(ent:GetOwner()) or ent:GetOwner():IsWorld()) then
|
||||
NADMOD.PlayerMakePropOwner(ent:GetOwner(), ent)
|
||||
elseif ent:EntIndex() == 0 then
|
||||
-- Players cannot take ownership of EntIndex 0 ents (constraints, func_'s, map lights)
|
||||
return false
|
||||
else
|
||||
NADMOD.PlayerMakePropOwner(ply, ent)
|
||||
NADMOD.Notify(ply, "You now own this " .. class .. " (" .. string.sub(table.remove(string.Explode("/", ent:GetModel() or "?")), 1,-5) .. ")" )
|
||||
return true
|
||||
end
|
||||
end
|
||||
if !NADMOD.Props[ent:EntIndex()] then
|
||||
-- To get here implies the ent has a 'valid' GetPlayer()/GetOwner(), but still couldn't get set properly
|
||||
-- For example, if an NPC is sitting in jeep (??), the jeep's GetPlayer returns the driver? or something
|
||||
ent:CPPISetOwnerless(true)
|
||||
if !NADMOD.Props[ent:EntIndex()] then return end
|
||||
end
|
||||
-- Ownerless props can be touched by all
|
||||
if NADMOD.Props[ent:EntIndex()].Name == "O" then return true end
|
||||
-- Admins can touch anyones props + world
|
||||
if NADMOD.PPConfig["adminall"] and NADMOD.IsPPAdmin(ply) then return true end
|
||||
-- Players can touch their own props and friends
|
||||
if NADMOD.Props[ent:EntIndex()].SteamID == ply:SteamID() or NADMOD.IsFriendProp(ply, ent) then return true end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- We could hook directly to PlayerCanTouch, but returning true stops other hooks from being called
|
||||
function NADMOD.PlayerCanTouchSafe(ply, ent)
|
||||
if !IsValid(ent) or ent:IsPlayer() then return end
|
||||
if !NADMOD.PlayerCanTouch(ply,ent) then return false end
|
||||
end
|
||||
hook.Add("PhysgunPickup", "NADMOD.PhysgunPickup", NADMOD.PlayerCanTouchSafe)
|
||||
hook.Add("CanProperty", "NADMOD.CanProperty", function(ply, mode, ent) return NADMOD.PlayerCanTouchSafe(ply, ent) end)
|
||||
hook.Add("CanEditVariable", "NADMOD.CanEditVariable", function(ent, ply, key, val, editor) return NADMOD.PlayerCanTouchSafe(ply, ent) end)
|
||||
|
||||
function NADMOD.OnPhysgunReload(weapon, ply)
|
||||
local tr = util.TraceLine(util.GetPlayerTrace(ply))
|
||||
if not tr.HitNonWorld or !tr.Entity:IsValid() or tr.Entity:IsPlayer() then return end
|
||||
if !NADMOD.PlayerCanTouch(ply, tr.Entity) then return false end
|
||||
end
|
||||
hook.Add("OnPhysgunReload", "NADMOD.OnPhysgunReload", NADMOD.OnPhysgunReload)
|
||||
|
||||
-- Basically just PlayerCanTouchSafe, but world props are fine to gravgun
|
||||
function NADMOD.GravGunPickup(ply, ent)
|
||||
if !IsValid(ent) or ent:IsPlayer() then return end
|
||||
if NADMOD.Props[ent:EntIndex()] and NADMOD.Props[ent:EntIndex()].Name == "W" then return end
|
||||
if !NADMOD.PlayerCanTouch(ply,ent) then return false end
|
||||
end
|
||||
hook.Add("GravGunPunt", "NADMOD.GravGunPunt", NADMOD.GravGunPickup)
|
||||
hook.Add("GravGunPickupAllowed", "NADMOD.GravGunPickupAllowed", NADMOD.GravGunPickup)
|
||||
|
||||
NADMOD.PPWeirdTraces = {"wire_winch","wire_hydraulic","slider","hydraulic","winch","muscle"}
|
||||
function NADMOD.CanTool(ply, tr, mode)
|
||||
local ent = tr.Entity
|
||||
if !ent:IsWorld() and (!ent:IsValid() or ent:IsPlayer()) then return false end
|
||||
if !NADMOD.PlayerCanTouch(ply, ent) then
|
||||
if not ((NADMOD.Props[ent:EntIndex()] or {}).Name == "W" and (mode == "wire_debugger" or mode == "wire_adv")) then
|
||||
return false
|
||||
end
|
||||
elseif(mode == "nail") then
|
||||
local Trace = {}
|
||||
Trace.start = tr.HitPos
|
||||
Trace.endpos = tr.HitPos + (ply:GetAimVector() * 16.0)
|
||||
Trace.filter = {ply, tr.Entity}
|
||||
local tr2 = util.TraceLine(Trace)
|
||||
if(tr2.Hit and IsValid(tr2.Entity) and !tr2.Entity:IsPlayer()) then
|
||||
if(!NADMOD.PlayerCanTouch(ply, tr2.Entity)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
elseif(table.HasValue(NADMOD.PPWeirdTraces, mode)) then
|
||||
local Trace = {}
|
||||
Trace.start = tr.HitPos
|
||||
Trace.endpos = Trace.start + (tr.HitNormal * 16384)
|
||||
Trace.filter = {ply}
|
||||
local tr2 = util.TraceLine(Trace)
|
||||
if(tr2.Hit and IsValid(tr2.Entity) and !tr2.Entity:IsPlayer()) then
|
||||
if(!NADMOD.PlayerCanTouch(ply, tr2.Entity)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
elseif(mode == "remover") then
|
||||
if(ply:KeyDown(IN_ATTACK2) or ply:KeyDownLast(IN_ATTACK2)) then
|
||||
for k,v in pairs(constraint.GetAllConstrainedEntities(ent) or {}) do
|
||||
if !NADMOD.PlayerCanTouch(ply, v) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("CanTool", "NADMOD.CanTool", NADMOD.CanTool)
|
||||
|
||||
function NADMOD.PlayerUse(ply, ent)
|
||||
if !NADMOD.PPConfig["use"] or NADMOD.PlayerCanTouch(ply, ent) or (ent:IsValid() and NADMOD.Props[ent:EntIndex()].Name == "W") then
|
||||
return
|
||||
end
|
||||
return false
|
||||
end
|
||||
hook.Add("PlayerUse", "NADMOD.PlayerUse", NADMOD.PlayerUse)
|
||||
|
||||
--==========================================================--
|
||||
-- Ownership Setting Functions --
|
||||
--==========================================================--
|
||||
|
||||
function NADMOD.PlayerMakePropOwner(ply,ent)
|
||||
if !IsValid(ent) or ent:IsPlayer() then return end
|
||||
if ply:IsWorld() then return NADMOD.SetOwnerWorld(ent) end
|
||||
if !IsValid(ply) or !ply:IsPlayer() then return end
|
||||
NADMOD.Props[ent:EntIndex()] = {
|
||||
Ent = ent,
|
||||
Owner = ply,
|
||||
SteamID = ply:SteamID(),
|
||||
Name = ply:Nick()
|
||||
}
|
||||
NADMOD.PropOwnersSmall[ent:EntIndex()] = ply:Nick()
|
||||
ent.SPPOwner = ply
|
||||
end
|
||||
-- Hook into the cleanup and sbox-limit adding functions to catch most props
|
||||
if(cleanup) then
|
||||
local backupcleanupAdd = cleanup.Add
|
||||
function cleanup.Add(ply, enttype, ent)
|
||||
if IsValid(ent) and ply:IsPlayer() then
|
||||
NADMOD.PlayerMakePropOwner(ply, ent)
|
||||
end
|
||||
backupcleanupAdd(ply, enttype, ent)
|
||||
end
|
||||
end
|
||||
if(metaply.AddCount) then
|
||||
local backupAddCount = metaply.AddCount
|
||||
function metaply:AddCount(enttype, ent)
|
||||
NADMOD.PlayerMakePropOwner(self, ent)
|
||||
backupAddCount(self, enttype, ent)
|
||||
end
|
||||
end
|
||||
hook.Add("PlayerSpawnedSENT", "NADMOD.PlayerSpawnedSENT", NADMOD.PlayerMakePropOwner)
|
||||
hook.Add("PlayerSpawnedVehicle", "NADMOD.PlayerSpawnedVehicle", NADMOD.PlayerMakePropOwner)
|
||||
hook.Add("PlayerSpawnedSWEP", "NADMOD.PlayerSpawnedSWEP", NADMOD.PlayerMakePropOwner)
|
||||
|
||||
function metaent:CPPISetOwnerless(bool)
|
||||
if !IsValid(self) or self:IsPlayer() then return end
|
||||
if(bool) then
|
||||
NADMOD.Props[self:EntIndex()] = {
|
||||
Ent = self,
|
||||
Owner = game.GetWorld(),
|
||||
SteamID = "O",
|
||||
Name = "O"
|
||||
}
|
||||
NADMOD.PropOwnersSmall[self:EntIndex()] = "O"
|
||||
self.SPPOwner = game.GetWorld()
|
||||
else
|
||||
NADMOD.EntityRemoved(self)
|
||||
end
|
||||
end
|
||||
|
||||
function NADMOD.SetOwnerWorld(ent)
|
||||
NADMOD.Props[ent:EntIndex()] = {
|
||||
Ent = ent,
|
||||
Owner = game.GetWorld(),
|
||||
SteamID = "W",
|
||||
Name = "W"
|
||||
}
|
||||
NADMOD.PropOwnersSmall[ent:EntIndex()] = "W"
|
||||
ent.SPPOwner = game.GetWorld()
|
||||
end
|
||||
|
||||
-- Loop through all entities that exist when the map is loaded, these are all "world owned" entities
|
||||
function NADMOD.WorldOwner()
|
||||
local WorldEnts = 0
|
||||
for k,v in pairs(ents.FindByClass("*")) do
|
||||
if(!v:IsPlayer() and (v:EntIndex() == 0 or !NADMOD.Props[v:EntIndex()])) and not IsValid(v.SPPOwner) then
|
||||
if game.GetMap() == "gm_construct" and v:GetClass() == "func_brush" then
|
||||
v:CPPISetOwnerless(true)
|
||||
else
|
||||
NADMOD.SetOwnerWorld(v)
|
||||
end
|
||||
WorldEnts = WorldEnts + 1
|
||||
end
|
||||
end
|
||||
print("Nadmod Prop Protection: "..WorldEnts.." props belong to world")
|
||||
end
|
||||
if CurTime() < 5 then timer.Create("NADMOD.PPFindWorldProps",7,1,NADMOD.WorldOwner) end
|
||||
|
||||
|
||||
function NADMOD.EntityRemoved(ent)
|
||||
NADMOD.Props[ent:EntIndex()] = nil
|
||||
NADMOD.PropOwnersSmall[ent:EntIndex()] = "-"
|
||||
if ent:IsValid() and ent:IsPlayer() and not ent:IsBot() then
|
||||
-- This is more reliable than PlayerDisconnect
|
||||
local steamid, nick = ent:SteamID(), ent:Nick()
|
||||
if NADMOD.PPConfig.autocdp > 0 and (NADMOD.PPConfig.autocdpadmins or not NADMOD.IsPPAdmin(ent)) then
|
||||
timer.Create("NADMOD.AutoCDP_"..steamid, NADMOD.PPConfig.autocdp, 1, function()
|
||||
local count = NADMOD.CleanupPlayerProps(steamid)
|
||||
if count > 0 then NADMOD.Notify(nick.."'s props ("..count..") have been autocleaned.") end
|
||||
end)
|
||||
NADMOD.AutoCDPTimers[nick] = steamid
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("EntityRemoved", "NADMOD.EntityRemoved", NADMOD.EntityRemoved)
|
||||
-- AutoCDP timer removal
|
||||
function NADMOD.ClearAutoCDP( ply, steamid, uniqueid )
|
||||
timer.Remove("NADMOD.AutoCDP_"..steamid)
|
||||
end
|
||||
hook.Add( "PlayerAuthed", "NADMOD.ClearAutoCDP", NADMOD.ClearAutoCDP ) -- This occurs at PlayerInitialSpawn, late
|
||||
hook.Add( "PlayerConnect", "NADMOD.ClearAutoCDP", function(nick, address) -- This occurs early but is unreliable
|
||||
NADMOD.ClearAutoCDP(nil, NADMOD.AutoCDPTimers[nick] or "")
|
||||
end)
|
||||
|
||||
|
||||
|
||||
|
||||
--==========================================================--
|
||||
-- Useful Concommands --
|
||||
--==========================================================--
|
||||
function NADMOD.CleanupPlayerProps(steamid)
|
||||
local count = 0
|
||||
for k,v in pairs(NADMOD.Props) do
|
||||
if(v.SteamID == steamid) then
|
||||
if IsValid(v.Ent) then
|
||||
if !v.Ent:GetPersistent() then
|
||||
v.Ent:Remove()
|
||||
count = count + 1
|
||||
end
|
||||
else
|
||||
NADMOD.EntityRemoved(v.Ent)
|
||||
end
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
function NADMOD.CleanPlayer(tar)
|
||||
if IsValid(tar) and tar:IsPlayer() then
|
||||
local count = NADMOD.CleanupPlayerProps(tar:SteamID())
|
||||
NADMOD.Notify(tar:Nick().."'s props have been cleaned up ("..count..")")
|
||||
end
|
||||
end
|
||||
|
||||
function NADMOD.CleanupProps(ply, cmd, args)
|
||||
local EntIndex = args[1]
|
||||
if not EntIndex or EntIndex == "" then
|
||||
local count = NADMOD.CleanupPlayerProps(ply:SteamID())
|
||||
NADMOD.Notify(ply,"Your props have been cleaned up ("..count..")")
|
||||
elseif !ply:IsValid() or NADMOD.IsPPAdmin(ply) then
|
||||
NADMOD.CleanPlayer(Entity(EntIndex))
|
||||
end
|
||||
end
|
||||
concommand.Add("nadmod_cleanupprops", NADMOD.CleanupProps)
|
||||
|
||||
function NADMOD.CleanPlayerConCommand(ply, cmd, args, fullstr)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
NADMOD.CleanPlayer(NADMOD.FindPlayer(fullstr))
|
||||
end
|
||||
concommand.Add("nadmod_cleanplayer", NADMOD.CleanPlayerConCommand)
|
||||
|
||||
-- Cleans all props whose owner's name contained arg1. nadmod_cleanplayer is better, but only works on online players
|
||||
function NADMOD.CleanName(ply, cmd, args, fullstr)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
if fullstr == "" or fullstr == "W" then return end
|
||||
local tarname = string.lower(fullstr)
|
||||
local count = 0
|
||||
for k,v in pairs(NADMOD.Props) do
|
||||
if IsValid(v.Ent) and string.find(string.lower(v.Name),tarname,1,true) then
|
||||
v.Ent:Remove()
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
NADMOD.Notify(fullstr.."'s props ("..count..") have been cleaned up")
|
||||
end
|
||||
concommand.Add("nadmod_cleanname",NADMOD.CleanName)
|
||||
|
||||
function NADMOD.CDP(ply, cmd, args)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
local count = 0
|
||||
for k,v in pairs(NADMOD.Props) do
|
||||
if not v.Ent:IsValid() then
|
||||
NADMOD.EntityRemoved(v.Ent)
|
||||
elseif not IsValid(v.Owner) and (v.Name != "O" and v.Name != "W") and !v.Ent:GetPersistent() then
|
||||
v.Ent:Remove()
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
NADMOD.Notify("Disconnected players props ("..count..") have been cleaned up")
|
||||
end
|
||||
concommand.Add("nadmod_cdp",NADMOD.CDP)
|
||||
|
||||
function NADMOD.CleanClass(ply,cmd,args)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
if args[1] == "npc_*" then NADMOD.Notify("NPCs have been cleaned up")
|
||||
elseif args[1] == "prop_ragdol*" then NADMOD.Notify("Ragdolls have been cleaned up")
|
||||
else NADMOD.Notify(args[1].." have been cleaned up")
|
||||
end
|
||||
for _,v in ipairs(ents.FindByClass(args[1])) do v:Remove() end
|
||||
end
|
||||
concommand.Add("nadmod_cleanclass", NADMOD.CleanClass)
|
||||
|
||||
function NADMOD.CleanCLRagdolls(ply,cmd,args)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
NADMOD.Notify("Clientside Ragdolls have been cleaned up")
|
||||
net.Start("nadmod_cleanclragdolls") net.Broadcast()
|
||||
game.RemoveRagdolls()
|
||||
end
|
||||
concommand.Add("nadmod_cleanclragdolls", NADMOD.CleanCLRagdolls)
|
||||
|
||||
function NADMOD.CleanWorldRopes(ply,cmd,args)
|
||||
if ply:IsValid() and not NADMOD.IsPPAdmin(ply) then return end
|
||||
NADMOD.Notify("World ropes have been cleaned up")
|
||||
for k,v in pairs(ents.FindByClass("keyframe_rope")) do
|
||||
if v.Ent1 and v.Ent1:IsWorld() and v.Ent2 and v.Ent2:IsWorld() then v:Remove() end
|
||||
end
|
||||
end
|
||||
concommand.Add("nadmod_cleanworldropes", NADMOD.CleanWorldRopes)
|
||||
|
||||
-- Sends a Hint to the player specified
|
||||
-- If only one argument, broadcast to all players
|
||||
function NADMOD.Notify(ply, text)
|
||||
net.Start("nadmod_notify")
|
||||
if not text then
|
||||
net.WriteString(ply)
|
||||
net.Broadcast()
|
||||
print("NADMOD: "..ply)
|
||||
else
|
||||
net.WriteString(text)
|
||||
net.Send(ply)
|
||||
end
|
||||
end
|
||||
|
||||
function NADMOD.DebugTotals(ply,cmd,args)
|
||||
-- Prints out a list of how many props are owned by each player.
|
||||
-- This information is available in the clientside admin panel, but this is nice for rcon
|
||||
if IsValid(ply) then return end -- PrintTable only shows in serverconsole
|
||||
local tab = {}
|
||||
for k,v in pairs(NADMOD.Props) do
|
||||
local name = v.Name
|
||||
if name == "O" then name = "Ownerless"
|
||||
elseif name == "W" then name = "World"
|
||||
elseif not v.SPPOwner:IsValid() then name = "[Disconnected]"..name
|
||||
end
|
||||
tab[name] = (tab[name] or 0) + 1
|
||||
end
|
||||
PrintTable(tab)
|
||||
end
|
||||
concommand.Add("nadmod_totals", NADMOD.DebugTotals)
|
||||
|
||||
|
||||
--=========================================================--
|
||||
-- Clientside Callbacks for the Friends/Options panels --
|
||||
--=========================================================--
|
||||
concommand.Add("npp_refreshconfig",function(ply,cmd,args)
|
||||
if not ply:IsValid() or not NADMOD.IsPPAdmin(ply) then return end
|
||||
net.Start("nadmod_ppconfig")
|
||||
net.WriteTable(NADMOD.PPConfig)
|
||||
net.Send(ply)
|
||||
end)
|
||||
net.Receive("nadmod_ppconfig",function(len,ply)
|
||||
if not ply:IsValid() or not NADMOD.IsPPAdmin(ply) then return end
|
||||
NADMOD.PPConfig = net.ReadTable()
|
||||
NADMOD.Save()
|
||||
NADMOD.Notify(ply, "Settings received!")
|
||||
end)
|
||||
concommand.Add("npp_refreshfriends",function(ply,cmd,args)
|
||||
if not ply:IsValid() then return end
|
||||
local friends = {}
|
||||
if NADMOD.Users[ply:SteamID()] then friends = table.Copy(NADMOD.Users[ply:SteamID()].Friends) or {} end
|
||||
if NADMOD.PPConfig["adminall"] then
|
||||
for _,v in pairs(player.GetAll()) do
|
||||
if NADMOD.IsPPAdmin(v) then friends[v:SteamID()] = true end
|
||||
end
|
||||
end
|
||||
net.Start("nadmod_ppfriends")
|
||||
net.WriteTable(friends)
|
||||
net.Send(ply)
|
||||
end)
|
||||
net.Receive("nadmod_ppfriends",function(len,ply)
|
||||
if not ply:IsValid() then return end
|
||||
if !NADMOD.Users[ply:SteamID()] then NADMOD.Users[ply:SteamID()] = {Rank = 1} end
|
||||
NADMOD.Users[ply:SteamID()].Friends = NADMOD.Users[ply:SteamID()].Friends or {}
|
||||
local outtab = NADMOD.Users[ply:SteamID()].Friends
|
||||
|
||||
local players = {}
|
||||
for _,v in pairs(player.GetAll()) do players[v:SteamID()] = v end
|
||||
|
||||
for steamid,bool in pairs(net.ReadTable()) do
|
||||
if players[steamid] and (not bool or not (NADMOD.IsPPAdmin(players[steamid]) and NADMOD.PPConfig["adminall"])) then -- Users may not add admins to their friends list
|
||||
if bool then outtab[steamid] = true else outtab[steamid] = nil end -- Don't bother storing falses
|
||||
end
|
||||
end
|
||||
NADMOD.Save()
|
||||
NADMOD.Notify(ply, "Friends received!")
|
||||
end)
|
||||
|
||||
function CPPI:GetName() return "Nadmod Prop Protection" end
|
||||
function CPPI:GetVersion() return NADMOD.PPVersion end
|
||||
function metaply:CPPIGetFriends()
|
||||
if not self:IsValid() then return {} end
|
||||
local ret = {}
|
||||
local friends = (NADMOD.Users[self:SteamID()] or {Friends={}}).Friends or {}
|
||||
for _,v in pairs(player.GetAll()) do
|
||||
if NADMOD.IsPPAdmin(v) or friends[v:SteamID()] then table.insert(ret,v) end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
function metaent:CPPIGetOwner() return self.SPPOwner end
|
||||
function metaent:CPPISetOwner(ply) return NADMOD.PlayerMakePropOwner(ply, self) end
|
||||
function metaent:CPPICanTool(ply,mode) return NADMOD.CanTool(ply,{Entity=self},mode) != false end
|
||||
function metaent:CPPICanPhysgun(ply) return NADMOD.PlayerCanTouch(ply,self) == true end
|
||||
function metaent:CPPICanPickup(ply) return NADMOD.GravGunPickup(ply, self) != false end
|
||||
function metaent:CPPICanPunt(ply) return NADMOD.GravGunPickup(ply, self) != false end
|
||||
if E2Lib and E2Lib.replace_function then
|
||||
E2Lib.replace_function("isOwner", function(ply, entity)
|
||||
return NADMOD.PlayerCanTouch(ply,entity)
|
||||
end)
|
||||
end
|
||||
|
||||
print("[NADMOD PP - NADMOD Prop Protection Module v"..NADMOD.PPVersion.." Loaded]")
|
Loading…
Reference in New Issue
Block a user