หลักการคือ config/customer/08_integrations.lua ระบุชื่อ Resource/Export ส่วน config/functions เป็น Adapter แปลง signature ของ resource ภายนอก เพื่อไม่กระจาย export call ไปทั่ว Core

text
config/customer/08_integrations.lua = ชื่อ resource / export / option
config/functions/                 = แปลง API ของ resource ภายนอก
Core                              = business logic ของ nX_police

External Notification#

Toast ปกติทั้งหมดของ nX Police วิ่งผ่าน Functions.Client.Notify() จุดเดียว จึงเปลี่ยน Provider ได้โดยไม่แตะ client/server Core

1. เลือก Provider#

lua
Config.Notification = {
    Enabled = true,
    Provider = 'external',
    Duration = 4500,
    External = {
        Resource = 'my_notify',
        FallbackToInternal = true,
        TypeMap = {
            info = 'info',
            success = 'success',
            error = 'error',
            warning = 'warning'
        }
    }
}

Resource ใช้ตรวจว่า Notify ภายนอกอยู่สถานะ started ก่อนเรียก ถ้า Adapter ใช้ global/event ที่ไม่ต้องตรวจ resource สามารถปล่อยค่าว่างได้

2. เชื่อม Adapter จุดเดียว#

แก้เฉพาะ Functions.Client.ExternalNotify() ใน config/functions/client.lua ฟังก์ชันต้องคืน true เมื่อแสดงสำเร็จ หรือ false, reason เมื่อเรียกไม่ได้

lua
-- ตัวอย่าง Export
function Functions.Client.ExternalNotify(message, kind, duration, settings)
    exports['my_notify']:Notify(message, kind, duration)
    return true
end

-- ตัวอย่าง Event
-- function Functions.Client.ExternalNotify(message, kind, duration, settings)
--     TriggerEvent('my_notify:show', message, kind, duration)
--     return true
-- end

3. TypeMap#

Core ใช้ชนิดมาตรฐาน info, success, error, warning หาก Notify ปลายทางใช้ชื่ออื่นให้เปลี่ยนเฉพาะค่าฝั่งขวา เช่น warning = 'warn' หรือ info = 'inform'

4. Fallback ที่แนะนำ#

ตั้ง FallbackToInternal = true เพื่อให้ Toast ภายในทำงานแทนเมื่อ resource ภายนอกหยุด, restart, export error หรือ Adapter คืน false ถ้าปิด fallback ข้อความนั้นจะไม่แสดงเมื่อ External Provider ล้มเหลว

อย่าทำให้ข้อความสำคัญหาย
Production แนะนำเปิด FallbackToInternal เสมอ โดยเฉพาะข้อความคดี เงิน Mailbox Jail และ permission ที่ผู้เล่นต้องเห็นผลลัพธ์ทันที

5. อะไรถูกส่งไป External Notify#

ส่งออกเฉพาะ Toast ปกติ เท่านั้น ส่วน Dispatch Card, Jail HUD, Department Announcement, Police Command, Report Chat, Mailbox, Countdown และ overlay ที่มี layout เฉพาะยังใช้ UI ของ nX Police

6. ใช้ Notification pipeline จาก resource อื่น#

lua
-- Client
exports['nX_police']:Notify('บันทึกสำเร็จ', 'success', 4500)

-- Server
exports['nX_police']:NotifyPlayer(playerSource, 'คุณได้รับข้อความจากหน่วยงาน', 'info', 4500)

Public API ทั้งสองแบบจะผ่าน Locale/ResolveText, Provider, TypeMap และ fallback ชุดเดียวกับ nX Police

Inventory#

ค่า Default รองรับ nc_inventory หากใช้ Inventory อื่นให้แก้เฉพาะ Integration + Adapter ที่เปิดให้แก้

lua
Config.Integrations.Inventory = {
    Enabled = true,
    Resource = 'my_inventory',
    SearchExport = 'OpenPlayerInventory',
    AddExport = 'AddItem',
    RemoveExport = 'RemoveItem',
    UseExportForMutations = true
}

ยึดของเข้าตู้หน่วยงาน#

เมื่อ Inventory รองรับ Search hooks สามารถให้ของที่ยึดเข้า Agency Safe โดยตรง:

lua
exports['nX_police']:ShouldRouteSearchSeizure(officerSource, targetSource, itemName, itemCount, itemType, searchType)

exports['nX_police']:DepositSearchSeizure(officerSource, targetSource, itemName, itemCount, itemType, searchType)

บันทึกหลักฐานหลัง Remove สำเร็จ#

lua
exports['nX_police']:RecordSeizedEvidence(
    officerSource, suspectSource, itemName, amount, itemType, itemLabel, suspectName
)
เรียกหลังยึดสำเร็จเท่านั้น
RecordSeizedEvidence มีหน้าที่บันทึกหลักฐาน ไม่ควรเรียกก่อน Inventory ยืนยันการ Remove เพราะอาจทำให้ข้อมูลหลักฐานไม่ตรงของจริง

Optional Resources#

  • screenshot-basic — ใช้แนบ Screenshot ใน Discord Log เมื่อเปิด Event ที่รองรับ
  • Playpass / Profile Avatar — เปิดใช้ตาม Integration ที่เซิร์ฟเวอร์มีจริง