Menu
CoddyTech

Jangan Pernah Percaya pada Client

Pelajaran 7 dari 18 dalam kursus Game Roblox: Simulator Hewan Peliharaan di Coddy.

Pemain mengendalikan perangkatnya sendiri, jadi pelaku eksploitasi bisa membuat perangkat itu memicu remote apa pun, dengan cara apa pun, dari mana pun, secepat yang mereka mau. Hit:FireServer(pile) dari seberang peta, seratus kali per detik, akan mengosongkan setiap tumpukan dalam game.

Jadi, server memeriksa setiap permintaan sebelum bertindak:

  • itu adalah tumpukan sungguhan (sebuah Instance di workspace.Piles),
  • pemain berada dalam jarak Settings.Reach darinya,
  • dan setidaknya Settings.HitCooldown detik telah berlalu sejak pukulan terakhir mereka.
if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
	return
end

Saat kamu menekan Periksa, pengujian akan melakukan hal-hal yang akan dilakukan pelaku eksploitasi. Aturan untuk setiap remote yang kamu tulis: client meminta, server memutuskan.

challenge icon

Tantangan

Sedang

Di PetServer, di awal handler Hit, lakukan return tanpa memukul jika:

  1. pile bukan Instance di piles,
  2. pemain tidak memiliki karakter, atau HumanoidRootPart-nya berjarak lebih dari Settings.Reach stud dari pile,
  3. pemain memukul kurang dari Settings.HitCooldown detik yang lalu (letakkan local lastHit = {} di dekat bagian atas, dan catat time() saat pukulan diizinkan).

Tekan Play, lalu Check: pemeriksaan menjalankan exploiter.

Coba sendiri

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local remotes = game.ReplicatedStorage.Remotes
local piles = workspace.Piles
local pileSpot = {} -- setiap tumpukan -> lokasi tempat tumpukan itu berada

print("A Meadow pile gives " .. Settings.PileValue .. " coins")

-- Setiap pemain mendapat Coins di papan peringkat
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local coins = Instance.new("IntValue")
	coins.Name = "Coins"
	coins.Parent = leaderstats
end)

-- Tumpukan koin di suatu lokasi: salinan ServerStorage.CoinPile dengan kesehatannya
-- dan nilainya sebagai atribut
local function spawnPile(spot)
	local pile = ServerStorage.CoinPile:Clone()
	pile.Position = spot.Position
	pile:SetAttribute("MaxHealth", Settings.PileHealth)
	pile:SetAttribute("Health", Settings.PileHealth)
	pile:SetAttribute("Value", Settings.PileValue)
	pileSpot[pile] = spot
	pile.Parent = piles
	return pile
end

-- Setiap pukulan mengurangi kesehatan tumpukan sebesar 1;
-- saat mencapai 0, tumpukan hancur dan memberikan nilainya
local function hitPile(player, pile)
	local health = pile:GetAttribute("Health") - 1
	if health > 0 then
		pile:SetAttribute("Health", health)
		return
	end
	player.leaderstats.Coins.Value += pile:GetAttribute("Value")
	local spot = pileSpot[pile]
	pileSpot[pile] = nil
	pile:Destroy()
	-- tumpukan baru di lokasi yang sama, beberapa detik kemudian
	task.delay(Settings.RespawnTime, spawnPile, spot)
end

-- Satu tumpukan di setiap lokasi di Meadow
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
	spawnPile(spot)
end

-- client meminta untuk memukul tumpukan
remotes.Hit.OnServerEvent:Connect(function(player, pile)
	hitPile(player, pile)
end)
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Game Roblox: Simulator Hewan Peliharaan

Latihan sendiri: Playground Roblox