Di game multiplayer Roblox, skrip anti-cheat sisi klien tidak efektif melawan memory injector modern yang dapat mematikan LocalScript dengan mudah.
Untuk melindungi integritas game, diperlukan arsitektur keamanan otoritatif di server. Dengan menghitung delta-time pergerakan, memproyeksikan raycast penembus dinding, dan menerapkan rubberbanding, kecurangan dapat dicegah total.
1. Mengapa Anti-Cheat Lokal Selalu Gagal
Memahami cara kerja eksploitasi klien pada ekosistem Roblox:
- Eksploitasi Lingkungan Lokal: Fungsi hookmetamethod memungkinkan peretas memodifikasi argumen remote.
- Manipulasi Skrip: Skrip yang berjalan di klien dapat dihentikan atau dihapus sesuka hati.
- Kepemilikan Fisika: Klien memiliki otoritas jaringan atas pergerakan HumanoidRootPart miliknya.
- Prinsip Zero-Trust: Jangan pernah mempercayai data posisi yang dikirim langsung oleh klien.
2. Verifikasi Kecepatan dan Teleportasi di Sisi Server
Mengukur perpindahan per frame tanpa memicu false positive akibat latensi:
- Jarak Delta-Time: Mengukur jarak Euclidean antara posisi sekarang dan posisi valid sebelumnya.
- Batas Kecepatan Dinamis: Toleransi pergerakan dihitung dari WalkSpeed dikali dt ditambah toleransi ping.
- Buffer Anomali: Mengumpulkan poin anomali sebelum memberikan tindakan hukuman.
- Rubberbanding: Membalikkan posisi karakter ke koordinat valid terakhir saat terjadi pelanggaran.
--!strict
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local AntiCheatService = {}
type PlayerRecord = {
lastPosition: Vector3,
lastTick: number,
anomalyBuffer: number,
isFalling: boolean
}
local trackedPlayers: { [Player]: PlayerRecord } = {}
local RAY_PARAMS = RaycastParams.new()
RAY_PARAMS.FilterType = RaycastFilterType.Exclude
function AntiCheatService.InitPlayer(player: Player)
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart") :: BasePart
trackedPlayers[player] = {
lastPosition = hrp.Position,
lastTick = os.clock(),
anomalyBuffer = 0,
isFalling = false
}
end
function AntiCheatService.OnHeartbeat(dt: number)
local now = os.clock()
for player, record in pairs(trackedPlayers) do
local char = player.Character
if not char then continue end
local hrp = char:FindFirstChild("HumanoidRootPart") :: BasePart?
local humanoid = char:FindFirstChildOfClass("Humanoid")
if not hrp or not humanoid or humanoid.Health <= 0 then continue end
local currentPos = hrp.Position
local displacement = (currentPos - record.lastPosition).Magnitude
local maxAllowed = (humanoid.WalkSpeed * dt * 1.35) + 0.5
if displacement > maxAllowed and not record.isFalling then
record.anomalyBuffer += (displacement - maxAllowed)
if record.anomalyBuffer > 15 then
hrp.CFrame = CFrame.new(record.lastPosition)
hrp.AssemblyLinearVelocity = Vector3.zero
record.anomalyBuffer = 0
continue
end
else
record.anomalyBuffer = math.max(0, record.anomalyBuffer - (dt * 5))
end
RAY_PARAMS.FilterDescendantsInstances = { char }
local dir = currentPos - record.lastPosition
if dir.Magnitude > 0.1 then
local hit = Workspace:Raycast(record.lastPosition, dir, RAY_PARAMS)
if hit and hit.Instance and hit.Instance.CanCollide then
hrp.CFrame = CFrame.new(record.lastPosition)
hrp.AssemblyLinearVelocity = Vector3.zero
continue
end
end
record.lastPosition = currentPos
record.lastTick = now
end
end
RunService.Heartbeat:Connect(AntiCheatService.OnHeartbeat)
Players.PlayerAdded:Connect(AntiCheatService.InitPlayer)
return AntiCheatService
3. Pencegahan Noclip dan Menembus Tembok Menggunakan Raycast
Mencegah karakter berjalan menembus dinding padat dan pintu terkunci:
- Uji Lintasan Raycast: Menembakkan berkas raycast antara dua titik pergerakan.
- Kapsul Multi-Ray: Tiga sinar sejajar di kaki, tubuh, dan kepala untuk deteksi akurat.
- Filter Dinamis: Mengabaikan objek tanpa CanCollide agar tidak membebani komputasi.
- Pengecualian Teleportasi: API server khusus untuk memperbarui posisi saat teleport resmi.
4. Kompensasi Ping dan Fluktuasi Jaringan
Menjaga keamanan tanpa mengorbankan kenyamanan pemain berping tinggi:
- Pemantauan RTT: Mengubah ambang batas pergerakan mengikuti fluktuasi ping.
- Penyerapan Paket Burst: Menghadapi paket data seluler yang menumpuk di jaringan.
- Sistem Rollback Server: Riwayat posisi historis untuk validasi tembakan yang adil.
- Pemberitahuan UI: Memberikan peringatan koneksi daripada melakukan kick instan.
5. Arsitektur Produksi Skala Besar & Telemetri
Menerapkan sistem keamanan tanpa menyebabkan penurunan performa server:
- Batching Pemain: Membagi validasi pemain ke dalam frame genap dan ganjil.
- Pencatatan Senyap: Mengirim log anomali ke webhook tanpa memberitahu pembuat cheat.
- Snapshot Replay: Menyimpan riwayat pergerakan beberapa detik sebelum pelanggaran.
- Konfigurasi Mesin: Memanfaatkan RejectCharacterDeletions dan CollisionGroups terisolasi.
Frequently Asked Questions
Mengapa LocalScript tidak aman untuk mendeteksi cheat?
Peretas dapat memanipulasi memori lokal dan menghentikan eksekusi LocalScript secara instan.
Bagaimana sistem menangani knockback atau kendaraan cepat?
Saat server memberikan gaya dorong, batas kecepatan maksimum pemain dinaikkan sementara.
Apakah raycasting di server menyebabkan lag?
50 raycast teroptimasi per frame hanya memakan kurang dari 0.2ms waktu CPU server.