Bringing in uclip

The only change was info.txt -> addon.txt. Also fixed an outdated email address in UPS.
This commit is contained in:
Nayruden 2012-11-03 16:16:52 -04:00
commit 16bedb5bf0
5 changed files with 391 additions and 0 deletions

17
addon.txt Normal file
View File

@ -0,0 +1,17 @@
"AddonInfo"
{
"name" "Uclip"
"version" "1.22"
"up_date" "00/00/00"
"author_name" "Team Ulysses and Ryno-SauruS"
"author_email" "megiddo@ulyssesmod.net"
"author_url" "http://ulyssesmod.net/"
"info" ""
// Won't be active unless the following GCFs are available and
// are mounted
"GCFRequires"
{
}
}

29
lua/autorun/cl_uclip.lua Normal file
View File

@ -0,0 +1,29 @@
-- Written by Team Ulysses, http://ulyssesmod.net/
module( "Uclip", package.seeall )
if not CLIENT then return end
-- This function checks the protector to see if ownership has changed from what we think it is. Notifies player for c-side prediction too.
function updateOwnership( ply, ent )
if noProtection then return end -- No point on going on
if not ent.Uclip then ent.Uclip = {} end -- Initialize table
end
-- Here's where the server notifies us of a new passable state. We need this for c-side prediction
function rcvOwnershipUpdate( um )
local ent = um:ReadEntity()
if not ent or not ent:IsValid() then return end
updateOwnership( LocalPlayer(), ent ) -- So it sets up the table if we don't have it already
local owns = um:ReadBool()
if owns == false then -- More convienent to store as nil, takes less memory!
owns = nil
end
ent.Uclip[ LocalPlayer() ] = owns
end
usermessage.Hook( "UclipOwnershipUpdate", rcvOwnershipUpdate )
function rcvNoProtection( um )
noProtection = true
end
usermessage.Hook( "UclipNoProtection", rcvNoProtection )

215
lua/autorun/sh_uclip.lua Normal file
View File

@ -0,0 +1,215 @@
-- Originally written by Team Ulysses, http://ulyssesmod.net/
-- Garry-bug workaround by Ryno-SauruS. Thanks a ton!
AddCSLuaFile( "autorun/sh_uclip.lua" )
AddCSLuaFile( "autorun/cl_uclip.lua" )
module( "Uclip", package.seeall )
------------
-- Config --
------------
maxrecurse = 4 -- Max recurses. Recursion is used when we need to test a new velocity.
-- Should rarely recurse more than twice or else objects are probably wedged together.
-- (We have checks for wedged objects too so don't worry about it). 0 = disable (not recommended but shouldn't have any problems)
maxloop = 50 -- Max loops. We need to loop to find objects behind other objects. 0 = infinite (not recommended but shouldn't have any problems)
-- This *could* open an exploit, but users would be hard pressed to use it... so we'll see.
--------------------------------------------------------
-- End config. DO NOT MODIFY ANYTHING BELOW THIS LINE!--
--------------------------------------------------------
-- This checks to see if a certain player should be able to go through everything or not.
local cvar_help = "Lets admins noclip through everything if enabled."
local uclip_ignore_admins = CreateConVar( "uclip_ignore_admins", 1, { FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY }, cvar_help )
function adminCheck( ply )
if not uclip_ignore_admins:GetBool() then return false end
if ulx and ply:query( "ulx noclip" ) then
return true
elseif ply:IsAdmin() or ply:IsSuperAdmin() then
return true
end
return false
end
noProtection = false -- If there's no protection whatsoever, this is flagged.
-- We need this flag because with a protector, we default to _not_ being able to go through things.
-- This flag saves us major memory/bandwidth when there's no protection
function checkOwnership( ply, ent )
if ent:IsPlayer() or ent:IsNPC() then return true end -- Let players go through other players and npcs (too problematic otherwise)
if noProtection then return true end -- No protection, they own everything.
updateOwnership( ply, ent ) -- Make sure server and the client are current.
return ent.Uclip[ ply ] -- This is flagged by updateOwnership. True if they own it, nil otherwise.
end
-- Check if a player is stuck in an object or in the world.
-- Returns true and ent they're stuck on if they're stuck.
function isStuck( ply, filter )
local ang = ply:EyeAngles()
local directions = {
ang:Right(),
ang:Right() * -1,
ang:Forward(),
ang:Forward() * -1,
ang:Up(),
ang:Up() * -1,
}
local ents = {}
local t = {}
t.start = ply:GetPos()
t.filter = filter
-- Check if they're stuck by checking each direction. A minimum number of directions should hit the same object if they're stuck.
for _, dir in ipairs( directions ) do
t.endpos = ply:GetPos() + dir
local tr = util.TraceEntity( t, ply )
if tr.Entity:IsValid() and tr.HitPos == tr.StartPos then
ents[ tr.Entity ] = ents[ tr.Entity ] or 0
ents[ tr.Entity ] = ents[ tr.Entity ] + 1
end
end
for ent, hits in pairs( ents ) do
if hits >= 4 then
return true, ent
end
end
return false
end
-- This function allows us to get the player's *attempted* velocity (incase we're overriding their *actual* velocity).
local sv_noclipspeed = GetConVar( "sv_noclipspeed" )
function getNoclipVel( ply )
local noclipspeed = sv_noclipspeed:GetFloat() * 100
local forward = ply:KeyDown( IN_FORWARD )
local back = ply:KeyDown( IN_BACK )
local left = ply:KeyDown( IN_MOVELEFT )
local right = ply:KeyDown( IN_MOVERIGHT )
local jump = ply:KeyDown( IN_JUMP )
local duck = ply:KeyDown( IN_DUCK )
local speed = ply:KeyDown( IN_SPEED )
-- Convert the input to numbers so we can perform arithmetic on them, to make the code smaller and neater.
local forwardnum = forward and 1 or 0
local backnum = back and 1 or 0
local leftnum = left and 1 or 0
local rightnum = right and 1 or 0
local jumpnum = jump and 1 or 0
local ducknum = duck and 1 or 0
local speednum = speed and 1 or 0
local vel = Vector( 0, 0, 0 )
vel = vel + ( ply:EyeAngles():Forward() * ( forwardnum - backnum ) ) -- Forward and back
vel = vel + ( ply:EyeAngles():Right() * ( rightnum - leftnum ) ) -- Left and right
vel = vel + ( Vector( 0, 0, 1 ) * jumpnum ) -- Up
vel = vel:GetNormalized()
vel = vel * noclipspeed
if duck then
vel = vel / 10
end
if speed then
vel = vel * 3
end
return vel
end
-- Given a velocity, normalized velocity, and a normal:
-- Calculate the velocity toward the wall and remove it so we can "slide" across the wall.
function calcWallSlide( vel, normal )
local toWall = normal * -1
local velToWall = vel:Dot( toWall ) * toWall
return vel - velToWall
end
local override_velocity -- This will be set as the current desired velocity, so we can later perform the movement manually.
function zeromove()
override_velocity = Vector( 0, 0, 0 )
end
-- The brain of Uclip, this makes sure they can move where they want to.
function checkVel( ply, move, vel, recurse, hitnorms )
if vel == Vector( 0, 0, 0 ) then return end -- No velocity, don't bother.
local ft = FrameTime()
local veln = vel:GetNormalized()
hitnorms = hitnorms or {} -- This is used so we won't process the same normal more than once. (IE, we don't get a wedge where we have to process velocity to 0)
recurse = recurse or 0 -- Keep track of how many recurses
recurse = recurse + 1
if recurse > maxrecurse and maxrecurse > 0 then -- Hard break
zeromove()
return
end
local t = {}
t.start = ply:GetPos()
t.endpos = ply:GetPos() + vel * ft + veln -- Add an extra unit in the direction they're headed just to be safe.
t.filter = { ply }
local tr = util.TraceEntity( t, ply )
local loops = 0
while tr.Hit do -- Recursively check all the hits. This is so we don't miss objects behind another object.
loops = loops + 1
if maxloop > 0 and loops > maxloop then
zeromove()
return
end
if tr.HitWorld or ( tr.Entity:IsValid() and (tr.Entity:GetClass() == "prop_dynamic" or (not checkOwnership( ply, tr.Entity ) and not isStuck( ply, t.filter ))) ) then -- If world or a prop they don't own that they're not stuck inside. Ignore prop_dynamic due to crash.
local slide = calcWallSlide( vel, tr.HitNormal )
override_velocity = slide
if table.HasValue( hitnorms, tr.HitNormal ) then -- We've already processed this normal. We can get this case when the player's noclipping into a wedge.
zeromove()
return
end
table.insert( hitnorms, tr.HitNormal )
return checkVel( ply, move, slide, recurse, hitnorms ) -- Return now so this func isn't left on stack
end
if tr.Entity and tr.Entity:IsValid() then -- Ent to add!
table.insert( t.filter, tr.Entity )
end
tr = util.TraceEntity( t, ply )
end
end
local sbox_noclip = GetConVar( "sbox_noclip" )
function move( ply, move )
if ply:GetMoveType() ~= MOVETYPE_NOCLIP then return end
if sbox_noclip:GetInt() == 2 then return end -- This allows servers to disable UClip by setting sbox_noclip to 2.
if adminCheck( ply ) then return end -- They can go through everything..
local ft = FrameTime()
local vel = getNoclipVel( ply ) -- How far are they trying to move this frame?
override_velocity = vel
checkVel( ply, move, vel )
if override_velocity ~= Vector( 0, 0, 0 ) then
move:SetOrigin( move:GetOrigin() + ( override_velocity * ft ) ) -- This actually performs the movement.
end
move:SetVelocity( override_velocity ) -- This doesn't actually move the player (thanks to garry), it just allows other code to detect the player's velocity.
return true -- Completely disable any engine movement, because we're doing it ourselves.
end
hook.Add( "Move", "UclipMove", move, ULib and 15 or nil ) -- If ULib is installed then set a low priority in its hook priority system.

49
lua/autorun/sv_uclip.lua Normal file
View File

@ -0,0 +1,49 @@
-- Written by Team Ulysses, http://ulyssesmod.net/
module( "Uclip", package.seeall )
if not SERVER then return end
hasCPPI = false -- Common Prop Protection Interface to check for ownership
-- We'll check status of protectors in this init
function initUclip()
hasCPPI = (type( CPPI ) == "table")
if not hasCPPI then
noProtection = true
umsg.Start( "UclipNoProtection" ) -- In case there's anyone connected right now.
umsg.End()
end
end
hook.Add( "Initialize", "UclipInitialize", initUclip )
-- Tell them there's no prop protection in the event there isn't.
function initialSpawn( ply )
if noProtection then
umsg.Start( "UclipNoProtection", ply )
umsg.End()
end
end
hook.Add( "PlayerInitialSpawn", "UclipInitialSpawn", initialSpawn )
-- This function checks the protector to see if ownership has changed from what we think it is. Notifies player for c-side prediction too.
function updateOwnership( ply, ent )
if noProtection then return end -- No point on going on
if not ent.Uclip then ent.Uclip = {} end -- Initialize table
local owns
if hasCPPI then
owns = ent:CPPICanPhysgun( ply )
end
if owns == false then -- More convienent to store as nil, takes less memory and bandwidth!
owns = nil
end
if ent.Uclip[ ply ] ~= owns then
ent.Uclip[ ply ] = owns
umsg.Start( "UclipOwnershipUpdate", ply )
umsg.Entity( ent )
umsg.Bool( owns )
umsg.End()
end
end

81
readme.txt Normal file
View File

@ -0,0 +1,81 @@
Title: Uclip Readme
*Uclip v1.22 (released 00/00/00)*
Uclip is a noclip alternative. By this we mean it's similar but different in the fact that you can't noclip
through anything but your own props (If you're running a prop protection). So, you can't noclip through the
world or through others' props. Admins can still noclip through everything.
Visit our homepage at <http://ulyssesmod.net/>.
You can talk to us on our forums at <http://forums.ulyssesmod.net/> or on our steam community, ULX <http://steamcommunity.com/groups/ULX>.
Group: Authors
Uclip is brought to you by..
* Brett "Megiddo" Smith - Contact: <megiddo@ulyssesmod.net>
* Ryno-SauruS
Group: Requirements
Uclip has no requirements, but it is recommended you use it with a supported prop protector. Supported protectors are below...
* UPS (recommended!)
* Simple Prop Protection
* FPP
* Anything else that supports CPPI (contact the mod author)
Group: Installation
To install Uclip, simply extract the files from the archive to your garrysmod/addons folder.
When you've done this, you should have a file structure like this--
<garrysmod>/addons/uclip/lua/autorun/sh_uclip.lua
etc..
Please note that installation is the same on dedicated servers.
You absolutely, positively have to do a full server restart after installing the files. A simple map
change will not cut it!
Group: Config
There is minimal config inside sh_uclip.lua but you will need basic knowledge of lua to use it.
Group: Changelog
v1.22 - *(00/00/00)*
* [FIX] garry breakages
v1.21 - *(06/10/11)*
* [FIX] Exploit where users could come through the bottom of props by moving slowly.
v1.20 - *(12/12/10)*
* [ADD] uclip_ignore_admins cvar.
* [FIX] Added a workaround for garry's broken movement system. This was added by Ryno-SauruS. Give him many thanks!
* [REMOVE] Hacks for hooking into (now way outdated) prop protectors. CPPI is adequate for our purposes.
v1.13 - *(04/21/08)*
* [ADD] Support for CPPI
v1.12 - *(12/04/07)*
* [FIX] +moveup/+movedown exploit
v1.11 - *(12/04/07)*
* [CHANGE] Wall slide calculation is now much faster
* [ADD] sbox_noclip 2 will now enables global "regular" noclip
v1.10 - *(08/27/07)*
* [ADD] Support for EPS and Simple Prop Protection
* [FIX] Now treats all prop_dynamic's like a wall. This means you won't be able to go through any door made by door mod. (Sorry! Gmod problem forced our hand.)
v1.00 - *(08/08/07)*
* Initial version
Group: License
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to
Creative Commons
543 Howard Street
5th Floor
San Francisco, California 94105
USA