add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,327 @@
local PLUGIN = PLUGIN
util.AddNetworkString("ixPromoCodeActivate")
util.AddNetworkString("ixPromoCodeResult")
util.AddNetworkString("ixPromoCodeCreate")
util.AddNetworkString("ixPromoCodeDelete")
util.AddNetworkString("ixPromoCodeList")
util.AddNetworkString("ixPromoCodeSync")
PLUGIN.promoCodes = PLUGIN.promoCodes or {}
PLUGIN.promoUsage = PLUGIN.promoUsage or {} -- [code] = {[steamID] = true}
-- Путь к файлу сохранения
local dataPath = "militaryrp/promocodes.txt"
-- Сохранение промокодов
function PLUGIN:SavePromoCodes()
local data = {
codes = self.promoCodes,
usage = self.promoUsage
}
file.CreateDir("militaryrp")
file.Write(dataPath, util.TableToJSON(data))
print("[PROMOCODES] Промокоды сохранены")
end
-- Загрузка промокодов
function PLUGIN:LoadPromoCodes()
if file.Exists(dataPath, "DATA") then
local jsonData = file.Read(dataPath, "DATA")
local data = util.JSONToTable(jsonData)
if data then
self.promoCodes = data.codes or {}
self.promoUsage = data.usage or {}
print("[PROMOCODES] Загружено " .. table.Count(self.promoCodes) .. " промокодов")
end
else
print("[PROMOCODES] Файл промокодов не найден, создается новый")
end
end
-- Генерация случайного кода
function PLUGIN:GenerateCode(length)
local chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
local code = ""
for i = 1, length do
local rand = math.random(1, #chars)
code = code .. string.sub(chars, rand, rand)
end
return code
end
-- Валидация именного промокода
function PLUGIN:ValidateCustomCode(code)
-- Проверка на пустоту
if not code or code == "" then
return false, "Код не может быть пустым"
end
-- Проверка длины (минимум 3, максимум 32 символа)
if #code < 3 then
return false, "Код должен содержать минимум 3 символа"
end
if #code > 32 then
return false, "Код должен содержать максимум 32 символа"
end
-- Проверка на допустимые символы (только A-Z, 0-9 и _)
if not string.match(code, "^[A-Z0-9_]+$") then
return false, "Код может содержать только буквы A-Z, цифры 0-9 и символ подчеркивания _"
end
return true, "OK"
end
-- Создание промокода
function PLUGIN:CreatePromoCode(admin, codeText, amount, maxUses, expiresAt, allowedRanks)
if not IsValid(admin) then return false, "Недействительный игрок" end
-- Проверка прав
if not admin:IsSuperAdmin() then
return false, "У вас нет прав для создания промокодов"
end
-- Генерация кода если не указан
if not codeText or codeText == "" then
codeText = self:GenerateCode(8)
print(string.format("[PROMOCODES] Сгенерирован случайный промокод: %s", codeText))
else
-- Валидация именного кода
local valid, error = self:ValidateCustomCode(codeText)
if not valid then
return false, error
end
print(string.format("[PROMOCODES] Создается именной промокод: %s", codeText))
end
codeText = string.upper(codeText)
-- Проверка существования
if self.promoCodes[codeText] then
return false, "Промокод с таким кодом уже существует"
end
-- Создание промокода
self.promoCodes[codeText] = {
code = codeText,
amount = math.max(1, tonumber(amount) or 100),
maxUses = math.max(1, tonumber(maxUses) or 1),
currentUses = 0,
expiresAt = tonumber(expiresAt) or (os.time() + 86400 * 30), -- По умолчанию 30 дней
allowedRanks = allowedRanks or {}, -- Пустой массив = доступно всем
createdBy = admin:SteamID(),
createdAt = os.time()
}
self.promoUsage[codeText] = {}
self:SavePromoCodes()
return true, "Промокод '" .. codeText .. "' создан на " .. self.promoCodes[codeText].amount .. " IGS"
end
-- Удаление промокода
function PLUGIN:DeletePromoCode(admin, codeText)
if not IsValid(admin) then return false, "Недействительный игрок" end
if not admin:IsSuperAdmin() then
return false, "У вас нет прав для удаления промокодов"
end
codeText = string.upper(codeText)
if not self.promoCodes[codeText] then
return false, "Промокод не найден"
end
self.promoCodes[codeText] = nil
self.promoUsage[codeText] = nil
self:SavePromoCodes()
return true, "Промокод '" .. codeText .. "' удален"
end
-- Проверка доступности промокода для игрока
function PLUGIN:CanUsePromoCode(client, codeText)
local promo = self.promoCodes[codeText]
if not promo then
return false, "Промокод не найден"
end
local steamID = client:SteamID()
-- Проверка использования игроком
if self.promoUsage[codeText] and self.promoUsage[codeText][steamID] then
return false, "Вы уже использовали этот промокод"
end
-- Проверка лимита использований
if promo.currentUses >= promo.maxUses then
return false, "Промокод исчерпан"
end
-- Проверка срока действия
if os.time() > promo.expiresAt then
return false, "Срок действия промокода истек"
end
-- Проверка доступных рангов
if promo.allowedRanks and #promo.allowedRanks > 0 then
local playerRank = client:GetUserGroup()
local hasAccess = false
for _, rank in ipairs(promo.allowedRanks) do
if playerRank == rank then
hasAccess = true
break
end
end
if not hasAccess then
return false, "Этот промокод недоступен для вашего ранга"
end
end
return true, "OK"
end
-- Активация промокода
function PLUGIN:ActivatePromoCode(client, codeText)
if not IsValid(client) then return false, "Недействительный игрок" end
codeText = string.upper(string.Trim(codeText))
if codeText == "" then
return false, "Введите промокод"
end
local canUse, reason = self:CanUsePromoCode(client, codeText)
if not canUse then
return false, reason
end
local promo = self.promoCodes[codeText]
local steamID = client:SteamID()
-- Начисление валюты через F4 плагин
local f4Plugin = ix.plugin.Get("f4menu")
if f4Plugin and f4Plugin.AdjustIGSBalance then
local success, error = f4Plugin:AdjustIGSBalance(client, promo.amount)
if not success then
return false, "Ошибка начисления валюты: " .. (error or "неизвестная ошибка")
end
else
return false, "Система доната недоступна"
end
-- Обновление данных промокода
promo.currentUses = promo.currentUses + 1
if not self.promoUsage[codeText] then
self.promoUsage[codeText] = {}
end
self.promoUsage[codeText][steamID] = true
self:SavePromoCodes()
-- Лог
print(string.format("[PROMOCODES] %s активировал промокод '%s' (+%d IGS)", client:Name(), codeText, promo.amount))
return true, string.format("Промокод активирован! Вы получили %d IGS", promo.amount)
end
-- Загрузка при старте
function PLUGIN:InitializedPlugins()
self:LoadPromoCodes()
end
-- Сетевые обработчики
net.Receive("ixPromoCodeActivate", function(len, client)
local code = net.ReadString()
local plugin = ix.plugin.Get("promocodes")
if not plugin then return end
local success, message = plugin:ActivatePromoCode(client, code)
net.Start("ixPromoCodeResult")
net.WriteBool(success)
net.WriteString(message)
net.Send(client)
end)
net.Receive("ixPromoCodeCreate", function(len, client)
if not client:IsSuperAdmin() then return end
local code = net.ReadString()
local amount = net.ReadUInt(32)
local maxUses = net.ReadUInt(16)
local expiresAt = net.ReadUInt(32)
local ranksCount = net.ReadUInt(8)
local allowedRanks = {}
for i = 1, ranksCount do
table.insert(allowedRanks, net.ReadString())
end
local plugin = ix.plugin.Get("promocodes")
if not plugin then return end
local success, message = plugin:CreatePromoCode(client, code, amount, maxUses, expiresAt, allowedRanks)
net.Start("ixPromoCodeResult")
net.WriteBool(success)
net.WriteString(message)
net.Send(client)
if success then
-- Отправляем обновленный список
plugin:SyncPromoCodesList(client)
end
end)
net.Receive("ixPromoCodeDelete", function(len, client)
if not client:IsSuperAdmin() then return end
local code = net.ReadString()
local plugin = ix.plugin.Get("promocodes")
if not plugin then return end
local success, message = plugin:DeletePromoCode(client, code)
net.Start("ixPromoCodeResult")
net.WriteBool(success)
net.WriteString(message)
net.Send(client)
if success then
plugin:SyncPromoCodesList(client)
end
end)
net.Receive("ixPromoCodeList", function(len, client)
if not client:IsSuperAdmin() then return end
local plugin = ix.plugin.Get("promocodes")
if not plugin then return end
plugin:SyncPromoCodesList(client)
end)
-- Синхронизация списка промокодов
function PLUGIN:SyncPromoCodesList(client)
if not IsValid(client) or not client:IsSuperAdmin() then return end
local codesList = {}
for code, data in pairs(self.promoCodes) do
table.insert(codesList, data)
end
net.Start("ixPromoCodeSync")
net.WriteString(util.TableToJSON(codesList))
net.Send(client)
end