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.Reachdarinya, - dan setidaknya
Settings.HitCooldowndetik telah berlalu sejak pukulan terakhir mereka.
if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
return
endSaat kamu menekan Periksa, pengujian akan melakukan hal-hal yang akan dilakukan pelaku eksploitasi. Aturan untuk setiap remote yang kamu tulis: client meminta, server memutuskan.
Tantangan
SedangDi PetServer, di awal handler Hit, lakukan return tanpa memukul jika:
- pile bukan Instance di
piles, - pemain tidak memiliki karakter, atau
HumanoidRootPart-nya berjarak lebih dariSettings.Reachstud dari pile, - pemain memukul kurang dari
Settings.HitCooldowndetik yang lalu (letakkanlocal lastHit = {}di dekat bagian atas, dan catattime()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)
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Game Roblox: Simulator Hewan Peliharaan
2Client dan Server
Koin di LayarLatihan sendiri: Playground Roblox