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

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด