This commit is contained in:
Nordi98 2025-07-29 22:15:20 +02:00
parent 8110c00382
commit 05b2063db3
17 changed files with 1553 additions and 1 deletions

View file

@ -0,0 +1,151 @@
local players = {}
local totalSumChance = 0
local QBCore = exports['qb-core']:GetCoreObject()
CreateThread(function()
for _,priceInfo in pairs(Config.Prices) do
totalSumChance = totalSumChance + priceInfo['chance']
end
end)
QBCore.Functions.CreateUseableItem('scratch_ticket', function(source)
local _source = source
DebugPrint(('%s just used a scratching ticket.'):format(GetPlayerName(_source)))
TriggerClientEvent("dr-scratching:isActiveCooldown", source)
end)
RegisterNetEvent("dr-scratching:handler", function(returncooldown, cooldown)
local _source <const> = source
local tempsrc <const> = tonumber(_source)
local playerName, playerIdentifier = GetPlayerName(_source), GetPlayerIdentifier(_source, 0)
local xPlayer <const> = QBCore.Functions.GetPlayer(_source)
local count <const> = xPlayer.Functions.GetItemByName('scratch_ticket').amount
local randomNumber <const> = math.random(1, totalSumChance)
local add = 0
if returncooldown then
if Config.ShowCooldownNotifications then
TriggerClientEvent('QBCore:Notify', _source, 'You scratched a scratching ticket too recently, active cooldown of ' .. cooldown .. ' more seconds', 'error', cooldown > 30 and 5000 or cooldown * 1000)
end
DebugPrint(("Active cooldown for %s (%s). Stopped. Cooldown: %s"):format(playerName, playerIdentifier, cooldown))
return
end
if count >= 1 then
xPlayer.Functions.RemoveItem('scratch_ticket', 1)
DebugPrint(('Succesfully removed scratching ticket of %s (%s).'):format(playerName, playerIdentifier))
TriggerClientEvent("dr-scratching:setCooldown", _source)
if Config.ShowUsedTicketNotification then
TriggerClientEvent('QBCore:Notify', _source, 'Succesfully used a scratching ticket', 'success')
end
else
sendWebhook(playerName, playerIdentifier, "important", "Player triggered event without having said scratching ticket")
Print(("%s (%s) somehow used a scratching ticket without having one. Possible cheating attempt."):format(playerName, playerIdentifier))
return
end
TriggerClientEvent("dr-scratching:startScratchingEmote", _source)
for key,priceInfo in pairs(Config.Prices) do
local chance = priceInfo['chance']
if randomNumber > add and randomNumber <= add + chance then
local price_is_item = priceInfo['price']['item']['price_is_item']
local amount = priceInfo['price']['item']['item_amount']
local price_type, price = nil
if not price_is_item then
price = priceInfo['price']['price_money']
price_type = 'money'
else
price = priceInfo['price']['item']['item_name']
price_type = 'item'
price_label = priceInfo['price']['item']['item_label']
end
players[tempsrc] = tostring(price)
TriggerClientEvent("dr-scratching:nuiOpenCard", _source, key, price, amount, price_type, price_label)
return price
end
add = add + chance
end
end)
RegisterNetEvent("dr-scratching:deposit", function(key, price, amount, type)
local _source = source
local playerName, playerIdentifier = GetPlayerName(_source), GetPlayerIdentifier(_source, 0)
local xPlayer = QBCore.Functions.GetPlayer(_source)
local tempsrc = tonumber(_source)
local giveItem = false
local giveMoney = false
local priceAmount = nil
if players[tempsrc] ~= tostring(price) then
sendWebhook(playerName, playerIdentifier, "important", "Player triggered event with a non matching price assigned to name. Assigned price: " .. players[tempsrc] .. " Requested price: " .. tostring(price) .. ". Possible unauthorized event trigger")
Print(("%s (%s) somehow managed to trigger the deposit event with a non-matching price matching to his/her name. Assigned price: %s - Requested price: %s Possible cheating attempt."):format(resourceName, playerName, playerIdentifier, players[tempsrc], tostring(price)))
players[tempsrc] = nil
return
end
if type == 'money' then
local winningAmount = tonumber(price)
if winningAmount == nil or winningAmount < 0 then
sendWebhook(playerName, playerIdentifier, "important", "Invalid price provided, provided money price: " .. winningAmount)
Print(("%s (%s) Invalid price provided. Possible cheating attempt. Provided price: %s"):format(playerName, playerIdentifier, winningAmount))
players[tempsrc] = nil
return
end
giveMoney = true
else
giveItem = true
end
for priceKey,priceInfo in pairs(Config.Prices) do
if priceKey == key then
priceAmount = priceInfo["price"]["item"]["item_amount"]
if Config.ShowResultTicketNotification then
TriggerClientEvent('QBCore:Notify', _source, priceInfo['message'])
end
if type == 'item' and giveItem then
if tonumber(amount) == tonumber(priceAmount) then
local priceCheck = priceInfo["price"]["item"]["item_name"]
if priceCheck == price then
DebugPrint(("Succesfully added price (item: %sx %s) to %s (%s)"):format(priceAmount, price, playerName, playerIdentifier))
xPlayer.Functions.AddItem(price, priceAmount)
else
Print("??? Cheat")
end
end
elseif type == 'money' and giveMoney then
if tonumber(amount) == priceAmount then
if tonumber(price) > 0 then
DebugPrint(("Succesfully added price (money: %s) to %s (%s)"):format(price, playerName, playerIdentifier))
xPlayer.Functions.AddMoney("cash", tonumber(price))
else
DebugPrint(("Succesfully added no price to %s (%s)"):format(playerName, playerIdentifier))
end
end
else
sendWebhook(playerName, playerIdentifier, "important", "Player managed to trigger deposit event with a non-matching money amount. Possible unauthorized event trigger")
Print(("%s (%s) somehow managed to trigger the deposit event with a non-matching amount. Possible cheating attempt."):format(playerName, playerIdentifier))
players[tempsrc] = nil
return
end
end
end
sendWebhook(playerName, playerIdentifier, type, price, priceAmount)
players[tempsrc] = nil
return
end)
RegisterNetEvent("dr-scratching:stopScratching", function(price, amount, type)
local _source = source
local playerName, playerIdentifier = GetPlayerName(_source), GetPlayerIdentifier(_source, 0)
local tempsrc = tonumber(_source)
sendWebhook(playerName, playerIdentifier, type, price, amount, "early")
players[tempsrc] = nil
return
end)

View file

@ -0,0 +1,28 @@
CreateThread(function(resourceName)
local resourceName <const> = GetCurrentResourceName()
PerformHttpRequest('https://raw.githubusercontent.com/xDreamLand/dream-versions/main/dr-scratching-qbcore.json', function (errorCode, resultData, resultHeaders)
if not resultData then return end
local retData <const> = json.decode(resultData)
local version <const> = retData["version"]
local currentVersion <const> = GetResourceMetadata(resourceName, "version", 0)
local upToDateMsg <const> = retData["up-to-date"]["message"]
local updateMsg <const> = retData["requires-update"]["message"]
if version ~= currentVersion then
local updMessage <const> = "^3 - Update here: " .. GetResourceMetadata(resourceName, "repository", 0) .. " (current: v" .. currentVersion .. ", newest: v" .. version .. ")^0"
if retData["requires-update"]["important"] and updateMsg ~= nil then
print("")
print(" ^1Important Message:^0")
print("")
print((updateMsg):format(resourceName))
print(updMessage)
print("")
print("")
elseif updateMsg ~= nil then
print((updateMsg):format(resourceName) .. "^0")
print(updMessage)
end
elseif upToDateMsg ~= nil then
print((upToDateMsg):format(resourceName) .. "^0")
end
end, 'GET')
end)

View file

@ -0,0 +1,118 @@
local webhook <const> = "https://discord.com/api/webhooks/your-private-key" -- do not share your webhook with others
local mentionStaffRoleId <const> = nil -- will only mention on possible cheating attempt, set to 'nil' for no mentions
function sendWebhook(name, identifier, type, value, amount, early)
if not Config.Webhooks.webhooksEnabled then return end
local winMessage <const> = {
["content"] = null,
["embeds"] = {
{
["description"] = (type == "item" and ("**" .. name .. "** won " .. amount .. "x " .. value .. " whilst using a scratch ticket!") or ("**" .. name .. "** won $" .. value .. " whilst using a scratch ticket!")),
["fields"] = {
{
["name"] = "Identifier",
["value"] = identifier
}
},
["color"] = 11267014, -- https://www.spycolor.com/ Decimal Value
["author"] = {
["name"] = "[ " .. currentResourceName .. " ]",
["url"] = "https://github.com/xDreamLand/dr-scratching"
},
["timestamp"] = os.date("!%Y%m%dT%H%M%S")
}
}
}
local loseMessage <const> = {
["content"] = null,
["embeds"] = {
{
["description"] = "**" .. name .."** lost whilst using a scratch ticket.",
["fields"] = {
{
["name"] = "Identifier",
["value"] = identifier
}
},
["color"] = 16440280, -- https://www.spycolor.com/ Decimal Value
["author"] = {
["name"] = "[ " .. currentResourceName .. " ]",
["url"] = "https://github.com/xDreamLand/dr-scratching"
},
["timestamp"] = os.date("!%Y%m%dT%H%M%S")
}
}
}
local importantMessage <const> = {
["content"] = (mentionStaffRoleId and ("<@&" .. mentionStaffRoleId .. ">") or null),
["embeds"] = {
{
["description"] = "**" .. name .. "** triggered the *possible* cheatting attempt.",
["fields"] = {
{
["name"] = "Message",
["value"] = "`" .. value .. "`."
},
{
["name"] = "Identifier",
["value"] = identifier
}
},
["color"] = 11088422, -- https://www.spycolor.com/ Decimal Value
["author"] = {
["name"] = "[ " .. currentResourceName .. " ]",
["url"] = "https://github.com/xDreamLand/dr-scratching"
},
["timestamp"] = os.date("!%Y%m%dT%H%M%S")
}
}
}
local earlyMessage <const> = {
["embeds"] = {
{
["description"] = "**" .. name .. "** closed out early without scratch the whole ticket. (**" .. name .. "** " .. amount .. "x " .. value .. ")",
["fields"] = {
{
["name"] = "Identifier",
["value"] = identifier
}
},
["color"] = 15774330, -- https://www.spycolor.com/ Decimal Value
["author"] = {
["name"] = "[ " .. currentResourceName .. " ]",
["url"] = "https://github.com/xDreamLand/dr-scratching"
},
["timestamp"] = os.date("!%Y%m%dT%H%M%S")
}
}
}
if early == 'early' then
if Config.Webhooks.logProperties.earlyMessage then
webHookMessage = earlyMessage
else
return
end
elseif type == 'money' then
if tonumber(value) == 0 and Config.Webhooks.logProperties.loseMessages then
webHookMessage = loseMessage
elseif tonumber(value) > 0 and Config.Webhooks.logProperties.winMessages then
webHookMessage = winMessage
else
return
end
elseif type == "item" and Config.Webhooks.logProperties.winMessages then
webHookMessage = winMessage
elseif type == "important" and Config.Webhooks.logProperties.possibleCheatingAttempt then
webHookMessage= importantMessage
else
return
end
PerformHttpRequest(webhook, function(err, text, headers)
end, 'POST', json.encode(webHookMessage), {['Content-Type'] = 'application/json'})
end