FiveM नोटिफिकेशन सिस्टम: टोस्ट्स, अलर्ट्स और ox_lib
एक परिष्कृत FiveM नोटिफिकेशन सिस्टम बनाएं। टोस्ट, प्रोग्रेस बार, रेडियल मेनू और ox_lib और शीर्ष स्क्रिप्ट क्लाइंट UI फीडबैक को कैसे संभालती हैं।
Agency Scripts
Agency Scripts के संस्थापक और प्रमुख डेवलपर
क्यों एक कस्टम नोटिफिकेशन सिस्टम बनाएं?
डिफ़ॉल्ट FiveM सूचनाएं कार्यात्मक हैं लेकिन दृश्य पॉलिश और लचीलापन की कमी है। अधिकांश रोलप्ले सर्वर सामान्य टेक्स्ट पॉपअप्स पर निर्भर करते हैं जो सभी समान दिखते हैं, जिससे खिलाड़ियों के लिए त्रुटि, सफलता पुष्टि, या सूचना अलर्ट के बीच अंतर करना मुश्किल हो जाता है। NUI के साथ निर्मित एक कस्टम नोटिफिकेशन सिस्टम आपको स्टाइलिंग, एनिमेशन, पोजिशनिंग, साउंड इफेक्ट्स, और कतारबद्ध व्यवहार पर पूर्ण नियंत्रण देता है। यह एक बुनियादी UI तत्व को कुछ ऐसा बनाता है जो आपके सर्वर की ब्रांड पहचान से मेल खाता है और खिलाड़ी अनुभव को काफी बेहतर बनाता है। इस ट्यूटोरियल में, हम Lua का उपयोग करके सर्वर और क्लाइंट साइड पर, HTML, CSS, और जावास्क्रिप्ट के साथ NUI फ्रंटेंड को पावर करते हुए, एक पूर्ण टोस्ट नोटिफिकेशन सिस्टम शुरू से बनाएंगे।
NUI लेयर सेट अप करना
FiveM में किसी भी कस्टम नोटिफिकेशन सिस्टम की नींव NUI (New UI) लेयर है। NUI आपको गेम के ऊपर HTML कंटेंट को ओवरले के रूप में रेंडर करने की अनुमति देता है, जिसका मतलब है कि आपके पास आधुनिक वेब तकनीकों की पूरी शक्ति उपलब्ध है। अपने रिसोर्स स्ट्रक्चर को एक के साथ बनाना शुरू करें fxmanifest.lua , एक क्लाइंट-साइड Lua स्क्रिप्ट, और एक html फोल्डर जिसमें आपकी UI फाइलें होती हैं। मैनिफेस्ट को आपकी NUI पेज घोषित करनी होती है और मैसेज हैंडलर रजिस्टर करने होते हैं ताकि आपकी Lua स्क्रिप्ट्स फ्रंटेंड के साथ संवाद कर सकें।
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
ui_page 'html/index.html'
files {
'html/index.html',
'html/style.css',
'html/script.js',
'html/sounds/*.ogg'
}
client_script 'client.lua'
server_script 'server.lua'
आपका html/index.html फ़ाइल न्यूनतम होनी चाहिए। इसमें केवल एक कंटेनर div होना चाहिए जहां नोटिफिकेशन को JavaScript द्वारा गतिशील रूप से इंजेक्ट किया जाएगा। HTML को हल्का रखें क्योंकि प्रत्येक नोटिफिकेशन तत्व प्रोग्रामेटिक रूप से बनाया और नष्ट किया जाता है। अपनी स्टाइलशीट और स्क्रिप्ट लिंक करें, और सुनिश्चित करें कि बॉडी का बैकग्राउंड पारदर्शी हो ताकि आपके नोटिफिकेशन के पीछे गेम की दुनिया दिखाई दे।
<!-- html/index.html -->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="notification-container"></div>
<script src="script.js"></script>
</body>
</html>
टॉस्ट सूचना CSS डिजाइन करना
टोस्टी सूचनाएं प्रकार द्वारा दृश्य रूप से अलग होनी चाहिए। अलग रंग योजनाएं परिभाषित करें सफलता, त्रुटि, जानकारी, और चेतावनी सूचनाएं। कंटेनर को स्क्रीन के ऊपर-दाएँ कोने में fixed पोजीशनिंग का उपयोग करके रखें, और सूचनाओं को छोटे अंतराल के साथ लंबवत स्टैक करें। प्रत्येक टोस्ट में subtle glassmorphism प्रभाव होना चाहिए जिसमें backdrop blur, प्रकार सूचित करने के लिए रंगीन बाएँ बॉर्डर, और smooth प्रवेश और निकास एनिमेशन शामिल हों। स्लाइड-इन के लिए CSS keyframes का उपयोग करें जो दाएँ से आता है और जब सूचना समाप्त होती है तो fade-out होता है।
/* html/style.css */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: transparent; font-family: 'Segoe UI', sans-serif; overflow: hidden; }
#notification-container {
position: fixed;
top: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 9999;
max-width: 380px;
width: 100%;
}
.toast {
background: rgba(15, 15, 25, 0.85);
backdrop-filter: blur(12px);
border-radius: 10px;
padding: 14px 18px;
border-left: 4px solid #3b82f6;
color: #e2e8f0;
animation: slideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
display: flex;
align-items: flex-start;
gap: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
.toast.success { border-left-color: #22c55e; }
.toast.error { border-left-color: #ef4444; }
.toast.warning { border-left-color: #f59e0b; }
.toast.info { border-left-color: #3b82f6; }
.toast-icon { font-size: 20px; flex-shrink: 0; margin-top: 2px; }
.toast-body { flex: 1; }
.toast-title { font-weight: 700; font-size: 14px; margin-bottom: 4px; }
.toast-msg { font-size: 13px; color: #94a3b8; line-height: 1.5; }
.toast-progress {
position: absolute;
bottom: 0; left: 0;
height: 3px;
background: currentColor;
border-radius: 0 0 0 10px;
animation: progress linear forwards;
}
@keyframes slideIn {
from { opacity: 0; transform: translateX(100px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideOut {
from { opacity: 1; transform: translateX(0); }
to { opacity: 0; transform: translateX(100px); }
}
@keyframes progress {
from { width: 100%; }
to { width: 0%; }
}
JavaScript नोटिफिकेशन क्यू बनाना
JavaScript परत Lua से आने वाले संदेशों को संभालती है, DOM तत्व बनाती है, कतार प्रबंधित करती है, और स्वचालित-dismissal को संभालती है। एक सूचना कतार आवश्यक है क्योंकि आप नहीं चाहते कि दस सूचनाएं एक साथ स्क्रीन पर जमा हों। दृश्य संख्या को अधिकतम पाँच तक सीमित करें, और किसी भी अधिभार सूचनाओं को कतारबद्ध करें ताकि वे पहले वाली समाप्त होने पर दिखाई दें। प्रत्येक सूचना की अवधि कॉन्फ़िगर करने योग्य होनी चाहिए, और सूचना पर क्लिक करने से वह तुरंत समाप्त हो जानी चाहिए। प्रत्येक टोस्ट के नीचे प्रगति बार खिलाड़ियों को एक दृश्य संकेत देता है कि सूचना स्क्रीन पर कितनी देर रहेगी।
// html/script.js
const container = document.getElementById('notification-container');
const MAX_VISIBLE = 5;
const queue = [];
let activeCount = 0;
const icons = {
success: '✔',
error: '✖',
warning: '⚠',
info: 'ℹ'
};
const sounds = {
success: new Audio('sounds/success.ogg'),
error: new Audio('sounds/error.ogg'),
warning: new Audio('sounds/warning.ogg'),
info: new Audio('sounds/info.ogg')
};
window.addEventListener('message', (event) => {
if (event.data.type === 'showNotification') {
addNotification(event.data);
}
});
function addNotification(data) {
if (activeCount >= MAX_VISIBLE) {
queue.push(data);
return;
}
createToast(data);
}
function createToast(data) {
activeCount++;
const duration = data.duration || 5000;
const toast = document.createElement('div');
toast.className = `toast ${data.style || 'info'}`;
toast.style.position = 'relative';
toast.innerHTML = `
<div class="toast-icon">${icons[data.style] || icons.info}</div>
<div class="toast-body">
<div class="toast-title">${data.title || ''}</div>
<div class="toast-msg">${data.message}</div>
</div>
<div class="toast-progress" style="animation-duration:${duration}ms"></div>
`;
toast.addEventListener('click', () => dismissToast(toast));
container.appendChild(toast);
if (data.sound !== false && sounds[data.style]) {
sounds[data.style].currentTime = 0;
sounds[data.style].play().catch(() => {});
}
setTimeout(() => dismissToast(toast), duration);
}
function dismissToast(toast) {
if (toast.dataset.dismissed) return;
toast.dataset.dismissed = 'true';
toast.style.animation = 'slideOut 0.3s ease forwards';
setTimeout(() => {
toast.remove();
activeCount--;
if (queue.length > 0) {
createToast(queue.shift());
}
}, 300);
}
क्लाइंट-साइड Lua इंटीग्रेशन
क्लाइंट पक्ष पर, आपको एक फ़ंक्शन की आवश्यकता है जो आपके HTML लेयर को NUI संदेश भेजे और एक एक्सपोर्ट जो अन्य संसाधन बिना सीधे आपकी स्क्रिप्ट के आंतरिक भागों पर निर्भर हुए सूचनाएं ट्रिगर कर सकें। SendNUIMessage native डेटा को ब्राउज़र संदर्भ में भेजता है जहां आपका JavaScript इसे उठाता है। इसे एक साफ API फ़ंक्शन में लपेटें जो शीर्षक, संदेश, प्रकार, और वैकल्पिक अवधि स्वीकार करता है। एक क्लाइंट इवेंट और एक एक्सपोर्ट दोनों को रजिस्टर करें ताकि नोटिफिकेशन सर्वर-साइड स्क्रिप्ट्स और अन्य क्लाइंट संसाधनों दोनों से ट्रिगर किए जा सकें। यह दोहरी विधि किसी भी फ्रेमवर्क के साथ अधिकतम संगतता सुनिश्चित करती है।
-- client.lua
local function ShowNotification(title, message, style, duration, sound)
SendNUIMessage({
type = 'showNotification',
title = title or '',
message = message or '',
style = style or 'info',
duration = duration or 5000,
sound = sound ~= false
})
end
-- Export for other resources
exports('ShowNotification', ShowNotification)
-- Event-based trigger from server
RegisterNetEvent('notifications:show', function(title, message, style, duration)
ShowNotification(title, message, style, duration)
end)
-- Convenience commands for testing
RegisterCommand('testnotify', function()
ShowNotification('Success', 'Your item has been saved.', 'success', 4000)
Wait(500)
ShowNotification('Error', 'Insufficient funds for this purchase.', 'error', 5000)
Wait(500)
ShowNotification('Warning', 'Your vehicle is low on fuel.', 'warning', 4000)
Wait(500)
ShowNotification('Info', 'Press E to interact with the NPC.', 'info', 3000)
end, false)
सर्वर-साइड इवेंट डिस्पैच
सर्वर-साइड स्क्रिप्ट विशिष्ट खिलाड़ियों, सभी खिलाड़ियों, या खिलाड़ियों के समूहों को सूचनाएं भेजने के लिए सहायक फ़ंक्शन प्रदान करता है। यहाँ आप प्रसारण घोषणाओं, लेनदेन पुष्टिकरण भेजने, या संदिग्ध गतिविधि के बारे में एडमिन को अलर्ट करने जैसे उपयोग मामलों को संभालते हैं। सर्वर पर डिस्पैच लॉजिक को केंद्रीकृत करके, आप सूचना वितरण पर एकल नियंत्रण बिंदु बनाए रखते हैं। आप यहां दर सीमितकरण भी जोड़ सकते हैं ताकि दुर्भावनापूर्ण या बग वाले क्लाइंट स्क्रिप्ट से नोटिफिकेशन स्पैम को रोका जा सके। सर्वर को नोटिफिकेशन पैरामीटर को अग्रेषित करने से पहले मान्य करना चाहिए ताकि तैयार संदेशों के माध्यम से NUI इंजेक्शन रोका जा सके।
-- server.lua
local function NotifyPlayer(source, title, message, style, duration)
if not source or source <= 0 then return end
title = tostring(title or '')
message = tostring(message or '')
style = style or 'info'
TriggerClientEvent('notifications:show', source, title, message, style, duration)
end
local function NotifyAll(title, message, style, duration)
TriggerClientEvent('notifications:show', -1, title, message, style, duration)
end
exports('NotifyPlayer', NotifyPlayer)
exports('NotifyAll', NotifyAll)
-- Example: welcome notification
AddEventHandler('playerJoining', function()
local src = source
Wait(3000)
NotifyPlayer(src, 'Welcome', 'Welcome to the server! Have fun.', 'success', 6000)
end)
-- Admin broadcast command
RegisterCommand('broadcast', function(source, args)
if source > 0 and not IsPlayerAceAllowed(source, 'command.broadcast') then return end
local msg = table.concat(args, ' ')
NotifyAll('Announcement', msg, 'info', 8000)
end, true)
ध्वनि प्रभाव और पॉलिश जोड़ना
ध्वनि प्रभाव सूचनाओं को केवल दृश्य तत्व से एक बहु-संवेदी प्रतिक्रिया तंत्र में बदल देते हैं। खिलाड़ी अक्सर गेम को पृष्ठभूमि में रखते हैं या ड्राइविंग पर ध्यान केंद्रित करते हैं और एक मौन टोस्ट मिस कर सकते हैं। सफलता सूचनाओं के लिए एक छोटा, सूक्ष्म चाइम, त्रुटियों के लिए एक कम बज़, और सूचना अलर्ट के लिए एक हल्का पिंग सुनिश्चित करता है कि खिलाड़ी महत्वपूर्ण जानकारी को तब भी समझें जब वे सूचना क्षेत्र को नहीं देख रहे हों। अपने ऑडियो फ़ाइलों को छोटा रखें, 500 मिलीसेकंड से कम, और ब्राउज़र संगतता के लिए OGG फॉर्मेट का उपयोग करें। वॉल्यूम लगभग 30 प्रतिशत सेट करें ताकि यह गेम ऑडियो के साथ मिश्रित हो जाए न कि उसे दबा दे। ध्वनि फ़ाइलों को अपने html/sounds directory and preload them in JavaScript to avoid playback delays on the first notification.
उन्नत फीचर्स और अनुकूलन
एक बार जब आपका कोर सिस्टम काम कर रहा हो, तो अपने सर्वर को अलग दिखाने के लिए उन्नत सुविधाएँ जोड़ने पर विचार करें। स्थायी नोटिफिकेशन जो स्क्रीन पर तब तक रहते हैं जब तक खिलाड़ी उन्हें स्पष्ट रूप से क्लिक न करे, महत्वपूर्ण अलर्ट जैसे लंबित फोन कॉल या जेल टाइमर के लिए उपयोगी हैं। नोटिफिकेशन के अंदर क्रिया बटन खिलाड़ियों को सीधे प्रतिक्रिया देने देते हैं, उदाहरण के लिए बिना अलग मेनू खोले ट्रेड अनुरोध स्वीकार करना। आप नोटिफिकेशन ग्रुपिंग भी लागू कर सकते हैं जहाँ बार-बार आने वाले समान नोटिफिकेशन एक एकल टोस्ट में समाहित हो जाते हैं जिसमें संख्या दर्शाने वाला बैज होता है। फ्रेमवर्क इंटीग्रेशन के लिए, ब्रिज फाइलें बनाएं जो QBCore या ESX में डिफ़ॉल्ट नोटिफिकेशन फ़ंक्शंस को ओवरराइड करें ताकि आपके सर्वर पर हर संसाधन स्वचालित रूप से आपके कस्टम सिस्टम का उपयोग करे बिना किसी कोड परिवर्तन के। फ्रेमवर्क डिफ़ॉल्ट्स को अपनी खुद की इम्प्लीमेंटेशन से बदलने का यह पैटर्न पूरे सर्वर के UI को एक कदम में अपग्रेड करने का साफ़ तरीका है।