ब्लॉग पर वापस
Tutorial11 मिनट पढ़ें

FiveM बैंकिंग और ATM स्क्रिप्ट्स: यथार्थवादी मनी सिस्टम्स

FiveM बैंकिंग और ATM स्क्रिप्ट के साथ एक विश्वसनीय अर्थव्यवस्था बनाएं। ट्रांसफर लॉजिक, UI विचार, शीर्ष मुफ्त और प्रीमियम संसाधन, साथ ही फ्रेमवर्क इंटीग्रेशन।

Agency Scripts

Agency Scripts के संस्थापक और प्रमुख डेवलपर

बैंकिंग सिस्टम वास्तुकला

एक बैंकिंग सिस्टम किसी भी FiveM रोलप्ले सर्वर की वित्तीय रीढ़ है, जो सरल नकद जमा से लेकर जटिल इंटर-प्लेयर ट्रांसफर और साझा संगठन खातों तक सब कुछ संभालता है। अधिकांश फ्रेमवर्क जैसे QBCore और ESX बुनियादी धन प्रबंधन शामिल करते हैं, लेकिन एक समर्पित बैंकिंग सिस्टम इसे उचित खाता प्रबंधन, लेनदेन लॉगिंग, और एक परिष्कृत ATM इंटरफ़ेस के साथ बढ़ाता है जो खिलाड़ियों को रोलप्ले के वित्तीय पक्ष में डुबो देता है। वास्तुकला तीन परतों में विभाजित होती है: डेटाबेस खाते के बैलेंस और लेनदेन रिकॉर्ड संग्रहीत करता है, सर्वर हर वित्तीय ऑपरेशन को सत्यापित करता है और व्यापार नियम लागू करता है, और क्लाइंट NUI के माध्यम से ATM और बैंक काउंटर इंटरफ़ेस प्रदान करता है। हर धन ऑपरेशन सर्वर साइड से गुजरना चाहिए क्योंकि क्लाइंट-साइड धन हेरफेर FiveM सर्वरों पर नंबर एक एक्सप्लॉइट वेक्टर है। यहां तक कि बैलेंस दिखाना भी सर्वर कॉलबैक से आना चाहिए, कभी भी कैश्ड क्लाइंट-साइड डेटा से नहीं जो छेड़छाड़ किया जा सकता है।

बैंकिंग के लिए डेटाबेस स्कीमा

आपके बैंकिंग डेटाबेस को व्यक्तिगत खाते, संगठनों और व्यवसायों के लिए साझा खाते, और एक व्यापक लेनदेन लॉग का समर्थन करना चाहिए। लेनदेन लॉग वैकल्पिक नहीं है क्योंकि यह दोनों खिलाड़ी-समक्ष फीचर और पैसे के शोषण की जांच के लिए एक एडमिन टूल के रूप में काम करता है। अपने स्कीमा को उच्च-थ्रूपुट ऑपरेशंस संभालने के लिए डिज़ाइन करें क्योंकि व्यस्त सर्वर पीक घंटों में प्रति मिनट सैकड़ों लेनदेन कर सकते हैं:

CREATE TABLE IF NOT EXISTS bank_accounts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    account_number VARCHAR(20) UNIQUE NOT NULL,
    owner_citizenid VARCHAR(50) NOT NULL,
    account_type ENUM('personal', 'business', 'gang', 'shared') DEFAULT 'personal',
    balance BIGINT DEFAULT 0,
    account_name VARCHAR(100) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_frozen BOOLEAN DEFAULT FALSE,
    INDEX idx_owner (owner_citizenid),
    INDEX idx_type (account_type)
);

CREATE TABLE IF NOT EXISTS bank_transactions (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    account_id INT NOT NULL,
    type ENUM('deposit', 'withdraw', 'transfer_in', 'transfer_out', 'paycheck', 'purchase') NOT NULL,
    amount BIGINT NOT NULL,
    balance_after BIGINT NOT NULL,
    description VARCHAR(255) DEFAULT NULL,
    other_account VARCHAR(20) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_account (account_id),
    INDEX idx_created (created_at),
    FOREIGN KEY (account_id) REFERENCES bank_accounts(id)
);

CREATE TABLE IF NOT EXISTS bank_account_access (
    account_id INT NOT NULL,
    citizenid VARCHAR(50) NOT NULL,
    permission ENUM('view', 'withdraw', 'full') DEFAULT 'view',
    PRIMARY KEY (account_id, citizenid),
    FOREIGN KEY (account_id) REFERENCES bank_accounts(id)
);

यह bank_account_access तालिका साझा खातों को सक्षम करती है जहाँ कई खिलाड़ी अलग-अलग अनुमति स्तर रख सकते हैं। एक गैंग लीडर को गैंग ट्रेजरी तक पूर्ण पहुंच हो सकती है जबकि सामान्य सदस्य केवल बैलेंस देख सकते हैं। उपयोग करते हुए BIGINT संतुलन फ़ील्ड के लिए, उन सर्वरों पर ओवरफ़्लो समस्याओं को रोकता है जिनकी अर्थव्यवस्थाएं बढ़ी हुई हैं जहां खिलाड़ी के बैलेंस अरबों तक पहुंच सकते हैं।

सर्वर-साइड लेनदेन लॉजिक

हर वित्तीय लेनदेन को एटॉमिक होना चाहिए और सर्वर पर मान्य किया जाना चाहिए। सुनिश्चित करने के लिए डेटाबेस ट्रांजेक्शंस का उपयोग करें कि ट्रांसफर के दौरान पैसा कभी बनाया या नष्ट न हो। जब खिलाड़ी A खिलाड़ी B को पैसा भेजता है, तो A से कटौती और B में जोड़ दोनों को एक साथ सफल होना चाहिए, या कोई भी लागू नहीं होना चाहिए। पर्याप्त बैलेंस, फ्रीज्ड अकाउंट स्थिति, दैनिक ट्रांसफर सीमाएं, और न्यूनतम लेनदेन राशि के लिए मान्यता जांच लागू करें। यहाँ एक सुरक्षित ट्रांसफर कार्यान्वयन है:

RegisterNetEvent('banking:server:transfer', function(targetAccount, amount, description)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    amount = math.floor(tonumber(amount) or 0)
    if amount <= 0 then
        TriggerClientEvent('QBCore:Notify', src, 'Invalid amount', 'error')
        return
    end

    local citizenid = Player.PlayerData.citizenid
    local senderAccount = GetPlayerPrimaryAccount(citizenid)

    if not senderAccount or senderAccount.is_frozen then
        TriggerClientEvent('QBCore:Notify', src, 'Account unavailable', 'error')
        return
    end

    if senderAccount.balance < amount then
        TriggerClientEvent('QBCore:Notify', src, 'Insufficient funds', 'error')
        return
    end

    -- Check daily transfer limit
    local todayTransfers = GetDailyTransferTotal(senderAccount.id)
    if todayTransfers + amount > Config.DailyTransferLimit then
        TriggerClientEvent('QBCore:Notify', src, 'Daily limit exceeded', 'error')
        return
    end

    -- Atomic transfer using database transaction
    local success = MySQL.transaction.await({
        {
            query = 'UPDATE bank_accounts SET balance = balance - ? WHERE id = ? AND balance >= ?',
            values = {amount, senderAccount.id, amount}
        },
        {
            query = 'UPDATE bank_accounts SET balance = balance + ? WHERE account_number = ?',
            values = {amount, targetAccount}
        },
        {
            query = 'INSERT INTO bank_transactions (account_id, type, amount, balance_after, description, other_account) VALUES (?, "transfer_out", ?, (SELECT balance FROM bank_accounts WHERE id = ?), ?, ?)',
            values = {senderAccount.id, amount, senderAccount.id, description or 'Transfer', targetAccount}
        },
    })

    if success then
        TriggerClientEvent('QBCore:Notify', src, 'Transfer complete: $' .. amount, 'success')
        TriggerClientEvent('banking:client:refreshBalance', src)
    else
        TriggerClientEvent('QBCore:Notify', src, 'Transfer failed', 'error')
    end
end)

ध्यान दें WHERE balance >= ? कटौती क्वेरी में क्लॉज, जो दो एक साथ होने वाले ट्रांसफर के कारण होने वाली रेस कंडीशंस के खिलाफ अंतिम सुरक्षा के रूप में कार्य करता है जहाँ खाता ओवरड्राफ्ट हो सकता है। यह डेटाबेस-स्तरीय जांच आवश्यक है भले ही आप Lua में पहले से ही बैलेंस की जांच करते हों, क्योंकि आपकी जांच और वास्तविक अपडेट के बीच कई अनुरोध आ सकते हैं।

ATM उपयोगकर्ता इंटरफ़ेस

ATM इंटरफ़ेस एक कॉम्पैक्ट NUI पैनल है जो मुख्य बैंकिंग कार्यों तक त्वरित पहुंच प्रदान करता है: बैलेंस जांचें, नकद जमा करें, नकद निकालें, और पैसे ट्रांसफर करें। डिज़ाइन को साफ़ और परिचित रखें क्योंकि खिलाड़ी सहज रूप से उम्मीद करते हैं कि ATM वास्तविक दुनिया के समान काम करे। वर्तमान बैलेंस को शीर्ष पर प्रमुखता से दिखाएं, प्रत्येक ऑपरेशन के लिए नीचे क्रियात्मक बटन रखें। जमा और निकासी दृश्य में सामान्य मानों जैसे $100, $500, $1000, और $5000 के लिए पूर्वनिर्धारित राशि बटन शामिल करें साथ ही एक कस्टम राशि इनपुट फ़ील्ड भी। ट्रांसफर के लिए, प्राप्तकर्ता खाता संख्या और राशि के लिए फ़ील्ड प्रदान करें, साथ ही वैकल्पिक मेमो फ़ील्ड भी। किसी भी लेनदेन को निष्पादित करने से पहले पुष्टि चरण दिखाएं ताकि गलती से क्लिक से खिलाड़ियों को पैसे का नुकसान न हो। हाल के लेनदेन की सूची शामिल करें जो पिछले 10 प्रविष्टियों को दिखाए ताकि खिलाड़ी बिना पूर्ण बैंक शाखा जाए अपनी वित्तीय गतिविधि की पुष्टि कर सकें। ATM UI को त्वरित महसूस होना चाहिए, इसलिए मेनू खुलते समय बैलेंस और लेनदेन डेटा एक ही कॉलबैक में प्राप्त करें बजाय प्रत्येक जानकारी के लिए अलग अनुरोध करने के।

ATM इंटरैक्शन सेटअप

GTA मानचित्र में मौजूदा ATM प्रॉप स्थानों पर ATM इंटरैक्शन पॉइंट्स रखें। FiveM ATM मॉडल हैश की एक सूची प्रदान करता है जिसे आप गेम वर्ल्ड में सभी ATM प्रॉप्स खोजने के लिए पुनरावृत्त कर सकते हैं। साफ इंटरैक्शन के लिए ox_target जैसे टारगेट सिस्टम का उपयोग करें, या प्रत्येक ATM प्रॉप के पास निकटता जांच पर वापस जाएं। जब खिलाड़ी ATM के साथ इंटरैक्ट करता है, तो खिलाड़ी के ATM का उपयोग करने का एनीमेशन चलाएं, फिर NUI पैनल खोलें:

local atmModels = {
    'prop_atm_01', 'prop_atm_02', 'prop_atm_03',
    'prop_fleeca_atm', 'v_5_b_atm1'
}

-- Using ox_target for ATM interaction
for _, model in ipairs(atmModels) do
    exports.ox_target:addModel(GetHashKey(model), {
        {
            name = 'use_atm',
            icon = 'fas fa-credit-card',
            label = 'Use ATM',
            onSelect = function(data)
                local ped = PlayerPedId()
                local atmCoords = GetEntityCoords(data.entity)

                -- Face the ATM
                TaskTurnPedToFaceCoord(ped, atmCoords.x, atmCoords.y, atmCoords.z, 1000)
                Wait(1000)

                -- Play ATM animation
                RequestAnimDict('mini@atmenter')
                while not HasAnimDictLoaded('mini@atmenter') do Wait(10) end
                TaskPlayAnim(ped, 'mini@atmenter', 'enter', 8.0, -8.0, -1, 0, 0, false, false, false)

                -- Open ATM UI
                QBCore.Functions.TriggerCallback('banking:server:getAccountData', function(data)
                    SetNuiFocus(true, true)
                    SendNUIMessage({
                        action = 'openATM',
                        balance = data.balance,
                        transactions = data.recentTransactions,
                        accountNumber = data.accountNumber
                    })
                end)
            end
        }
    })
end

लेनदेन इतिहास और विवरण

लेनदेन इतिहास आपके बैंकिंग सिस्टम को एक साधारण जमा और निकासी मशीन से पूर्ण वित्तीय प्रबंधन उपकरण में बदल देता है। खिलाड़ियों को बैंक शाखा स्थानों पर अपनी पूरी लेनदेन इतिहास देख पाने में सक्षम होना चाहिए, जिसे तारीख सीमा, लेनदेन प्रकार, या राशि द्वारा फ़िल्टर किया जा सके। प्रत्येक लेनदेन प्रविष्टि में तारीख, प्रकार, राशि, परिणामी बैलेंस, विवरण, और ट्रांसफर के लिए दूसरी पार्टी दिखाई जानी चाहिए। सर्वर साइड पर पेजिनेशन लागू करें क्योंकि हजारों लेनदेन एक साथ लोड करने से NUI फ्रेम फ्रीज हो सकता है और सर्वर मेमोरी उपयोग बढ़ सकता है। प्रति पेज 20-30 लेनदेन लौटाएं और खिलाड़ी को आवश्यकता अनुसार और लोड करने दें। बैंक शाखा स्थानों के लिए, एटीएम से अधिक अतिरिक्त सुविधाएं प्रदान करें, जैसे नए खाते खोलना, साझा खाता अनुमतियों का प्रबंधन, विशिष्ट अवधि के लिए खाता विवरण उत्पन्न करना, और यदि आपका सर्वर उस मैकेनिक का समर्थन करता है तो ऋण के लिए आवेदन करना। लेनदेन विवरण को मानव-पठनीय स्ट्रिंग्स के रूप में स्टोर करें ताकि नौकरियों, दुकान खरीदारी, और सरकारी करों से स्वचालित लेनदेन सभी स्पष्ट प्रविष्टियाँ दिखाएं जिन्हें खिलाड़ी बिना संदर्भ के समझ सकें।

बैंक डकैती तंत्र

बैंक डकैती किसी भी रोलप्ले सर्वर पर सबसे रोमांचक घटनाओं में से एक है, जो अपराधियों, पुलिस, बंधक वार्ताकारों और दर्शकों को शामिल करने वाले उच्च-दांव वाले परिदृश्य बनाती है। एक अच्छी तरह से डिज़ाइन किया गया डकैती सिस्टम कई चरणों को शामिल करता है: बैंक की जाँच करना, डकैती शुरू करना, मिनीगेम के माध्यम से सुरक्षा प्रणालियों को हैक या ड्रिल करना, लूट लोड करना, और पुलिस की पीछा करते हुए भागना। शुरू करें यह परिभाषित करके कि कौन से बैंक लूटे जा सकते हैं, उनकी कठिनाई स्तर, कूलडाउन टाइमर, और आवश्यक वस्तुएं। डकैती के लिए विशेष उपकरणों की आवश्यकता होती है जैसे वॉल्ट दरवाजों के लिए थर्माइट, सुरक्षा पैनलों के लिए हैकिंग डिवाइस, और लूट ले जाने के लिए डफल बैग। प्रत्येक सुरक्षा परत के लिए प्रगतिशील कठिनाई मिनीगेम लागू करें, जहां हैक विफल होने पर अतिरिक्त अलार्म बजते हैं या वॉल्ट और अधिक लॉक हो जाता है:

Config.BankRobberies = {
    ['fleeca_1'] = {
        label = 'Fleeca Bank - Legion Square',
        coords = vector3(149.73, -1042.65, 29.37),
        vault = vector3(144.87, -1044.16, 29.37),
        tier = 1,  -- 1=Fleeca, 2=Paleto, 3=Pacific Standard
        cooldown = 7200,  -- 2 hours
        minPolice = 3,
        requiredItems = {'electronickit', 'thermite'},
        reward = { min = 40000, max = 80000, markedBills = true },
        securityLayers = {
            { type = 'hack', difficulty = 'easy', time = 30 },
            { type = 'thermite', time = 10 },
            { type = 'drill', time = 45 },
        },
    },
    ['pacific_standard'] = {
        label = 'Pacific Standard Bank',
        coords = vector3(255.85, 225.60, 101.88),
        vault = vector3(262.20, 222.10, 101.68),
        tier = 3,
        cooldown = 14400,  -- 4 hours
        minPolice = 6,
        requiredItems = {'electronickit', 'thermite', 'advancedlaptop'},
        reward = { min = 200000, max = 400000, markedBills = true },
        securityLayers = {
            { type = 'hack', difficulty = 'hard', time = 20 },
            { type = 'hack', difficulty = 'hard', time = 20 },
            { type = 'thermite', time = 8 },
            { type = 'drill', time = 60 },
            { type = 'hack', difficulty = 'expert', time = 15 },
        },
    },
}

चोरी के इनाम के रूप में साफ नकदी के बजाय चिह्नित बिलों का उपयोग करें, जिससे अपराधियों को अतिरिक्त गेमप्ले लूप जैसे मनी लॉन्ड्रिंग स्थानों या गंदे पैसे के एक्सचेंज के माध्यम से पैसे धोने के लिए मजबूर किया जाता है। यह चोरी के रोलप्ले को हीस्ट से आगे बढ़ाता है और पुलिस जांच के अवसर बनाता है। जब चोरी शुरू होती है तो पुलिस डिस्पैच सिस्टम को सूचित करें और चोरी की प्रगति को सर्वर-साइड ट्रैक करें ताकि अधिकारी अपराधियों की प्रगति के आधार पर रणनीतिक रूप से प्रतिक्रिया कर सकें।

सुरक्षा और एंटी-एक्सप्लॉइट उपाय

वित्तीय प्रणालियाँ शोषकों के लिए प्राथमिक लक्ष्य हैं क्योंकि पैसा सीधे इन-गेम शक्ति में परिवर्तित होता है। पहले से चर्चा किए गए सर्वर-साइड सत्यापन के अलावा, कई अतिरिक्त सुरक्षा परतें लागू करें। सभी बैंकिंग घटनाओं पर दर सीमा जोड़ें ताकि एक खिलाड़ी प्रति सेकंड सैकड़ों जमा या स्थानांतरण अनुरोध न भेज सके। प्रत्येक वित्तीय लेनदेन को स्रोत खिलाड़ी के पहचानकर्ताओं और टाइमस्टैम्प के साथ लॉग करें ताकि व्यवस्थापक धन प्रवाह का पता लगा सकें और डुप्लिकेशन शोषण की पहचान कर सकें। एक लेनदेन उलट प्रणाली लागू करें जिसका उपयोग व्यवस्थापक धोखाधड़ी लेनदेन को वापस लेने के लिए कर सकें जब शोषण पाए जाएं। अधिकतम एकल-लेनदेन सीमाएँ और दैनिक संचयी सीमाएँ सेट करें जो खिलाड़ी के खाते की उम्र और कुल खेल समय के साथ स्केल करें, जिससे ताजा बनाए गए खाते मनी लॉन्ड्रिंग के लिए कम उपयोगी हों। संदिग्ध पैटर्न जैसे दो खातों के बीच तेज़ राउंड-ट्रिप ट्रांसफर, दूसरे खिलाड़ी से निकासी के बराबर जमा जो सेकंडों में होता है, या बिना संबंधित लेनदेन रिकॉर्ड के बैलेंस वृद्धि की निगरानी करें। संदिग्ध गतिविधि का पता चलने पर Discord वेबहुक अलर्ट भेजें ताकि आपका मॉडरेशन टीम वास्तविक समय में जांच कर सके बिना खिलाड़ी रिपोर्ट का इंतजार किए। एक फ्रोज़न अकाउंट सिस्टम लागू करने पर विचार करें जहाँ व्यवस्थापक जांच के दौरान खातों को लॉक कर सकें, जिससे शोषित धन का खर्च या स्थानांतरण रोका जा सके जब तक समस्या हल न हो।

सर्वर अर्थव्यवस्था के साथ एकीकरण

आपकी बैंकिंग प्रणाली सर्वर पर सभी मौद्रिक प्रवाह के लिए केंद्रीय हब के रूप में काम करनी चाहिए। नौकरी के वेतन को बैंकिंग सिस्टम के माध्यम से रूट करें ताकि खिलाड़ी अपना वेतन बैंक जमा के रूप में प्राप्त करें जिसमें स्पष्ट लेनदेन रिकॉर्ड हो कि किस नौकरी ने उन्हें कितना भुगतान किया। जब खिलाड़ी नकद के बजाय कार्ड से भुगतान करते हैं तो शॉप खरीद को बैंक निकासी से जोड़ें, जिससे एक पेपर ट्रेल बनती है जो यथार्थवाद जोड़ती है और खिलाड़ियों को सरल भंडारण से परे बैंकिंग सिस्टम का उपयोग करने का कारण देती है। संपत्ति कर, वाहन बीमा, और व्यवसाय संचालन खर्च जैसे आवर्ती लागतों के लिए स्वचालित बिलिंग लागू करें जो नियमित अंतराल पर खिलाड़ी के बैंक खाते से कटौती करती है। यदि किसी खिलाड़ी के खाते में स्वचालित भुगतान के लिए अपर्याप्त धन है, तो सिस्टम असफल भुगतान लॉग करे और संपत्ति जब्ती चेतावनी या बीमा अवधि समाप्ति जैसे परिणाम ट्रिगर करे। बैंकिंग सिस्टम को अपने फोन संसाधन से लिंक करें ताकि खिलाड़ी अपना बैलेंस जांच सकें, हाल के लेनदेन देख सकें, और बिना ATM या बैंक शाखा जाए तेज़ ट्रांसफर कर सकें। यह एकीकरण बैंकिंग सिस्टम को एक पृथक फीचर से बदलकर आपके सर्वर पर हर आर्थिक गतिविधि से जुड़ी वित्तीय तंत्रिका प्रणाली बनाता है।

शुरू करने के लिए तैयार?

हमारी शॉप से स्क्रिप्ट लें, या सपोर्ट, अपडेट और आगे आने वाली चीज़ों की झलक के लिए Discord से जुड़ें।