Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --//AntiExploitModule [Main]
- --[[
- █████╗ ███╗ ██╗████████╗██╗ ███████╗██╗ ██╗██████╗ ██╗ ██████╗ ██╗████████╗
- ██╔══██╗████╗ ██║╚══██╔══╝██║ ██╔════╝╚██╗██╔╝██╔══██╗██║ ██╔═══██╗██║╚══██╔══╝
- ███████║██╔██╗ ██║ ██║ ██║█████╗█████╗ ╚███╔╝ ██████╔╝██║ ██║ ██║██║ ██║
- ██╔══██║██║╚██╗██║ ██║ ██║╚════╝██╔══╝ ██╔██╗ ██╔═══╝ ██║ ██║ ██║██║ ██║
- ██║ ██║██║ ╚████║ ██║ ██║ ███████╗██╔╝ ██╗██║ ███████╗╚██████╔╝██║ ██║
- ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝
- \\ version: 1/31/2021 //
- For more Information Please Look At My DevForum Post About It:
- https://devforum.roblox.com/t/anti-exploit-framework-unknownparabellum/721362/32
- //How To Get Started\\
- 1.Create a new Script
- 2.Move the Script to ServerScriptStorage
- 3.Copy and paste this into the script:
- local AntiExploit = require(script.AntiExploitModule)
- AntiExploit:Start()
- 4. And after that you are set!
- ]]
- local RunService = game:GetService("RunService")
- local Players = game:GetService("Players")
- local PlayerClass = require(script.PlayerClass)
- local Utils = require(script.Utils)
- local ThreadUtil = Utils.ThreadUtil
- local Maid = Utils.Maid
- local AntiExploit = {}
- AntiExploit.PlayersMonitoring = {}
- AntiExploit.FlaggedPlayers = {}
- AntiExploit.Config = {
- ["Increment"] = 0.05,
- }
- AntiExploit._maid = Maid.new()
- AntiExploit.Started = false
- function AntiExploit:AddPlayer(plr) --Adds a player to PlayersMonitoring, queueing them up to be monitored
- --Here is where you should add any exceptions for Admins.
- local obj = PlayerClass.new(plr)
- self.PlayersMonitoring[plr.Name] = obj
- self._maid[plr.UserId] = obj
- end
- function AntiExploit:RemovePlayer(plr)
- self._maid[plr.UserId] = nil
- self.PlayersMonitoring[plr.Name] = nil
- self.FlaggedPlayers[plr.Name] = nil
- end
- function AntiExploit:Start()
- if self.Started then
- warn("Anti-Exploit Already Started")
- return
- end
- self.Started = true
- print("Started Anti Exploit")
- for _,plr in pairs(Players:GetPlayers())do
- self:AddPlayer(plr)
- end
- self._maid["PlayerAdded"] = Players.PlayerAdded:Connect(function(plr)
- self:AddPlayer(plr)
- end)
- self._maid["PlayerRemoved"] = Players.PlayerRemoving:Connect(function(plr)
- self:RemovePlayer(plr)
- end)
- self._maid["RepeatingChecks"] = ThreadUtil.DelayRepeat(self.Config.Increment,
- function()
- for name,player in pairs(AntiExploit.PlayersMonitoring)do
- player:Update()
- if player.Flags.NumberOfFlags > 5 then
- if not AntiExploit.FlaggedPlayers[player.Info.Name] then
- warn(player.Info.Name.." has exeeded 5 flags...")
- AntiExploit.FlaggedPlayers[player.Info.Name] = player
- end
- end
- end
- end
- )
- end
- function AntiExploit:Stop()
- if not self.Started then
- warn("Anti-Exploit Already Stopped")
- return
- end
- self.Started = false
- warn("Anti-Exploit Stopped")
- self._maid:DoCleaning()
- self.PlayersMonitoring = {}
- self.FlaggedPlayers = {}
- end
- return AntiExploit
- ----------//PlayerClass\\----------------
- local FlagClass = require(script.Parent.FlagClass)
- local ExploitChecks = require(script.ExploitChecks)
- local Utils = require(script.Parent.Utils)
- local ThreadUtil = Utils.ThreadUtil
- local Maid = Utils.Maid
- local PlayerClass = {}
- PlayerClass.__index = PlayerClass
- local function dist(Pos1,Pos2)
- return (Pos1-Pos2).Magnitude
- end
- function PlayerClass:AddFlag(Reason)
- local flag = FlagClass.new(Reason)
- self.Flags[flag.Id] = flag
- self.Flags.NumberOfFlags += 1
- end
- function PlayerClass:RemoveFlag(id)
- self.Flags[id] = nil
- self.Flags.NumberOfFlags -= 1
- end
- function PlayerClass:ResetStats(resetMessage,shouldWarn)
- resetMessage = resetMessage or "No Message Given"
- local info = self.Info
- if info.LastReset and info.LastChecked then
- if (info.LastReset>info.LastChecked) then
- return
- end
- end
- local whiteList = {
- ["Name"] = true,
- ["Player"] = true,
- }
- for name,val in pairs(info)do
- local valType = typeof(val)
- if not whiteList[name] then
- if valType == "table" then
- info[name] = {}
- else
- info[name] = nil
- end
- end
- end
- info.LastReset = tick()
- if not shouldWarn then
- warn(info.Name.."'s Data Wiped Because: "..resetMessage)
- end
- end
- function PlayerClass:UpdateStats()
- local clientInfo = self.Info
- local Character = clientInfo.Player.Character
- if self.CanUpdate and Character then
- local rootPart = Character:FindFirstChild("HumanoidRootPart")
- local head = Character:FindFirstChild("Head")
- clientInfo.LastChecked = tick()
- clientInfo.RootPart = rootPart
- clientInfo.Head = head
- clientInfo.LastPosition = rootPart.Position
- end
- end
- function StopPlayer(Character)
- ThreadUtil.Spawn(function()
- for _, Part in pairs(Character:GetDescendants()) do
- if Part:IsA("BasePart")then
- if Part:CanSetNetworkOwnership() then
- Part:SetNetworkOwner(nil)
- end
- Part.Anchored = true
- end
- end
- end)
- ThreadUtil.Delay(5,function()
- for _, Part in pairs(Character:GetDescendants()) do
- if Part:IsA("BasePart")then
- Part.Anchored = false
- if Part:CanSetNetworkOwnership() then
- Part:SetNetworkOwner(game.Players:GetPlayerFromCharacter(Character))
- end
- end
- end
- end)
- end
- function PlayerClass:Update()
- local clientInfo = self.Info
- local client = clientInfo.Player
- local character = client.Character
- if character and self.CanUpdate then
- local rootPart = character:FindFirstChild("HumanoidRootPart")
- local playerHead = character:FindFirstChild("Head")
- if rootPart and playerHead then
- if clientInfo.LastPosition then
- if dist(clientInfo.LastPosition,rootPart.Position) < 0.3 then
- return
- end
- else
- self:UpdateStats()
- end
- clientInfo.RootPart = rootPart --Setting new value
- clientInfo.Head = playerHead
- for _,exploit in pairs(ExploitChecks)do --Checking for any exploits
- local Passed,ReturnMessage = exploit:Check(self)
- if not Passed then
- exploit:Punish(self)
- self:AddFlag(ReturnMessage)
- StopPlayer(character)
- warn(ReturnMessage)
- break
- end
- end
- self:UpdateStats()
- elseif not rootPart or not playerHead then
- self.Info.Player:LoadCharacter()
- warn(self.Info.Player.Name.." doesn't have an important body part")
- end
- end
- end
- function PlayerClass.new(Player)
- local self = setmetatable({
- ["Flags"] = {["NumberOfFlags"] = 0,},
- ["TimeStarted"] = tick(),
- ["CanUpdate"] = true,
- ["Info"] = {
- ["Name"] = Player.Name,
- ["Player"] = Player,
- ["Humanoid"] = nil, --This is so we know what you can usually index
- ["Head"] = nil,
- ["RootPart"] = nil,
- ["LastPosition"] = nil,
- ["LastChecked"] = nil,
- ["LastUpdated"] = nil,
- },
- ["_maid"] = Maid.new(),
- ["_state"] = true,
- },PlayerClass)
- self._maid["CharacterChanged"] = Player.CharacterAdded:Connect(function(Char)
- local Root = Char:WaitForChild("HumanoidRootPart")
- if self._maid["CFrameChanged"] then
- self._maid["CFrameChanged"] = nil
- end
- self._maid["CFrameChanged"] = Root:GetPropertyChangedSignal("CFrame"):Connect(function()
- self.CanUpdate = false
- self:ResetStats(Player.Name.." CFrame changed because of the Server",true)
- ThreadUtil.Delay(3,
- function()
- self.CanUpdate = true
- end
- )
- end)
- if Root then
- self.CanUpdate = true
- self:UpdateStats()
- end
- end)
- self._maid["CharacterRemoved"] = Player.CharacterRemoving:Connect(function(Char)
- self.CanUpdate = false
- end)
- return self
- end
- function PlayerClass:Destroy()
- self._maid:DoCleaning()
- end
- return PlayerClass
- ----------//FlagClass\\----------------
- local HttpService = game:GetService("HttpService")
- local Flag = {}
- Flag.__index = Flag
- function Flag.new(Reason)
- return setmetatable({
- ["TimeOfFlag"] = tick(),
- ["Reason"] = Reason,
- ["Id"] = HttpService:GenerateGUID(false)
- },Flag)
- end
- return Flag
- ---//Utils\\---
- --// Assorted Util modules
- local utils = {}
- setmetatable(utils,{ --Lazy loads Utils
- __index = function(tbl,index)
- local util = require(script[index])
- tbl[index] = util
- return util
- end,
- })
- return utils
Add Comment
Please, Sign In to add comment