Server Script FiveM คืออะไร? ทำงานอย่างไร และใช้ทำอะไรบ้าง
Server Script FiveM คือ Script ที่ทำงานอยู่บน FXServer ไม่ได้รันบนเครื่องผู้เล่นแต่ละคนเหมือน Client Script หน้าที่หลักคือจัดการ Logic กลางของเซิร์ฟเวอร์ เช่น Player Data, Permission, Money, Inventory, Database, Reward, Server Events และการตรวจสอบข้อมูลสำคัญ
ถ้าระบบ FiveM ถูกออกแบบอย่างถูกต้อง Client จะทำหน้าที่เกี่ยวกับ Gameplay และ UI ส่วน Server จะเป็นผู้ตรวจสอบและตัดสินข้อมูลสำคัญ
ตัวอย่างแนวคิดคือ
Player
↓
Client Script
↓
ส่ง Request
↓
Server Script
↓
ตรวจสอบข้อมูล
↓
ดำเนินการ
↓
Database
↓
ส่งผลกลับ Client
การเข้าใจ Server Script เป็นพื้นฐานสำคัญมากสำหรับ FiveM Developer เพราะระบบที่เกี่ยวข้องกับเงิน Item Reward Permission หรือ Database ไม่ควรปล่อยให้ Client เป็นผู้ตัดสินใจเอง
① Server Script FiveM คืออะไร
FiveM Resource สามารถมี Script ที่ทำงานบน Server ได้
ชื่อไฟล์ที่นิยมใช้ เช่น
server.lua
server.js
server.net.dll
สำหรับ Lua มักพบ
server.lua
แต่ FiveM ไม่ได้บังคับว่าต้องใช้ชื่อนี้เสมอ
สามารถตั้งชื่อเป็น
main_server.lua
database.lua
players.lua
garage_server.lua
ได้
สิ่งสำคัญคือกำหนดไว้ใน fxmanifest.lua
ตัวอย่าง
fx_version 'cerulean'
game 'gta5'
server_script 'server.lua'
บรรทัด
server_script 'server.lua'
บอก FiveM ให้โหลดไฟล์ดังกล่าวบนฝั่ง Server
② Server Script ทำงานที่ไหน
Server Script ทำงานบน
FXServer
ไม่ใช่เครื่องของผู้เล่น
สมมติมีผู้เล่น 100 คน
Client Script จะทำงานแยกบน Client ของผู้เล่นแต่ละคน
แต่ Server Script ของ Resource จะทำงานใน Server Runtime
ภาพรวมคือ
FXServer
│
Server Script
│
┌──────┼──────┐
↓ ↓ ↓
Player A Player B Player C
Client Client Client
Server จึงเป็นจุดกลางที่สามารถจัดการข้อมูลของผู้เล่นหลายคนร่วมกันได้
③ Server Script ใช้ภาษาอะไรเขียนได้บ้าง
FiveM รองรับ Server Scripting ด้วย Runtime หลัก ได้แก่
Lua
JavaScript
C#
ตัวอย่าง Lua
print('Server script started')
JavaScript
console.log('Server script started');
และ C# ใช้ Server Assembly ที่อ้างอิง CitizenFX Server Runtime
ดังนั้น Server Logic ไม่ได้จำกัดเฉพาะ Lua
แต่ในบทความนี้จะใช้ Lua เป็นตัวอย่างหลัก เพราะอ่านง่ายและพบได้บ่อยใน FiveM Community
④ วิธีสร้าง Server Script FiveM
สร้าง Resource เช่น
resources/
└── [local]/
└── server_example/
├── fxmanifest.lua
└── server.lua
ใน fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
author 'Your Name'
description 'Server Script Example'
version '1.0.0'
server_script 'server.lua'
จากนั้นใน server.lua
print('Server script loaded')
เพิ่มใน server.cfg
ensure server_example
เมื่อ Resource Start ข้อความจะปรากฏใน Server Console
⑤ server_script กับ server_scripts ต่างกันอย่างไร
ถ้ามี Server Script ไฟล์เดียว ใช้
server_script 'server.lua'
ถ้ามีหลายไฟล์ สามารถใช้
server_scripts {
'server/main.lua',
'server/players.lua',
'server/database.lua'
}
หรือใช้ Globbing
server_scripts {
'server/*.lua'
}
FiveM Resource Manifest รองรับการกำหนด Server Script หลายไฟล์ได้
สำหรับ Resource ใหญ่ การแบ่ง File ตาม Responsibility จะช่วยให้ดูแลง่ายกว่าเขียนทุกอย่างใน server.lua ไฟล์เดียว
⑥ Server Script ใช้ทำอะไรบ้าง
Server Script เหมาะกับระบบ เช่น
Player Data
Money
Inventory
Jobs
Permission
Admin System
Reward
Database
Ownership
Transactions
Server Events
Server Commands
Logging
Security Validation
Global Logic
ตัวอย่างเช่น Player ขอซื้อ Item
Client ไม่ควรเพิ่ม Item ให้ตัวเองโดยตรง
ควรเป็น
Client
↓
ขอซื้อ Item
↓
Server
↓
ตรวจราคา
↓
ตรวจเงิน
↓
หักเงิน
↓
เพิ่ม Item
นี่คือหน้าที่หลักของ Server Script
⑦ Server Script ต่างจาก Client Script อย่างไร
ความแตกต่างหลักคือสถานที่ทำงานและระดับความน่าเชื่อถือ
Client Script
ทำงานบนเครื่องผู้เล่น
เหมาะกับ
Ped
Vehicle
Controls
Marker
Blip
Animation
Camera
NUI
Server Script
ทำงานบน FXServer
เหมาะกับ
Money
Inventory
Database
Permissions
Reward
Server Validation
Player Data
จำง่าย ๆ ว่า
Client = Gameplay / Presentation
Server = Authority / Validation / Persistent Data
นี่ไม่ใช่กฎตายตัวทุกกรณี แต่เป็นแนวทาง Architecture ที่สำคัญมาก
⑧ Server Script รับ Event จาก Client อย่างไร
Lua สามารถใช้
RegisterNetEvent()
เพื่อรับ Network Event
ตัวอย่าง Server
RegisterNetEvent('example:hello', function()
print('Received event from client')
end)
Client ส่งด้วย
TriggerServerEvent('example:hello')
Flow คือ
Client
↓
TriggerServerEvent
↓
Network
↓
Server
↓
RegisterNetEvent
↓
Server Logic
นี่คือหนึ่งในรูปแบบพื้นฐานที่สุดของ FiveM Client → Server Communication
⑨ source ใน Server Event คืออะไร
ภายใน Server Event จะพบ Variable พิเศษชื่อ
source
ซึ่งใช้ระบุ Player Source ที่ Trigger Event เข้ามาใน Context นั้น
ตัวอย่าง
RegisterNetEvent('example:hello', function()
local playerId = source
print('Player:', playerId)
end)
สิ่งสำคัญคือควรเก็บค่า source ไว้ใน Local Variable หากต้องใช้ใน Async Flow หรือ Logic ที่ซับซ้อน
เช่น
RegisterNetEvent('example:hello', function()
local src = source
print('Player:', src)
end)
รูปแบบนี้อ่านง่ายและลดความสับสนใน Function ที่ยาวขึ้น
⑩ Server ส่ง Event ไป Client อย่างไร
ใช้
TriggerClientEvent()
ตัวอย่าง
RegisterNetEvent('example:requestWelcome', function()
local src = source
TriggerClientEvent(
'example:welcome',
src
)
end)
ฝั่ง Client รับ
RegisterNetEvent('example:welcome', function()
print('Welcome!')
end)
Flow คือ
Server
↓
TriggerClientEvent
↓
Network
↓
Client
↓
RegisterNetEvent
Server สามารถเลือกส่งให้ Player เฉพาะคนหรือ Target ที่ต้องการตาม API ได้
⑪ Server ส่ง Event ให้ผู้เล่นทุกคนได้ไหม
ได้
ในหลาย API ของ FiveM การใช้ Target
-1
หมายถึงส่งไปยัง Client ทุกคน
ตัวอย่าง
TriggerClientEvent(
'example:announcement',
-1,
'Server restart soon'
)
แต่ไม่ควร Broadcast ข้อมูลขนาดใหญ่หรือ Event ถี่เกินไปโดยไม่มีเหตุผล
เพราะ Network Traffic ก็เป็นส่วนหนึ่งของ Performance
⑫ Server Event ต้อง Validate ข้อมูลหรือไม่
ต้อง โดยเฉพาะ Event ที่ Client เรียกได้
นี่เป็นเรื่องสำคัญที่สุดของ Server Script
สมมติ Client ส่ง
TriggerServerEvent(
'shop:buy',
'water',
10
)
Server ไม่ควรเชื่อว่า
Item = water
Amount = 10
ถูกต้องเสมอ
ควรตรวจ
Item มีจริงหรือไม่
จำนวนสมเหตุสมผลหรือไม่
Player มีเงินพอหรือไม่
Player อยู่ในสถานะที่ซื้อได้หรือไม่
Player อยู่ใกล้ร้านหรือไม่ หาก Logic ต้องการ
Permission ถูกต้องหรือไม่
Cfx.re แนะนำให้ดึงข้อมูลสำคัญและตรวจสอบด้วยวิธี Server-side แทนการเชื่อค่าที่ Client ส่งมา
⑬ ตัวอย่าง Server Event ที่ไม่ปลอดภัย
ตัวอย่างที่ไม่ควรทำ
RegisterNetEvent('job:reward', function(amount)
local src = source
GiveMoney(src, amount)
end)
Client สามารถพยายามส่ง
TriggerServerEvent(
'job:reward',
1000000
)
ถ้า Server เชื่อจำนวนเงินโดยตรง ระบบจะมีช่องโหว่ด้าน Logic
ปัญหาไม่ใช่ RegisterNetEvent
ปัญหาคือ Server เชื่อ Client Input
⑭ Server Event ที่ปลอดภัยกว่าควรเป็นอย่างไร
ให้ Client ส่งเพียง Request
TriggerServerEvent(
'job:complete'
)
จากนั้น Server ตรวจเอง
RegisterNetEvent('job:complete', function()
local src = source
local job = activeJobs[src]
if not job then
return
end
-- ตรวจเงื่อนไขเพิ่มเติม
local reward = 500
-- Server เป็นคนกำหนด reward
GiveMoney(src, reward)
activeJobs[src] = nil
end)
หลักสำคัญคือ
Client ขอ
↓
Server ตรวจ
↓
Server คำนวณ
↓
Server ดำเนินการ
ไม่ใช่
Client ตัดสิน
↓
Server ทำตาม
⑮ AddEventHandler กับ RegisterNetEvent ต่างกันอย่างไร
เรื่องนี้สำคัญด้าน Security
Cfx.re แนะนำว่า Event ที่ควรถูกเรียกภายใน Context เดียวกัน เช่น Server → Server ควรใช้ Event Handler ที่ไม่จำเป็นต้องเปิดให้ Network
ตัวอย่าง Local Server Event
AddEventHandler(
'example:serverOnly',
function()
print('Server-only event')
end
)
หาก Event จำเป็นต้องรับจาก Client จึงใช้ Network Event เช่น
RegisterNetEvent(
'example:clientRequest',
function()
-- validation
end
)
อย่าเปิด Event เป็น Networked โดยไม่จำเป็น
เพราะจะเพิ่มพื้นที่ที่ Client สามารถพยายามเรียกเข้ามาได้
⑯ Server Script ใช้ Command ได้ไหม
ได้
ตัวอย่าง
RegisterCommand(
'serverhello',
function(source, args, rawCommand)
print('Hello from server')
end,
false
)
Server Command สามารถถูกเรียกตาม Context และ Permission ที่ออกแบบไว้
ถ้า source เป็น Player Source ก็สามารถตรวจผู้เล่นได้
ถ้าเป็น Console Context ค่าของ source อาจแตกต่างตาม API และการเรียก Command
Developer จึงควรอ่าน Behavior ของ Command ที่ใช้งานจริง
⑰ Server Script ใช้กับ Permission ได้ไหม
ได้ และเป็นจุดที่เหมาะกับการตรวจ Permission
ตัวอย่างระบบ Admin ควรทำประมาณ
Client
↓
ขอใช้ Admin Action
↓
Server
↓
ตรวจ Permission
↓
อนุญาตหรือปฏิเสธ
ไม่ควรทำเพียง
if Config.IsAdmin then
-- admin logic
end
บน Client แล้วถือว่าปลอดภัย
เพราะ Client-side State ไม่ควรเป็น Authority สำหรับ Permission สำคัญ
⑱ Server Script เชื่อม Database ได้ไหม
ได้ และโดยทั่วไป Database Logic ควรอยู่ Server-side
Architecture เช่น
Client
↓
Server Event / Callback
↓
Server Script
↓
Database Library
↓
MySQL / MariaDB
ข้อมูลที่มักเก็บใน Database ได้แก่
Character
Money
Inventory
Vehicle
Housing
Jobs
Phone
Transactions
Persistent Settings
Client ไม่ควรมี Database Credential หรือเชื่อม Database โดยตรง
⑲ ทำไม Database ต้องอยู่ฝั่ง Server
เหตุผลหลักคือ
Security
ไม่ต้องส่ง Database Password ไป Client
Validation
Server สามารถตรวจ Input ก่อน Query
Data Integrity
Logic สำคัญถูกรวมอยู่ที่จุดกลาง
Connection Management
Server สามารถจัดการ Connection Pool และ Database Library อย่างเหมาะสม
Audit
Logging และ Transaction Management ทำได้ง่ายกว่า
ดังนั้น Architecture ที่ดีควรเป็น
Client Request
↓
Server Validation
↓
Database
⑳ Server Script ใช้ oxmysql ได้ไหม
ได้ และ FiveM Resource จำนวนมากใช้ Database Layer เช่น oxmysql กับ MySQL/MariaDB
แนวคิดคือ
server.lua
↓
oxmysql
↓
MySQL / MariaDB
Server Script สามารถใช้ Database เพื่อ
Query
Insert
Update
Transaction
ตาม API ของ Library ที่ติดตั้ง
ควรตรวจ Documentation ของ Version ที่ใช้งานจริงเสมอ เพราะ API ของ Library สามารถเปลี่ยนได้
㉑ อย่า Query Database ทุก Tick
นี่เป็นข้อผิดพลาดที่ควรหลีกเลี่ยง
เช่น
ทุก Frame/Tick
↓
SELECT database
↓
SELECT database
↓
SELECT database
เป็น Design ที่ไม่ดีในระบบส่วนใหญ่
ควรพิจารณา
Cache
Event-driven Update
Query เมื่อจำเป็น
Batch Operations
Index
Transaction
Database ไม่ควรถูกใช้แทน Memory State ทุกอย่าง
㉒ Server Script เก็บ Player Data ใน Memory ได้ไหม
ได้
ตัวอย่าง
local players = {}
จากนั้นเก็บข้อมูล
players[source] = {
job = 'police',
duty = true
}
เหมาะกับข้อมูล Runtime ที่ไม่จำเป็นต้อง Query Database ทุกครั้ง
แต่ต้องจัดการ Lifecycle เช่น Player Disconnect
ตัวอย่าง
AddEventHandler(
'playerDropped',
function()
players[source] = nil
end
)
เพื่อไม่ให้ข้อมูลค้างโดยไม่จำเป็น
㉓ Player Dropped สำคัญอย่างไร
เมื่อ Player ออกจาก Server ข้อมูล Temporary ที่ผูกกับ Source ควรถูก Cleanup
เช่น
Active Job
Cooldown
Session
Temporary Cache
Routing State
หากไม่ Cleanup อาจเกิด
Memory สะสม
State เก่า
Logic ผิด
Source Reuse Problem
ดังนั้น Server Developer ต้องคิดเรื่อง Player Lifecycle ด้วย
㉔ Server Script ใช้ Thread ได้ไหม
ได้
Lua Server สามารถใช้
CreateThread(function()
while true do
Wait(60000)
print('Server task running')
end
end)
ใช้กับงาน Background บางประเภท เช่น
Periodic Cleanup
Scheduled Logic
State Refresh
แต่ไม่ควรสร้าง Loop ถี่โดยไม่จำเป็น
Server CPU มีผลกับผู้เล่นทุกคน ดังนั้น Server-side Performance สำคัญมาก
㉕ Server Script มี Wait ได้ไหม
ได้
ตัวอย่าง
CreateThread(function()
while true do
Wait(10000)
-- periodic logic
end
end)
แต่ค่า Interval ต้องเลือกตามความต้องการของระบบ
ระบบ Cleanup อาจทำทุก 60 วินาที
แต่ระบบอื่นอาจต้องทำถี่กว่า
อย่า Copy Wait(0) หรือ Wait(1000) ไปทุก Loop โดยไม่เข้าใจเหตุผล
㉖ Server Script กิน CPU ได้อย่างไร
ตัวอย่างสาเหตุ
Loop ถี่เกินไป
Loop Player ทุกคนบ่อยเกินไป
Entity Query จำนวนมาก
Database Query มากเกินไป
Event Spam
Serialization Data ขนาดใหญ่
Table Processing หนัก
Logging มากเกินไป
Algorithm ไม่มีประสิทธิภาพ
Server Script ที่ใช้ CPU สูงสามารถทำให้เกิด
Tick Delay
Hitch Warning
Response ช้า
Event Delay
Player Experience แย่
จึงควร Optimize Server Resource อย่างจริงจัง
㉗ Server Script กับ Hitch Warning เกี่ยวข้องกันอย่างไร
หาก Server Thread ถูก Block หรือ Resource ใช้เวลานานผิดปกติ อาจพบ Warning เกี่ยวกับ Server Hitch
สาเหตุอาจมาจาก
Heavy Loop
Blocking Operation
Database ช้า
Resource ทำงานหนัก
Server Hardware
External Service
อย่าตัดสินทันทีว่า FiveM หรือ Framework มีปัญหา
ควรใช้ Profiler และ Log เพื่อหาต้นเหตุ
㉘ Server Script ใช้ Native ได้ไหม
FiveM มี Server-side Native API หลายตัว
แต่ ไม่ใช่ Native ทุกตัวที่ใช้ได้ฝั่ง Server
Native Documentation จะระบุ API Set และ Context ที่เกี่ยวข้อง
ดังนั้น Code แบบ
PlayerPedId()
ที่ใช้บน Client ไม่ควรถูก Copy เข้า server.lua โดยสมมติว่าจะทำงานเหมือนกัน
Server มีวิธีจัดการ Player/Entity ตาม Server API ที่ FiveM รองรับ
ควรตรวจ Native Documentation ทุกครั้ง
㉙ Server-side Entity คืออะไร
ในระบบ OneSync FiveM สามารถสร้างหรือจัดการ Entity บางประเภท Server-side ได้ตาม Native และ API ที่รองรับ
เช่น
Vehicle
Ped
Object
ในบาง Architecture การให้ Server สร้าง Entity สามารถช่วยเรื่อง Authority และ Persistence ของระบบได้
แต่ Developer ต้องเข้าใจ
Network ID
Entity Ownership
Scope
OneSync
เพิ่มเติม
ไม่ควรสร้าง Entity จำนวนมากโดยไม่วาง Cleanup
㉚ Server Script กับ OneSync เกี่ยวข้องอย่างไร
OneSync ทำให้ Server สามารถจัดการระบบ Networked Entity และ Player Scope ได้ในระดับที่ซับซ้อนขึ้น
เรื่องที่เกี่ยวข้อง เช่น
Server-created entities
Entity ownership
Network ID
Player scope
State Bags
Routing Buckets
เมื่อ Server มีผู้เล่นจำนวนมาก การออกแบบ Logic โดยเข้าใจ OneSync จะช่วยลดปัญหา Sync และ Entity ได้มาก
㉛ Server Script ใช้ State Bags ได้ไหม
ได้
State Bags ใช้เก็บ State ที่เกี่ยวข้องกับ
Entity
Player
Global State
ตัวอย่าง Concept
Player
├── duty
└── status
Vehicle
├── locked
└── fuel
Server สามารถใช้ State Bag เพื่อควบคุม State ที่ต้อง Replicate ตามระบบ FiveM
แต่ไม่ควรใช้ State Bags แทน Database ทุกอย่าง
State Bag เหมาะกับ Runtime/Replicated State มากกว่า Persistent Storage ระยะยาว
㉜ Server Script ใช้ Routing Bucket ได้ไหม
ได้
Routing Bucket ถูกควบคุม Server-side และสามารถใช้แยก Player/Entity ออกเป็น Instance
Use Case เช่น
Character Selection
Mission
Apartment
Private Lobby
Match
Instanced Interior
แนวคิด
Bucket 0
├── Player A
└── Player B
Bucket 10
├── Player C
└── Mission Entity
แต่ Routing Bucket ไม่ควรถูกใช้แทน Interior System ทุกกรณีโดยไม่เข้าใจข้อจำกัดของ OneSync
㉝ Server Script ใช้ Export ได้ไหม
ได้
Server Resource สามารถเปิด Function ให้ Resource อื่นเรียกได้
ตัวอย่าง Lua
exports(
'GetPlayerJob',
function(playerId)
return 'police'
end
)
Resource อื่นสามารถเรียก Export ตามชื่อ Resource
ข้อดีคือสามารถแบ่งระบบเป็น Module
เช่น
core_resource
↓
Export
↓
job_resource
ช่วยลด Code ซ้ำ
㉞ server_export ใน fxmanifest.lua ยังใช้ได้ไหม
Resource Manifest ยังมี Directive สำหรับ Server Export
แต่เอกสาร Cfx.re แนะนำ Runtime Export API เช่น
exports('name', function()
end)
มากกว่าในหลายกรณี
เพราะชัดเจนและอยู่ใกล้ Implementation
ดังนั้น Resource ใหม่มักใช้ Runtime Exports
㉟ Server Script ใช้ Callback ได้ไหม
ได้ และ Framework/Library จำนวนมากสร้าง Callback System เพื่อให้ Client ขอข้อมูลจาก Server แล้วรอ Result
แนวคิด
Client
↓
Request
↓
Server
↓
ตรวจข้อมูล
↓
Database / Logic
↓
Response
↓
Client
ตัวอย่าง Use Case
ขอข้อมูล Garage
ขอ Inventory
ขอ Character Data
ขอราคา
ขอ Permission
Callback สะดวก แต่ไม่ควรใช้ถี่เกินไปโดยไม่มีเหตุผล
㊱ Event กับ Callback ต่างกันอย่างไร
Event เป็นแนวคิด
ส่งข้อมูล
→ ไม่จำเป็นต้องรอ Return โดยตรง
Callback เป็นแนวคิด
Request
↓
รอผล
↓
Response
ตัวอย่าง
เปิดประตูอาจใช้ Event
แต่โหลดรายการรถจาก Database อาจเหมาะกับ Callback
ไม่มีคำตอบว่าต้องใช้แบบใดเสมอไป
เลือกตาม Flow ของระบบ
㊲ Server Script ทำงานกับ ESX อย่างไร
ESX มี Server-side API สำหรับระบบ เช่น
Player
Money
Job
Inventory
Callback
Resource ESX จำนวนมากมี
client.lua
+
server.lua
โดย Client จัด Gameplay
Server จัด Framework Data และ Database Logic
แต่ถึงใช้ ESX ก็ยังต้องทำ Server Validation
Framework ไม่ได้ทำให้ Event ทุกตัวปลอดภัยโดยอัตโนมัติ
㊳ Server Script ทำงานกับ QBCore อย่างไร
หลักการคล้ายกัน
Server Resource อาจใช้ QBCore API เพื่อ
หา Player
ตรวจ Job
เพิ่ม/ลดเงิน
จัด Item
Callback
Permission
แต่ Client Input ต้อง Validate เหมือนเดิม
อย่าคิดว่าเพียงเรียก
QBCore.Functions...
แล้ว Event จะปลอดภัยโดยอัตโนมัติ
Security อยู่ที่การออกแบบ Logic ทั้งระบบ
㊴ Server Script ทำงานกับ Qbox อย่างไร
Qbox ก็เป็น Framework Layer เหนือ FiveM Core
Server Script ยังคงต้องเข้าใจ
Player Source
Events
Exports
State
Database
Security
พื้นฐาน FiveM เหล่านี้ยังใช้เหมือนเดิม
การเข้าใจ Server Script Core ทำให้ย้าย Framework ง่ายขึ้นมาก
㊵ Server Script เก็บ Secret ได้ไหม
Server-side เหมาะกับข้อมูลที่ไม่ควรถูกส่งไป Client มากกว่า Client Script
เช่น
API Credentials
Private Configuration
Database Connection Information
แต่ก็ยังต้องจัดการอย่างปลอดภัย
ไม่ควร
Commit Secret ลง Public Git Repository
Print Secret ลง Log
ส่ง Secret ผ่าน Event ไป Client
Server-side ไม่ได้หมายความว่าสามารถจัดการ Secret แบบไม่ระวังได้
㊶ Shared Script ใส่ Secret ได้ไหม
ไม่ควร
เพราะ
shared_script 'config.lua'
หมายความว่า Script ถูกโหลดทั้ง Client และ Server
ดังนั้นหากไฟล์มี
API Key
Password
Private Token
ข้อมูลเหล่านั้นอาจไปถึง Client
ข้อมูลลับควรเก็บใน Server-only Context
㊷ Server Script ควรตรวจ Player Position ไหม
หาก Action มีข้อจำกัดตำแหน่งและมีผลสำคัญ ก็ควรตรวจฝั่ง Server เมื่อทำได้
ตัวอย่างระบบส่งของ
Client บอกว่า
ฉันถึงจุดส่งของแล้ว
Server ไม่ควรเชื่ออย่างเดียว
ควรตรวจ State และ Position Server-side ตามข้อมูล/Native ที่ระบบรองรับ
Cfx.re เองแนะนำให้ Event สำคัญตรวจสิ่งอย่าง Player Position, Money, Inventory, State Bags และ Permission ฝั่ง Server
㊸ Server Script ควรตรวจ Cooldown ไหม
ควรสำหรับ Event ที่อาจถูก Spam
ตัวอย่าง
local cooldowns = {}
จากนั้น Server ตรวจเวลาในการเรียกครั้งล่าสุด
Use Case เช่น
Reward
Shop
Job Complete
Admin Action
Expensive Database Request
Cooldown ไม่ใช่ Security ทั้งหมด แต่ช่วยลด Abuse และ Event Spam
㊹ Server Script ควร Rate Limit Event ไหม
Event ที่มีต้นทุนสูงหรือมีผลสำคัญควรพิจารณา Rate Limiting
ตัวอย่าง
Client Trigger
↓
ตรวจ Rate Limit
↓
Validate
↓
Business Logic
โดยเฉพาะ Event ที่
Query Database
สร้าง Entity
ส่งข้อมูลขนาดใหญ่
เรียก External API
ไม่ควรเปิดให้ Trigger ได้ไม่จำกัด
㊺ Server Script ควร Log อะไร
Logging มีประโยชน์กับ
Admin Actions
Money Transactions
Inventory Transactions
Security Rejection
Database Error
Resource Error
แต่ไม่ควร Log ทุกสิ่งทุก Tick
Logging มากเกินไปสามารถ
เพิ่ม Disk I/O
ทำ Log ใหญ่
หาเหตุการณ์จริงยาก
กระทบ Performance
จึงควร Log เฉพาะข้อมูลที่มีประโยชน์
㊻ Server Script Debug อย่างไร
เริ่มจาก
print('server script started')
หรือ
RegisterNetEvent('example:test', function()
local src = source
print('event from:', src)
end)
จากนั้นดู Server Console
เวลา Error ให้ไล่ตาม
Resource
↓
File
↓
Line
↓
Error Message
↓
Input
↓
State
ไม่ควรแก้ Code โดยเดา
㊼ Error Server Script ที่พบบ่อย
attempt to index a nil value
Variable หรือ Table ไม่มีข้อมูล
attempt to call a nil value
Function หรือ Export ไม่มีอยู่
Database Connection Failed
Database หรือ Connection String มีปัญหา
Export not found
Resource Dependency หรือชื่อ Export ไม่ตรง
Event ไม่ทำงาน
อาจเป็น
Event Name ไม่ตรง
Resource ไม่ Start
Context ผิด
Register ผิด
Client ไม่ได้ Trigger
ให้ตรวจ Flow ทีละจุด
㊽ Server Console สำคัญอย่างไร
Server Console เป็นหนึ่งในเครื่องมือสำคัญที่สุดของ FiveM Developer
ช่วยดู
Resource Start/Stop
Lua Error
JavaScript Error
C# Error
Database Error
Server Warning
Script Print
Hitch Warning
ถ้าระบบไม่ทำงาน ควรดู Console ก่อน Search Error แบบสุ่ม
ข้อความ Error มักบอก File และ Line ที่เกี่ยวข้องอยู่แล้ว
㊾ Server Script Restart ได้ไหม
ได้
ใช้คำสั่ง เช่น
restart my_resource
หรือ
ensure my_resource
ตามสถานะ Resource
แต่ต้องระวัง Resource State
เช่น
Cache
Temporary Player Data
Database Transaction
Server-created Entity
Running Threads
Resource ที่ดีควรออกแบบ Lifecycle ให้รับมือ Start/Stop/Restart ได้
㊿ Resource Restart แล้ว Player Data หายไหม
ขึ้นอยู่กับว่าเก็บไว้ที่ไหน
ถ้าเก็บเฉพาะ
local players = {}
ข้อมูลใน Memory ของ Resource จะหายเมื่อ Resource Restart
ถ้าต้องการ Persistence ต้องบันทึกลง Database หรือ Storage ที่เหมาะสม
ดังนั้นควรแยก
Runtime State
กับ
Persistent Data
ให้ออกจากกัน
51 Server Script ควร Cache Database Data ไหม
บางกรณีควร
ตัวอย่างข้อมูลที่ถูกอ่านบ่อยแต่เปลี่ยนไม่ถี่ เช่น
Item Config
Job Config
Static Data
สามารถ Cache เพื่อไม่ Query ซ้ำ
แต่ข้อมูลอย่างเงินหรือ Inventory อาจต้องออกแบบ Consistency ให้ดี
อย่า Cache ทุกอย่างโดยไม่มี Strategy
เพราะจะเกิดปัญหา Data ไม่ตรง Database ได้
52 Server Script ควรใช้ Transaction เมื่อไร
Database Transaction เหมาะกับ Operation ที่ต้องสำเร็จหลายขั้นพร้อมกัน
เช่น
ซื้อรถ
↓
หักเงิน
+
เพิ่มรถ
ถ้าหักเงินสำเร็จแต่เพิ่มรถไม่สำเร็จ ข้อมูลจะผิด
Transaction ช่วยให้ Operation ที่เกี่ยวข้องถูก Commit หรือ Rollback เป็นชุดตาม Database ที่รองรับ
ระบบการเงินควรให้ความสำคัญกับ Data Integrity มากเป็นพิเศษ
53 Server Script ควรแยก Business Logic ออกจาก Event ไหม
ควรสำหรับ Project ใหญ่
แทนที่จะเขียน
RegisterNetEvent('shop:buy', function(...)
-- 200 บรรทัด
end)
ควรแยก Function
local function buyItem(src, itemName, amount)
-- validation
-- business logic
end
จากนั้น Event เรียก
RegisterNetEvent('shop:buy', function(itemName, amount)
local src = source
buyItem(
src,
itemName,
amount
)
end)
ช่วย
Test ง่าย
อ่านง่าย
Reuse ได้
ลด Event Handler ขนาดใหญ่
54 Server Script ควรจัด Folder อย่างไร
Resource ใหญ่สามารถแยก
my_resource/
├── fxmanifest.lua
├── shared/
│ └── config.lua
├── client/
│ └── main.lua
└── server/
├── main.lua
├── players.lua
├── database.lua
└── security.lua
แล้ว Manifest
shared_scripts {
'shared/*.lua'
}
client_scripts {
'client/*.lua'
}
server_scripts {
'server/*.lua'
}
Structure ที่ดีช่วยให้ Resource โตได้โดยไม่กลายเป็นไฟล์เดียวหลายพันบรรทัด
55 Server Script Performance ควรดูอะไรบ้าง
ตรวจ
CPU
Server Tick
Hitch
Database Query
Event Rate
Player Loop
Entity Count
Memory
External API
อย่า Optimize จากความรู้สึก
ใช้ Profiler, Console, Database Slow Query และข้อมูลจริงเพื่อหาปัญหา
56 สิ่งที่ไม่ควรทำใน Server Script
หลีกเลี่ยง
เชื่อ Client Input
โดยไม่ Validate
Query Database ถี่เกินไป
โดยไม่มี Cache/เหตุผล
เปิด Network Event ทุกอย่าง
แม้ Event เป็น Server-only
สร้าง Entity โดยไม่ Cleanup
เก็บ Player Data แล้วไม่ลบเมื่อ Disconnect
ส่งข้อมูลลับให้ Client
ทำ Heavy Loop ถี่เกินไป
ให้ Client กำหนด Reward
ทั้งหมดนี้เป็นสาเหตุของทั้ง Security และ Performance Problem
57 Checklist ก่อนสร้าง Server Event
ก่อนเปิด Event ให้ Client เรียก ลองถาม
① Event นี้ต้อง Networked จริงไหม
② Client ส่งข้อมูลอะไรมา
③ Server ตรวจ Type หรือยัง
④ Server ตรวจ Range หรือยัง
⑤ Server ตรวจ Permission หรือยัง
⑥ Server ตรวจ Money/Item หรือยัง
⑦ Server ตรวจ Position/State หรือยัง
⑧ ต้องมี Cooldown หรือ Rate Limit ไหม
⑨ Event นี้ Query Database หนักไหม
⑩ Client สามารถกำหนด Reward เองหรือไม่
ถ้าข้อสุดท้ายตอบว่า “ใช่” ควรกลับไปออกแบบใหม่
58 Server Script เหมาะกับอะไรที่สุด
ถ้าจะสรุปสั้น ๆ Server Script เหมาะกับ
Authority
Validation
Persistence
Coordination
คือ
Authority
ตัดสินข้อมูลสำคัญ
Validation
ตรวจ Request จาก Client
Persistence
จัดการ Database
Coordination
ประสานผู้เล่นและ Resource หลายตัว
นี่คือเหตุผลที่ Server Script เป็นหัวใจของ FiveM Server Architecture
59 Client กับ Server ควรแบ่งงานอย่างไร
ตัวอย่างระบบ Garage
Client
แสดง Marker
เปิด Menu
หา Vehicle
Animation
Camera
Server
โหลดรถจาก Database
ตรวจ Ownership
ตรวจ Permission
บันทึกสถานะรถ
Validate Request
Flow ที่เหมาะคือ
Client UX
↓
Server Authority
↓
Client Result
ถ้าแบ่ง Responsibility ชัด Resource จะ Debug และ Secure ง่ายขึ้นมาก
60 Server Script สำคัญแค่ไหนสำหรับ FiveM Developer
สำคัญมาก
Developer ที่เขียน Client Effect สวยแต่ไม่เข้าใจ Server Logic อาจสร้าง Script ที่
โกงง่าย
ข้อมูลผิด
Database พัง
Server หน่วง
Maintain ยาก
ดังนั้นถ้าตั้งใจเป็น FiveM Developer จริง ต้องเข้าใจ Server Script อย่างน้อยเรื่อง
Events
source
Validation
Database
Permissions
Security
Resource Lifecycle
Performance
ให้แน่น
คำถามที่พบบ่อยเกี่ยวกับ Server Script FiveM
Server Script FiveM คืออะไร
คือ Script ที่ทำงานบน FXServer และใช้จัดการ Logic กลางของ Server
Server Script เขียนด้วยภาษาอะไร
FiveM รองรับ Lua, JavaScript และ C# ตาม Server Scripting Runtime
server.lua ต้องชื่อแบบนี้ไหม
ไม่จำเป็น สามารถตั้งชื่ออื่นได้แล้วกำหนดผ่าน fxmanifest.lua
Server Script เชื่อม Database ได้ไหม
ได้ และ Database Logic โดยทั่วไปควรอยู่ Server-side
Server Script ให้เงิน Player ได้ไหม
ได้ผ่านระบบ Framework/Logic ที่เหมาะสม และ Server ควรเป็นผู้ตรวจและคำนวณ Reward
Server รับข้อมูลจาก Client อย่างไร
สามารถใช้ Network Event เช่น RegisterNetEvent รับ Event ที่ Client ส่งผ่าน TriggerServerEvent
Server เชื่อข้อมูล Client ได้ไหม
ไม่ควรเชื่อโดยตรง ข้อมูลสำคัญต้อง Validate ฝั่ง Server
Server Script ใช้ Native ได้ไหม
ได้สำหรับ Server-side Native ที่ FiveM รองรับ แต่ Native ไม่ได้ใช้ได้ทั้ง Client และ Server ทุกตัว
Server Script ทำให้ Server Lag ได้ไหม
ได้ หากมี Heavy Loop, Database Query จำนวนมาก, Event Spam หรือ Logic ที่ใช้ CPU สูง
Client Script กับ Server Script ต่างกันอย่างไร
Client ทำงานบนเครื่องผู้เล่นและเหมาะกับ Gameplay/UI ส่วน Server ทำงานบน FXServer และเหมาะกับ Authority, Validation และ Database
สรุป Server Script FiveM คืออะไร
Server Script FiveM คือ Script ที่ทำงานบน FXServer และเป็นส่วนสำคัญสำหรับ Logic ที่ต้องมี Authority และความน่าเชื่อถือสูงกว่า Client
งานที่เหมาะกับ Server ได้แก่
Player Data
Money
Items
Rewards
Permissions
Database
Server Events
Security
Transactions
Persistent Data
Architecture ที่ควรจำคือ
Client
↓
Request
↓
Server
↓
Validate
↓
Business Logic
↓
Database
↓
Response
อย่าออกแบบระบบเป็น
Client
↓
ส่งค่าที่ต้องการ
↓
Server เชื่อทั้งหมด
เพราะ Client สามารถถูกดัดแปลงหรือใช้เพื่อ Trigger Network Event ในรูปแบบที่ Developer ไม่คาดคิดได้
สำหรับผู้ที่กำลังเรียน FiveM Developer กับ comsiam การเข้าใจ Server Script จะเป็นพื้นฐานโดยตรงของหัวข้อ Event, TriggerServerEvent, TriggerClientEvent, Callback, Database และ Security ต่อจากนี้
เมื่อเข้าใจว่าหน้าที่ของ Client คืออะไร และ Server ควรรับผิดชอบอะไร คุณจะสามารถสร้าง Resource ที่ไม่เพียง “ใช้งานได้” แต่มีโครงสร้างที่ปลอดภัย ดูแลง่าย และรองรับการขยาย Server ในอนาคตได้ดีขึ้น ซึ่งเป็นพื้นฐานสำคัญของงาน FiveM Developer บน comsiam
Comments
Post a Comment