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.

2 Likes

@targetframed @makeitxx I made it!!! It still has issues and I’m going to add these features

  1. Include all instances
  2. Make gui
  3. Add the anti cheat into it (or make it so I can call it in anti cheat)
  4. Add delete/library system
    please suggest more ideas
    https://youtu.be/ukP3wYiWTfY
1 Like

This is great, I love the idea of it I’m working on a anti cheat myself for my new game and I had some struggles with ideas and I saw this post this would help me a lot and it’s actually pretty smart as well but in terms of performance etc I’m just worried about that

1 Like

It should not be impacting performance at all. Stuff like citadel and chickynoid is going to impact performance because it is doing something totally unnecessary. That is ultimately Roblox’s job to prevent those things from occurring. Our jobs as developers is to protect what we need to. You should ask yourself what is the main objective of the game? That is what you need to be worried about. You can detect fly, noclip, walkspeed, infinite jump, but remember, all it takes is 1 of those cheats to work for them to gain an advantage. If your main objective is to kill a boss with 1 million HP, how long would it take a legitimate player to kill that boss? Sure, exploiter can fly around and infinite jump, but guess what? All of it is completely useless if you kick players who beat it too quickly… so all you have to do is protect your main objective and protect the data stores in your game, and let exploiters do as they wish! There’s nothing to be afraid about them doing those things as it won’t help them or benefit them even in the slightest. Whether they use 1 cheat, or 100 cheats, those cheats should not be helping them gain an advantage whatsoever, but it will if you choose citadel or chickynoid because those are not protecting anything important and only preventing cheats from occurring. So they could practically beat the game in 2 seconds and win instead of being kicked for that.

1 Like

I mean yeah your right, it wouldn’t affect the performance and protecting your games main objectives is true as well, only reason I’d implement this would be for farming or botting

1 Like

I learned how to do this from a friendly developer who took a 12 week, full time paid opportunity to become a software engineer at Roblox. All you have to do is set up a leaderboard that detects the statistics of players and ban the ones whose statistics are suspicious. You can always put your discord and ask them to contact you there for further investigation. You set up a remote event logging history that logs how quickly each player fires remote events, and in your investigation if you find the player appealing fired remote events in a way that doesn’t align with legitimate players, you politely tell them why they got banned and then ban them from your discord server and keep them banned from the Roblox game and investigate any potential alt accounts they may be linked to.

citadel in no way prevents injection or execution via garbage collection

2 Likes

It’s detects injections, I saw someone do it and I sent a hacker message in their discord

i’m NOT going to bypass citadel just to know what it’s using for detections

???
what are you babbling about

2 Likes

Obsidian is the owner of citadel anti cheat. Obsidian wasn’t saying it doesn’t detect SOME injections, rather was saying it doesn’t detect SOME injections through garbage collection. It does detect SOME of them but not the way you might think and Obsidian doesn’t want people trying to make false claims as to how it works.

2 Likes