Recording hackers (with scripts)

i see youve got it to work, looks really good

Hmm, I can’t get it to work
My script (changed it so it’s only one server script):

-- Services
local DataStoreService = game:GetService("DataStoreService")
local recordStore = DataStoreService:GetDataStore("RecordStore")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

-- Constants
local MAX_CHUNK_SIZE = 500000  -- Define a safe chunk size well below 4MB

-- Variables
local Possessions = {}
local replaying = false
local recording
local regionSize = Vector3.new(50, 50, 50)
local Tracked = {}

-- Unique ID generator
local function generateUniqueId()
	return tostring(math.random(100000, 999999))
end

-- Function to save blocks and players in an area
local function saveBlocksAndPlayersAroundCheater(player)
	local position = player.Character.HumanoidRootPart.Position
	local region = Region3.new(position - (regionSize / 2), position + (regionSize / 2))
	local parts = workspace:FindPartsInRegion3(region, nil, math.huge)
	local frameData = { blocks = {}, players = {} }

	for _, part in ipairs(parts) do
		if part:IsA("BasePart") then
			if not Tracked[part] then
				Tracked[part] = true
			end

			part:SetAttribute("UniqueId", part:GetAttribute("UniqueId") or generateUniqueId())

			table.insert(frameData.blocks, {
				uniqueId = part:GetAttribute("UniqueId"),
				name = part.Name,
				size = {part.Size.X, part.Size.Y, part.Size.Z},
				position = {part.Position.X, part.Position.Y, part.Position.Z},
				rotation = {part.Orientation.X, part.Orientation.Y, part.Orientation.Z},
				color = part.BrickColor.Name,
				material = part.Material.Name,
				transparency = part.Transparency,
				reflectance = part.Reflectance
			})
		end

		if part.Parent:FindFirstChild("Humanoid") then
			local playerName = part.Parent.Name
			if not table.find(frameData.players, playerName) then
				table.insert(frameData.players, playerName)
			end
		end
	end

	return frameData
end

-- Function to disable joints and anchor parts
local function disableJoints(rig)
	for _, v in pairs(rig:GetDescendants()) do
		if v:IsA("JointInstance") then
			if v.Part0.Parent ~= rig or v.Part1.Parent ~= rig then
				continue
			end
			v.Enabled = false
		elseif v:IsA("BasePart") and v.Parent == rig then
			v.Anchored = true
			v.CanCollide = false
		end
	end
end

-- Function to start replay
local function startReplay(currentPossession)
	if recording or replaying or currentPossession > #Possessions then
		return
	end
	replaying = true

	local Models = {}
	local tb = Possessions[currentPossession]

	for part, _ in pairs(Tracked) do
		part.Archivable = true
		local rig = part:Clone()
		rig.Parent = workspace
		disableJoints(rig)
		part.Archivable = false
		Models[part.Name] = rig
	end

	for _, gotPossession in pairs(tb) do
		for character, bodyParts in pairs(gotPossession) do
			if typeof(bodyParts) == "CFrame" then
				Models[character].CFrame = bodyParts
			else
				for i, v in pairs(bodyParts) do
					Models[character][i].CFrame = v
				end
			end
		end
		wait() 
	end

	for _, v in pairs(Models) do
		v:Destroy()
	end

	Models = nil
	replaying = false
end

-- Function to start recording
local function startRecording(player)
	if replaying then return end
	if recording then
		recording:Disconnect()
		recording = nil
		print("Recording stopped")
		return
	end

	Possessions[#Possessions + 1] = {}
	print("Recording started")
	local time = 0

	recording = RunService.Heartbeat:Connect(function()
		local frameData = saveBlocksAndPlayersAroundCheater(player)
		Possessions[#Possessions][time] = frameData
		time += 1
	end)
end

-- Function to split data into chunks for DataStore
local function splitIntoChunks(data)
	local jsonData = game:GetService("HttpService"):JSONEncode(data)
	local chunks = {}

	for i = 1, #jsonData, MAX_CHUNK_SIZE do
		local chunk = jsonData:sub(i, math.min(i + MAX_CHUNK_SIZE - 1, #jsonData))
		table.insert(chunks, chunk)
	end

	return chunks
end

-- Function to save the recording to DataStore in chunks
local function saveRecording(name)
	local success, err = pcall(function()
		local chunks = splitIntoChunks(Possessions)

		-- Save each chunk with a unique key
		for i, chunk in ipairs(chunks) do
			recordStore:SetAsync(name .. "_Chunk_" .. i, chunk)
		end

		-- Save the number of chunks
		recordStore:SetAsync(name .. "_Meta", { chunkCount = #chunks })
	end)

	if success then
		print("Recording saved as", name)
	else
		warn("Error saving recording:", err)
	end
end

-- Function to load the recording from DataStore in chunks
local function loadRecording(name)
	local success, data = pcall(function()
		local meta = recordStore:GetAsync(name .. "_Meta")
		if not meta then
			warn("No metadata found for recording:", name)
			return nil
		end

		local chunks = {}
		for i = 1, meta.chunkCount do
			local chunk = recordStore:GetAsync(name .. "_Chunk_" .. i)
			if chunk then
				table.insert(chunks, chunk)
			end
		end

		-- Concatenate all chunks and decode JSON
		local jsonData = table.concat(chunks)
		return game:GetService("HttpService"):JSONDecode(jsonData)
	end)

	if success then
		Possessions = data or {}
		print("Recording loaded:", name)
	else
		warn("Error loading recording:", data)
	end
end

-- Chat commands for saving and loading
Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		local command, arg = string.match(message, "/(%w+)%s?(.*)")
		if command == "saverecording" then
			saveRecording(arg)
		elseif command == "loadrecording" then
			loadRecording(arg)
		elseif command == "startrecording" then
			startRecording(player)
		elseif command == "stoprecording" then
			if recording then
				recording:Disconnect()
				recording = nil
				print("Recording stopped")
			end
		end
	end)
end)

Thanks!

Forgot to say the error, It prints everything (to record, stop, save, load), but it never loads and plays the thing recorded @makeitxx

This is a horrible idea lol. Really popular games on Roblox just run basic server sided checks on objectives in your game that need to be protected. You can narrow your anti cheat down to something as basic as a player having too much of an item or a statistic which is always 1000% trackable. This is just totally unnecessary. Example: Instead of recording a video of a cheater using fly hacks in an obby with 1000 checkpoints, you can just check how long it took them to finish the 1000 checkpoints and if they completed it too quickly you can kick and/or ban them.

It’s because it’s a better way to make sure there’s no false positives. I wish roblox had cursing

i was replying to his post based on his concept. its obvious im already aware of all that lol. i would do it that way as well

1 Like

Just so you all know I’m still going to use an anti cheat, I’m making this so I can check if they were actually cheating. Also It’s for inappropriate/rule breaking people in my game not just hackers.

1 Like