Client กับ Server FiveM ต่างกันอย่างไร? FiveM Developer ต้องแยกให้ออก
Client กับ Server FiveM ต่างกันที่ตำแหน่งที่ Script ทำงาน หน้าที่ของแต่ละฝั่ง และระดับความน่าเชื่อถือของข้อมูล
Client Script ทำงานอยู่บนเครื่องของผู้เล่นแต่ละคน เหมาะกับสิ่งที่เกี่ยวข้องกับ Gameplay และการแสดงผล เช่น Ped, Vehicle, Marker, Blip, Animation, Camera, Controls และ NUI
ส่วน Server Script ทำงานบน FXServer และเหมาะกับระบบที่ต้องเป็นศูนย์กลางหรือมี Authority เช่น เงิน Item, Permission, Reward, Database, Player Data และการตรวจสอบ Request จาก Client
แนวคิดพื้นฐานที่ควรจำคือ
Client
→ Gameplay / UI / Input
Server
→ Authority / Validation / Database
ถ้า FiveM Developer แยกสองส่วนนี้ไม่ออก จะเกิดปัญหาได้ทั้งด้าน Security, Performance และการ Sync ข้อมูล
บทความนี้จะอธิบายว่า Client กับ Server FiveM ต่างกันอย่างไร พร้อมตัวอย่างการแบ่งระบบจริงตั้งแต่ Shop, Garage, Job ไปจนถึง Database
① Client FiveM คืออะไร
Client หมายถึง FiveM ที่ทำงานอยู่บนเครื่องของผู้เล่น
สมมติเซิร์ฟเวอร์มีผู้เล่น 100 คน
ก็จะมี FiveM Client ของผู้เล่นแต่ละคน เช่น
Player 1 → Client
Player 2 → Client
Player 3 → Client
...
Player 100 → Client
Client Script ของ Resource จะถูกโหลดไปทำงานใน Context ของผู้เล่นแต่ละคนตาม Resource System
ดังนั้น Client Script จึงเหมาะกับงานที่ต้องรู้หรือควบคุมสิ่งที่เกิดขึ้นบนเกมของผู้เล่นคนนั้น
② Server FiveM คืออะไร
Server หมายถึง
FXServer
ซึ่งเป็นตัวกลางของ FiveM Server
Server Script ทำงานอยู่บน Server ไม่ได้ถูก Execute เป็น Script Instance เดียวกันบนเครื่องผู้เล่นแต่ละคน
หน้าที่หลักมักเกี่ยวข้องกับ
Player Data
Money
Inventory
Permission
Job
Reward
Database
Server Events
Security
Entity Management
Persistent Data
สามารถคิดว่า Server เป็นส่วนที่ช่วยตัดสินว่า Request จาก Player ควรได้รับอนุญาตหรือไม่
③ ภาพรวม Client กับ Server FiveM
โครงสร้างง่ายที่สุดคือ
FXServer
│
Server Script
│
┌───────┼───────┐
↓ ↓ ↓
Client A Client B Client C
↓ ↓ ↓
Player A Player B Player C
แต่ละ Client มี Gameplay State ของตัวเอง
ส่วน Server เป็นจุดกลางสำหรับประสานข้อมูลระหว่างผู้เล่นและระบบของเซิร์ฟเวอร์
④ Client Script อยู่ไฟล์ไหน
สำหรับ Lua มักตั้งชื่อ
client.lua
ตัวอย่าง Resource
my_resource/
├── fxmanifest.lua
├── client.lua
└── server.lua
ใน fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
client_script 'client.lua'
server_script 'server.lua'
ตรง
client_script 'client.lua'
หมายถึงโหลด Script ฝั่ง Client
ส่วน
server_script 'server.lua'
หมายถึงโหลด Script ฝั่ง Server
⑤ Client กับ Server ต้องใช้ภาษาเดียวกันไหม
ไม่จำเป็นในระดับ Runtime ของ FiveM
FiveM รองรับ Scripting Runtime หลัก เช่น
Lua
JavaScript
C#
แต่ใน Project จริง การใช้ภาษาและ Coding Standard ให้สม่ำเสมอมักดูแลง่ายกว่า
ตัวอย่าง Resource Lua
client.lua
server.lua
หรือ JavaScript
client.js
server.js
ไม่ว่าภาษาใด แนวคิด Client/Server ยังคงเหมือนเดิม
⑥ Client เหมาะกับงานอะไร
Client เหมาะกับงานที่เกี่ยวข้องกับ GTA V บนเครื่อง Player เช่น
Player Ped
Vehicle
Marker
Blip
Animation
Camera
Input
Keyboard
Game Controls
Effects
NUI
HUD
Gameplay Interaction
ตัวอย่าง
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
print(coords)
Code นี้เหมาะกับ Client เพราะกำลังอ่าน Player Ped ของ Local Player
⑦ Server เหมาะกับงานอะไร
Server เหมาะกับงาน เช่น
ตรวจ Player
เงิน
Item
Inventory
Permission
Reward
Ownership
Database
Transactions
Logging
Security Validation
Persistent State
ตัวอย่างระบบซื้อสินค้า
Server ควรเป็นผู้ตรวจว่า
Item มีจริงไหม
↓
ราคาเท่าไร
↓
Player มีเงินไหม
↓
ซื้อได้ไหม
↓
หักเงิน
↓
เพิ่ม Item
ไม่ควรให้ Client เป็นผู้ตัดสินทั้งหมด
⑧ Client กับ Server ใช้ Native เหมือนกันไหม
ไม่ทั้งหมด
FiveM/GTA V Native มี Context หรือ API Set ที่แตกต่างกัน
ตัวอย่าง
PlayerPedId()
เป็น Native ที่ใช้ใน Client Context
จึงสามารถเขียนใน client.lua
local ped = PlayerPedId()
แต่ไม่ควร Copy ไปใช้ใน Server Script โดยคิดว่า Server จะหา Local Player แบบเดียวกัน
Server มี API และ Native สำหรับ Server Context ของตัวเอง
ดังนั้นก่อนใช้ Native ควรตรวจเสมอว่าใช้ได้กับ
Client
Server
หรือทั้งสองฝั่ง
⑨ Client มี Local Player แต่ Server เห็นผู้เล่นหลายคน
นี่เป็นความแตกต่างสำคัญ
บน Client
PlayerPedId()
หมายถึง Player Ped ของผู้เล่นที่กำลังรัน Client นั้น
แต่ Server ต้องจัดการผู้เล่นหลายคน เช่น
Player 1
Player 5
Player 27
Player 84
จึงมีแนวคิด Player Source หรือ Server-side Player Identification เข้ามาเกี่ยวข้อง
⑩ source ใน Server Script คืออะไร
เมื่อ Client Trigger Network Event ไป Server ฝั่ง Server จะสามารถทราบ Player Source ที่เรียก Event
ตัวอย่าง
RegisterNetEvent('example:test', function()
local src = source
print('Player source:', src)
end)
source ใน Event Context ใช้ระบุผู้เล่นที่ Trigger Event นั้นเข้ามา
นี่แตกต่างจาก Client ที่มักรู้ Local Player อยู่แล้ว
⑪ Client กับ Server ติดต่อกันอย่างไร
Client และ Server ไม่ได้ใช้ Variable เดียวกันโดยตรง
ต้องใช้ระบบ Communication เช่น
Network Events
Callbacks
State Bags
Exports
ตาม Use Case
ตัวอย่าง Client → Server
Client
↓
TriggerServerEvent
↓
Network
↓
Server
และ Server → Client
Server
↓
TriggerClientEvent
↓
Network
↓
Client
⑫ ตัวอย่าง Client ส่ง Event ไป Server
Client
RegisterCommand('hello', function()
TriggerServerEvent(
'example:hello'
)
end, false)
Server
RegisterNetEvent(
'example:hello',
function()
local src = source
print(
'Event from player:',
src
)
end
)
เมื่อ Player ใช้ Command Client จะส่ง Network Event ไป Server
⑬ Server ส่ง Event กลับ Client อย่างไร
Server
RegisterNetEvent(
'example:requestWelcome',
function()
local src = source
TriggerClientEvent(
'example:welcome',
src
)
end
)
Client
RegisterNetEvent(
'example:welcome',
function()
print('Welcome!')
end
)
Flow คือ
Client
↓
Request
↓
Server
↓
Process
↓
Response
↓
Client
รูปแบบนี้เป็นพื้นฐานของ FiveM Resource จำนวนมาก
⑭ Variable Client กับ Server แชร์กันไหม
ไม่
สมมติ Client มี
local money = 5000
ไม่ได้หมายความว่า server.lua จะเห็น Variable นี้
และถ้า Server มี
local money = 10000
Client ก็ไม่ได้เห็นโดยอัตโนมัติ
Client กับ Server เป็น Execution Context แยกกัน
ถ้าต้องการส่งข้อมูลต้องใช้ Communication Mechanism ที่เหมาะสม
⑮ Shared Script แปลว่า Variable Shared ไหม
ไม่
แม้ใช้
shared_script 'config.lua'
FiveM จะโหลดไฟล์นั้นทั้ง Client และ Server
แต่ Memory ยังแยกกัน
เช่น
Config.Price = 500
Client และ Server เริ่มด้วยค่าเดียวกันจาก Source Code
แต่ถ้า Client เปลี่ยนเป็น
Config.Price = 1
Server Copy ไม่ได้กลายเป็น 1 ตามไปด้วย
Shared Script ไม่ใช่ Shared Memory
⑯ Client เชื่อถือได้ไหม
สำหรับ Security ต้องถือว่า Client ไม่ใช่ Trusted Authority
Client-side Checks มีประโยชน์ต่อ UX และช่วยลด Request ที่ไม่จำเป็นได้ แต่ไม่ควรเป็นการตรวจสอบเดียวสำหรับ Action สำคัญ
ตัวอย่าง Client ตรวจว่า
Player มีเงิน 5,000
แล้วส่ง Server ว่า
ซื้อได้
Serverยังควรตรวจเงินจริงของ Player ด้วยวิธี Server-side
⑰ ทำไม Client ถึงไม่ควรถูกเชื่อทั้งหมด
เพราะ Client อยู่บนเครื่องผู้เล่น
ผู้เล่นที่ใช้ Cheat หรือ Tool บางประเภทอาจพยายาม
Trigger Event เอง
เปลี่ยน Argument
เปลี่ยน Local State
ข้าม Client Check
เรียก Event ซ้ำ
ดังนั้น Network Event ที่มีผลสำคัญต้องมี Server Validation
หลักง่าย ๆ คือ
Client Request
≠
Server ต้องเชื่อทันที
⑱ ตัวอย่าง Event ที่ออกแบบไม่ดี
Client
TriggerServerEvent(
'job:reward',
1000000
)
Server
RegisterNetEvent(
'job:reward',
function(amount)
GiveMoney(
source,
amount
)
end
)
ปัญหาคือ Client เป็นผู้กำหนดจำนวน Reward
ถ้า Event ถูก Abuse ผู้เล่นอาจพยายามเปลี่ยน Amount
⑲ รูปแบบที่ดีกว่า
Client ส่งเพียง
TriggerServerEvent(
'job:complete'
)
Server
RegisterNetEvent(
'job:complete',
function()
local src = source
-- ตรวจงาน
-- ตรวจสถานะ
-- ตรวจตำแหน่ง
-- ตรวจ cooldown
local reward = 500
GiveMoney(
src,
reward
)
end
)
Server เป็นฝ่ายกำหนด Reward เอง
รูปแบบจึงกลายเป็น
Client ขอรับ Reward
↓
Server ตรวจ
↓
Server คำนวณ
↓
Serverให้ Reward
ปลอดภัยกว่า
⑳ Money ควรอยู่ Client หรือ Server
ข้อมูลเงินจริงควรมี Server-side Authority
Client สามารถเก็บ Copy เพื่อแสดง UI เช่น
$25,000
แต่ Transaction จริงควรถูกตรวจ Server
เช่น
ซื้อรถ
↓
Server ตรวจเงิน
↓
Server หักเงิน
↓
Server บันทึก
↓
Client Update UI
อย่าปล่อยให้ Client ทำ
money = money - price
แล้วถือว่านั่นคือเงินจริงของ Server
㉑ Inventory ควรอยู่ฝั่งไหน
Inventory ที่มีผลต่อ Gameplay และ Economy ควรถูกควบคุมด้วย Server Authority
Client มีหน้าที่
เปิด Inventory UI
Drag Item
แสดง Icon
แสดง Weight
ส่ง Request
Server มีหน้าที่
ตรวจว่า Item มีจริง
ตรวจจำนวน
ตรวจ Ownership
Move Item
Add/Remove Item
บันทึก Data
รูปแบบนี้ลดโอกาสข้อมูลผิดหรือถูก Manipulate จาก Client
㉒ Database อยู่ Client หรือ Server
Database ควรอยู่ Server-side
Architecture ที่แนะนำคือ
Client
↓
Server Event / Callback
↓
Server Script
↓
Database Library
↓
MySQL / MariaDB
ไม่ควรใส่
Database Username
Database Password
Connection String
ไว้ใน Client Script
Client ไม่จำเป็นต้องเชื่อม Database โดยตรง
㉓ Client Query Database เองได้ไหม
ใน Architecture FiveM ทั่วไปไม่ควร
สมมติต้องการเปิด Garage
Client ควรทำ
เปิด Garage
↓
ขอรายการรถจาก Server
Server
ตรวจ Player
↓
Query Database
↓
ได้รายการรถ
↓
ส่งข้อมูลที่จำเป็นกลับ Client
Client จึงไม่ต้องรู้รายละเอียด Connection ของ Database
㉔ Client เหมาะกับ NUI มากกว่า Server อย่างไร
NUI แสดงผลอยู่ฝั่ง Client
ดังนั้น Client Script มักทำหน้าที่
FiveM Client
↓
SendNUIMessage
↓
NUI JavaScript
↓
HTML/CSS
และจัด Focus ด้วย Function ที่เกี่ยวข้อง
ส่วน Server ไม่ได้ควบคุม DOM ของ NUI โดยตรง
ถ้าต้องแสดงข้อมูล Database
Server
↓
ส่ง Data
↓
Client
↓
ส่งเข้า NUI
㉕ ตัวอย่างระบบ Shop ที่แบ่ง Client/Server ถูกต้อง
Client
ทำ
Marker
Detect Player
กด E
เปิด Shop UI
เลือกสินค้า
จากนั้นส่ง
ฉันต้องการซื้อ water จำนวน 2
Server
ทำ
ตรวจ
waterมีจริงตรวจ Amount
ตรวจราคา Server-side
ตรวจเงิน
ตรวจ Inventory
หักเงิน
เพิ่ม Item
ส่ง Result กลับ
Client ดูแล Interaction
Server ดูแล Transaction
㉖ ตัวอย่าง Garage
Client
เหมาะกับ
Marker
Blip
Camera
Vehicle Interaction
UI
Animation
Server
เหมาะกับ
Vehicle Ownership
Database
Stored State
Permission
Garage Access
Player Identifier
Flow
Player เปิด Garage
↓
Client
↓
ขอรถ
↓
Server
↓
Database
↓
ส่งรายการรถ
↓
Client แสดง UI
㉗ ตัวอย่าง Job System
Client อาจทำ
Marker
Blip
Animation
Route
Vehicle Interaction
Server ทำ
ตรวจ Job จริง
ตรวจ Mission State
ตรวจ Reward
ตรวจ Cooldown
ให้เงิน
บันทึกข้อมูล
อย่าให้ Client ส่งเพียง
ฉันทำงานครบแล้ว
ให้ฉัน 100,000
แล้ว Server ทำตามทันที
㉘ ตัวอย่างระบบ Police
Client
Animation
Handcuff Visual
UI
Vehicle Interaction
Target Interaction
Server
ตรวจ Job
ตรวจ Permission
ตรวจ Player Target
State สำคัญ
Inventory
Database
Server ควรเป็นผู้ตรวจว่าผู้เล่นเป็นตำรวจจริง ไม่ใช่เชื่อ Boolean จาก Client
㉙ ตัวอย่าง Admin System
Client ทำ
Admin Menu
Button
UI
Spectate View
Camera
Server ทำ
Permission Check
Role Check
Admin Action Validation
Logging
ตัวอย่างอันตรายคือ Client เก็บ
local isAdmin = true
แล้วใช้ Local Variable นี้เป็น Security Check เพียงอย่างเดียว
Permission สำคัญต้องตรวจ Server-side
㉚ Client กับ Server เรื่อง Position
Client เหมาะกับการอ่าน Position เพื่อ Gameplay และ UX
เช่น
local coords =
GetEntityCoords(
PlayerPedId()
)
แต่ถ้า Position ถูกใช้เพื่ออนุมัติ Reward สำคัญ Server ควรตรวจข้อมูลตำแหน่งด้วยวิธี Server-side ที่ระบบรองรับ
ตัวอย่าง
Client บอกว่า
"ฉันอยู่จุดส่งของ"
Server
↓
ตรวจ Position/State อีกครั้ง
↓
จึงให้ Reward
㉛ Client กับ Server เรื่อง Entity
Client ทำงานกับ Entity บ่อยมาก เช่น
Ped
Vehicle
Object
แต่ FiveM Networking มีเรื่อง
Entity Owner
Network ID
Scope
OneSync
เข้ามาเกี่ยวข้อง
ดังนั้น Entity ไม่ได้เป็นเรื่อง Client-only เสมอไป
ระบบขั้นสูงอาจให้ Server สร้างหรือควบคุม Networked Entity ตาม Architecture ที่เหมาะสม
㉜ Client กับ Server เรื่อง Network ID
Entity Handle ที่ Client ใช้อยู่ไม่ควรถูกมองว่าเป็น Global ID ของ Entity สำหรับทุก Context
เมื่อ Entity ต้องอ้างถึงข้าม Network จะมีแนวคิด
Network ID
เข้ามาเกี่ยวข้อง
เช่น
Client A
↓
Network ID
↓
Server
↓
Client B
หัวข้อนี้สำคัญมากเมื่อสร้างระบบรถ Ped หรือ Object ที่ต้อง Sync ระหว่างผู้เล่น
㉝ Client กับ Server เรื่อง State Bags
State Bags เป็นระบบ State Replication ของ FiveM
สามารถใช้กับ
Player
Entity
Global State
ตัวอย่าง
Vehicle
└── locked = true
หรือ
Player
└── duty = true
แต่ต้องเข้าใจ Authority และ Replication Rules
State Bags ไม่ได้ทำให้ Client กลายเป็น Trusted Authority สำหรับข้อมูลทุกประเภท
㉞ Client กับ Server เรื่อง Routing Bucket
Routing Bucket ถูกควบคุมจาก Server และใช้แยก Player หรือ Entity เป็น Instance
ตัวอย่าง
Bucket 0
├── Player A
└── Player B
Bucket 10
├── Player C
└── Mission Entity
Client ไม่ควรเป็นผู้กำหนด Bucket ของตัวเองตามใจโดยไม่มี Server Logic
ระบบเช่น
Character Selection
Mission
Lobby
Instance
จึงมักมี Server เป็นผู้จัดการ
㉟ Client กับ Server เรื่อง OneSync
OneSync เพิ่มความสามารถของ Server ในการจัดการ
Players
Networked Entities
Ownership
Scope
Server-side Entity
State
Routing Buckets
ดังนั้นเมื่อสร้าง Server ขนาดใหญ่ ความเข้าใจ Client/Server จะเชื่อมต่อโดยตรงกับ OneSync
หากยังแยก Client กับ Server ไม่ออก การ Debug Entity Sync จะยากมาก
㊱ Client Performance กับ Server Performance ต่างกันอย่างไร
Client Resource ที่หนักอาจกระทบ
FPS ของผู้เล่น
Client Frame Time
ความลื่นของเกม
Server Resource ที่หนักอาจกระทบ
Server Tick
Event Response
Hitch
ผู้เล่นทุกคน
ดังนั้น Script ทั้งสองฝั่งต้อง Optimize แต่ผลกระทบไม่เหมือนกัน
㊲ Client Loop ควรระวังอะไร
ตัวอย่าง
CreateThread(function()
while true do
Wait(0)
-- Logic
end
end)
ถ้า Logic หนัก จะทำงานถี่มาก
ถามเสมอว่า
ต้องทำทุก Tick จริงไหม?
หากไม่จำเป็น ใช้ Interval ที่สูงขึ้นหรือ Event-driven Logic
Client Performance มีผลกับ FPS ของ Player โดยตรง
㊳ Server Loop ควรระวังอะไร
Server ก็สามารถมี Thread
CreateThread(function()
while true do
Wait(1000)
-- server logic
end
end)
ต้องระวัง
Loop Players จำนวนมาก
Database Query
Entity Processing
Event Spam
Heavy Calculation
เพราะ Server CPU ถูกแชร์โดยระบบของผู้เล่นทั้งหมด
㊴ Client Error ดูที่ไหน
Error ฝั่ง Client มักดูจาก
F8 Console
ตัวอย่าง
SCRIPT ERROR
ให้ดูต่อว่า
Resource ไหน
File ไหน
Line ไหน
Error อะไร
เช่น Error ใน client.lua ไม่จำเป็นต้องปรากฏเป็น Server-side Script Error แบบเดียวกัน
㊵ Server Error ดูที่ไหน
Server-side Error ดูจาก
Server Console
อาจพบ
Lua Error
JavaScript Error
C# Error
Database Error
Resource Error
Hitch Warning
ดังนั้นเวลา Script ไม่ทำงานควรถามก่อนว่า
ปัญหาเกิด Client หรือ Server?
แล้วจึงเลือก Console ที่ถูกต้อง
㊶ Client print กับ Server print ไปที่เดียวกันไหม
ไม่จำเป็น
ตัวอย่าง Client
print('hello from client')
มักดูที่ Client Console
ส่วน Server
print('hello from server')
ดูที่ Server Console
นี่เป็นวิธี Debug พื้นฐานที่สุดในการตาม Flow ของ Script
㊷ Client กับ Server เรื่อง Resource Restart
เมื่อ Resource Restart ทั้ง Client และ Server Context ที่เกี่ยวข้องจะผ่าน Resource Lifecycle
ตัวอย่าง State ใน Memory เช่น
local cache = {}
อาจถูก Reset
ดังนั้นต้องระวัง
Client
NUI Focus
Camera
Blip
Temporary Entity
Local State
Server
Player Cache
Running Job State
Temporary Data
Entity
Timers
Resource ที่ดีควรจัดการ Cleanup ตามความเหมาะสม
㊸ Runtime State กับ Database ต่างกันอย่างไร
สมมติ Server มี
local players = {}
นี่คือ Runtime State ใน Memory
ถ้า Resource Restart Data อาจหาย
แต่ข้อมูลใน
MySQL / MariaDB
เป็น Persistent Data
ดังนั้นระบบ FiveM มักมี
Database
↓
โหลดเข้า Server Memory
↓
Server Logic
↓
ส่งข้อมูลที่จำเป็นให้ Client
Server จึงเป็นจุดเชื่อมสำคัญระหว่าง Database และ Player
㊹ Client ควรมีข้อมูลเท่าที่จำเป็น
ไม่ควรส่งข้อมูล Server ทุกอย่างไป Client เพียงเพราะสะดวก
ตัวอย่าง Client ต้องการแค่
ชื่อ Item
ราคา
Icon
ไม่จำเป็นต้องส่ง
Internal Security State
Private Metadata
Secret Token
ข้อมูลผู้เล่นคนอื่นทั้งหมด
หลัก
ส่งเท่าที่ Client ต้องใช้
ช่วยทั้ง Security, Privacy และ Network Performance
㊺ Server ควร Validate อะไรบ้าง
Network Event สำคัญควรตรวจตาม Use Case เช่น
Player
Permission
Money
Inventory
Item
Amount
Position
State
Cooldown
Role
Experience
ไม่จำเป็นต้องตรวจทุกอย่างในทุก Event
แต่ต้องตรวจสิ่งที่ Client สามารถ Manipulate แล้วสร้างผลเสียต่อระบบได้
㊻ AddEventHandler กับ RegisterNetEvent เกี่ยวข้องกับ Client/Server อย่างไร
ถ้า Event ใช้ภายใน Context เดียว เช่น
Server → Server
หรือ
Client → Client
สามารถใช้ Local Event Handler ตาม API ที่เหมาะสม
ถ้าต้องข้าม Network เช่น
Client → Server
หรือ
Server → Client
จึงต้องใช้ Network Event
ไม่ควรเปิด Event เป็น Networked โดยไม่มีเหตุผล
㊼ TriggerEvent กับ TriggerServerEvent ต่างกันอย่างไร
TriggerEvent
ใช้เรียก Event ใน Context เดียวกัน
ตัวอย่าง Client
Client → Client Event
หรือ Server
Server → Server Event
ส่วน
TriggerServerEvent()
ใช้จาก Client เพื่อส่ง Event ไป Server
ดังนั้นชื่อใกล้กันแต่ขอบเขตต่างกันมาก
㊽ TriggerClientEvent ใช้ฝั่งไหน
โดยทั่วไป Server ใช้เพื่อส่ง Network Event ไป Client
ตัวอย่าง
TriggerClientEvent(
'example:update',
source,
data
)
Client รับด้วย Network Event Handler
หัวข้อนี้จะลงรายละเอียดอีกครั้งในบทความเฉพาะของ Event ต่อจากนี้
㊾ Client กับ Server ต่างกันเรื่อง Trust อย่างไร
นี่คือประเด็นสำคัญที่สุด
Client:
ไม่ควรถือว่าเชื่อถือได้
Server:
ควรเป็น Authority ของข้อมูลสำคัญ
แต่ Server Script เองก็ต้องเขียนถูกต้อง
การย้าย Logic จาก Client ไป Serverไม่ได้ทำให้ Security ดีทันที หาก Server ยังรับ Input แล้วทำตามโดยไม่มี Validation
㊿ ย้ายทุกอย่างไป Server ดีไหม
ไม่ดีเช่นกัน
Client มีหน้าที่สำคัญมาก
หากย้าย
Marker Rendering
Camera
Input
Animation
NUI
ไป Server โดยไม่จำเป็น จะไม่ใช่ Architecture ที่ถูกต้อง
เป้าหมายไม่ใช่
ทุกอย่างต้อง Server
แต่คือ
งานแต่ละอย่างอยู่ฝั่งที่เหมาะสม
51 สูตรแบ่งงาน Client กับ Server
ใช้หลักง่าย ๆ
ถ้าต้องแสดงให้ Player เห็น
มักเริ่มที่ Client
ถ้าต้องรับ Input จาก Player
Client
ถ้าต้องควบคุม Camera หรือ Animation
Client
ถ้าต้องตัดสินเงินหรือ Item
Server
ถ้าต้องตรวจ Permission
Server
ถ้าต้อง Query Database
Server
ถ้าต้องให้ Reward
Server
ถ้าต้อง Sync State
ออกแบบร่วมกันทั้ง Client + Server + Networking
52 ตัวอย่างระบบ Banking
Client
เปิด Banking UI
↓
กรอกจำนวนเงิน
↓
ส่ง Request
Server
รับ Request
↓
ตรวจ Amount
↓
ตรวจ Account
↓
ตรวจ Balance
↓
ทำ Transaction
↓
บันทึก Database
↓
ส่งยอดใหม่
Client
รับยอดใหม่
↓
Update NUI
นี่เป็นตัวอย่าง Client/Server Separation ที่ชัดเจน
53 ตัวอย่างซื้อรถ
Client
เปิด Showroom
Preview รถ
Camera
UI
เลือกรถ
Server
ตรวจ Model ที่อนุญาต
ตรวจราคา
ตรวจเงิน
หักเงิน
สร้าง Ownership Data
บันทึก Database
จากนั้น Client แสดงผลตาม Result
ไม่ควรให้ Client บอก Server ว่า
รถคันนี้ราคา 1 บาท
แล้ว Server เชื่อ
54 ตัวอย่าง Teleport
Teleport ทั่วไปอาจเป็น Client Action
แต่ถ้า Teleport เป็น Admin Feature ต้องมี Server Permission Check ก่อน
Flow
Admin กด Teleport
↓
Client ส่ง Request
↓
Server ตรวจ Permission
↓
Server อนุญาต
↓
Client ทำ Teleport
นี่แสดงให้เห็นว่าระบบหนึ่งอาจต้องใช้ทั้ง Client และ Serverร่วมกัน
55 ตัวอย่าง Door Lock
Client
แสดงสถานะประตู
Interaction
Animation
Server
ตรวจ Job/Permission
เก็บ Authority State
Sync State
Network/State Bag
กระจายสถานะ Lock ให้ผู้เล่นที่เกี่ยวข้อง
ระบบจริงจึงมักไม่ได้แบ่งง่าย ๆ ว่า “ทั้งหมด Client” หรือ “ทั้งหมด Server”
แต่แบ่ง Responsibility
56 Framework เปลี่ยนหลัก Client/Server หรือไม่
ไม่
ไม่ว่าจะใช้
ESX
QBCore
Qbox
Standalone
พื้นฐาน Client/Server ยังคงเหมือนเดิม
Framework เพียงเพิ่ม API และ Structure
หากไม่เข้าใจ Client/Server Core เวลา Framework Event มีปัญหาจะ Debug ยากมาก
57 วิธีดูว่า Code ควรอยู่ฝั่งไหน
ถาม 5 คำถาม
① ต้องเข้าถึง Local Game หรือไม่?
② ต้องเป็นข้อมูลที่เชื่อถือได้หรือไม่?
③ ต้องใช้ Database หรือไม่?
④ ต้องเป็นความลับหรือไม่?
⑤ ต้อง Sync หลาย Player หรือไม่?
ถ้าต้องเข้าถึง Local Game
→ Client มักเหมาะ
ถ้าต้อง Trust, Database หรือ Secret
→ Server มักเหมาะ
ถ้าต้อง Sync
→ ต้องออกแบบทั้ง Client และ Server
58 ข้อผิดพลาดมือใหม่ที่พบบ่อย
ใส่ PlayerPedId ใน server.lua
Context ผิด
เก็บ Database Password ใน client.lua
Security ผิด
ให้ Client กำหนด Reward
Authority ผิด
เชื่อ Event Parameter โดยไม่ Validate
Security ผิด
คิดว่า Shared Variable Sync กัน
Architecture ผิด
Query Database จาก Client
Architecture ผิด
ทำ Loop ทุก Tick โดยไม่จำเป็น
Performance ผิด
ถ้าเข้าใจ Client/Server ตั้งแต่ต้น Error ประเภทนี้จะลดลงมาก
59 Checklist ก่อนเขียนระบบ FiveM
ก่อนสร้าง Feature ใหม่ ให้กำหนดก่อนว่า
CLIENT
- Player Input อะไร?
- UI อะไร?
- Gameplay อะไร?
SERVER
- Validate อะไร?
- Authority อะไร?
- Database อะไร?
NETWORK
- ส่ง Event อะไร?
- ส่ง Data เท่าไร?
- Client เชื่อถือได้แค่ไหน?
การวาง Flow ก่อนเขียน Code ทำให้ Resource มี Structure ดีกว่าการเขียนทุกอย่างลงไฟล์เดียวแล้วค่อยแยกภายหลัง
60 สรุป Client กับ Server FiveM ต่างกันอย่างไร
ความแตกต่างที่สำคัญที่สุดคือ
CLIENT
ทำงานบนเครื่องผู้เล่น
↓
Gameplay
UI
Input
Ped
Vehicle
Animation
Camera
NUI
SERVER
ทำงานบน FXServer
↓
Authority
Validation
Money
Inventory
Permission
Database
Reward
Persistent Data
Client และ Server เป็น Execution Context คนละฝั่ง Variable ไม่ได้แชร์ Memory กันโดยตรง และต้องใช้ Event, Callback, State Bag หรือ Networking Mechanism ที่เหมาะสมเพื่อสื่อสารกัน
ด้าน Security ต้องถือว่า Client สามารถถูกดัดแปลงหรือ Trigger Network Event ได้ จึงไม่ควรเชื่อ Client-side Check เพียงอย่างเดียว
ระบบสำคัญควรใช้ Flow
Client Request
↓
Server Validation
↓
Business Logic
↓
Database / State
↓
Server Result
↓
Client Display
สำหรับคนที่กำลังเรียน FiveM Developer กับ comsiam เรื่อง Client กับ Server ถือเป็นพื้นฐานที่ต้องเข้าใจให้แน่นก่อนเรียน Event เพราะ TriggerEvent, TriggerServerEvent, TriggerClientEvent และ RegisterNetEvent ล้วนขึ้นอยู่กับความเข้าใจว่า Code กำลังทำงานอยู่ Context ไหน
เมื่อแยก Client, Server และ Network ได้แล้ว การเรียน FiveM ขั้นต่อไปจะง่ายขึ้นมาก ทั้ง Database, OneSync, Entity, State Bags, NUI และ Security และเนื้อหาต่อไปของ comsiam จะเข้าสู่หัวข้อสำคัญโดยตรงคือ FiveM Event คืออะไร
Comments
Post a Comment