· 5 years ago · Sep 03, 2020, 01:24 AM
1--[[
2ANTI-EXPLOIT FRAMEWORK
3
4By default, it can help protect against No-Clip and Fly exploits
5
6My DevForum post about this Anti-Exploit framework is in this link:
7https://devforum.roblox.com/t/anti-exploit-framework-unknownparabellum/721362
8The post contains a video showcasing it protecting against no-clip and floating in air [fly] hacks
9
10Video:
11https://youtu.be/MXKUL1k0la4
12
13This paste bin is separated into 3 parts,
14-one for the main anti-exploit module script
15-Another module script named "PlayerClass"
16-And lastly, a module script named "FlagClass"
17]]
18
19----------//AntiExploitModule\\----------------
20--[[
21!API REFERENCE!
22This is taken from my Devforum Post,
23https://devforum.roblox.com/t/anti-exploit-framework-unknownparabellum/721362
24
25AntiExploitModule:
26This module manages all players/PlayerClasses.
27Properties:
28
29table AntiExploit.PlayersMonitoring
30This table should contain all PlayerClass’ that the module is monitoring.
31
32table AntiExploit.FlaggedPlayers
33By default, this table contains all players that have more than 5 flags
34
35Functions:
36
37function AntiExploit:Start()
38This function starts the AntiExploit.
39There are 2 key things that happen in this function:
40
411: It connects to the Players.CharacterAdded event and the Players.CharacterRemoving event to add or remove PlayerClass’ objects. These objects are placed into AntiExploit.PlayersMonitoring
422: It starts a while loop that loops through all players that it is monitoring [AntiExploit.PlayersMonitoring] and calls the PlayerClass:Update() function. It also adds players with more than 5 flags into the AntiExploit.FlaggedPlayers.
43PlayerClass
44This Class manages player stats, checking for exploits and punishing players for said exploits.
45Properties:
46
47table PlayerClass.Exploits
48Contains all exploits that are to be checked and punished for.
49
50bool PlayerClass.CanUpdate
51This value determines if the PlayerClass can run PlayerClass:Update() and PlayerClass:UpdateStats()
52
53instance PlayerClass.RootPart
54This value is the player’s HumanoidRootPart
55
56Vector3 PlayerClass.LastPosition
57This value is the Position of the player’s HumanoidRootPart, the last time it updated.
58
59table PlayerClass.Flags
60This table contains all the flags the player has received since they joined
61
62Please note that there are a few more properties however they are much less important
63
64Functions:
65
66function PlayerClass:ResetStats()
67Sets all, except a few values specified in the function, values to nil or an empty table.
68
69function PlayerClass:AddFlag()
70Adds a flag to PlayerClass.Flags
71
72number function PlayerClass:RemoveFlag(FlagTime)
73Removes the flag in PlayerClass.Flags that was made at the FlagTime. [Time is in the same format as tick()]
74
75function PlayerClass:LoadCharacter()
76Respawns the player and changes PlayerClass.CanUpdate to false until the player is added[Assumed]. Also PlayerClass:ResetStats() is called.
77
78function PlayerClass:UpdateStats()
79Updates the PlayerClass information
80
81instance function PlayerClass.new(Player)
82Creates a new PlayerClass object. “Player” parameter must be a player instance.
83
84FlagClass
85This class simply creates a new table with when the flag was made and the reason
86
87Properties:
88
89number FlagClass.TimeOfFlag
90This is the time the flag was made. Time is in tick() format
91
92string FlagClass.Reason
93This is the reason the flag was made. By default, it’s the return message of whatever exploit the module detected.
94
95Functions:
96
97FlagClass.new()
98This creates a new Flag
99
100Adding New Checks and Punishments for Specific Exploits
101To add a new exploit to check and punish for:
102
1031: Add a table to PlayerClass.Exploits. The index of the table should be the name of the exploit you want to protect against.
104Ex:
105PlayerClass.Exploits = {
106 ExploitName = {},
107}
1082: Add 2 methods to your new exploit. One named Check and another named Punish.
109Punish and check should have the player class as a parameter. Check() must return 2 values,
110Passed and ReturnMessage
111Ex:
112
113PlayerClass.Exploits = {
114 ExploitName = {},
115}
116function PlayerClass.Exploits.ExploitName:Check(PlayerObj)
117 local Passed = true
118 local ReturnMessage = ""
119 return Passed,ReturnMessage
120end
121
122function PlayerClass.Exploits.ExploitName:Punish(PlayerObj)
123
124end
125]]
126
127local Players = game:GetService("Players")
128local PlayerClass = require(script.PlayerClass)
129
130local AntiExploit = {}
131AntiExploit.Increment = 0.1
132
133AntiExploit.PlayersMonitoring = {}
134AntiExploit.FlaggedPlayers = {}
135
136function AntiExploit:Start()
137 local WhiteList = {}
138 Players.PlayerAdded:Connect(function(plr)
139 local Obj = PlayerClass.new(plr)
140 AntiExploit.PlayersMonitoring[plr] = Obj
141 end)
142 Players.PlayerRemoving:Connect(function(plr)
143 if AntiExploit[plr] then
144 AntiExploit.PlayersMonitoring[plr] = nil
145 end
146 end)
147
148 while true do
149 wait(self.Increment)
150 for Name,Player in pairs(AntiExploit.PlayersMonitoring)do
151 Player:Update()
152 if #Player.Flags > 5 then
153 if not AntiExploit.FlaggedPlayers[Player.Player] then
154 warn(Player.Player.Name.." has exeeded 5 flags...")
155 AntiExploit.FlaggedPlayers[Player.Player] = Player
156 end
157 end
158 end
159 end
160end
161
162return AntiExploit
163----------//PlayerClass\\----------------
164
165local FlagClass = require(script.Parent.FlagClass)
166
167local PlayerClass = {
168 ["CanUpdate"] = true,
169
170 ["Player"] = nil,
171 ["Head"] = nil,
172 ["RootPart"] = nil,
173 ["TimeStarted"] = nil,
174 ["LastPosition"] = nil,
175 ["InAir"] = nil,
176 ["Flags"] = {},
177}
178PlayerClass.__index = PlayerClass
179
180PlayerClass.Exploits = {
181 NoClip = {},
182 Fly = {
183 MaxTimeInAir = 10
184 },
185}
186
187function PlayerClass.Exploits.NoClip:Check(PlayerObj)--Class
188 local Passed = true
189 local ReturnMessage = ""
190 local RootPos = PlayerObj.RootPart.Position
191 local LastPos = PlayerObj.LastPosition
192
193 local NewRay = Ray.new(LastPos,(RootPos-LastPos).Unit * dist(LastPos,RootPos))
194
195 local Part,Pos = workspace:FindPartOnRay(NewRay,PlayerObj.Player.Character)
196 if Part then
197 if Part.CanCollide == true then
198 Passed = false
199 ReturnMessage = PlayerObj.Player.Name.."'s path went through a wall or something that isn't a descendant of their character. Part:"..Part:GetFullName()
200 end
201 end
202
203 return Passed,ReturnMessage
204end
205
206function PlayerClass.Exploits.NoClip:Punish(PlayerObj)--Class
207 PlayerObj.Player.Character:SetPrimaryPartCFrame(CFrame.new(PlayerObj.LastPosition))
208end
209
210function PlayerClass.Exploits.Fly:Check(PlayerObj)--Class
211 local Passed = true
212 local ReturnMessage = ""
213 local RootPos = PlayerObj.RootPart.Position
214 local LastPos = PlayerObj.LastPosition
215 local BottomPos = RootPos - Vector3.new(0,10,0)
216 local NewRay = Ray.new(RootPos,(BottomPos- RootPos).Unit * dist(BottomPos,RootPos))
217
218 local Part,Pos = workspace:FindPartOnRay(NewRay,PlayerObj.Player.Character)
219 if not Part then
220 PlayerObj.InAir = PlayerObj.InAir or tick()
221 if tick() - PlayerObj.InAir > self.MaxTimeInAir then
222 Passed = false
223 ReturnMessage = PlayerObj.Player.Name.." was in the air for longer than: ".. tostring(self.MaxTimeInAir)
224 end
225 elseif Part then
226 PlayerObj.InAir = nil
227 end
228
229 return Passed,ReturnMessage
230end
231
232function PlayerClass.Exploits.Fly:Punish(PlayerObj)--Class
233 PlayerObj:LoadCharacter()
234end
235
236-----------------------------------------------------------
237
238function dist(Pos1,Pos2)
239 return (Pos1-Pos2).Magnitude
240end
241
242function PlayerClass:AddFlag(Reason)
243 table.insert(self.Flags,
244 FlagClass.new(Reason)
245 )
246end
247
248function PlayerClass:RemoveFlag(FlagTime)
249 for i,v in pairs(self.Flags)do
250 if v.TimeOfFlag == FlagTime then
251 table.remove(self.Flags,i)
252 end
253 end
254end
255
256function PlayerClass:ResetStats()
257 local WhiteList = {
258 ["Player"] = true,
259 ["TimeStarted"] = true,
260 ["Flags"] = true
261 }
262 for Name,Value in pairs(self)do
263 local ValueType = typeof(Value)
264 if ValueType ~= "Function" and not WhiteList[Name] then
265 if ValueType == "Table" then
266 self[Name] = {}
267 else
268 self[Name] = nil
269 end
270 end
271 end
272 warn(self.Player.Name.."'s Data Wiped")
273end
274
275function PlayerClass:LoadCharacter()
276 self.CanUpdate = false
277 self:ResetStats()
278 self.Player:LoadCharacter()
279 self.CanUpdate = true
280 self:UpdateStats()
281end
282
283function PlayerClass:UpdateStats()
284 local Character = self.Player.Character
285 if self.CanUpdate and Character then
286 local PlayerRootPart = Character:FindFirstChild("HumanoidRootPart")
287 local PlayerHead = Character:FindFirstChild("Head")
288
289 self.RootPart = PlayerRootPart
290 self.Head = PlayerHead
291 self.LastPosition = PlayerRootPart.Position
292 end
293end
294
295function PlayerClass:Update()
296 local CurrentPlayer = self.Player
297 local Character = CurrentPlayer.Character
298 if Character then
299 local PlayerRootPart = Character:FindFirstChild("HumanoidRootPart")
300 local PlayerHead = Character:FindFirstChild("Head")
301 if PlayerRootPart and PlayerHead and self.CanUpdate then
302
303 if self.LastPosition then
304 if dist(self.LastPosition,PlayerRootPart.Position) < 1 then
305 return
306 end
307 else
308 self:UpdateStats()
309 end
310
311 self.RootPart = PlayerRootPart --Setting new value
312 self.Head = PlayerHead
313 for Name,Exploit in pairs(self.Exploits)do --Checking for any exploits
314 local Passed,ReturnMessage = Exploit:Check(self)
315 if not Passed then
316 Exploit:Punish(self)
317 self:AddFlag(ReturnMessage)
318 print(#self.Flags)
319 end
320 end
321 self:UpdateStats()
322 elseif not PlayerRootPart or not PlayerHead then
323 self:LoadCharacter()
324 warn(self.Player.Name.." doesn't have an important body part")
325 end
326 end
327end
328
329function PlayerClass.new(Player)
330 assert(Player:IsA("Player"),"Must be a player instance!")
331 return setmetatable({
332 ["CanUpdate"] = true,
333
334 ["Player"] = Player,
335 ["Head"] = nil,
336 ["RootPart"] = nil,
337 ["TimeStarted"] = tick(),
338 ["LastPosition"] = nil,
339 ["Flags"] = {},
340 },PlayerClass)
341end
342
343return PlayerClass
344----------//FlagClass\\----------------
345local Flag = {
346 ["TimeOfFlag"] = nil,
347 ["Reason"] = nil,
348}
349Flag.__index = Flag
350
351function Flag.new(Reason)
352 return setmetatable({
353 ["TimeOfFlag"] = tick(),
354 ["Reason"] = Reason,
355 },Flag)
356end
357
358return Flag
359