Загрузка данных
-- Tokens_kdm1eHvH.lua
-- Система токенов + промокоды
-- ============================================================
-- БД
-- ============================================================
local function InitDB()
-- Токены игроков
if not sql.TableExists("player_tokens") then
sql.Query([[
CREATE TABLE player_tokens (
steamid TEXT PRIMARY KEY,
tokens INTEGER DEFAULT 0
)
]])
print("[Tokens] Таблица player_tokens создана")
end
-- Промокоды
if not sql.TableExists("promo_codes") then
sql.Query([[
CREATE TABLE promo_codes (
code TEXT PRIMARY KEY,
tokens INTEGER DEFAULT 0,
max_uses INTEGER DEFAULT 1,
uses INTEGER DEFAULT 0,
created INTEGER DEFAULT 0,
created_by TEXT DEFAULT ''
)
]])
print("[Tokens] Таблица promo_codes создана")
end
-- Кто использовал промокоды
if not sql.TableExists("promo_used") then
sql.Query([[
CREATE TABLE promo_used (
code TEXT,
steamid TEXT,
used_at INTEGER DEFAULT 0
)
]])
print("[Tokens] Таблица promo_used создана")
end
end
InitDB()
-- ============================================================
-- Функции токенов
-- ============================================================
function GetTokens(ply)
if not IsValid(ply) then return 0 end
local steamid = ply:SteamID()
local q = "SELECT tokens FROM player_tokens WHERE steamid = " .. sql.SQLStr(steamid)
local res = sql.QueryRow(q, 1)
if res then return tonumber(res.tokens) or 0 end
return 0
end
function AddTokens(ply, amount)
if not IsValid(ply) then return end
local steamid = ply:SteamID()
local current = GetTokens(ply)
local new = current + amount
sql.Query("INSERT INTO player_tokens (steamid, tokens) VALUES (" ..
sql.SQLStr(steamid) .. ", " .. new .. ") " ..
"ON CONFLICT(steamid) DO UPDATE SET tokens = " .. new)
ply:SetNWInt("kdm1e_Tokens", new)
end
function RemoveTokens(ply, amount)
if not IsValid(ply) then return end
local steamid = ply:SteamID()
local current = GetTokens(ply)
local new = math.max(0, current - amount)
sql.Query("UPDATE player_tokens SET tokens = " .. new .. " WHERE steamid = " .. sql.SQLStr(steamid))
ply:SetNWInt("kdm1e_Tokens", new)
end
-- ============================================================
-- Загрузка токенов при заходе
-- ============================================================
hook.Add("PlayerInitialSpawn", "Tokens_Load", function(ply)
timer.Simple(1.5, function()
if not IsValid(ply) then return end
local t = GetTokens(ply)
ply:SetNWInt("kdm1e_Tokens", t)
end)
end)
-- ============================================================
-- КОМАНДЫ
-- ============================================================
-- !mytokens — свой баланс
concommand.Add("kdm1e_mytokens", function(ply)
if not IsValid(ply) then return end
ply:PrintMessage(HUD_PRINTTALK, "У тебя токенов: " .. GetTokens(ply))
end)
-- !promo КОД — активировать
concommand.Add("kdm1e_promo", function(ply, cmd, args)
if not IsValid(ply) then return end
if #args < 1 then
ply:PrintMessage(HUD_PRINTTALK, "Использование: !promo КОД")
return
end
local code = string.upper(args[1])
local steamid = ply:SteamID()
-- Проверяем, есть ли такой код
local q = "SELECT * FROM promo_codes WHERE code = " .. sql.SQLStr(code)
local res = sql.QueryRow(q, 1)
if not res then
ply:PrintMessage(HUD_PRINTTALK, "Промокод не найден!")
return
end
-- Проверяем лимит
local uses = tonumber(res.uses) or 0
local max_uses = tonumber(res.max_uses) or 1
if uses >= max_uses then
ply:PrintMessage(HUD_PRINTTALK, "Промокод больше не действует!")
return
end
-- Проверяем, не использовал ли уже
local q2 = "SELECT * FROM promo_used WHERE code = " .. sql.SQLStr(code) ..
" AND steamid = " .. sql.SQLStr(steamid)
local res2 = sql.QueryRow(q2, 1)
if res2 then
ply:PrintMessage(HUD_PRINTTALK, "Ты уже использовал этот промокод!")
return
end
-- Активируем
local tokens = tonumber(res.tokens) or 0
AddTokens(ply, tokens)
sql.Query("UPDATE promo_codes SET uses = " .. (uses + 1) .. " WHERE code = " .. sql.SQLStr(code))
sql.Query("INSERT INTO promo_used (code, steamid, used_at) VALUES (" ..
sql.SQLStr(code) .. ", " .. sql.SQLStr(steamid) .. ", " .. os.time() .. ")")
ply:PrintMessage(HUD_PRINTTALK, "Промокод активирован! +" .. tokens .. " токенов")
end)
-- !promocodeadmin "код" "лимит" "токены" — создать промокод
concommand.Add("kdm1e_promocodeadmin", function(ply, cmd, args)
-- Проверка прав
if IsValid(ply) then
local ok = ply:IsSuperAdmin() or (RANKS and RANKS.HasPerm(ply, "canEverything"))
if not ok then
ply:PrintMessage(HUD_PRINTTALK, "Нет прав!")
return
end
end
if #args < 3 then
local msg = "Использование: !promocodeadmin \"КОД\" \"ЛИМИТ\" \"ТОКЕНЫ\""
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, msg) else print(msg) end
return
end
local code = string.upper(args[1])
local maxUses = tonumber(args[2]) or 1
local tokens = tonumber(args[3]) or 0
-- Проверяем, есть ли уже
local q = "SELECT * FROM promo_codes WHERE code = " .. sql.SQLStr(code)
if sql.QueryRow(q, 1) then
local msg = "Промокод уже существует!"
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, msg) else print(msg) end
return
end
local creator = IsValid(ply) and ply:SteamID() or "console"
sql.Query("INSERT INTO promo_codes (code, tokens, max_uses, uses, created, created_by) VALUES (" ..
sql.SQLStr(code) .. ", " .. tokens .. ", " .. maxUses .. ", 0, " .. os.time() .. ", " ..
sql.SQLStr(creator) .. ")")
local msg = "Промокод '" .. code .. "' создан! Токенов: " .. tokens .. ", лимит: " .. maxUses
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, msg) else print(msg) end
end)
-- !promolist — список промокодов
concommand.Add("kdm1e_promolist", function(ply)
if IsValid(ply) then
local ok = ply:IsSuperAdmin() or (RANKS and RANKS.HasPerm(ply, "canEverything"))
if not ok then
ply:PrintMessage(HUD_PRINTTALK, "Нет прав!")
return
end
end
local res = sql.Query("SELECT * FROM promo_codes ORDER BY created DESC LIMIT 20")
if not res or #res == 0 then
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, "Промокодов нет") end
return
end
if IsValid(ply) then
ply:PrintMessage(HUD_PRINTTALK, "=== ПРОМОКОДЫ ===")
for _, row in ipairs(res) do
ply:PrintMessage(HUD_PRINTTALK,
row.code .. " | " .. row.tokens .. " токенов | " ..
row.uses .. "/" .. row.max_uses)
end
else
print("=== ПРОМОКОДЫ ===")
for _, row in ipairs(res) do
print(row.code .. " | " .. row.tokens .. " | " .. row.uses .. "/" .. row.max_uses)
end
end
end)
-- !deletepromo КОД — удалить
concommand.Add("kdm1e_deletepromo", function(ply, cmd, args)
if IsValid(ply) then
local ok = ply:IsSuperAdmin() or (RANKS and RANKS.HasPerm(ply, "canEverything"))
if not ok then
ply:PrintMessage(HUD_PRINTTALK, "Нет прав!")
return
end
end
if #args < 1 then
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, "Использование: !deletepromo КОД") end
return
end
local code = string.upper(args[1])
sql.Query("DELETE FROM promo_codes WHERE code = " .. sql.SQLStr(code))
if IsValid(ply) then
ply:PrintMessage(HUD_PRINTTALK, "Промокод '" .. code .. "' удалён")
end
end)
-- !givetokens SteamID кол-во — выдать
concommand.Add("kdm1e_givetokens", function(ply, cmd, args)
if IsValid(ply) then
local ok = ply:IsSuperAdmin() or (RANKS and RANKS.HasPerm(ply, "canEverything"))
if not ok then
ply:PrintMessage(HUD_PRINTTALK, "Нет прав!")
return
end
end
if #args < 2 then
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, "Использование: !givetokens SteamID кол-во") end
return
end
local sid = args[1]
local amount = tonumber(args[2]) or 0
for _, p in ipairs(player.GetAll()) do
if IsValid(p) and (p:SteamID() == sid or p:SteamID64() == sid) then
AddTokens(p, amount)
if IsValid(ply) then
ply:PrintMessage(HUD_PRINTTALK, "Выдано " .. amount .. " токенов игроку " .. p:Nick())
end
p:PrintMessage(HUD_PRINTTALK, "Тебе выдано " .. amount .. " токенов!")
return
end
end
-- Если оффлайн — пишем в БД
local q = "SELECT tokens FROM player_tokens WHERE steamid = " .. sql.SQLStr(sid)
local res = sql.QueryRow(q, 1)
local current = res and tonumber(res.tokens) or 0
local new = current + amount
sql.Query("INSERT INTO player_tokens (steamid, tokens) VALUES (" ..
sql.SQLStr(sid) .. ", " .. new .. ") " ..
"ON CONFLICT(steamid) DO UPDATE SET tokens = " .. new)
if IsValid(ply) then
ply:PrintMessage(HUD_PRINTTALK, "Выдано " .. amount .. " токенов (оффлайн)")
end
end)
-- !removetokens SteamID кол-во — забрать
concommand.Add("kdm1e_removetokens", function(ply, cmd, args)
if IsValid(ply) then
local ok = ply:IsSuperAdmin() or (RANKS and RANKS.HasPerm(ply, "canEverything"))
if not ok then
ply:PrintMessage(HUD_PRINTTALK, "Нет прав!")
return
end
end
if #args < 2 then
if IsValid(ply) then ply:PrintMessage(HUD_PRINTTALK, "Использование: !removetokens SteamID кол-во") end
return
end
local sid = args[1]
local amount = tonumber(args[2]) or 0
for _, p in ipairs(player.GetAll()) do
if IsValid(p) and (p:SteamID() == sid or p:SteamID64() == sid) then
RemoveTokens(p, amount)
if IsValid(ply) then
ply:PrintMessage(HUD_PRINTTALK, "Снято " .. amount .. " токенов у " .. p:Nick())
end
p:PrintMessage(HUD_PRINTTALK, "У тебя снято " .. amount .. " токенов!")
return
end
end
end)
-- ============================================================
-- Чат-команды
-- ============================================================
hook.Add("PlayerSay", "Tokens_ChatCommands", function(ply, text, team)
if not IsValid(ply) then return end
local lower = string.lower(text)
if lower == "!mytokens" or lower == "/mytokens" then
ply:ConCommand("kdm1e_mytokens")
return ""
end
if string.StartWith(lower, "!promo ") or string.StartWith(lower, "/promo ") then
local args = string.Explode(" ", text)
table.remove(args, 1)
ply:ConCommand("kdm1e_promo " .. table.concat(args, " "))
return ""
end
if string.StartWith(lower, "!promocodeadmin ") or string.StartWith(lower, "/promocodeadmin ") then
local args = string.Explode(" ", text)
table.remove(args, 1)
ply:ConCommand("kdm1e_promocodeadmin " .. table.concat(args, " "))
return ""
end
if lower == "!promolist" or lower == "/promolist" then
ply:ConCommand("kdm1e_promolist")
return ""
end
end)
print("[Tokens] Система токенов загружена")