FiveM Event คืออะไร? เข้าใจ Event, TriggerEvent และ RegisterNetEvent แบบง่าย ๆ
FiveM Event คือระบบสำหรับส่งสัญญาณหรือข้อมูลจาก Script ส่วนหนึ่งไปยังอีกส่วนหนึ่ง เพื่อให้ Function ที่รอ Event นั้นทำงาน โดย Event ถือเป็นพื้นฐานสำคัญมากของการเขียน FiveM Script เพราะใช้ทั้งภายใน Resource, ระหว่าง Resource และการสื่อสารระหว่าง Client กับ Server
ตัวอย่างง่าย ๆ เช่น
ผู้เล่นกดซื้อสินค้า
↓
Client Trigger Event
↓
Server รับ Event
↓
ตรวจสอบข้อมูล
↓
ซื้อสินค้า
↓
Server ส่ง Event กลับ Client
↓
แสดงผล
FiveM มี Event หลายรูปแบบ เช่น
TriggerEvent
AddEventHandler
RegisterNetEvent
TriggerServerEvent
TriggerClientEvent
แต่แต่ละตัวไม่ได้ใช้แทนกันทั้งหมด
สิ่งสำคัญที่สุดคือ Developer ต้องรู้ว่า Event นั้นทำงานอยู่ใน Client หรือ Server Context และจำเป็นต้องข้าม Network หรือไม่
① FiveM Event คืออะไร
Event สามารถคิดง่าย ๆ ว่าเป็น “ข้อความแจ้งเหตุการณ์”
สมมติเราสร้าง Event ชื่อ
shop:open
เมื่อ Script Trigger Event นี้ Function ที่กำลัง Listen ชื่อนี้จะทำงาน
ตัวอย่าง Lua
AddEventHandler('shop:open', function()
print('Shop opened')
end)
แล้ว Trigger
TriggerEvent('shop:open')
เมื่อ Code ถึง TriggerEvent() Handler จะถูกเรียก
Flow คือ
TriggerEvent
↓
Event Name
↓
AddEventHandler
↓
Function
นี่คือพื้นฐานของ Event System
② ทำไม FiveM ต้องมี Event
ถ้าไม่มี Event Script แต่ละส่วนอาจต้องเรียก Function กันโดยตรงตลอดเวลา ทำให้ Resource ผูกกันแน่นและแก้ไขยาก
Event ช่วยให้สามารถออกแบบเป็น
เกิดเหตุการณ์
↓
แจ้ง Event
↓
ระบบที่สนใจตอบสนอง
ตัวอย่าง Player เข้า Zone
Player เข้า Garage
↓
garage:enter
↓
เปิด Marker
↓
โหลดข้อมูล
↓
Update UI
ระบบแต่ละส่วนไม่จำเป็นต้องรู้ Implementation ของกันและกันทั้งหมด
③ Event Name คืออะไร
Event จะมีชื่อสำหรับใช้ระบุว่าเป็นเหตุการณ์อะไร
ตัวอย่าง
garage:open
garage:close
shop:buy
police:handcuff
job:complete
ตัวอย่าง
TriggerEvent('garage:open')
Handler ต้อง Listen ชื่อเดียวกัน
AddEventHandler('garage:open', function()
print('Opening garage')
end)
ถ้าชื่อไม่ตรง Event จะไม่ถูก Handler ตัวนั้นรับ
④ ควรตั้งชื่อ Event อย่างไร
ควรใช้ชื่อที่ชัดและลดโอกาสชนกับ Resource อื่น
แนวทางที่ดี เช่น
resourceName:eventName
ตัวอย่าง
mygarage:open
mygarage:storeVehicle
mygarage:requestVehicles
หรือ
comsiam_shop:buy
ดีกว่าชื่อสั้นทั่วไปอย่าง
open
buy
update
เพราะ FiveM Server สามารถมี Resource จำนวนมาก และชื่อ Event ที่กว้างเกินไปอาจทำให้อ่าน Code ยากหรือชนกันได้
⑤ Local Event คืออะไร
Local Event หมายถึง Event ที่ทำงานอยู่ใน Context เดียวกัน
เช่น
Client → Client
หรือ
Server → Server
ใน Lua สามารถใช้
TriggerEvent()
ร่วมกับ
AddEventHandler()
ตัวอย่าง
AddEventHandler('example:hello', function()
print('Hello Event')
end)
TriggerEvent('example:hello')
ถ้า Code นี้อยู่ใน Client Script Event ก็ทำงาน Client-side
ถ้าอยู่ Server Script ก็ทำงาน Server-side
⑥ TriggerEvent คืออะไร
TriggerEvent() ใช้เรียก Event ภายใน Context เดียวกัน
Syntax หลักคือ
TriggerEvent('eventName')
สามารถส่ง Parameter เพิ่มได้
TriggerEvent(
'player:update',
'John',
5000
)
Handler รับข้อมูล
AddEventHandler(
'player:update',
function(name, money)
print(name, money)
end
)
ดังนั้น Event สามารถส่งข้อมูลได้หลายค่า
⑦ TriggerEvent ส่งจาก Client ไป Server ได้ไหม
ไม่ได้ในรูปแบบ Local Event ปกติ
หาก Client เขียน
TriggerEvent('example:test')
Event จะถูก Trigger ใน Client Context
มันไม่ได้วิ่งข้าม Network ไป Server โดยอัตโนมัติ
ถ้าต้องการ Client → Server ต้องใช้
TriggerServerEvent()
นี่เป็นความแตกต่างสำคัญมาก
⑧ TriggerServerEvent คืออะไร
TriggerServerEvent() ใช้สำหรับส่ง Network Event จาก Client ไป Server
ตัวอย่าง Client
TriggerServerEvent(
'shop:buy',
'water'
)
Server รับด้วย
RegisterNetEvent(
'shop:buy',
function(itemName)
print(itemName)
end
)
Flow คือ
Client
↓
TriggerServerEvent
↓
Network
↓
Server
↓
RegisterNetEvent
นี่คือรูปแบบที่ใช้บ่อยมากใน FiveM
⑨ TriggerClientEvent คืออะไร
TriggerClientEvent() ใช้ฝั่ง Server เพื่อส่ง Event ไป Client
ตัวอย่าง Server
TriggerClientEvent(
'shop:open',
source
)
Client รับ
RegisterNetEvent(
'shop:open',
function()
print('Open shop')
end
)
Flow คือ
Server
↓
TriggerClientEvent
↓
Network
↓
Client
↓
RegisterNetEvent
⑩ RegisterNetEvent คืออะไร
RegisterNetEvent() ใช้ Register Event ให้สามารถใช้ผ่าน Network ได้
ตัวอย่าง
RegisterNetEvent(
'example:hello',
function()
print('Event fired')
end
)
อีกแบบหนึ่งคือ
RegisterNetEvent('example:hello')
AddEventHandler(
'example:hello',
function()
print('Event fired')
end
)
รูปแบบแรกสั้นและอ่านง่ายกว่าในหลายกรณี
⑪ AddEventHandler คืออะไร
AddEventHandler() ใช้ผูก Function เข้ากับ Event
ตัวอย่าง
AddEventHandler(
'example:test',
function()
print('Test Event')
end
)
จากนั้น
TriggerEvent('example:test')
ก็จะเรียก Handler
สำหรับ Event ที่ทำงานภายใน Context เดียวกันและไม่จำเป็นต้องข้าม Network การใช้ AddEventHandler เป็นแนวทางที่เหมาะสม
⑫ RegisterNetEvent กับ AddEventHandler ต่างกันอย่างไร
จำง่าย ๆ ว่า
AddEventHandler
→ Local Event / Handler
RegisterNetEvent
→ Network-capable Event
ถ้า Event ต้องใช้
Client → Server
หรือ
Server → Client
จึงต้อง Register ให้รองรับ Network
ไม่ควร Register ทุก Event เป็น Network Event เพียงเพราะสะดวก
⑬ ทำไมไม่ควรใช้ RegisterNetEvent ทุก Event
เพราะ Event ที่เปิดให้ใช้ผ่าน Network มี Attack Surface มากขึ้น
ถ้าระบบหนึ่งเป็น Server-only เช่น
Server Resource A
↓
Server Resource B
และไม่จำเป็นต้องให้ Client เรียก ก็ควรใช้ Local Event
เช่น
AddEventHandler(
'internal:refresh',
function()
-- server-only
end
)
ไม่จำเป็นต้องเปิดเป็น
RegisterNetEvent(...)
หาก Client ไม่ควรเข้าถึง
⑭ FiveM Event ส่ง Parameter ได้หรือไม่
ได้
ตัวอย่าง
TriggerEvent(
'example:user',
'John',
25,
true
)
รับด้วย
AddEventHandler(
'example:user',
function(name, level, online)
print(name)
print(level)
print(online)
end
)
สามารถส่งข้อมูลหลาย Type ได้ตามระบบ Serialization ที่รองรับ
แต่ Network Event ไม่ควรส่งข้อมูลขนาดใหญ่เกินความจำเป็น
⑮ Event ส่ง Table ได้ไหม
ได้ในหลายกรณี
ตัวอย่าง
local player = {
name = 'John',
job = 'police'
}
TriggerServerEvent(
'example:data',
player
)
แต่ควรส่งเฉพาะข้อมูลที่จำเป็น
ไม่ควรส่ง Table ขนาดใหญ่ทั้งก้อนเพียงเพราะสะดวก
ตัวอย่างที่ดีกว่าอาจส่งเพียง
playerId
itemName
amount
ตามความต้องการจริงของ Event
⑯ ทำไมไม่ควรส่งข้อมูลเยอะเกินไป
Network Event มีต้นทุนด้าน
Serialization
Network Bandwidth
Deserialization
Processing
ถ้าส่งข้อมูลจำนวนมากโดยไม่จำเป็น เช่น Player Data ทั้งหมดทุกครั้ง จะเพิ่มภาระ Network
หลักที่ดีคือ
ส่งเท่าที่ต้องใช้
โดยเฉพาะ Event ที่ถูกเรียกบ่อย
⑰ ถ้าต้องส่งข้อมูลขนาดใหญ่มากทำอย่างไร
FiveM มี Latent Events สำหรับกรณีที่ต้องส่งข้อมูลขนาดใหญ่กว่า Event ปกติ
แนวคิดคือช่วยจำกัด Bandwidth และไม่ให้ข้อมูลจำนวนมากไป Block Network Channel แบบเดียวกับการส่งก้อนใหญ่ทันที
ตัวอย่างชื่อ Function ที่เกี่ยวข้อง เช่น
TriggerLatentServerEvent
TriggerLatentClientEvent
แต่ Resource ทั่วไปไม่ควรใช้ Latent Event โดยอัตโนมัติ
ใช้เมื่อมี Payload ขนาดใหญ่จริง ๆ
⑱ Event กับ Function ต่างกันอย่างไร
Function เป็น Code ที่เรียกโดยตรง
local function openShop()
print('Open')
end
openShop()
Event เป็นการส่ง Signal ตามชื่อ
TriggerEvent('shop:open')
แล้ว Handler จึงทำงาน
AddEventHandler(
'shop:open',
openShop
)
Event มีข้อดีตรงที่ Producer ไม่จำเป็นต้องรู้ Implementation ทั้งหมดของ Consumer
⑲ ควรใช้ Function หรือ Event
ถ้า Logic อยู่ใน Resource และ Module เดียวกัน และไม่มีเหตุผลต้อง Broadcast Event การเรียก Function โดยตรงมักง่ายกว่า
ใช้ Event เมื่อ
ต้องสื่อสารระหว่างส่วนที่แยกกัน
ต้องสื่อสารระหว่าง Resource
ต้องข้าม Client/Server
ต้องการ Event-driven Architecture
อย่าใช้ Event กับทุก Function จน Code ตาม Flow ยากเกินไป
⑳ Event ระหว่าง Resource ใช้ได้ไหม
ได้
ตัวอย่าง Resource A
TriggerEvent(
'garage:vehicleStored',
plate
)
Resource B
AddEventHandler(
'garage:vehicleStored',
function(plate)
print(
'Stored vehicle:',
plate
)
end
)
ถ้าอยู่ Context เดียวกัน Event สามารถใช้สื่อสารระหว่าง Resource ได้
อย่างไรก็ตาม หากต้องการเรียก Function และรับ Return Value โดยตรง Export อาจเหมาะกว่า
㉑ Event กับ Export ต่างกันอย่างไร
Event เหมาะกับ
มีบางอย่างเกิดขึ้น
↓
แจ้งระบบอื่น
Export เหมาะกับ
Resource A
↓
เรียก Function ของ Resource B
↓
ต้องการผลลัพธ์หรือ Functionality
ตัวอย่าง Event
player died
อาจแจ้งหลายระบบ
ส่วน Export
GetPlayerJob()
เป็นการขอข้อมูลหรือเรียก Function แบบตรงกว่า
เลือกตาม Use Case
㉒ Event กับ Callback ต่างกันอย่างไร
Event ทั่วไปเป็นลักษณะ
ส่ง
↓
ทำงาน
Callback มักเป็น
Request
↓
Server
↓
Response
↓
Client ได้ผลลัพธ์
ตัวอย่างเปิด Garage
Client ต้องการรายการรถ
Client Request
↓
Server Query Database
↓
Server Response
↓
Client แสดงรถ
ระบบ Callback จึงเหมาะกว่า Event แบบ One-way บางกรณี
㉓ Event สำคัญกับ ESX อย่างไร
ESX ใช้ Event และ Callback จำนวนมากในการสื่อสาร Resource และ Framework
จึงพบ Code เช่น
RegisterNetEvent
TriggerServerEvent
TriggerClientEvent
บ่อยมาก
แต่การใช้ Framework ไม่ได้ทำให้คุณไม่ต้องเข้าใจ Event
ถ้าเข้าใจ FiveM Event Core การ Debug ESX จะง่ายขึ้นมาก
㉔ Event สำคัญกับ QBCore อย่างไร
QBCore ก็ใช้ Event เป็นส่วนสำคัญของ Architecture
เช่น
Player Loaded
Job Updated
Item Action
Server Callback
Resource Interaction
Developer ที่เข้าใจ Event Flow จะสามารถตามได้ว่า
ใคร Trigger
↓
ใครรับ
↓
ข้อมูลมาจากไหน
↓
ไปฝั่งไหน
ซึ่งช่วย Debug Framework ได้มาก
㉕ Event สำคัญกับ Qbox อย่างไร
หลักเดียวกัน
Qbox มี API และ Event ของ Framework แต่พื้นฐานยังทำงานบนระบบ FiveM
ดังนั้นก่อนจำ Event ของ Framework จำนวนมาก ควรเข้าใจ
Local Event
Network Event
Client
Server
Validation
ให้แน่นก่อน
㉖ Event Security สำคัญแค่ไหน
สำคัญมาก โดยเฉพาะ Network Event
Cfx.re ระบุชัดว่า Client ที่ถูกดัดแปลงสามารถพยายาม Trigger Event ใน Context ต่าง ๆ ได้
ดังนั้นอย่าคิดว่า
Event นี้ถูกเรียกจาก Menu ของฉันเท่านั้น จึงปลอดภัย
ผู้โจมตีไม่จำเป็นต้องกด Menu ตาม Flow ที่คุณออกแบบ
Server ต้องตรวจ Event Input และ State เอง
㉗ ตัวอย่าง Event ที่ไม่ปลอดภัย
Client
TriggerServerEvent(
'bank:addMoney',
1000000
)
Server
RegisterNetEvent(
'bank:addMoney',
function(amount)
AddMoney(
source,
amount
)
end
)
ระบบนี้ให้ Client ตัดสิน Amount
จึงมีความเสี่ยงสูง
㉘ Event ที่ปลอดภัยกว่าควรออกแบบอย่างไร
ให้ Client Request Action
TriggerServerEvent(
'job:finish'
)
Server
RegisterNetEvent(
'job:finish',
function()
local src = source
-- ตรวจว่ามีงานจริง
-- ตรวจ progress
-- ตรวจ position
-- ตรวจ cooldown
local reward = 500
AddMoney(
src,
reward
)
end
)
Server เป็นผู้ตัดสินข้อมูลสำคัญเอง
㉙ Server Event ควรตรวจอะไรบ้าง
ขึ้นอยู่กับระบบ แต่ตัวอย่างที่ควรพิจารณา ได้แก่
Player
Permission
Job
Money
Inventory
Item
Amount
Position
State
Cooldown
Entity Ownership
ไม่จำเป็นต้องตรวจทุกอย่างในทุก Event
แต่ต้องตรวจสิ่งที่มีผลต่อระบบและ Client สามารถส่งค่าปลอมได้
㉚ Type ของ Parameter ต้องตรวจไหม
ควร โดยเฉพาะ Network Event
ตัวอย่าง
RegisterNetEvent(
'shop:buy',
function(item, amount)
if type(item) ~= 'string' then
return
end
if type(amount) ~= 'number' then
return
end
end
)
จากนั้นตรวจ Range เพิ่ม
if amount < 1 or amount > 100 then
return
end
การตรวจ Type อย่างเดียวไม่ได้ป้องกันทุกอย่าง แต่เป็นพื้นฐานที่ดี
㉛ Event ควรมี Cooldown ไหม
Event ที่สามารถถูก Spam และมีต้นทุนสูงควรพิจารณา Cooldown หรือ Rate Limit
เช่น
Reward
Database Query
Entity Spawn
External API
Admin Action
Flow อาจเป็น
Event
↓
Rate Limit
↓
Validation
↓
Business Logic
ช่วยลด Abuse และ Load ที่ไม่จำเป็น
㉜ Event Spam คืออะไร
Event Spam คือการเรียก Event จำนวนมากในช่วงเวลาสั้น ๆ
เช่น
100 ครั้ง/วินาที
500 ครั้ง/วินาที
ถ้า Event นั้น Query Database หรือสร้าง Entity ทุกครั้ง อาจกระทบ Server Performance อย่างหนัก
Developer จึงต้องคิดทั้ง Security และ Performance พร้อมกัน
㉝ Event Name ถือเป็น Secret ไหม
ไม่ควรถือว่า Event Name เป็นระบบ Security
การตั้งชื่อ Event แปลก ๆ เช่น
x9y7_secret_reward_123
ไม่ได้ทำให้ Event ปลอดภัย
Security ต้องมาจาก
Server-side Validation
Permission
State
Rate Limit
Authority
ไม่ใช่หวังว่าผู้เล่นจะหา Event Name ไม่เจอ
㉞ สามารถ Trigger Event จาก Resource อื่นได้ไหม
Local Event สามารถใช้สื่อสารระหว่าง Resource ใน Context เดียวกันได้หากชื่อและ Environment ตรงกัน
นี่เป็นเหตุผลหนึ่งที่ Event Naming Convention สำคัญ
ถ้า Resource หลายตัวมี
update
เหมือนกัน อาจทำให้สับสนมาก
ควรตั้งชื่อเฉพาะ เช่น
mygarage:vehicleUpdated
㉟ Event Handler หลายตัวฟัง Event เดียวกันได้ไหม
ได้ใน Event-driven Design
แนวคิดเช่น
player:loaded
↓
Handler A → โหลด HUD
Handler B → โหลด Job
Handler C → โหลด Phone
ระบบหลายส่วนสามารถตอบสนอง Event เดียวกันได้
แต่ต้องระวัง Side Effect และ Debugging
หาก Handler จำนวนมากทำงานจาก Event เดียวกัน ควร Document ให้ชัด
㊱ Event ทำงานตามลำดับแน่นอนไหม
ไม่ควรออกแบบระบบสำคัญโดยสมมติว่า Handler หลายตัวจะทำ Business Logic ที่พึ่งลำดับแบบซับซ้อนโดยไม่มีการควบคุม
ถ้า Step ต้องเกิดตามลำดับแน่นอน เช่น
Validate
↓
หักเงิน
↓
บันทึก Database
↓
ให้ Item
ควรเขียน Flow ให้ชัดภายใน Function/Service ที่ควบคุมลำดับเอง
อย่าแตกเป็น Event หลายตัวจน Transaction ตามยาก
㊲ Event ใช้กับ Database อย่างไร
ตัวอย่าง Client ต้องการข้อมูลรถ
Client
↓
Event/Callback
↓
Server
↓
Database
↓
Result
↓
Client
Database Query ควรอยู่ Server-side
Client ไม่ควรส่ง SQL Query มาให้ Server Execute โดยตรง
เช่นห้ามออกแบบ
Client ส่ง:
SELECT * FROM users
แล้ว Server Execute ตามนั้น
นี่เป็น Security Design ที่แย่มาก
㊳ Event ใช้กับ NUI อย่างไร
Flow ตัวอย่าง
NUI
↓
Client Callback
↓
Client Event
↓
TriggerServerEvent
↓
Server
แล้วผลกลับ
Server
↓
TriggerClientEvent
↓
Client
↓
SendNUIMessage
↓
NUI
ระบบ UI ขนาดใหญ่จึงพึ่ง Event และ Callback อย่างมาก
㊴ Event ใช้กับ Entity อย่างไร
ตัวอย่าง Player ต้องการ Spawn รถ
Client Request
↓
Server ตรวจ Permission
↓
Server/Client สร้าง Entity
↓
Network ID
↓
Sync
Event อาจใช้ส่ง Request และ Result
แต่ Entity Lifecycle, Ownership และ OneSync ต้องจัดการแยกอย่างถูกต้อง
Event ไม่ได้แก้เรื่อง Entity Sync อัตโนมัติ
㊵ Event ใช้กับ State Bags ต่างกันอย่างไร
Event เป็นการส่งข้อมูล ณ ช่วงเวลาหนึ่ง
เกิดเหตุการณ์
↓
ส่ง Event
State Bag เก็บ State ที่สามารถ Replicate ตามระบบ FiveM
ตัวอย่าง
Event:
vehicle:locked
State:
locked = true
บางระบบอาจใช้ Event เพื่อสั่ง Action และ State Bag เพื่อเก็บ State ปัจจุบัน
สองอย่างสามารถทำงานร่วมกันได้
㊶ Event ใช้กับ OneSync อย่างไร
OneSync เกี่ยวข้องกับ Player และ Entity Networking
Event ยังใช้สำหรับส่ง Request หรือ Notification ระหว่าง Client/Server
แต่ Server ขนาดใหญ่ควรระวังการ Broadcast Event จำนวนมาก
เช่น
TriggerClientEvent(
'example:update',
-1,
data
)
ถ้าทำบ่อยและ Payload ใหญ่ จะส่งให้ผู้เล่นทุกคน
ควรส่งเฉพาะ Target ที่ต้องใช้เมื่อทำได้
㊷ TriggerClientEvent -1 คืออะไร
ใน Server Lua
TriggerClientEvent(
'example:announcement',
-1,
'Hello'
)
Target -1 ใช้ส่ง Event ไป Client ทุกคน
เหมาะกับ
Announcement
Global Update ที่จำเป็น
แต่ไม่ควรใช้ Broadcast กับข้อมูลเฉพาะ Player
ตัวอย่าง Bank Balance ของ Player A ไม่ควรถูกส่งให้ทุก Client
㊸ Event กับ Network Performance
Event ที่ส่งผ่าน Network มีต้นทุน
ปัญหาที่พบบ่อย ได้แก่
Trigger ถี่เกินไป
Broadcast ทุก Player
Payload ใหญ่
ส่งข้อมูลซ้ำ
ส่ง Table ทั้งหมดแทนข้อมูลที่เปลี่ยน
วิธีปรับปรุง เช่น
ส่งเฉพาะเมื่อข้อมูลเปลี่ยน
ส่งเฉพาะ Target
ส่งเฉพาะ Field ที่จำเป็น
ลด Event Frequency
㊹ Event ควร Trigger ทุก Tick ไหม
โดยทั่วไปควรหลีกเลี่ยงถ้าไม่จำเป็น
ตัวอย่าง
CreateThread(function()
while true do
Wait(0)
TriggerServerEvent(
'player:update'
)
end
end)
อาจส่ง Event ทุก Tick ซึ่งเป็น Load ที่สูงมาก
ถ้าต้อง Update เป็นระยะ ใช้ Interval ที่เหมาะสม
หรือถ้าข้อมูลเปลี่ยนเฉพาะบางเวลา ให้ Trigger เฉพาะเมื่อเปลี่ยน
㊺ Event Loop คืออะไร
Event Loop ในที่นี้หมายถึงการสร้าง Flow ที่ Event Trigger กันกลับไปกลับมาโดยไม่ได้ตั้งใจ
ตัวอย่าง
Event A
↓
Trigger Event B
↓
Event B
↓
Trigger Event A
↓
วนไม่จบ
อาจทำให้
CPU สูง
Event Spam
Stack/Runtime Problem
Server Lag
เวลาสร้าง Event Chain ควรตาม Flow ให้ชัดว่าแต่ละ Event จบที่ไหน
㊻ วิธี Debug FiveM Event
เริ่มจากใส่ print()
Client
print(
'Triggering shop:buy'
)
TriggerServerEvent(
'shop:buy',
'water'
)
Server
RegisterNetEvent(
'shop:buy',
function(item)
print(
'shop:buy received',
source,
item
)
end
)
จะช่วยรู้ว่า Event วิ่งถึง Server หรือไม่
㊼ Event ไม่ทำงานตรวจอะไรบ้าง
ตรวจตามลำดับ
① Resource Start หรือยัง
② Event Name ตรงไหม
③ Trigger อยู่ Client หรือ Server
④ Handler อยู่ Context ถูกไหม
⑤ ต้อง RegisterNetEvent หรือไม่
⑥ Parameter ถูกไหม
⑦ มี Error ก่อนถึง Event หรือไม่
⑧ ดู F8 Console หรือยัง
⑨ ดู Server Console หรือยัง
อย่าเปลี่ยน Code หลายส่วนพร้อมกันก่อนรู้ว่า Event หายตรงไหน
㊽ Event Name ตัวพิมพ์เล็กใหญ่สำคัญไหม
ควรถือว่าชื่อต้องตรงกันทุกตัว
ถ้า Trigger
TriggerEvent(
'Garage:Open'
)
แต่ Handler
AddEventHandler(
'garage:open',
function()
end
)
อย่าคาดหวังให้ระบบจับคู่ชื่อที่แตกต่างให้เอง
ใช้ Naming Convention เดียวกันทั้ง Project
㊾ Event Parameter ไม่ตรงกันเกิดอะไรขึ้น
สมมติ Trigger
TriggerEvent(
'example:user',
'John',
5000
)
Handler
AddEventHandler(
'example:user',
function(name)
print(name)
end
)
Handler ใช้เพียง Parameter แรกก็อาจทำงานตาม Lua Behavior ได้
แต่ถ้า Handler คาดหวัง Parameter ที่ไม่ได้ส่ง
function(name, money, job)
job อาจกลายเป็น nil
จึงควร Document Event Contract ให้ชัด
㊿ Event Contract คืออะไร
Event Contract คือการกำหนดว่า Event หนึ่ง
ชื่ออะไร
Trigger จากไหน
รับ Parameter อะไร
Type อะไร
Server Validate อะไร
Return/Response อย่างไร
ตัวอย่าง
shop:buy
Direction:
Client → Server
Parameters:
itemName: string
amount: number
Server checks:
item exists
amount range
money
inventory
distance
Project ใหญ่ควรมี Contract ลักษณะนี้เพื่อให้ทีม Developer เข้าใจตรงกัน
51 ควรรวม Event ไว้ไฟล์เดียวไหม
Project เล็กอาจทำได้
แต่ Project ใหญ่ควรแบ่งตาม Feature เช่น
server/
├── shops.lua
├── garage.lua
├── jobs.lua
└── police.lua
แทนการสร้าง
events.lua
ไฟล์เดียว 5,000 บรรทัด
การวาง Handler ใกล้ Business Logic ที่เกี่ยวข้องมักตาม Code ง่ายกว่า
52 ควรตั้ง Prefix Event ตาม Resource ไหม
แนะนำ
ตัวอย่าง Resource ชื่อ
mygarage
ใช้
mygarage:open
mygarage:store
mygarage:spawn
ช่วยให้
Search Code ง่าย
ลดชื่อชน
อ่าน Log ง่าย
Debug ง่าย
โดยเฉพาะ Server ที่มี Resource จำนวนมาก
53 Event ที่ Built-in กับ Custom Event ต่างกันอย่างไร
FiveM มี Built-in Events จากระบบ เช่น Resource Lifecycle หรือ Player Events บางประเภท
และ Developer สามารถสร้าง Custom Events เอง
ตัวอย่าง Custom
myjob:started
myjob:completed
ไม่ว่าจะ Built-in หรือ Custom ต้องอ่าน Documentation ของ Event นั้นว่า
ทำงาน Client หรือ Server
มี Parameter อะไร
Trigger เมื่อไร
54 Event กับ Resource Start
FiveM มี Event เกี่ยวกับ Resource Lifecycle เช่น Resource Start/Stop ใน Context ที่เกี่ยวข้อง
สามารถใช้สำหรับ
Initialize Data
Cleanup
Reload State
Debug
แต่ต้องระวังว่า Resource Restart อาจทำให้ Handler และ State ถูกสร้างใหม่ตาม Lifecycle
Resource ควรออกแบบให้ Restart ได้อย่างปลอดภัย
55 Event กับ playerDropped
Server มี Event สำหรับ Player Disconnect เช่น playerDropped
สามารถใช้ Cleanup Runtime State เช่น
Active Job
Cooldown
Session
Temporary Cache
ตัวอย่างแนวคิด
AddEventHandler(
'playerDropped',
function()
local src = source
activeJobs[src] = nil
end
)
การ Cleanup ช่วยลด State เก่าและ Memory ที่ไม่จำเป็น
56 Event กับ Security ควรจำอะไรที่สุด
จำ 3 ข้อนี้
① Local Event ไม่ต้องเปิด Network หากไม่จำเป็น
② Network Event ต้อง Validate Input
③ Client ไม่ใช่ Trusted Authority
ถ้าทำสามข้อนี้ได้ จะลดปัญหา Event Security จำนวนมาก
57 Event กับ Performance ควรจำอะไรที่สุด
จำ
อย่าส่งบ่อยเกินไป
อย่าส่งข้อมูลเกินจำเป็น
อย่า Broadcast ถ้าไม่จำเป็น
Event ที่ดีควร Trigger เมื่อมีเหตุผล
ไม่ใช่ใช้ Network เป็น Global Variable Sync ทุก Frame
58 Checklist ก่อนสร้าง FiveM Event
ก่อนเขียน Event ใหม่ถามว่า
① Event นี้ Local หรือ Network
② ใครเป็นคน Trigger
③ ใครเป็นคนรับ
④ Client หรือ Server
⑤ Parameter มีอะไร
⑥ Client สามารถปลอมค่าอะไรได้
⑦ Server Validate อะไร
⑧ Event Trigger บ่อยแค่ไหน
⑨ Payload ใหญ่แค่ไหน
⑩ ต้องใช้ Event จริง หรือ Function/Export เหมาะกว่า
คำถามเหล่านี้ช่วยทั้ง Architecture และ Security
59 มือใหม่ควรฝึก Event อย่างไร
เริ่มจากลำดับนี้
ขั้นที่ 1 — Local Client Event
TriggerEvent
+
AddEventHandler
ขั้นที่ 2 — Local Server Event
ฝึก Context ให้เข้าใจ
ขั้นที่ 3 — Client → Server
TriggerServerEvent
+
RegisterNetEvent
ขั้นที่ 4 — Server → Client
TriggerClientEvent
+
RegisterNetEvent
ขั้นที่ 5 — ส่ง Parameter
ขั้นที่ 6 — Validate Input
ขั้นที่ 7 — ทำระบบ Shop หรือ Job เล็ก ๆ
เมื่อทำครบจะเข้าใจ Event Flow มากขึ้นมาก
60 FiveM Event Flow ที่ควรจำ
สรุปเป็นภาพเดียวได้ดังนี้
LOCAL CLIENT
TriggerEvent
↓
Client AddEventHandler
LOCAL SERVER
TriggerEvent
↓
Server AddEventHandler
CLIENT → SERVER
TriggerServerEvent
↓
Server RegisterNetEvent
SERVER → CLIENT
TriggerClientEvent
↓
Client RegisterNetEvent
ถ้าจำโครงสร้างนี้ได้ การเรียนหัวข้อ Event ต่อจากนี้จะง่ายขึ้นมาก
คำถามที่พบบ่อยเกี่ยวกับ FiveM Event
FiveM Event คืออะไร
คือระบบสำหรับ Trigger เหตุการณ์และส่งข้อมูลให้ Event Handler ที่รอ Event นั้นทำงาน
TriggerEvent คืออะไร
ใช้ Trigger Event ภายใน Context เดียวกัน เช่น Client → Client หรือ Server → Server
TriggerServerEvent คืออะไร
ใช้ส่ง Network Event จาก Client ไป Server
TriggerClientEvent คืออะไร
ใช้ส่ง Network Event จาก Server ไป Client
RegisterNetEvent คืออะไร
ใช้ Register Event ให้สามารถรับ Network Event ได้
AddEventHandler คืออะไร
ใช้เพิ่ม Handler ที่ทำงานเมื่อ Event ที่ระบุถูก Trigger
TriggerEvent ส่งจาก Client ไป Server ได้ไหม
ไม่ได้โดยตรง ต้องใช้ TriggerServerEvent
FiveM Event ส่งข้อมูลได้ไหม
ได้ สามารถส่ง Parameter ไปกับ Event ได้
Event ส่ง Table ได้ไหม
ได้ในรูปแบบที่ Runtime Serialization รองรับ แต่ควรส่งเฉพาะข้อมูลที่จำเป็น
Event Name เป็น Security ได้ไหม
ไม่ได้ อย่าพึ่งการซ่อนชื่อ Event ต้องใช้ Server-side Validation
Network Event ปลอดภัยไหม
ปลอดภัยได้เมื่อออกแบบถูก แต่ Server ต้องไม่เชื่อ Client Input โดยตรง
Event ทำให้ Server Lag ได้ไหม
ได้ หาก Trigger ถี่เกินไป ส่ง Payload ใหญ่ หรือ Handler ทำงานหนัก
Event กับ Callback ต่างกันอย่างไร
Event มักเป็นการแจ้งเหตุการณ์ ส่วน Callback มักใช้ Request แล้วรอ Response
สรุป FiveM Event คืออะไร
FiveM Event คือระบบสำคัญสำหรับให้ Script ส่วนต่าง ๆ ติดต่อกันและตอบสนองต่อเหตุการณ์ โดยสามารถใช้ได้ทั้งภายใน Context เดียวกันและข้าม Network ระหว่าง Client กับ Server
สิ่งที่ต้องแยกให้ออกคือ
TriggerEvent
→ Local Event
AddEventHandler
→ รับ Local Event
TriggerServerEvent
→ Client ส่งไป Server
TriggerClientEvent
→ Server ส่งไป Client
RegisterNetEvent
→ Register Network Event
และหลัก Security ที่สำคัญที่สุดคือ
Client Request
↓
Server Validate
↓
Server ตัดสิน
ไม่ใช่
Client ส่งค่าอะไรก็ได้
↓
Server เชื่อทันที
สำหรับคนที่เรียน FiveM Developer กับ comsiam หากเข้าใจ Event Flow ให้แน่น จะสามารถอ่าน Resource ขนาดใหญ่ได้ง่ายขึ้นมาก เพราะ Framework อย่าง ESX, QBCore และ Qbox ล้วนพึ่ง Event และ Callback เป็นส่วนสำคัญ
บทความถัดไปของ comsiam จะเจาะเฉพาะ TriggerEvent ว่าทำงานอย่างไร ต่างจาก TriggerServerEvent และ TriggerClientEvent ตรงไหน และควรใช้เมื่อใด
Comments
Post a Comment