FiveM हथियार शॉप सिस्टम: लाइसेंस प्राप्त गन स्टोर स्क्रिप्ट्स
अपने FiveM सर्वर के लिए एक लाइसेंस प्राप्त गन शॉप बनाएं। परमिट, पृष्ठभूमि जांच, गोला-बारूद, अटैचमेंट और रोलप्ले के लिए शीर्ष हथियार दुकान स्क्रिप्ट।
Agency Scripts
Agency Scripts के संस्थापक और प्रमुख डेवलपर
Weapon Shop Architecture Overview
FiveM रोलप्ले सर्वर पर एक हथियार दुकान प्रणाली को कानून का पालन करने वाले नागरिकों के लिए पहुंच और वास्तविक प्रतिबंधों के बीच संतुलन बनाना होता है जो गेमप्ले की गहराई पैदा करते हैं। वास्तुकला दो अलग शाखाओं में विभाजित होती है: कानूनी दुकानें जो हथियार लाइसेंसिंग, पृष्ठभूमि जांच, और खरीद कूलडाउन लागू करती हैं, और अवैध काला बाजार डीलर जो बिना कागजी कार्रवाई के उच्च कीमतों पर अनट्रेसेबल हथियार बेचते हैं। दोनों सिस्टम समान अंतर्निहित इन्वेंटरी और लेनदेन लॉजिक साझा करते हैं, लेकिन उनकी पहुंच आवश्यकताओं और प्रत्येक हथियार से जुड़े मेटाडेटा में भिन्न होते हैं। कानूनी हथियारों को खरीदार के नागरिक ID से जुड़े सीरियल नंबर मिलते हैं, जिससे पुलिस द्वारा उनका पता लगाया जा सकता है, जबकि काला बाजार हथियारों के सीरियल नंबर खरोंचे हुए होते हैं जिन्हें किसी विशिष्ट खिलाड़ी से ट्रेस नहीं किया जा सकता। यह द्वि-मार्ग डिजाइन स्वाभाविक रोलप्ले तनाव पैदा करता है क्योंकि खिलाड़ियों को कानूनी खरीद की सुविधा और कम लागत के खिलाफ काला बाजार की गुमनामी का मूल्यांकन करना पड़ता है।
हथियारों और लाइसेंस के लिए डेटाबेस स्कीमा
आपके डेटाबेस को प्रत्येक शॉप के हथियार इन्वेंटरी, व्यक्तिगत हथियार सीरियल नंबर, खिलाड़ी लाइसेंस, और खरीद इतिहास ट्रैक करना चाहिए। सीरियल नंबर सिस्टम महत्वपूर्ण है क्योंकि यह हथियार दुकान और पुलिस जांच सिस्टम के बीच पुल का काम करता है। हर कानूनी रूप से खरीदा गया हथियार एक अनूठा सीरियल नंबर प्राप्त करता है जिसे पुलिस ट्रैफिक स्टॉप या अपराध स्थल जांच के दौरान देख सकती है। स्कीमा को शॉप स्टॉक प्रबंधन और व्यक्तिगत हथियार ट्रैकिंग दोनों संभालने के लिए डिज़ाइन करें:
CREATE TABLE IF NOT EXISTS weapon_shops (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
type ENUM('legal', 'blackmarket') DEFAULT 'legal',
coords_x FLOAT NOT NULL,
coords_y FLOAT NOT NULL,
coords_z FLOAT NOT NULL,
is_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE IF NOT EXISTS weapon_inventory (
id INT AUTO_INCREMENT PRIMARY KEY,
shop_id INT NOT NULL,
weapon_name VARCHAR(50) NOT NULL,
label VARCHAR(100) NOT NULL,
price INT NOT NULL,
ammo_price INT DEFAULT 0,
category ENUM('handguns', 'smgs', 'rifles', 'shotguns', 'melee', 'throwables') NOT NULL,
license_required ENUM('none', 'basic', 'advanced', 'military') DEFAULT 'none',
stock INT DEFAULT -1,
INDEX idx_shop (shop_id),
FOREIGN KEY (shop_id) REFERENCES weapon_shops(id)
);
CREATE TABLE IF NOT EXISTS weapon_serials (
serial VARCHAR(20) PRIMARY KEY,
weapon_name VARCHAR(50) NOT NULL,
owner_citizenid VARCHAR(50) DEFAULT NULL,
is_scratched BOOLEAN DEFAULT FALSE,
purchased_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
shop_id INT DEFAULT NULL,
INDEX idx_owner (owner_citizenid)
);
CREATE TABLE IF NOT EXISTS weapon_licenses (
id INT AUTO_INCREMENT PRIMARY KEY,
citizenid VARCHAR(50) NOT NULL,
license_type ENUM('basic', 'advanced', 'military') NOT NULL,
issued_by VARCHAR(50) DEFAULT NULL,
issued_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP NULL,
revoked BOOLEAN DEFAULT FALSE,
UNIQUE KEY unique_license (citizenid, license_type)
);
यह weapon_serials तालिका हर हथियार को उसके जीवनचक्र के दौरान व्यक्तिगत रूप से ट्रैक करती है। जब कोई खिलाड़ी कानूनी रूप से हथियार खरीदता है, तो एक सीरियल उत्पन्न होता है और उनके सिटिजन ID से जुड़ा होता है। यदि वे ब्लैक मार्केट सेवा का उपयोग करके सीरियल को स्क्रैच करते हैं, तो is_scratched फ्लैग true में बदलता है और owner_citizenid रद्द कर दिया जाता है। stock में फ़ील्ड weapon_inventory उपयोग करता है -1 असीमित स्टॉक को सूचित करने के लिए, जबकि सकारात्मक मान सीमित आपूर्ति तंत्र को सक्षम करते हैं जो कमी पैदा करते हैं और काला बाज़ार मांग को बढ़ाते हैं।
कानूनी हथियार दुकान कार्यान्वयन
कानूनी हथियार दुकानें अधिकांश खिलाड़ियों के लिए रोलप्ले सर्वर पर आग्नेयास्त्र प्राप्त करने का प्राथमिक तरीका हैं। वे लाइसेंसिंग आवश्यकताओं को लागू करती हैं, थोक खरीद को रोकने के लिए खरीद कूलडाउन लागू करती हैं, और हर बेचे गए हथियार के लिए ट्रेस करने योग्य सीरियल नंबर उत्पन्न करती हैं। दुकान UI को श्रेणी द्वारा हथियारों को समूहित करके दिखाना चाहिए और स्पष्ट संकेतक दिखाने चाहिए कि प्रत्येक हथियार के लिए कौन सा लाइसेंस स्तर आवश्यक है। बिना उचित लाइसेंस वाले खिलाड़ी हथियार देख सकते हैं लेकिन खरीद नहीं सकते, जिससे वे सरकारी अधिकारियों के साथ लाइसेंसिंग प्रक्रिया का रोलप्ले करने के लिए प्रोत्साहित होते हैं। एक कूलडाउन सिस्टम लागू करें जो खिलाड़ियों को वास्तविक समय के दिन में एक निर्धारित संख्या से अधिक हथियार खरीदने से रोकता है ताकि काले बाजार में पुनर्विक्रय के लिए भंडारण न हो सके:
RegisterNetEvent('weaponshop:server:purchase', function(shopId, weaponName)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local citizenid = Player.PlayerData.citizenid
local item = GetShopItem(shopId, weaponName)
if not item then
TriggerClientEvent('QBCore:Notify', src, 'Item not available', 'error')
return
end
-- Check license requirement
if item.license_required ~= 'none' then
local hasLicense = HasValidLicense(citizenid, item.license_required)
if not hasLicense then
TriggerClientEvent('QBCore:Notify', src, 'You need a ' .. item.license_required .. ' weapons license', 'error')
return
end
end
-- Check purchase cooldown
local recentPurchases = GetRecentPurchaseCount(citizenid, 86400) -- last 24h
if recentPurchases >= Config.DailyPurchaseLimit then
TriggerClientEvent('QBCore:Notify', src, 'Daily purchase limit reached', 'error')
return
end
-- Check stock
if item.stock ~= -1 then
if item.stock <= 0 then
TriggerClientEvent('QBCore:Notify', src, 'Out of stock', 'error')
return
end
end
-- Check funds
if Player.PlayerData.money.bank < item.price then
TriggerClientEvent('QBCore:Notify', src, 'Insufficient funds', 'error')
return
end
-- Generate serial number
local serial = GenerateWeaponSerial()
-- Process purchase
Player.Functions.RemoveMoney('bank', item.price, 'weapon-purchase')
Player.Functions.AddItem(weaponName, 1, false, { serial = serial })
-- Record serial
MySQL.insert('INSERT INTO weapon_serials (serial, weapon_name, owner_citizenid, shop_id) VALUES (?, ?, ?, ?)',
{ serial, weaponName, citizenid, shopId })
-- Update stock
if item.stock ~= -1 then
MySQL.update('UPDATE weapon_inventory SET stock = stock - 1 WHERE shop_id = ? AND weapon_name = ?',
{ shopId, weaponName })
end
TriggerClientEvent('QBCore:Notify', src, 'Purchased ' .. item.label .. ' (S/N: ' .. serial .. ')', 'success')
end)
function GenerateWeaponSerial()
local chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
local serial = ''
for i = 1, 3 do
serial = serial .. chars:sub(math.random(#chars), math.random(#chars))
end
serial = serial .. '-'
for i = 1, 5 do
serial = serial .. tostring(math.random(0, 9))
end
return serial
end
गोली और संलग्नक प्रणाली
गोली प्रबंधन एक संसाधन खपत जोड़ता है जो खिलाड़ियों को अर्थव्यवस्था के साथ जुड़ा रखता है और अनंत गोला-बारूद के दुरुपयोग को रोकता है। गोला-बारूद को एक सामान्य आइटम के रूप में बेचने के बजाय, इसे विशिष्ट कैलिबर प्रकारों से जोड़ें जो हथियार श्रेणियों से मेल खाते हैं। एक पिस्तौल 9mm राउंड का उपयोग करता है, एक SMG 9mm साझा कर सकता है या .45 ACP का उपयोग कर सकता है, और राइफलें मॉडल के अनुसार 5.56 या 7.62 का उपयोग करती हैं। यह कैलिबर प्रणाली अधिक यथार्थवादी अनुभव बनाती है और दुकान मालिकों को विभिन्न गोला-बारूद प्रकारों की कीमत निर्धारण में लचीलापन देती है। गोला-बारूद की गिनती को अलग इन्वेंटरी आइटम के बजाय हथियार मेटाडेटा पर संग्रहित करें ताकि प्रत्येक हथियार अपने लोडेड राउंड को ट्रैक करे। संलग्नक उसी मेटाडेटा पैटर्न का पालन करते हैं जहां प्रत्येक हथियार आइटम स्थापित घटकों की सूची संग्रहीत करता है जैसे स्कोप, सप्रेसर, विस्तारित मैगज़ीन, और फ्लैशलाइट:
Config.AmmoTypes = {
['ammo_9mm'] = { label = '9mm Rounds', price = 5, amount = 24, weapons = {'WEAPON_PISTOL', 'WEAPON_COMBATPISTOL', 'WEAPON_SMG'} },
['ammo_45acp'] = { label = '.45 ACP Rounds', price = 7, amount = 24, weapons = {'WEAPON_APPISTOL', 'WEAPON_MACHINEPISTOL'} },
['ammo_556'] = { label = '5.56 Rounds', price = 12, amount = 30, weapons = {'WEAPON_CARBINERIFLE', 'WEAPON_ASSAULTRIFLE'} },
['ammo_762'] = { label = '7.62 Rounds', price = 15, amount = 30, weapons = {'WEAPON_SNIPERRIFLE', 'WEAPON_MARKSMANRIFLE'} },
['ammo_12gauge'] = { label = '12ga Shells', price = 10, amount = 8, weapons = {'WEAPON_PUMPSHOTGUN', 'WEAPON_ASSAULTSHOTGUN'} },
}
Config.Attachments = {
['attachment_suppressor'] = {
label = 'Suppressor',
price = 8500,
component = 'COMPONENT_AT_PI_SUPP_02',
compatible = {'WEAPON_PISTOL', 'WEAPON_COMBATPISTOL', 'WEAPON_SMG', 'WEAPON_CARBINERIFLE'},
license_required = 'advanced',
},
['attachment_scope'] = {
label = 'Holographic Scope',
price = 3200,
component = 'COMPONENT_AT_SCOPE_MACRO_02',
compatible = {'WEAPON_SMG', 'WEAPON_CARBINERIFLE', 'WEAPON_ASSAULTRIFLE'},
license_required = 'basic',
},
['attachment_extmag'] = {
label = 'Extended Magazine',
price = 4500,
component = 'COMPONENT_CARBINERIFLE_CLIP_02',
compatible = {'WEAPON_CARBINERIFLE', 'WEAPON_ASSAULTRIFLE', 'WEAPON_SMG'},
license_required = 'basic',
},
['attachment_flashlight'] = {
label = 'Flashlight',
price = 1200,
component = 'COMPONENT_AT_AR_FLSH',
compatible = {'WEAPON_PISTOL', 'WEAPON_COMBATPISTOL', 'WEAPON_CARBINERIFLE', 'WEAPON_PUMPSHOTGUN'},
license_required = 'none',
},
}
जब कोई खिलाड़ी एक अटैचमेंट खरीदता है, तो सत्यापित करें कि उनका वर्तमान हथियार compatible सूची बनाएं, उनके लाइसेंस टियर की जांच करें, फिर कंपोनेंट हैश को हथियार के मेटाडेटा टेबल में जोड़ें। हथियार इक्विप होने पर, स्टोर किए गए कंपोनेंट्स के माध्यम से इटरेट करें और उन्हें लागू करें GiveWeaponComponentToPedयह तरीका सुनिश्चित करता है कि अटैचमेंट्स सत्रों के बीच बने रहें और क्लाइंट को मैनिपुलेट करके डुप्लिकेट न किए जा सकें।
ब्लैक मार्केट मैकेनिक्स
ब्लैक मार्केट वह जगह है जहां असली रोलप्ले गहराई रहती है। स्थिर कानूनी दुकानों के विपरीत, ब्लैक मार्केट डीलर खतरनाक और विशिष्ट महसूस होने चाहिए। घुमावदार डीलर स्थान लागू करें जो हर कुछ घंटों में बदलते हैं ताकि खिलाड़ियों को उन्हें खोजने के लिए अंदरूनी जानकारी या संपर्कों की आवश्यकता हो। एक प्रतिष्ठा प्रणाली आवश्यक करें जहां नए खिलाड़ियों को उच्च-स्तरीय हथियारों तक पहुंच प्राप्त करने से पहले छोटे खरीद के माध्यम से डीलर के साथ विश्वास बनाना पड़ता है। ब्लैक मार्केट हथियार बेचता है जिनके सीरियल नंबर नहीं होते, प्रतिबंधित सैन्य-ग्रेड उपकरण जो कानूनी दुकानें स्टॉक नहीं कर सकतीं, और सेवाएं जैसे सीरियल नंबर स्क्रैचिंग जो कानूनी रूप से खरीदे गए हथियारों को अनट्रेसेबल बनाती हैं। जोखिम प्रीमियम को दर्शाने और कानूनी और अवैध रास्तों के बीच वास्तविक आर्थिक तनाव बनाने के लिए सब कुछ कानूनी दुकानों की तुलना में 2-3 गुना महंगा रखें:
Config.BlackMarket = {
rotationInterval = 10800, -- 3 hours between location changes
locations = {
{ coords = vector3(89.98, -1810.87, 24.98), heading = 230.0, label = 'Underground Parking' },
{ coords = vector3(1394.27, 1141.48, 114.33), heading = 90.0, label = 'Desert Warehouse' },
{ coords = vector3(-58.21, 6443.31, 31.43), heading = 45.0, label = 'Paleto Docks' },
{ coords = vector3(981.45, -1812.66, 31.14), heading = 180.0, label = 'Industrial Zone' },
},
reputationTiers = {
[0] = { label = 'Unknown', items = {'WEAPON_KNIFE', 'WEAPON_BAT'} },
[1] = { label = 'Associate', items = {'WEAPON_PISTOL', 'WEAPON_MICROSMG', 'ammo_9mm'} },
[2] = { label = 'Trusted', items = {'WEAPON_SMG', 'WEAPON_PUMPSHOTGUN', 'ammo_45acp', 'ammo_12gauge', 'attachment_suppressor'} },
[3] = { label = 'Inner Circle', items = {'WEAPON_ASSAULTRIFLE', 'WEAPON_CARBINERIFLE', 'ammo_556', 'service_scratch_serial'} },
[4] = { label = 'Arms Dealer', items = {'WEAPON_SNIPERRIFLE', 'WEAPON_RPG', 'WEAPON_GRENADELAUNCHER', 'ammo_762', 'armor_heavy'} },
},
priceMultiplier = 2.5,
reputationGainPerPurchase = 0.15,
}
-- Serial scratching service
RegisterNetEvent('blackmarket:server:scratchSerial', function(weaponSlot)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local citizenid = Player.PlayerData.citizenid
local reputation = GetBlackMarketReputation(citizenid)
if reputation < 3 then
TriggerClientEvent('QBCore:Notify', src, 'You don\'t have enough reputation', 'error')
return
end
local item = Player.Functions.GetItemBySlot(weaponSlot)
if not item or not item.info or not item.info.serial then
TriggerClientEvent('QBCore:Notify', src, 'No weapon with serial found', 'error')
return
end
local cost = Config.ScratchSerialPrice -- e.g., 15000
if Player.PlayerData.money.cash < cost then
TriggerClientEvent('QBCore:Notify', src, 'Not enough cash', 'error')
return
end
Player.Functions.RemoveMoney('cash', cost, 'serial-scratch')
-- Update database
MySQL.update('UPDATE weapon_serials SET is_scratched = TRUE, owner_citizenid = NULL WHERE serial = ?',
{ item.info.serial })
-- Update item metadata
item.info.serial = 'SCRATCHED'
Player.Functions.SetInventoryItem(item.name, item.amount, item.info, weaponSlot)
TriggerClientEvent('QBCore:Notify', src, 'Serial number removed', 'success')
end)
Weapon Licensing System
लाइसेंसिंग प्रणाली एक महत्वपूर्ण नौकरशाही रोलप्ले परत बनाती है जो हथियार दुकानों को सरकार और कानून प्रवर्तन गुटों से जोड़ती है। खिलाड़ियों को हथियार लाइसेंस के लिए सिटी हॉल या पुलिस स्टेशन में आवेदन करना चाहिए, एक पृष्ठभूमि जांच से गुजरना चाहिए जो उनके आपराधिक रिकॉर्ड की जांच करती है, और संभवतः एक अधिकारी द्वारा आयोजित शूटिंग रेंज परीक्षण में भाग लेना चाहिए। तीन लाइसेंस स्तर लागू करें: हैंडगन और शॉटगन के लिए बेसिक, SMG और राइफल के लिए एडवांस्ड, और भारी हथियारों के लिए मिलिट्री जो आमतौर पर नागरिकों को नहीं दिए जाते। लाइसेंस की समाप्ति तिथि होनी चाहिए, आमतौर पर 30 वास्तविक दिनों की, जिसे नवीनीकरण की आवश्यकता होती है। पुलिस अधिकारियों को एक कमांड चाहिए जिससे वे हिंसक अपराधों के दोषसिद्धि पर लाइसेंस रद्द कर सकें, जो तुरंत उन्हें कानूनी दुकानों से खरीदारी करने से रोकता है और ब्लैक मार्केट की मांग बनाता है। लाइसेंस स्थिति डेटाबेस में संग्रहीत करें और हर खरीद प्रयास पर सर्वर-साइड जांच करें, क्लाइंट-साइड लाइसेंस जांच पर कभी भरोसा न करें क्योंकि उन्हें आसानी से बायपास किया जा सकता है।
क्लाइंट-साइड शॉप इंटरफेस
हथियार दुकान NUI को एक पेशेवर स्टोरफ्रंट की तरह महसूस होना चाहिए जिसमें हथियार वर्गीकृत टैब में प्रदर्शित हों। प्रत्येक हथियार को उसके नाम, कीमत, आवश्यक लाइसेंस, वर्तमान स्टॉक स्तर, और एक छोटा पूर्वावलोकन चित्र या आइकन के साथ दिखाएं। एक अलग सेक्शन शामिल करें जहाँ खिलाड़ी पहले अपना हथियार चुनें, फिर केवल संगत गोलियों के प्रकार देखें। अटैचमेंट सेक्शन इसी तरह काम करता है, केवल उन घटकों को दिखाते हुए जो खिलाड़ी के वर्तमान सुसज्जित हथियार के साथ संगत हों। एक शॉपिंग कार्ट सिस्टम लागू करें जो खिलाड़ियों को कई आइटम कतारबद्ध करने और एक ही लेनदेन में चेकआउट करने की अनुमति देता है बजाय हर आइटम को अलग से खरीदने के। ब्लैक मार्केट UI के लिए, एक गहरा सौंदर्यशास्त्र उपयोग करें जिसमें प्रतिष्ठा प्रगति पट्टी हो जो दिखाए कि खिलाड़ी अगली स्तर के कितने करीब है। लॉक किए गए आइटमों को सिल्हूट के रूप में दिखाएं जिन पर प्रतिष्ठा आवश्यकतानुसार लेबल हो ताकि खिलाड़ी जान सकें कि वे किसके लिए काम कर रहे हैं। दोनों दुकान प्रकारों को खोलने पर एक सर्वर कॉलबैक ट्रिगर करना चाहिए ताकि वास्तविक समय की कीमतें और स्टॉक प्राप्त हो सकें, कैश्ड कॉन्फ़िग मानों पर निर्भर न रहें, क्योंकि एडमिन सर्वर अर्थव्यवस्था की स्थितियों के आधार पर कीमतों को गतिशील रूप से समायोजित कर सकते हैं।
एंटी-एक्सप्लॉइट और पुलिस एकीकरण
हथियार की दुकानें महंगे हथियारों की नकल करने या बिना भुगतान के आइटम उत्पन्न करने वाले शोषकों के लिए प्रमुख लक्ष्य होती हैं। किसी भी आइटम को बनाने से पहले खिलाड़ी के पैसे, लाइसेंस स्थिति, दुकान की निकटता, और खरीद कूलडाउन की जांच करके प्रत्येक खरीद को सर्वर-साइड सत्यापित करें। हर हथियार लेनदेन को खरीदार के पहचानकर्ता, हथियार सीरियल, दुकान ID, और टाइमस्टैम्प के साथ लॉग करें ताकि प्रशासक सर्वर पर किसी भी हथियार की उत्पत्ति का पता लगा सकें। पुलिस MDT सिस्टम के साथ एकीकरण करें ताकि अधिकारी जांच के दौरान हथियार सीरियल देख सकें और पंजीकृत मालिक, खरीद तिथि, और क्या सीरियल स्क्रैच किया गया है, देख सकें। एक हथियार रजिस्ट्री निर्यात लागू करें जो किसी विशिष्ट नागरिक के लिए सभी पंजीकृत हथियारों की रिपोर्ट उत्पन्न करता है, जो प्रोबेशन जांचों के लिए उपयोगी है। खरीद घटनाओं को दर-सीमा लगाएं ताकि तेजी से अनुरोधों को रोका जा सके जो कूलडाउन जांचों को रेस कंडीशंस के माध्यम से बायपास कर सकते हैं। जब उच्च-स्तरीय सैन्य हथियार काले बाजार में बेचे जाते हैं तो Discord वेबहुक अलर्ट भेजें ताकि आपका मॉडरेशन टीम दुरुपयोग की निगरानी कर सके। उचित सर्वर-साइड सत्यापन, व्यापक लॉगिंग, और पुलिस एकीकरण का संयोजन एक हथियार अर्थव्यवस्था बनाता है जो यथार्थवादी महसूस होती है और शोषण के प्रति प्रतिरोधी रहती है।