FiveM Entity Lockdown คืออะไร ป้องกัน Client Spawn Entity อย่างไร
FiveM Entity Lockdown คือระบบของ OneSync ที่ให้ Server กำหนดได้ว่า Client สามารถสร้าง Networked Entity เช่น Vehicle, Ped หรือ Object ภายใน Routing Bucket ได้มากน้อยแค่ไหน โดยสามารถใช้ร่วมกับ Server-created Entities เพื่อทำให้ Server เป็นผู้ควบคุมการ Spawn Entity มากขึ้น
ตัวอย่างเช่นกำหนด Bucket 10 เป็น strict
SetRoutingBucketEntityLockdownMode(
10,
'strict'
)
แล้วย้าย Player เข้า Bucket นั้น
SetPlayerRoutingBucket(
source,
10
)
เมื่อเป็น strict เอกสาร Cfx.re ปัจจุบันระบุว่า Client จะไม่สามารถสร้าง Entity ใน Bucket นั้นได้
แนวคิดจึงเปลี่ยนจาก
Client
↓
Spawn Vehicle เอง
↓
Server รับรู้ภายหลัง
เป็น
Client
↓
ขอ Spawn Vehicle
↓
Server ตรวจสอบ
↓
Server อนุญาตหรือปฏิเสธ
↓
Server สร้าง Vehicle
↓
OneSync Sync ไป Client
นี่เป็นแนวทางสำคัญสำหรับ Server ที่ต้องการลดปัญหา Client Spawn รถ, Ped หรือ Object โดยไม่ได้รับอนุญาต
แต่ต้องเข้าใจว่า Entity Lockdown ไม่ใช่ Anti-Cheat สำเร็จรูป และไม่ได้แทน Server-side Validation ของ Money, Inventory, Permission หรือ Network Events
① FiveM Entity Lockdown คืออะไร
Entity Lockdown คือ Policy ระดับ Routing Bucket ที่ควบคุมการสร้าง Entity จาก Client
ตัวอย่าง
Bucket 0
→ inactive
Bucket 100
→ strict
Bucket 200
→ relaxed
แต่ละ Instance สามารถใช้ Policy ต่างกันได้
นี่ทำให้ Server ไม่จำเป็นต้องใช้ Security Policy เดียวกันกับทุก Gameplay Mode
② Entity Lockdown อยู่ในระบบอะไร
Entity Lockdown เป็น Feature ของ
OneSync
+
Routing Buckets
ดังนั้นก่อนใช้ต้องมี OneSync/State Awareness ทำงานอยู่
ตัวอย่าง server.cfg
set onesync on
Resource ที่ต้องใช้ OneSync โดยตรงยังสามารถประกาศ
dependency '/onesync'
ใน fxmanifest.lua
③ Entity Lockdown ป้องกันอะไร
เป้าหมายหลักคือจำกัด
Client-authored Entities
เช่น Client พยายามสร้าง
Vehicle
Ped
Object
ผ่าน Game/Script Networking
Server สามารถกำหนด Bucket ให้เข้มงวดขึ้นเพื่อไม่อนุญาตการสร้าง Entity ลักษณะนั้น
④ Entity Lockdown ป้องกันรถโกง Spawn ได้ไหม
ช่วยลดช่องทาง Client-created Network Entities ได้อย่างมาก โดยเฉพาะเมื่อใช้ strict
ตัวอย่างคนโกงพยายามสร้าง
Adder
Tank
Helicopter
Random Objects
NPC
ภายใน Bucket ที่เป็น strict
Network Entity Creation จาก Client จะถูก Block ตาม Policy
แต่ยังต้องมี Security ชั้นอื่นสำหรับ Events และ Server Actions
⑤ Function หลักคืออะไร
ใช้
SetRoutingBucketEntityLockdownMode(
bucketId,
mode
)
ตัวอย่าง
SetRoutingBucketEntityLockdownMode(
100,
'strict'
)
Parameter คือ
bucketId
→ Routing Bucket
mode
→ Lockdown Policy
⑥ Entity Lockdown Mode มีอะไรบ้าง
เอกสาร OneSync ปัจจุบันระบุ Mode หลัก
full
strict
relaxed
inactive
แต่ full มีข้อจำกัดเฉพาะ FiveM บน GTAV Enhanced
สำหรับ Server ทั่วไป Concept ที่เจอบ่อยที่สุดคือ
strict
relaxed
inactive
⑦ strict คืออะไร
strict เป็น Mode ที่เข้มงวดมาก
เอกสาร Cfx.re ระบุว่า
strict
→ Clients สร้าง Entities ไม่ได้
ดังนั้น Entity ที่ต้องการใช้ใน Bucket นี้ควรให้ Server เป็นผู้สร้าง
เหมาะกับระบบแบบ
Client Request
↓
Server Validate
↓
Server Spawn
⑧ relaxed คืออะไร
เอกสารปัจจุบันอธิบาย relaxed ว่า Block เฉพาะ Script-owned Entities ที่ Client สร้าง
จึงเปิดกว้างกว่า strict
เหมาะกับ Server ที่ต้องการเพิ่มข้อจำกัดบางส่วน แต่ยังมี Resource ที่ต้องพึ่ง Client Entity Creation อยู่
⑨ inactive คืออะไร
inactive หมายถึง Entity Lockdown ไม่ทำงานในลักษณะที่จำกัด Client Creation
Concept คือ
Client
→ สามารถสร้าง Entity ได้ตามระบบปกติ
เหมาะกับ Compatibility สูง แต่ Server ต้องพึ่ง Security Layer อื่นมากขึ้น
⑩ full คืออะไร
เอกสาร OneSync ปัจจุบันระบุ Mode
full
สำหรับ FiveM บน GTAV Enhanced เท่านั้น
Mode นี้เพิ่มการปิด Dummy Object Creation ตามระบบ Enhanced
หากไม่ได้ใช้งาน GTAV Enhanced ไม่ควรนำ Mode นี้มาใช้โดยไม่ตรวจ Environment
⑪ Mode ไหนปลอดภัยที่สุด
ถ้ามองเฉพาะการจำกัด Client-created Entity
strict
เป็นตัวเลือกที่เข้มมากสำหรับ FiveM ปกติ
แต่คำว่า “ปลอดภัยที่สุด” ไม่ได้หมายความว่าเปิดแล้ว Resource ทุกตัวจะทำงานได้
Compatibility ต้องตรวจด้วย
⑫ ทำไม strict อาจทำ Script พัง
เพราะ FiveM Resource จำนวนหนึ่งยังใช้ Client เป็นผู้สร้าง Entity
เช่น
CreateVehicle(...)
CreatePed(...)
CreateObject(...)
จาก Client
ถ้า Bucket เป็น strict
Entity Creation เหล่านี้อาจถูก Block
ดังนั้นก่อนเปิด Production ต้อง Audit Resource
⑬ Resource ประเภทไหนมักได้รับผล
ตัวอย่าง
Garage
Vehicle Shop
Job Vehicle
NPC Script
Prop System
Housing
Furniture
Carry Objects
Police Objects
Mechanic Props
ถ้า Resource เหล่านี้ Spawn Network Entity จาก Client ต้องตรวจ Architecture ก่อนใช้ strict
⑭ วิธีตรวจว่า Resource Spawn Entity ฝั่งไหน
ค้นหา Code เช่น
CreateVehicle
CreatePed
CreateObject
CreateObjectNoOffset
จากนั้นตรวจว่าอยู่ใน
client.lua
หรือ
server.lua
อย่าดูแค่ชื่อ Function เพราะ FiveM มี Client/Server Native Variants และ RPC Behavior ต่างกัน
⑮ Architecture ที่เหมาะกับ strict
แนวทางที่ดีคือ
Client
↓
Request
↓
Server
↓
Validation
↓
Server-side Entity Creation
↓
State Bag / Network ID
↓
Client
Client ทำหน้าที่ขอ
Server ทำหน้าที่ตัดสินและสร้าง
⑯ ตัวอย่าง Vehicle Spawn แบบเดิม
Client
local vehicle =
CreateVehicle(
model,
x,
y,
z,
heading,
true,
true
)
ถ้า Server ใช้ Strict Lockdown Client-authored Entity แบบนี้อาจถูก Block
Resource จึงต้องปรับ Architecture หาก Vehicle ต้อง Network
⑰ ตัวอย่าง Spawn ผ่าน Server
Client
TriggerServerEvent(
'garage:requestVehicle',
vehicleId
)
Server
RegisterNetEvent(
'garage:requestVehicle',
function(vehicleId)
local src = source
-- validate vehicleId
-- validate ownership
-- validate garage
-- validate cooldown
end
)
หลัง Validation จึงสร้างรถ
⑱ Server-created Vehicle ใช้อะไร
หนึ่งใน API ที่ Cfx.re แนะนำคือ
CreateVehicleServerSetter(
modelHash,
vehicleType,
x,
y,
z,
heading
)
ตัวอย่าง
local vehicle =
CreateVehicleServerSetter(
joaat('sultan'),
'automobile',
215.0,
-810.0,
30.0,
157.0
)
จากนั้นนำ Entity เข้า Bucket เดียวกับ Player
⑲ Vehicle ต้องย้ายเข้า Bucket ด้วย
สมมติ Player อยู่
Bucket 100
หลัง Server สร้าง Vehicle แล้วควร
SetEntityRoutingBucket(
vehicle,
100
)
ไม่เช่นนั้น Player กับ Vehicle อาจอยู่คนละ Routing Context
⑳ ตัวอย่าง strict Bucket แบบพื้นฐาน
local bucket = 100
SetRoutingBucketEntityLockdownMode(
bucket,
'strict'
)
SetRoutingBucketPopulationEnabled(
bucket,
false
)
SetPlayerRoutingBucket(
source,
bucket
)
ตอนนี้ Player อยู่ใน Instance ที่ Client Entity Creation ถูกจำกัดอย่างเข้มงวด
㉑ ทำไม Cfx.re Example ปิด Population ด้วย
ถ้า Bucket เป็น strict และต้องการ Controlled Environment การปิด Population ช่วยไม่ให้ระบบ Ambient Population สร้างสิ่งที่ไม่ต้องการใน Instance
ใช้
SetRoutingBucketPopulationEnabled(
bucket,
false
)
เหมาะกับ
Character Selection
Mission
Private Lobby
Training
Controlled Scene
㉒ strict ต้องปิด Population เสมอไหม
ไม่จำเป็นเสมอไป
Entity Lockdown กับ Population เป็นคนละ Setting
Lockdown
→ Client Entity Creation
Population
→ Ambient Population Management
สามารถเลือกตาม Gameplay
แต่ Controlled Mission มักปิด Population เพื่อให้ World State Predictable มากขึ้น
㉓ Entity Lockdown ใช้ได้เฉพาะ Bucket 0 ไหม
ไม่
จุดเด่นคือกำหนดต่อ Routing Bucket
เช่น
SetRoutingBucketEntityLockdownMode(
0,
'inactive'
)
SetRoutingBucketEntityLockdownMode(
100,
'strict'
)
SetRoutingBucketEntityLockdownMode(
200,
'relaxed'
)
แต่ละ World/Instance มี Policy ต่างกันได้
㉔ Main World ควร strict ไหม
ขึ้นกับ Resource Architecture ทั้ง Server
ถ้า Server Resources ทั้งหมดรองรับ Server-created Entity และไม่มี Feature ที่จำเป็นต้องสร้าง Network Entity จาก Client ก็สามารถพิจารณา Policy ที่เข้มได้
แต่การเปิด strict ใน Bucket 0 โดยไม่ Audit Resources ก่อนอาจทำให้ระบบจำนวนมากพังพร้อมกัน
㉕ เริ่มจาก Private Bucket ดีกว่าไหม
สำหรับการ Migration Server เก่า วิธีที่ปลอดภัยกว่าคือเริ่มทดลองกับ Controlled Instance
เช่น
Character Selection
Mission Test
Training Bucket
ตั้งเป็น strict
แล้วตรวจ Resource Behavior
เมื่อ Architecture พร้อมค่อยขยาย Policy
㉖ Entity Lockdown เป็น Global Setting ไหม
ไม่ใน API นี้
เป็น
Per Routing Bucket
จึงสามารถกำหนด Security Context ได้ละเอียด
นี่เป็นข้อดีมากสำหรับ Server ที่มีหลาย Gameplay Systems
㉗ Client รู้ Bucket ID แล้วหลบ Lockdown ได้ไหม
ไม่ควรพึ่ง Bucket ID เป็น Security Secret
Server เป็นผู้กำหนดว่า Player อยู่ Bucket ไหน
Client ไม่ควรสามารถเปลี่ยน Bucket เองตามใจ
ดังนั้น Security Flow คือ
Server controls Bucket
+
Server controls Lockdown Mode
ไม่ใช่ซ่อนหมายเลข Bucket
㉘ อย่าเปิด Event ให้ Client ตั้ง Bucket เอง
ตัวอย่างอันตราย
RegisterNetEvent(
'bucket:set',
function(bucket)
SetPlayerRoutingBucket(
source,
bucket
)
end
)
Client อาจขอเข้า Bucket ที่
relaxed
inactive
Private
Admin
Mission อื่น
แล้วหลีกเลี่ยง Policy ที่ตั้งใจไว้
㉙ วิธีที่ถูกต้อง
Client ส่ง Business Request
TriggerServerEvent(
'mission:join',
missionId
)
Server
ตรวจ Mission
↓
ตรวจ Membership
↓
หา Bucket
↓
Set Player Bucket
Client ไม่ได้เป็นคนเลือก Routing Security Policy
㉚ strict ป้องกัน TriggerServerEvent โกงไหม
ไม่
นี่เป็นคนละ Layer
Entity Lockdown ป้องกันด้าน
Client Entity Creation
แต่ Network Event อย่าง
TriggerServerEvent(
'money:add',
999999
)
ยังต้อง Secure ด้วย Server Validation
ดังนั้นต้องมีทั้ง
Entity Lockdown
+
Secure Events
㉛ strict ป้องกัน GiveMoney Cheat ไหม
ไม่โดยตรง
ถ้า Serverมี Event
RegisterNetEvent(
'reward',
function(amount)
AddMoney(
source,
amount
)
end
)
คนโกงยังสามารถพยายาม Abuse Event ได้
Entity Lockdown ไม่เกี่ยวกับ Economy Validation
㉜ strict ป้องกัน Spawn จาก Server Event ที่ไม่ปลอดภัยไหม
ไม่
สมมติ Serverมี
RegisterNetEvent(
'spawn:anyVehicle',
function(model)
CreateVehicleServerSetter(
joaat(model),
'automobile',
...
)
end
)
แม้ Bucket เป็น strict
Client ยังสามารถพยายาม Trigger Event นี้ได้
และ Server เป็นผู้สร้าง Entity ให้เอง
ดังนั้น Event ต้องมี
Permission
Model Allowlist
Cooldown
Position Validation
State Validation
ด้วย
㉝ Entity Lockdown ไม่แทน Allowlist
ถ้า Client ขอ Vehicle
rhino
lazer
adder
Server ต้องมี Allowlist
local AllowedVehicles = {
sultan = 'automobile',
blista = 'automobile'
}
แล้วตรวจ
local vehicleType =
AllowedVehicles[model]
if not vehicleType then
return
end
ก่อน Spawn
㉞ Model ควรมาจาก Server หรือ Client
ถ้าระบบรู้ล่วงหน้าว่าจะ Spawn รุ่นไหน ให้ Serverกำหนดเองจะดีที่สุด
ตัวอย่าง Mission
ไม่จำเป็นต้อง Client ส่ง
model = sultan
ถ้า Config ฝั่ง Serverรู้อยู่แล้ว
local model =
MissionConfig.vehicle
ลด Untrusted Input
㉟ Entity Lockdown กับ Vehicle Shop
Flow ที่ดี
Player ซื้อรถ
↓
Server ตรวจ Account
↓
Server ตรวจ Database
↓
สร้าง Vehicle Record
↓
Server Create Vehicle
↓
Set Routing Bucket
↓
Set State Bag
↓
ส่ง Network ID
Client ไม่ต้อง Spawn Network Vehicle เอง
㊱ Entity Lockdown กับ Garage
Client
ขอเบิกรถ ID 521
Server ตรวจ
รถมีจริงไหม?
เจ้าของตรงไหม?
รถถูกเก็บอยู่ไหม?
Garage ถูกต้องไหม?
Player อยู่ใกล้ Garage ไหม?
Cooldown ผ่านไหม?
แล้วจึง Create Entity
นี่เป็น Architecture ที่เข้ากับ strict ได้ดี
㊲ Entity Lockdown กับ Job Vehicle
Serverรู้ Job ของ Player อยู่แล้ว
Flow
Client Request Job Vehicle
↓
Server ตรวจ Job
↓
ตรวจ Duty
↓
ตรวจ Grade
↓
Server เลือก Model
↓
Create Vehicle
Client ไม่ควรส่ง
job = police
grade = 10
model = whatever
แล้ว Serverเชื่อทั้งหมด
㊳ Entity Lockdown กับ Props
ระบบ Police อาจสร้าง
Cone
Barrier
Spike Strip
แทนให้ Client Create Object แบบ Networked โดยตรง
Client สามารถส่ง
ขอวาง cone
Serverตรวจ
Job
Duty
Position
Rate Limit
จำนวน Props ที่วางแล้ว
แล้ว Serverสร้าง Object
ช่วยควบคุม Object Spam ได้มากขึ้น
㊴ ต้อง Rate Limit Entity Spawn ไหม
ควรสำหรับ Event ที่สามารถสร้าง Entity
แม้ Serverตรวจ Model แล้ว แต่ Client อาจ Spam
100 Requests / second
จน Serverสร้าง Entityจำนวนมาก
ดังนั้นควรมี
Cooldown
Rate Limit
Per-player Entity Limit
Global Limit
ตามระบบ
㊵ ตัวอย่าง Spawn Cooldown
local cooldowns = {}
local function canSpawn(src)
local now =
os.time()
local last =
cooldowns[src] or 0
if now - last < 5 then
return false
end
cooldowns[src] =
now
return true
end
ก่อน Spawn
if not canSpawn(src) then
return
end
เป็นเพียง Pattern เบื้องต้น
㊶ จำกัดจำนวน Entity ต่อ Player
สามารถเก็บ
local PlayerEntities = {}
ตัวอย่าง
PlayerEntities[src] =
PlayerEntities[src] or {}
ก่อน Spawn ตรวจ
if #PlayerEntities[src]
>= 5 then
return
end
ช่วยลด Spam แม้ Request ผ่าน Cooldown
㊷ ต้อง Cleanup Entity ด้วย
Security ไม่ควรจบตอน Spawn
ต้องคิด Lifecycle
Spawn
↓
Use
↓
Mission End
↓
Delete
ถ้า Player Spawn ได้ทีละคันแต่รถเก่าไม่เคยถูกลบ Server ก็ยังสะสม Entity ต่อไปได้
㊸ playerDropped ต้อง Cleanup ไหม
สำหรับ Temporary Entities ควรพิจารณา
AddEventHandler(
'playerDropped',
function()
local src =
source
-- cleanup temporary entities
end
)
อย่าปล่อย Job Vehicles หรือ Mission Props ค้างหลัง Player ออกจาก Server
㊹ Entity Lockdown กับ Entity Ownership
สองระบบนี้ไม่เหมือนกัน
Entity Lockdown
→ ใครสามารถ Author/Create Entity
ส่วน
Entity Ownership
→ Client ใดกำลังควบคุม Network Simulation
แม้ Vehicle ถูก Serverสร้างภายใต้ Strict Bucket
Client ก็ยังสามารถเป็น Network Owner ในภายหลังได้
㊺ strict แปลว่า Client ไม่มี Entity Control เลยไหม
ไม่
strict จำกัด Entity Creation
ไม่ได้หมายความว่า Client จะไม่เป็น Network Owner ของ Server-created Entity
เมื่อ Vehicle ถูก Sync ไป Client ระบบ OneSync Ownership ยังทำงานตามปกติ
ต้องแยก
Creation Authority
ออกจาก
Network Simulation Ownership
㊻ Server-created Vehicle ยังขับได้ไหม
ได้ตาม Gameplay
Server สร้าง Vehicle ไม่ได้หมายความว่า Client ใช้ Vehicle ไม่ได้
Player ยังสามารถ
เข้า
ขับ
Interact
รับ Network Ownership
ตามระบบ FiveM
Strict Lockdown เพียงป้องกันไม่ให้ Client Author Entity Creation เอง
㊼ NetworkRequestControlOfEntity ยังเกี่ยวไหม
เกี่ยวกับ Existing Entity Control
ไม่ใช่ Entity Creation
ดังนั้นแม้ strict Client อาจยังมี Network Control Behavior กับ Entities ที่มีอยู่ตาม OneSync
Server Security ยังสามารถพิจารณา
sv_filterRequestControl
เพื่อจำกัด Control Requests เพิ่มเติม
㊽ Entity Lockdown กับ sv_filterRequestControl ต่างกันอย่างไร
จำง่าย ๆ
Entity Lockdown
→ ใครสร้าง Entity ได้
sv_filterRequestControl
→ Client ขอ Control Entity ได้แค่ไหน
ใช้แก้คนละปัญหา
Server Security ระดับสูงอาจใช้ทั้งสองร่วมกัน
㊾ Entity Lockdown กับ State Bag
Server-created Entity สามารถมี State Bag
Entity(vehicle).state:set(
'garage:owner',
src,
true
)
หรือ
Entity(vehicle).state:set(
'mission:id',
missionId,
true
)
ช่วยส่ง Runtime State ไป Relevant Clients
แต่ State Bag ไม่ใช่ Permission System โดยอัตโนมัติ
㊿ sv_stateBagStrictMode ใช้ร่วมได้ไหม
ได้ใน Architecture ที่ Resource รองรับ
set sv_stateBagStrictMode true
ตามเอกสารปัจจุบันจะทำให้เฉพาะ Server สามารถแก้ State Bags ได้
ดังนั้นสามารถมีแนวคิด
Entity Creation
→ Server only ผ่าน strict
State Bag Writing
→ Server only ผ่าน strict mode
ทำให้ Server Authority แข็งแรงขึ้น
แต่ต้อง Audit Resource Compatibility ก่อน
51 Controlled Mission Architecture
ตัวอย่าง Mission แบบควบคุมเข้ม
Bucket 100
↓
Entity Lockdown = strict
Population = false
Player
↓
Request Mission
Server
↓
Validate
↓
Create Vehicle
↓
Create Peds
↓
Create Objects
↓
Set Bucket
↓
Set State Bags
Client ทำหน้าที่แสดงผลและควบคุม Gameplay ที่ Serverอนุญาต
52 Character Selection ควรใช้ strict ไหม
เป็น Use Case ที่เหมาะมาก
Character Selection มักต้องการ
ไม่มี Traffic
ไม่มี Random NPC
ไม่มี Client Spawn
จึงสามารถตั้ง
SetRoutingBucketEntityLockdownMode(
bucket,
'strict'
)
SetRoutingBucketPopulationEnabled(
bucket,
false
)
เพื่อให้ Environment ควบคุมง่าย
53 Private Lobby ใช้ strict ได้ไหม
ได้เช่นกัน
ถ้า Lobby ไม่ต้องการ Client-created Entities
Lobby
↓
strict
↓
population off
แล้ว Serverสร้างเฉพาะ Entity ที่ Lobby ต้องการ
ช่วยลด State ที่ไม่แน่นอน
54 Entity Lockdown กับ Interior
Lockdown Policy ผูกกับ Routing Bucket
แต่ต้องจำว่า Cfx.re ไม่แนะนำ Routing Buckets เป็น Solution ทั่วไปสำหรับ Interior
ดังนั้นอย่าสร้าง Bucket ใหม่สำหรับทุก Interior เพียงเพื่อใช้ Lockdown โดยไม่พิจารณา Interior Architecture
55 Debug ว่า Client Spawn ถูก Block หรือไม่
สร้าง Test Bucket
Server
RegisterCommand(
'lockdown',
function(source)
if source <= 0 then
return
end
local bucket =
9000
SetRoutingBucketEntityLockdownMode(
bucket,
'strict'
)
SetRoutingBucketPopulationEnabled(
bucket,
false
)
SetPlayerRoutingBucket(
source,
bucket
)
end,
true
)
จากนั้นทดสอบ Resource ที่ Client Spawn Entity
อย่าทดลองบน Production Main Bucket ก่อนรู้ผลกระทบ
56 Command กลับ Main World
RegisterCommand(
'unlocktest',
function(source)
if source <= 0 then
return
end
SetPlayerRoutingBucket(
source,
0
)
end,
true
)
ช่วยให้ Admin ออกจาก Test Bucket ได้
อย่าลืม Cleanup Test Entities ด้วย
57 ตรวจ Player Bucket ก่อน Spawn
Server Event
local bucket =
GetPlayerRoutingBucket(
src
)
จากนั้นใช้ Bucket นี้กับ Entity
SetEntityRoutingBucket(
vehicle,
bucket
)
ไม่ควรให้ Client ส่ง Bucket ID มาเอง
58 ตัวอย่าง Secure Server Vehicle Spawn
local AllowedVehicles = {
sultan = 'automobile',
blista = 'automobile'
}
local cooldowns = {}
RegisterNetEvent(
'vehicle:requestSpawn',
function(model)
local src =
source
if type(model)
~= 'string' then
return
end
local vehicleType =
AllowedVehicles[model]
if not vehicleType then
return
end
local now =
os.time()
local last =
cooldowns[src] or 0
if now - last < 5 then
return
end
cooldowns[src] =
now
local ped =
GetPlayerPed(src)
if ped == 0 then
return
end
local coords =
GetEntityCoords(ped)
local heading =
GetEntityHeading(ped)
local bucket =
GetPlayerRoutingBucket(
src
)
local vehicle =
CreateVehicleServerSetter(
joaat(model),
vehicleType,
coords.x + 5.0,
coords.y,
coords.z,
heading
)
if vehicle == 0 then
return
end
SetEntityRoutingBucket(
vehicle,
bucket
)
SetEntityOrphanMode(
vehicle,
2
)
end
)
Client ขอ Spawn
แต่ Server ตัดสินทุกอย่างสำคัญ
59 Checklist เปิด Entity Lockdown
ก่อนเปิด strict ตรวจ
① OneSync เปิดหรือยัง?
② Bucket ไหนต้องการ Lockdown?
③ Resource ใดสร้าง Vehicle ฝั่ง Client?
④ Resource ใดสร้าง Ped ฝั่ง Client?
⑤ Resource ใดสร้าง Object ฝั่ง Client?
⑥ Entity เหล่านั้นควรย้ายมาสร้าง Server-side หรือไม่?
⑦ ใช้ CreateVehicleServerSetter ได้หรือไม่?
⑧ Server Event Spawn มี Allowlist หรือไม่?
⑨ ตรวจ Permission หรือยัง?
⑩ ตรวจ Job/Grade หรือยัง?
⑪ ตรวจ Position หรือยัง?
⑫ มี Rate Limit หรือไม่?
⑬ จำกัดจำนวน Entity หรือไม่?
⑭ Entity ถูก Set Bucket ถูกต้องหรือไม่?
⑮ Population ต้องปิดหรือไม่?
⑯ Entity Cleanup ถูกออกแบบหรือไม่?
⑰ playerDropped Cleanup หรือไม่?
⑱ Resource พึ่ง Client-created Props หรือไม่?
⑲ Network Ownership ถูกแยกจาก Creation Authority หรือไม่?
⑳ sv_filterRequestControl ต้องปรับหรือไม่?
㉑ State Bags มี Client-written State หรือไม่?
㉒ sv_stateBagStrictMode เหมาะหรือไม่?
㉓ Test ใน Bucket แยกก่อน Production หรือยัง?
⑥⓪ ตัวอย่าง Entity Lockdown System แบบสมบูรณ์
ตัวอย่างนี้สร้าง Private Instance ที่
Entity Lockdown = strict
Population = off
Server เป็นผู้ Spawn Vehicle
Client เลือก Model ได้เฉพาะ Allowlist
server.lua
local nextBucket =
5000
local PlayerBuckets = {}
local PlayerVehicles = {}
local AllowedVehicles = {
sultan = 'automobile',
blista = 'automobile'
}
local function createSecureBucket(
src
)
nextBucket =
nextBucket + 1
local bucket =
nextBucket
SetRoutingBucketEntityLockdownMode(
bucket,
'strict'
)
SetRoutingBucketPopulationEnabled(
bucket,
false
)
SetPlayerRoutingBucket(
src,
bucket
)
PlayerBuckets[src] =
bucket
return bucket
end
เข้า Secure Instance
RegisterNetEvent(
'secureInstance:enter',
function()
local src =
source
if PlayerBuckets[src] then
return
end
if GetPlayerRoutingBucket(src)
~= 0 then
return
end
createSecureBucket(
src
)
end
)
Request Vehicle
RegisterNetEvent(
'secureInstance:spawnVehicle',
function(model)
local src =
source
if type(model)
~= 'string' then
return
end
local vehicleType =
AllowedVehicles[model]
if not vehicleType then
return
end
local bucket =
PlayerBuckets[src]
if not bucket then
return
end
if GetPlayerRoutingBucket(src)
~= bucket then
return
end
local oldVehicle =
PlayerVehicles[src]
if oldVehicle
and DoesEntityExist(
oldVehicle
) then
DeleteEntity(
oldVehicle
)
end
local ped =
GetPlayerPed(src)
if ped == 0 then
return
end
local coords =
GetEntityCoords(ped)
local heading =
GetEntityHeading(ped)
local vehicle =
CreateVehicleServerSetter(
joaat(model),
vehicleType,
coords.x + 4.0,
coords.y,
coords.z,
heading
)
if vehicle == 0 then
return
end
SetEntityRoutingBucket(
vehicle,
bucket
)
SetEntityOrphanMode(
vehicle,
2
)
Entity(vehicle).state:set(
'secureInstance:vehicle',
true,
true
)
PlayerVehicles[src] =
vehicle
local netId =
NetworkGetNetworkIdFromEntity(
vehicle
)
TriggerClientEvent(
'secureInstance:vehicleCreated',
src,
netId
)
end
)
ออกจาก Instance
local function leaveInstance(
src
)
local vehicle =
PlayerVehicles[src]
PlayerVehicles[src] =
nil
if vehicle
and DoesEntityExist(
vehicle
) then
DeleteEntity(
vehicle
)
end
PlayerBuckets[src] =
nil
SetPlayerRoutingBucket(
src,
0
)
end
RegisterNetEvent(
'secureInstance:leave',
function()
leaveInstance(
source
)
end
)
Disconnect Cleanup
AddEventHandler(
'playerDropped',
function()
local src =
source
local vehicle =
PlayerVehicles[src]
PlayerVehicles[src] =
nil
PlayerBuckets[src] =
nil
if vehicle
and DoesEntityExist(
vehicle
) then
DeleteEntity(
vehicle
)
end
end
)
Flow ทั้งระบบคือ
Player
↓
ขอเข้า Secure Instance
↓
Server Allocate Bucket
↓
strict Lockdown
↓
Population Off
↓
Player เข้า Bucket
↓
Client ขอ Vehicle
↓
Server Allowlist
↓
Server Validation
↓
Server Create Vehicle
↓
Vehicle เข้า Bucket
↓
OneSync Replicate
↓
Client ใช้งาน
↓
Leave / Disconnect
↓
Cleanup
นี่คือพื้นฐานของ Server-authoritative Entity Creation ที่ใช้ Entity Lockdown ได้อย่างมีประสิทธิภาพ
คำถามที่พบบ่อยเกี่ยวกับ FiveM Entity Lockdown
FiveM Entity Lockdown คืออะไร
คือ OneSync Feature ที่กำหนดว่า Client สามารถสร้าง Entity ใน Routing Bucket ได้มากน้อยแค่ไหน
ใช้ Function อะไร
ใช้
SetRoutingBucketEntityLockdownMode(
bucket,
mode
)
strict คืออะไร
ไม่อนุญาตให้ Clients สร้าง Entity ใน Bucket นั้น
relaxed คืออะไร
ตามเอกสารปัจจุบัน จะ Block Script-owned Entities ที่ Client สร้าง แต่เปิดกว้างกว่า strict
inactive คืออะไร
Client สามารถสร้าง Entity ได้ตามปกติ ไม่มี Lockdown ในลักษณะที่ Mode อื่นกำหนด
full คืออะไร
Mode สำหรับ FiveM บน GTAV Enhanced ที่เกี่ยวกับการปิด Dummy Object Creation เพิ่มเติม
strict ป้องกัน Client Spawn รถได้ไหม
ช่วย Block Client-authored Entity Creation ใน Bucket นั้น
strict ป้องกัน TriggerServerEvent Cheat ไหม
ไม่ Network Events ต้อง Secure Server-side แยกต่างหาก
strict ป้องกัน Money Cheat ไหม
ไม่โดยตรง
strict ทำให้ Client ขับรถไม่ได้ไหม
ไม่ Server-created Vehicle ยังสามารถถูก Sync และใช้งานโดย Clientได้
strict ทำให้ Server เป็น Network Owner ตลอดไหม
ไม่ Entity Network Ownership ยังทำงานตาม OneSync และสามารถ Migration ไปยัง Client
Server ควรสร้าง Vehicle อย่างไร
ในหลาย Use Cases สามารถใช้ Server Setter เช่น
CreateVehicleServerSetter(...)
Vehicle ที่สร้างต้อง Set Bucket ไหม
ถ้าต้องอยู่ Instance เดียวกับ Player ควร
SetEntityRoutingBucket(
vehicle,
bucket
)
ต้องปิด Population ด้วยไหม
ไม่บังคับ แต่ Controlled Instance จำนวนมากเหมาะกับ SetRoutingBucketPopulationEnabled(bucket, false)
Entity Lockdown ใช้กับ Bucket 0 ได้ไหม
ได้ แต่ควร Audit Resources ทั้ง Server ก่อนใช้ Policy เข้มกับ Main World
Client-created Script เก่าจะพังไหม
มีโอกาสถ้า Resource พึ่ง Client Network Entity Creation
ควรเปิด strict ทันทีทั้ง Server ไหม
Server เก่าควรทดสอบทีละ Controlled Bucket ก่อน แล้ว Audit Compatibility
Entity Lockdown ใช้แทน Anti-Cheat ได้ไหม
ไม่ได้ ควรใช้เป็น Defense-in-depth
Entity Lockdown กับ Entity Ownership ต่างกันอย่างไร
Lockdown ควบคุมการสร้าง Entity ส่วน Ownership ระบุว่าใครกำลัง Simulation Network Entity
Entity Lockdown กับ sv_filterRequestControl ต่างกันอย่างไร
Lockdown จำกัด Entity Creation ส่วน sv_filterRequestControl จำกัดการขอ Control ของ Existing Entity
Entity Lockdown กับ sv_stateBagStrictMode ใช้ร่วมกันได้ไหม
ได้ หาก Resources รองรับ โดยตัวแรกควบคุม Entity Creation ส่วนตัวหลังควบคุมว่าใครแก้ State Bags ได้
Routing Bucket จำเป็นไหม
Entity Lockdown Policy ถูกกำหนดต่อ Routing Bucket จึงเกี่ยวข้องโดยตรง
สรุป FiveM Entity Lockdown คืออะไร ป้องกัน Client Spawn Entity อย่างไร
FiveM Entity Lockdown คือระบบของ OneSync ที่ช่วยให้ Server ควบคุม Client-created Entities ในแต่ละ Routing Bucket และเป็นหนึ่งในเครื่องมือสำคัญสำหรับสร้าง Server-authoritative Entity Architecture
ถ้าตั้ง
SetRoutingBucketEntityLockdownMode(
bucket,
'strict'
)
Client ใน Bucket นั้นจะไม่สามารถ Author Entity Creation ได้ตาม Policy ของ strict
Architecture ที่ควรใช้คือ
Client
↓
Request
↓
Server
↓
Validate Player
↓
Validate Permission
↓
Validate Model
↓
Validate State
↓
Rate Limit
↓
Server Create Entity
↓
Set Routing Bucket
↓
Set State
↓
OneSync Replicate
สำหรับ Controlled Instance ยังสามารถใช้
SetRoutingBucketPopulationEnabled(
bucket,
false
)
เพื่อปิด Ambient Population และสร้าง World ที่ Serverควบคุมได้ง่ายขึ้น
แต่ต้องจำว่ามีหลาย Layer ที่แตกต่างกัน
Entity Lockdown
→ ใครสร้าง Entity ได้
Network Ownership
→ ใคร Simulation Entity
sv_filterRequestControl
→ Client ขอ Control Existing Entity ได้แค่ไหน
sv_stateBagStrictMode
→ ใครแก้ State Bag ได้
และ
Secure Events
→ Client Request ถูกตรวจอย่างไร
จึงไม่ควรเปิด strict แล้วคิดว่า Server ปลอดภัยจาก Cheat ทุกประเภททันที
ถ้า Server Event ยังรับ
model
reward
money
permission
จาก Client แล้วเชื่อทั้งหมด ช่องโหว่ก็ยังมีอยู่
สำหรับผู้ที่กำลังเรียน FiveM Developer กับ comsiam วิธีที่ควรคิดคือ Entity Lockdown ไม่ได้มีไว้แค่ Block คนโกง Spawn รถ แต่มีไว้เปลี่ยน Architecture จาก Client-authoritative Spawn ไปสู่ Server-controlled Spawn
และหลักสำคัญจาก comsiam คือ Client ควรบอก Server ว่าอยากทำอะไร ไม่ใช่สร้างสิ่งนั้นเองแล้วบอก Server ว่าทำเสร็จแล้ว
เมื่อเข้าใจ Entity Lockdown แล้ว เราจะจบกลุ่ม OneSync/Entity Security และเข้าสู่พื้นฐาน Resource โดยตรงในหัวข้อถัดไปคือ FiveM Resource คืออะไร ซึ่งเป็นรากฐานของ Script FiveM ทุกตัว ตั้งแต่ Folder, fxmanifest.lua, Client Script, Server Script ไปจนถึง Resource Lifecycle
Comments
Post a Comment