FiveM playerConnecting คืออะไร? วิธีตรวจผู้เล่นก่อนเข้า Server ทำ Allowlist และ Ban Check

 FiveM playerConnecting คือ Server Event ที่ทำงานในช่วงที่ผู้เล่นกำลังพยายามเชื่อมต่อเข้า Server โดย Developer สามารถใช้ Event นี้ตรวจ Identifier, ตรวจ Allowlist, ตรวจ Ban, เรียก Database/API และตัดสินใจว่าจะอนุญาตหรือปฏิเสธ Connection ก่อนที่ผู้เล่นจะเข้า Server สมบูรณ์ได้.

Cfx.re ยังมีระบบ deferrals สำหรับเลื่อนการตอบรับ Connection ออกไปชั่วคราว เหมาะกับงานที่ต้องรอผลแบบ Asynchronous เช่น Database Query หรือ Web API ก่อนตัดสินใจว่าจะให้ Player เข้า Server หรือไม่.

Meta SEO

Meta Title: FiveM playerConnecting คืออะไร? วิธีทำ Allowlist และ Ban Check

Meta Description: อธิบาย FiveM playerConnecting แบบละเอียด วิธีใช้ deferrals, GetPlayerIdentifiers, License Check, Allowlist, Ban Check และแก้ปัญหาผู้เล่นค้างตอน Connecting

Focus Keyword: FiveM playerConnecting

Related Keywords: FiveM deferrals, FiveM allowlist, FiveM whitelist, FiveM ban check, GetPlayerIdentifiers, FiveM connecting script

สารบัญ

① playerConnecting คืออะไร

playerConnecting เป็น Server-side Event ที่ถูก Trigger เมื่อ Player กำลังพยายามเชื่อมต่อเข้า Server.

โครงสร้าง Lua พื้นฐานมีลักษณะ:

AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
    local src = source

    print(playerName .. ' is connecting')
end)

ใน Event นี้สามารถตรวจข้อมูลที่จำเป็นก่อน Player ผ่านเข้าสู่ขั้นตอนถัดไปของ Connection

② playerConnecting ทำงานตอนไหน

ลำดับเชิงแนวคิดคือ:

Player กดเข้า Server
↓
เริ่ม Connection
↓
playerConnecting
↓
ตรวจ Identifier / Allowlist / Ban
↓
อนุญาตหรือปฏิเสธ
↓
Player เข้า Server ต่อ

Cfx.re ระบุว่า Event นี้เกิดในช่วงที่ Player กำลัง Connecting และสามารถยกเลิกเพื่อ Reject Player ได้ในกรณีที่ยังไม่ได้ Yield.

③ playerConnecting มี Parameters อะไร

Cfx.re ระบุ Parameters หลัก ได้แก่:

playerName
setKickReason
deferrals

รวมถึง source ซึ่งในช่วงนี้เป็น Temporary Player ID ที่ใช้ได้กับ Function บางส่วนเท่านั้น.

④ playerName คืออะไร

playerName คือชื่อแสดงผลของ Player ที่กำลัง Connecting.

ตัวอย่าง:

AddEventHandler('playerConnecting', function(playerName)
    print(('Player %s is connecting'):format(playerName))
end)

ไม่ควรใช้ Player Name เป็น Persistent Account Key เพราะชื่อแสดงผลไม่ใช่ Identifier หลักของ Account

⑤ setKickReason คืออะไร

setKickReason ใช้กำหนดข้อความเหตุผลในกรณี Event ถูก Cancel เพื่อปฏิเสธ Connection.

ตัวอย่างเชิงโครงสร้าง:

AddEventHandler('playerConnecting', function(playerName, setKickReason)
    setKickReason('You cannot join this server.')
    CancelEvent()
end)

สำหรับระบบที่ต้องรอ Database หรือ API ควรใช้ Deferrals แทนวิธีนี้

⑥ source ใน playerConnecting คืออะไร

Cfx.re ระบุว่า source ใน playerConnecting เป็น Temporary Player ID และใช้ได้กับชุด Function ที่จำกัดในช่วง Connection นี้.

ดังนั้นควรเก็บค่าไว้ตอนเริ่ม Handler:

local src = source

โดยเฉพาะก่อนทำงานแบบ Async

⑦ Temporary ID ต่างจาก Player ID หลังเข้า Server

เมื่อ Player Connecting อยู่ จะยังใช้ Temporary ID

Cfx.re มี Event playerJoining ซึ่งเกิดเมื่อ Player ได้รับ NetID ที่ Assign สมบูรณ์แล้ว และเอกสารระบุ oldID เป็น TempID เดิมจากช่วง playerConnecting.

จึงไม่ควรนำ Temporary source ไปใช้เป็น Persistent Database Identifier

⑧ ควรใช้ Identifier แทน source สำหรับ Database

หากต้องการผูกข้อมูล Player ข้ามหลาย Session ให้ใช้ Identifier ที่เหมาะสมแทน Server/Temporary ID

Cfx.re มี GetPlayerIdentifiers() ซึ่งคืนรายการ Identifiers ของ Player เช่น license, license2, fivem, steam, discord และ ip ตามที่มีอยู่จริง.

⑨ deferrals คืออะไร

Deferrals คือระบบสำหรับ เลื่อนการตอบรับ Connection

เหมาะกับกรณี:

  • Query Database

  • ตรวจ Allowlist

  • ตรวจ Ban

  • เรียก Web API

  • ตรวจ Account Status

Cfx.re ระบุชัดว่า Deferrals ถูกออกแบบสำหรับงานที่ต้องรอ Async Task ก่อน Connection จะเสร็จสมบูรณ์.

⑩ deferrals.defer() ใช้ทำอะไร

เริ่ม Deferral ด้วย:

deferrals.defer()

หลังเรียก defer() Cfx.re กำหนดให้ต้อง รออย่างน้อยหนึ่ง Tick ก่อนเรียก update, presentCard หรือ done.

ตัวอย่าง:

deferrals.defer()

Wait(0)

deferrals.update('Checking your account...')

⑪ ทำไมต้อง Wait หลัง defer

เพราะ Cfx.re ระบุ Requirement ว่าต้องรออย่างน้อยหนึ่ง Tick หลัง deferrals.defer() ก่อนเรียก Method ถัดไป.

ดังนั้นไม่ควรเขียน:

deferrals.defer()
deferrals.done()

ติดกันทันที

⑫ deferrals.update() ใช้ทำอะไร

ใช้ส่งข้อความ Progress ให้ Player ระหว่างที่ Server กำลังตรวจสอบข้อมูล.

ตัวอย่าง:

deferrals.update('กำลังตรวจสอบ Allowlist...')

จากนั้น Server สามารถ Query Database ต่อได้

⑬ ข้อความ Update ควรเขียนอย่างไร

ควรสั้นและชัด เช่น:

กำลังตรวจสอบบัญชี...
กำลังตรวจสอบสิทธิ์เข้า Server...
กำลังตรวจสอบข้อมูลผู้เล่น...

ไม่ควรแสดงรายละเอียด Internal System, Query หรือข้อมูลสำคัญที่ Player ไม่จำเป็นต้องรู้

⑭ deferrals.done() คืออะไร

deferrals.done() ใช้ปิด Deferral

หากเรียกโดยไม่มี Failure Reason Player จะได้รับอนุญาตให้ Connect ต่อ แต่หากใส่ข้อความ Failure Reason Connection จะถูกปฏิเสธและ Player จะเห็นข้อความนั้น.

อนุญาต:

deferrals.done()

ปฏิเสธ:

deferrals.done('คุณยังไม่มีสิทธิ์เข้า Server นี้')

⑮ ต้อง Wait ก่อน done ด้วยหรือไม่

Cfx.re ระบุว่าหลังเรียก Deferral Method ก่อนหน้า จะต้องรออย่างน้อยหนึ่ง Tickก่อนเรียก done().

ดังนั้นเมื่อเขียนระบบ Connection ควรรักษา Deferral Flow ให้ถูกต้อง

⑯ presentCard คืออะไร

deferrals.presentCard() สามารถส่ง Adaptive Card ให้ Player ระหว่าง Connection และสามารถกำหนด Callback เมื่อ Playerกด Action.Submit ได้.

เหมาะกับระบบ Connection UI ขั้นสูง

แต่ Server ทั่วไปไม่จำเป็นต้องใช้ หากต้องการเพียงตรวจ Database แล้ว Allow/Deny

⑰ handover คืออะไร

deferrals.handover() ใช้ส่งข้อมูลบางชุดให้ Client เพื่อนำไปใช้ภายหลัง และ FiveM Loading Screen สามารถเข้าถึงข้อมูลนี้ผ่าน window.nuiHandoverData.

ตัวอย่าง Official Documentation ใช้ส่งชื่อ Player ไปยัง Loading Screen.

⑱ ตรวจ Identifier ตอน playerConnecting ได้ไหม

ได้

Cfx.re ระบุว่า GetPlayerIdentifiers() เหมาะกับการใช้งานร่วมกับ playerConnecting และคืน Identifiers ของ Player ที่มีอยู่ใน Session.

ตัวอย่าง:

local identifiers = GetPlayerIdentifiers(source)

for _, identifier in ipairs(identifiers) do
    print(identifier)
end

⑲ Identifier ที่ตรวจได้มีอะไรบ้าง

Documentation ปัจจุบันระบุประเภท:

steam
discord
license
license2
fivem
ip

โดย license และ license2 มาจาก Rockstar Online Services และ fivem เป็น Cfx User ID.

⑳ ตัวอย่างหา License Identifier

local function getIdentifierByPrefix(src, prefix)
    for _, identifier in ipairs(GetPlayerIdentifiers(src)) do
        if identifier:sub(1, #prefix + 1) == prefix .. ':' then
            return identifier
        end
    end

    return nil
end

จากนั้น:

local license = getIdentifierByPrefix(source, 'license')

ควรตรวจ nil ก่อนนำไป Query Database

㉑ อย่าสมมติว่าทุกคนมีทุก Identifier

GetPlayerIdentifiers() คืนเฉพาะ Identifier ที่มีอยู่สำหรับ Player นั้น และ Cfx.re แยกหลาย Provider ออกจากกัน.

ดังนั้น Code แบบนี้ไม่ควร Assume ว่าต้องเจอ discord: เสมอ

if not discord then
    -- จัดการกรณีไม่มี identifier
end

㉒ license2 อาจเหมือน license

Cfx.re ระบุว่า license2 สำหรับผู้ใช้ Steam สามารถมีค่าเหมือนกับ license ได้.

ดังนั้นอย่าออกแบบ Database โดยสมมติว่าทั้งสองค่าต้องแตกต่างกันเสมอ

㉓ playerConnecting ใช้ทำ Allowlist ได้อย่างไร

แนวคิดคือ:

Player Connecting
↓
ดึง Identifier
↓
Query Allowlist
↓
พบ → Allow
ไม่พบ → Reject

Deferrals เหมาะกับขั้นตอนนี้เพราะสามารถรอ Database Query ก่อนตัดสิน Connection ได้.

㉔ ตัวอย่าง Allowlist แบบง่าย

AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
    local src = source

    deferrals.defer()
    Wait(0)

    deferrals.update('กำลังตรวจสอบสิทธิ์เข้า Server...')

    local allowed = checkAllowlist(src)

    Wait(0)

    if not allowed then
        deferrals.done('คุณยังไม่ได้รับอนุญาตให้เข้า Server')
        return
    end

    deferrals.done()
end)

checkAllowlist() ในตัวอย่างเป็น Function สมมติ ซึ่ง Server จริงต้องเชื่อมกับ Database หรือระบบ Allowlist ของตัวเอง

㉕ Allowlist ไม่จำเป็นต้องเขียนเองทั้งหมด

txAdmin มี Whitelist System ที่รองรับรูปแบบต่างๆ เช่น Discord Member, Discord Role, Approved License และ Admin-only ตามฟีเจอร์ปัจจุบันของ Cfx.re.

ดังนั้น Server Owner ควรพิจารณาก่อนว่าจำเป็นต้องสร้าง Resource Allowlist ใหม่เองจริงหรือไม่

㉖ txAdmin มี Permission สำหรับ Whitelist ไหม

มี Permission:

players.whitelist

สำหรับจัดการ Whitelist Player ใน txAdmin.

จึงสามารถแยก Staff ที่มีสิทธิ์ Approve Player ออกจาก Staff ที่มีสิทธิ์ Restart Server หรือแก้ Config ได้

㉗ playerConnecting ใช้ตรวจ Ban ได้ไหม

ได้

หน้า Official playerConnecting ของ Cfx.re มีตัวอย่างตรวจ License Identifier กับ Ban List ก่อนตัดสินใจอนุญาตหรือปฏิเสธ Connection โดยตรง.

นี่เป็นหนึ่งใน Use Case หลักของ Event นี้

㉘ Flow ของ Ban Check

playerConnecting
↓
GetPlayerIdentifiers
↓
หา License
↓
Query Ban Database
↓
ไม่ Ban → done()
Ban → done("เหตุผล")

ควร Query ผ่าน Database อย่างมีประสิทธิภาพและหลีกเลี่ยง Query ซ้ำโดยไม่จำเป็น

㉙ Ban Check ต้องใช้ Deferrals ไหม

ถ้า Ban Check เป็น Async Database Query ก็ควรใช้ Deferrals เพราะ Cfx.re ออกแบบ Deferrals สำหรับงานที่ต้องรอ Async Task ก่อน Connection Complete.

ถ้าไม่ Deferral แล้ว Handler จบก่อน Query เสร็จ อาจทำให้ Logic ไม่ทำงานตามที่ตั้งใจ

㉚ txAdmin มีระบบ Ban อยู่แล้วหรือไม่

มี

Cfx.re ระบุว่า txAdmin Player Manager มีระบบ Ban แบบ Temporary และ Permanent รวมถึง Warning, Whitelist และ Player Database.

จึงควรหลีกเลี่ยงการสร้างระบบซ้ำซ้อนหาก txAdmin ตอบโจทย์ Server อยู่แล้ว

㉛ txAdmin มี Permission Ban แยกไหม

มี:

players.ban

สำหรับ Ban/Unban Player และยังมี Permission แยกสำหรับ Warn, Kick และ Whitelist.

ช่วยลดการแจก Admin Permission มากเกินจำเป็น

㉜ ปฏิเสธ Connection ด้วย deferrals.done

วิธีที่เหมาะกับ Async Flow คือ:

deferrals.done('คุณไม่มีสิทธิ์เข้า Server นี้')

Cfx.re ระบุว่าหาก failureReason ถูกส่งเข้า done() Connection จะถูกปฏิเสธและ Player จะเห็นข้อความดังกล่าว.

㉝ ข้อความ Reject ควรชัดเจน

ตัวอย่างที่ดี:

คุณยังไม่ได้รับการอนุมัติให้เข้า Server
บัญชีนี้ถูกระงับการเข้าใช้งาน
ไม่สามารถตรวจสอบบัญชีได้ กรุณาลองใหม่

ควรหลีกเลี่ยงข้อความ Error ทางเทคนิคยาวๆ ที่ผู้เล่นแก้เองไม่ได้

㉞ อย่าเปิดข้อมูล Internal ใน Reject Message

ไม่ควรแสดง:

  • Database Query

  • Table Name

  • Internal API

  • Secret

  • Stack Trace

ให้ผู้เล่นเห็น

เก็บ Technical Details ไว้ใน Server Logs และให้ Player เห็นเพียงข้อความที่จำเป็นต่อการแก้ปัญหา

㉟ CancelEvent กับ deferrals.done ต่างกันอย่างไร

Cfx.re ระบุว่า playerConnecting สามารถ Cancel เพื่อ Reject Player ได้ทันที หาก Handler ยังไม่ได้ Yield.

แต่เมื่อมี Async Work เช่น Database Query ให้ใช้ Deferrals เพื่อเลื่อนการตัดสินใจ Connection ไปจนกว่างานจะเสร็จ.

㊱ Connection Check หลายตัวควรจัดลำดับอย่างไร

ตัวอย่าง:

Identifier
↓
Allowlist
↓
Ban
↓
Account Status
↓
Database Ready
↓
Allow

ควรทำ Checks ที่เร็วและราคาถูกก่อน Checks ที่ใช้ Database/API หนักกว่าเมื่อเป็นไปได้

และควรหยุดทันทีเมื่อมีเหตุผลที่แน่นอนว่าจะ Reject

㊲ อย่า Query Database ซ้ำหลาย Resource

หาก Server มี Resource A, B, C ต่างคนต่าง Query Player เดียวกันใน playerConnecting จำนวนมาก อาจเพิ่ม Connection Latency

ควรออกแบบ Connection Pipeline ให้ชัดว่า Resource ใดรับผิดชอบ

  • Identity

  • Allowlist

  • Ban

  • Account Initialization

เพื่อลดความซ้ำซ้อน

㊳ playerConnecting ค้างทำให้ Player ค้างหน้า Connecting ได้หรือไม่

หาก Resource เริ่ม Deferral แล้วไม่ Finalize ด้วย deferrals.done() อย่างถูกต้อง Connection สามารถค้างรอ Logic นั้นได้ตาม Flow ของ Deferral

Cfx.re ระบุว่า done() เป็น Method สำหรับ Finalize Deferral.

จึงควรตรวจทุก Code Path ว่าสุดท้ายต้องถึง Allow หรือ Reject

㊴ ทุก Branch ต้องจบด้วย done

ตัวอย่างที่ควรระวัง:

if databaseError then
    print('Database error')
    return
end

ถ้าอยู่ใน Deferral Flow แล้ว Return โดยไม่ done() Player อาจไม่ได้รับ Final Result

ควรเขียน:

if databaseError then
    deferrals.done('ไม่สามารถตรวจสอบข้อมูลได้ กรุณาลองใหม่')
    return
end

㊵ ใช้ Timeout กับ External API

ถ้า Allowlist ต้องเรียก External Service ควรมี Timeout และ Failure Handling ของระบบเอง

ไม่ควรปล่อย Connection รอ API แบบไม่มีจุดสิ้นสุด

Cfx.re ออกแบบ Deferrals ให้รองรับการรอ Web API/Async Task แต่ Logic Timeout ของระบบที่เรียกใช้งานยังเป็นหน้าที่ของ Resource Developer.

㊶ Player ค้าง Checking Allowlist

ตรวจ:

  1. deferrals.defer() ถูกเรียกหรือไม่

  2. Wait อย่างน้อยหนึ่ง Tick หรือไม่

  3. Database Callback กลับมาหรือไม่

  4. ทุก Branch มี deferrals.done() หรือไม่

  5. Resource มี Error หรือไม่

  6. Database/API Timeout หรือไม่

เริ่มจาก txAdmin Live Console ซึ่งมี Log, Command History และ Search.

㊷ Player เข้าไม่ได้หลังติดตั้ง Whitelist Script

Stop Resource ใหม่ใน Development Environment แล้วทดสอบใหม่

หาก Player เข้าได้ทันที มีน้ำหนักว่า Connection Logic ของ Resource ใหม่เกี่ยวข้อง

จากนั้นดู Console ในช่วง playerConnecting

อย่าเริ่มจากเปิด Port หรือเปลี่ยน DNS หากปัญหาเริ่มตรงกับการติดตั้ง Connection Resource ชัดเจน

㊸ Player ทุกคนถูก Reject

ตรวจ:

  • Identifier ที่ Resource คาดหวัง

  • Query Database

  • Allowlist Table

  • Default Result

  • Error Handling

  • done() Message

โดยเฉพาะ Code ที่เขียนว่า:

if not license then
    reject
end

ต้องตรวจก่อนว่า Resource เลือก Identifier Type ที่เหมาะสมกับ Environment จริง

㊹ Identifier เป็น nil

ใช้:

GetPlayerIdentifiers(source)

แล้ว Print รายการใน Development Environment เพื่อดูว่าผู้เล่นมี Identifier ประเภทใดจริง

Cfx.re ระบุประเภทที่อาจมีหลายแบบ และไม่ควรถือว่าทุก Provider ต้องปรากฏกับ Player ทุกคน.

㊺ Database ช้า ทำให้ Connecting ช้า

ถ้า playerConnecting รอ Database Query Response การตอบ Connection ก็ต้องรอ Logic นั้นตาม Deferral Flow.

ดังนั้น Query ที่ทำตอน Connect ควรจำกัดเฉพาะข้อมูลที่จำเป็น

งาน Initialization ที่ไม่จำเป็นต้อง Block Connection อาจย้ายไปทำหลัง Player เข้าได้ตาม Architecture ของ Server

㊻ External API ล่มควรทำอย่างไร

ต้องกำหนด Policy ให้ชัด

เช่น:

API Error
↓
Reject พร้อมข้อความชั่วคราว

หรือ Server บางระบบอาจมี Cache/Fallback ตาม Requirement

สิ่งสำคัญคืออย่าปล่อย Deferral ค้างโดยไม่มี Final Result

㊼ ใช้ Loading Screen แสดงข้อมูล Connection ได้ไหม

ได้

Cfx.re ระบุว่า deferrals.handover() สามารถส่งข้อมูลจาก Server Script ไปยัง Loading Screen ผ่าน window.nuiHandoverData.

สามารถใช้กับข้อมูล Public เช่นชื่อ Player หรือข้อมูล UI ที่เหมาะสม

㊽ อย่าส่ง Secret ผ่าน handover

Handover ส่งข้อมูลให้ฝั่ง Client/Loading Screen ใช้งาน จึงไม่ควรนำข้อมูลลับของ Server ไปส่งผ่านช่องทางนี้

ใช้เฉพาะข้อมูลที่ตั้งใจให้ Client เห็น

㊾ txAdmin หรือเขียน Allowlist เองดีกว่า

ใช้ txAdmin เมื่อ

  • ต้องการระบบพร้อมใช้

  • ต้องการ Approved License

  • ใช้ Discord Role/Member

  • ต้องการ Staff Manage ผ่าน Panel

Cfx.re ระบุว่า txAdmin มี Whitelist System หลายรูปแบบอยู่แล้ว.

เขียน Resource เองเมื่อ

  • มี Business Logic เฉพาะ

  • ต้องเชื่อม Database ภายใน

  • ต้องใช้ Account System ของ Server

  • ต้องทำ Workflow ที่ txAdmin ไม่รองรับ

㊿ Checklist playerConnecting ก่อนใช้ Production

ตรวจว่า:

  1. Resource Start ปกติ

  2. playerConnecting Trigger

  3. เก็บ source ถูกต้อง

  4. Identifier Check รองรับกรณีไม่มีบาง Type

  5. deferrals.defer() ถูกใช้เมื่อมี Async

  6. Wait อย่างน้อยหนึ่ง Tick

  7. update() ทำงาน

  8. Database มี Timeout

  9. Allowlist Query ถูก

  10. Ban Query ถูก

  11. ทุก Branch มี Final done()

  12. Reject Message ชัดเจน

  13. ไม่เปิดข้อมูล Internal

  14. Console ไม่มี Error

  15. Player ที่ Allowed เข้าได้

  16. Player ที่ไม่ Allowed ถูก Reject ถูกต้อง

  17. Player ที่ถูก Ban ถูก Reject

  18. Database ล่มมี Failure Handling

  19. Restart Resource แล้วระบบยังทำงาน

  20. Restart Server แล้วยังทำงาน

ตัวอย่าง playerConnecting ตรวจ License

local function getLicense(src)
    for _, identifier in ipairs(GetPlayerIdentifiers(src)) do
        if identifier:sub(1, 8) == 'license:' then
            return identifier
        end
    end

    return nil
end

AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
    local src = source

    deferrals.defer()
    Wait(0)

    deferrals.update('กำลังตรวจสอบข้อมูลผู้เล่น...')

    local license = getLicense(src)

    Wait(0)

    if not license then
        deferrals.done('ไม่สามารถตรวจสอบบัญชีของคุณได้')
        return
    end

    deferrals.done()
end)

ตัวอย่างนี้แสดงแนวคิด GetPlayerIdentifiers + Deferrals ตาม APIs ของ Cfx.re เท่านั้น ระบบ Production ต้องเพิ่ม Database, Logging และ Error Handling ของตัวเอง.

ตัวอย่าง Allowlist Flow

AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
    local src = source

    deferrals.defer()
    Wait(0)

    deferrals.update('กำลังตรวจสอบ Allowlist...')

    local allowed = IsPlayerAllowed(src)

    Wait(0)

    if not allowed then
        deferrals.done('บัญชีของคุณยังไม่ได้รับอนุญาตให้เข้า Server')
        return
    end

    deferrals.done()
end)

IsPlayerAllowed() เป็น Function สมมติสำหรับแสดง Architecture เท่านั้น

ตัวอย่าง Ban Check Flow

AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
    local src = source

    deferrals.defer()
    Wait(0)

    deferrals.update('กำลังตรวจสอบสถานะบัญชี...')

    local banned, reason = IsPlayerBanned(src)

    Wait(0)

    if banned then
        deferrals.done(reason or 'บัญชีนี้ไม่สามารถเข้า Server ได้')
        return
    end

    deferrals.done()
end)

Cfx.re มีตัวอย่าง Official ที่ตรวจ License Identifier กับ Ban List ภายใน playerConnecting เช่นกัน.

FAQ FiveM playerConnecting

FiveM playerConnecting คืออะไร

เป็น Server Event ที่ Trigger เมื่อ Player กำลังพยายามเชื่อมเข้า Server และสามารถใช้ตรวจข้อมูลก่อนอนุญาต Connection.

playerConnecting ใช้ทำ Whitelist ได้ไหม

ได้ โดยใช้ Identifier และ Deferrals เพื่อตรวจ Database หรือระบบ Allowlist ก่อนเรียก deferrals.done().

playerConnecting ใช้ตรวจ Ban ได้ไหม

ได้ Cfx.re มีตัวอย่าง Official ที่ตรวจ License Identifier กับ Ban List ใน Event นี้โดยตรง.

deferrals.defer ต้อง Wait ไหม

ต้องรออย่างน้อยหนึ่ง Tick ก่อนเรียก update, presentCard หรือ done ตาม Documentation ของ Cfx.re.

deferrals.done ไม่มีข้อความหมายถึงอะไร

หมายถึง Finalize Deferral และอนุญาต Player ให้ Connect ต่อ หากไม่มี Failure Reason.

deferrals.done มีข้อความหมายถึงอะไร

Connection จะถูกปฏิเสธ และ Player จะเห็นข้อความ Failure Reason ที่กำหนด.

source ใน playerConnecting ใช้เป็น Database ID ได้ไหม

ไม่ควร เพราะในช่วงนี้ source เป็น Temporary Player ID; สำหรับข้อมูลถาวรควรใช้ Player Identifier ที่เหมาะสมแทน.

txAdmin มี Whitelist อยู่แล้วไหม

มี โดย Cfx.re ระบุว่า txAdmin รองรับ Whitelist แบบ Discord Member, Discord Role, Approved License และ Admin-only.

ประเด็นสำคัญ

FiveM playerConnecting เป็นหัวใจของระบบตรวจผู้เล่น ก่อนเข้า Server เพราะ Event ทำงานระหว่าง Connection และสามารถใช้ร่วมกับ GetPlayerIdentifiers() เพื่อตรวจ license, license2, fivem, steam, discord หรือ Identifier อื่นที่มีอยู่จริงของ Player.

ถ้าต้องรอ Database หรือ Web API ให้ใช้ Deferrals โดยลำดับพื้นฐานคือ defer() → รออย่างน้อยหนึ่ง Tick → update() → ทำ Query → รอ Tick ตาม Requirement → done() เพื่อ Allow หรือ Reject Connection.

จุดที่ต้องระวังที่สุดคือ ทุกเส้นทางของ Code ต้อง Finalize Connection ไม่ว่าจะสำเร็จหรือผิดพลาด เพราะ deferrals.done() เป็นตัวจบ Deferral Flow และสามารถส่ง Failure Reason เพื่อปฏิเสธ Player ได้.

สำหรับ Server ที่ไม่ต้องการสร้างระบบเอง txAdmin มี Whitelist, Ban, Player Database และ Permission แยกสำหรับ players.whitelist และ players.ban อยู่แล้ว จึงควรตรวจความสามารถของ txAdmin ก่อนสร้างระบบซ้ำ.

สำหรับผู้อ่าน comsiam ให้จำสูตร “Connecting → Identifier → Deferral → Check → Done” และ comsiam แนะนำให้เริ่ม Connection Logic แบบเรียบง่ายก่อน แล้วเพิ่ม Allowlist, Ban และ API ทีละส่วน พร้อมตรวจ txAdmin Console ทุกครั้ง เพื่อป้องกัน Resource ตัวเดียวทำให้ผู้เล่นทั้ง Server ค้างอยู่หน้า Connecting

Comments

Popular posts from this blog

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

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

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