add sborka
This commit is contained in:
2709
garrysmod/gamemodes/militaryrp/plugins/f4menu/cl_plugin.lua
Normal file
2709
garrysmod/gamemodes/militaryrp/plugins/f4menu/cl_plugin.lua
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,253 @@
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
PLUGIN.donateCatalog = PLUGIN.donateCatalog or {
|
||||
{
|
||||
id = "currency",
|
||||
name = "Рубли",
|
||||
tagline = "Пополнение игрового баланса",
|
||||
accent = { r = 1, g = 104, b = 44 },
|
||||
items = {
|
||||
{
|
||||
id = "money_1000",
|
||||
title = "1.000 ₽",
|
||||
price = 50,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Пополнение игрового баланса",
|
||||
"Мгновенное зачисление",
|
||||
"Использование в магазинах"
|
||||
},
|
||||
reward = {
|
||||
type = "money",
|
||||
amount = 1000
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "money_5000",
|
||||
title = "5.000 ₽",
|
||||
price = 225,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Пополнение игрового баланса",
|
||||
"Мгновенное зачисление",
|
||||
"Использование в магазинах",
|
||||
"Выгодно: +10% бонус"
|
||||
},
|
||||
tag = "ВЫГОДНО",
|
||||
reward = {
|
||||
type = "money",
|
||||
amount = 5000
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "money_10000",
|
||||
title = "10.000 ₽",
|
||||
price = 400,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Пополнение игрового баланса",
|
||||
"Мгновенное зачисление",
|
||||
"Использование в магазинах",
|
||||
"Выгодно: +20% бонус"
|
||||
},
|
||||
tag = "ХИТ",
|
||||
reward = {
|
||||
type = "money",
|
||||
amount = 10000
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "money_25000",
|
||||
title = "25.000 ₽",
|
||||
price = 900,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Пополнение игрового баланса",
|
||||
"Мгновенное зачисление",
|
||||
"Использование в магазинах",
|
||||
"Максимально выгодно: +28% бонус"
|
||||
},
|
||||
tag = "ЛУЧШЕЕ",
|
||||
reward = {
|
||||
type = "money",
|
||||
amount = 25000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "weapons",
|
||||
name = "Оружие",
|
||||
tagline = "Донатное оружие в ваш арсенал",
|
||||
accent = { r = 1, g = 104, b = 44 },
|
||||
items = {
|
||||
{ id = "ak12", title = "AK-12", price1Month = 1200, price3Month = 3200, currency = "IGS", perks = { "Доступен в арсенале", "Кулдаун 10 минут", "Любая фракция" }, reward = { type = "weapon", weaponClass = "tacrp_ak_ak12", name = "AK-12" } },
|
||||
{ id = "mdr", title = "Desert Tech MDR", price1Month = 1500, price3Month = 4000, currency = "IGS", perks = { "Доступен в арсенале", "Кулдаун 10 минут", "Любая фракция" }, reward = { type = "weapon", weaponClass = "arc9_eft_mdr", name = "MDR" } },
|
||||
{ id = "mp7a1", title = "MP7A1", price1Month = 1300, price3Month = 3500, currency = "IGS", perks = { "Доступен в арсенале", "Кулдаун 10 минут", "Любая фракция" }, reward = { type = "weapon", weaponClass = "arc9_eft_mp7a1", name = "MP7A1" } },
|
||||
{ id = "ai_axmc", title = "AI AXMC", price1Month = 2000, price3Month = 5500, currency = "IGS", perks = { "Снайперская винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_ai_axmc", name = "AI AXMC" } },
|
||||
{ id = "t5000", title = "T-5000", price1Month = 1900, price3Month = 5200, currency = "IGS", perks = { "Снайперская винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_t5000", name = "T-5000" } },
|
||||
{ id = "saiga12k", title = "Сайга-12К", price1Month = 1400, price3Month = 3800, currency = "IGS", perks = { "Автоматический дробовик", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_saiga12k", name = "Сайга-12К" } },
|
||||
{ id = "deagle", title = "Desert Eagle XIX", price1Month = 800, price3Month = 2200, currency = "IGS", perks = { "Мощный пистолет", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_deagle_xix", name = "Desert Eagle" } },
|
||||
{ id = "apb", title = "АПБ", price1Month = 700, price3Month = 1900, currency = "IGS", perks = { "Бесшумный пистолет", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_apb", name = "АПБ" } },
|
||||
{ id = "spear", title = "SPEAR", price1Month = 1600, price3Month = 4400, currency = "IGS", perks = { "Доступен в арсенале", "Кулдаун 10 минут", "Любая фракция" }, reward = { type = "weapon", weaponClass = "arc9_eft_spear", name = "SPEAR" } },
|
||||
{ id = "sr25", title = "SR-25", price1Month = 1800, price3Month = 4900, currency = "IGS", perks = { "Снайперская винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_sr25", name = "SR-25" } },
|
||||
{ id = "dvl10", title = "ДВЛ-10", price1Month = 1900, price3Month = 5200, currency = "IGS", perks = { "Снайперская винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_dvl10", name = "ДВЛ-10" } },
|
||||
{ id = "hultafors", title = "Dead Blow Hammer", price1Month = 300, price3Month = 800, currency = "IGS", perks = { "Холодное оружие", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_melee_hultafors", name = "Hammer" } },
|
||||
{ id = "cultist", title = "Cultist Knife", price1Month = 400, price3Month = 1100, currency = "IGS", perks = { "Холодное оружие", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_melee_cultist", name = "Cultist Knife" } },
|
||||
{ id = "akula", title = "Akula", price1Month = 350, price3Month = 950, currency = "IGS", perks = { "Холодное оружие", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_melee_akula", name = "Akula" } },
|
||||
{ id = "crash", title = "Crash Axe", price1Month = 350, price3Month = 950, currency = "IGS", perks = { "Холодное оружие", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_melee_crash", name = "Crash Axe" } },
|
||||
{ id = "kukri", title = "Kukri", price1Month = 400, price3Month = 1100, currency = "IGS", perks = { "Холодное оружие", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_melee_kukri", name = "Kukri" } },
|
||||
{ id = "ak50", title = "AK-50", price1Month = 2200, price3Month = 6000, currency = "IGS", perks = { "Мощная штурмовая винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, tag = "ХИТ", reward = { type = "weapon", weaponClass = "arc9_eft_ak50", name = "AK-50" } },
|
||||
{ id = "vss", title = "ВСС Винторез", price1Month = 1500, price3Month = 4100, currency = "IGS", perks = { "Бесшумная винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_vss", name = "ВСС" } },
|
||||
{ id = "mr43", title = "МР-43", price1Month = 1000, price3Month = 2700, currency = "IGS", perks = { "Дробовик", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_mr43", name = "МР-43" } },
|
||||
{ id = "rpk16", title = "РПК-16", price1Month = 1700, price3Month = 4600, currency = "IGS", perks = { "Ручной пулемёт", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_rpk16", name = "РПК-16" } },
|
||||
{ id = "rshg2", title = "РШГ-2", price1Month = 2500, price3Month = 6800, currency = "IGS", perks = { "Гранатомёт", "Доступен в арсенале", "Кулдаун 10 минут" }, tag = "РЕДКОЕ", reward = { type = "weapon", weaponClass = "arc9_eft_rshg2", name = "РШГ-2" } },
|
||||
{ id = "ash12", title = "АШ-12", price1Month = 1800, price3Month = 4900, currency = "IGS", perks = { "Штурмовая винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_ash12", name = "АШ-12" } },
|
||||
{ id = "rd704", title = "RD-704", price1Month = 1400, price3Month = 3800, currency = "IGS", perks = { "Штурмовая винтовка", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_rd704", name = "RD-704" } },
|
||||
{ id = "ppsh41", title = "ППШ-41", price1Month = 900, price3Month = 2400, currency = "IGS", perks = { "Легендарный ПП", "Доступен в арсенале", "Кулдаун 10 минут" }, reward = { type = "weapon", weaponClass = "arc9_eft_ppsh41", name = "ППШ-41" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "other",
|
||||
name = "Другое",
|
||||
tagline = "Дополнительные возможности",
|
||||
accent = { r = 1, g = 104, b = 44 },
|
||||
items = {
|
||||
{
|
||||
id = "voice_chat",
|
||||
title = "Говорилка",
|
||||
price = 500,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Разблокировка голосового чата",
|
||||
"Радиус слышимости 200м",
|
||||
"Без ограничений по времени",
|
||||
"Мгновенная активация"
|
||||
},
|
||||
reward = {
|
||||
type = "voice_chat",
|
||||
successMessage = "Голосовой чат разблокирован!"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "privileges",
|
||||
name = "Привелегии",
|
||||
tagline = "VIP статусы и возможности",
|
||||
accent = { r = 1, g = 104, b = 44 },
|
||||
items = {
|
||||
{
|
||||
id = "vip",
|
||||
title = "VIP",
|
||||
price1Month = 300,
|
||||
price3Month = 800,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Цветной ник и иконка VIP в чате",
|
||||
"Приоритет при входе на сервер",
|
||||
"Скидка 10% в арсенале",
|
||||
"Доступ к VIP-командам"
|
||||
},
|
||||
reward = {
|
||||
type = "privilege",
|
||||
tier = "vip"
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "vip_plus",
|
||||
title = "VIP+",
|
||||
price1Month = 500,
|
||||
price3Month = 1400,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Все преимущества VIP",
|
||||
"Увеличенная зарплата (+15%)",
|
||||
"Скидка 15% в арсенале",
|
||||
"Доступ к уникальным моделям",
|
||||
"Еженедельный бонус валюты"
|
||||
},
|
||||
reward = {
|
||||
type = "privilege",
|
||||
tier = "vip_plus"
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "premium",
|
||||
title = "Premium",
|
||||
price1Month = 800,
|
||||
price3Month = 2200,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Все преимущества VIP+",
|
||||
"Увеличенная зарплата (+25%)",
|
||||
"Скидка 20% в арсенале",
|
||||
"Приоритетный спавн техники",
|
||||
"Доступ к Premium-командам",
|
||||
"Уникальные анимации и эффекты"
|
||||
},
|
||||
tag = "ХИТ",
|
||||
reward = {
|
||||
type = "privilege",
|
||||
tier = "premium"
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "sponsor",
|
||||
title = "Спонсор",
|
||||
price1Month = 1300,
|
||||
price3Month = 3600,
|
||||
currency = "IGS",
|
||||
perks = {
|
||||
"Доступ к личному Discord-серверу разработчиков проекта с различной информацией, включая оповещения о свежих обновлениях",
|
||||
"Увеличенный доход за убийство противника на сервере",
|
||||
"Быстрый захват точки противника (в 1,5 раза быстрее)",
|
||||
"Уменьшенное ограничение (по времени) на выкат техники",
|
||||
"Постоянно действующие скидки в 20% на покупку доната (НЕ ЧЕРЕЗ АВТО-ДОНАТ)",
|
||||
"Уникальные возможности на сервере",
|
||||
"Участие в закрытых бета-тестированиях и голосованиях"
|
||||
},
|
||||
tag = "ЭКСКЛЮЗИВ",
|
||||
reward = {
|
||||
type = "privilege",
|
||||
tier = "sponsor"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local function BuildDonateLookup()
|
||||
PLUGIN.donateItemsByID = {}
|
||||
for _, category in ipairs(PLUGIN.donateCatalog or {}) do
|
||||
for _, item in ipairs(category.items or {}) do
|
||||
PLUGIN.donateItemsByID[item.id] = item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
BuildDonateLookup()
|
||||
|
||||
function PLUGIN:GetDonateCatalog()
|
||||
return self.donateCatalog or {}
|
||||
end
|
||||
|
||||
function PLUGIN:GetDonateCategory(identifier)
|
||||
if not identifier then return end
|
||||
|
||||
for _, category in ipairs(self:GetDonateCatalog()) do
|
||||
if category.id == identifier then
|
||||
return category
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:GetDonateProduct(identifier)
|
||||
if not identifier then return end
|
||||
|
||||
if not self.donateItemsByID then
|
||||
BuildDonateLookup()
|
||||
end
|
||||
|
||||
return self.donateItemsByID[identifier]
|
||||
end
|
||||
36
garrysmod/gamemodes/militaryrp/plugins/f4menu/sh_plugin.lua
Normal file
36
garrysmod/gamemodes/militaryrp/plugins/f4menu/sh_plugin.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
PLUGIN.name = "F4 Menu"
|
||||
PLUGIN.author = "RefoselTeamWork"
|
||||
PLUGIN.description = "F4 Menu for Military RP"
|
||||
|
||||
-- Ссылки на социальные сети
|
||||
PLUGIN.socialLinks = {
|
||||
discord = "https://discord.gg/paQdrP7aD7",
|
||||
steam = "https://steamcommunity.com/sharedfiles/filedetails/?id=3630170114",
|
||||
tiktok = "https://www.tiktok.com/@front.team0?_t=ZS-8zQYdHdzDB1&_r=1",
|
||||
telegram = "https://t.me/frontteamproject"
|
||||
}
|
||||
|
||||
-- Материалы иконок социальных сетей
|
||||
PLUGIN.socialIcons = {
|
||||
discord = "materials/ft_ui/military/vnu/f4menu/icons/discord.png",
|
||||
steam = "materials/ft_ui/military/vnu/f4menu/icons/steam.png",
|
||||
tiktok = "materials/ft_ui/military/vnu/f4menu/icons/tiktok.png",
|
||||
telegram = "materials/ft_ui/military/vnu/f4menu/icons/telegram.png"
|
||||
}
|
||||
|
||||
ix.util.Include("sh_donate_config.lua")
|
||||
ix.util.Include("sh_thanks_config.lua")
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
ix.util.Include("cl_plugin.lua")
|
||||
|
||||
ix.command.Add("Donate", {
|
||||
description = "Открыть меню доната (IGS)",
|
||||
alias = {"Donat", "Донат"},
|
||||
OnRun = function(self, client)
|
||||
if (CLIENT) then
|
||||
RunConsoleCommand("igs")
|
||||
else
|
||||
client:ConCommand("igs")
|
||||
end
|
||||
end
|
||||
})
|
||||
@@ -0,0 +1,181 @@
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
PLUGIN.thanksPages = PLUGIN.thanksPages or {
|
||||
{
|
||||
id = "founders",
|
||||
title = "Руководители",
|
||||
people = {
|
||||
{
|
||||
name = "Oleg Zakon",
|
||||
model = "models/player/gman_high.mdl",
|
||||
sequence = "pose_standing_01",
|
||||
description = "Основатель и идейный вдохновитель Front Team. Отвечает за общее развитие проекта, стратегию и ключевые решения. Следит за качеством контента, стабильностью сервера и взаимодействием с сообществом.",
|
||||
link = "https://steamcommunity.com/profiles/76561198204118180"
|
||||
},
|
||||
{
|
||||
name = "Бугор",
|
||||
model = "models/player/breen.mdl",
|
||||
sequence = "pose_standing_01",
|
||||
description = "Правая рука владельца. Курирует техническую часть, развитие игровых механик и поддержку проекта. Обеспечивает бесперебойную работу сервера и помогает в реализации идей сообщества.",
|
||||
link = "https://steamcommunity.com/profiles/76561199186141452"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "developers",
|
||||
title = "Разработчики",
|
||||
people = {
|
||||
|
||||
{
|
||||
name = "Биба",
|
||||
model = "models/player/police.mdl",
|
||||
sequence = "pose_ducking_01",
|
||||
description = "Настройщик игровых механик",
|
||||
link = "https://steamcommunity.com/profiles/76561199189433293"
|
||||
},
|
||||
{
|
||||
name = "Scripty",
|
||||
model = "models/player/skeleton.mdl",
|
||||
sequence = "pose_standing_04",
|
||||
description = "Разработчик",
|
||||
link = "https://steamcommunity.com/profiles/76561198164572709"
|
||||
},
|
||||
{
|
||||
name = "ItzTomber",
|
||||
model = "models/player/kleiner.mdl",
|
||||
sequence = "pose_standing_04",
|
||||
description = "Разработчик",
|
||||
link = "https://steamcommunity.com/profiles/76561198341626975"
|
||||
},
|
||||
{
|
||||
name = "Hari",
|
||||
model = "models/player/magnusson.mdl",
|
||||
sequence = "pose_standing_02",
|
||||
description = "Разработчик.",
|
||||
link = "https://steamcommunity.com/profiles/76561198201651767"
|
||||
},
|
||||
{
|
||||
name = "Refosel",
|
||||
model = "models/kemono_friends/ezo_red_fox/ezo_red_fox_player.mdl",
|
||||
sequence = "pose_standing_01",
|
||||
description = "Главный Разработчик",
|
||||
link = "https://steamcommunity.com/profiles/76561198393073512"
|
||||
},
|
||||
{
|
||||
name = "Прохор",
|
||||
model = "models/player/odessa.mdl",
|
||||
sequence = "pose_standing_02",
|
||||
description = "Маппер.",
|
||||
link = "no link"
|
||||
},
|
||||
{
|
||||
name = "Сварщик",
|
||||
model = "models/player/eli.mdl",
|
||||
sequence = "pose_standing_04",
|
||||
description = "Модделер.",
|
||||
link = "https://steamcommunity.com/profiles/76561198440513870"
|
||||
},
|
||||
{
|
||||
name = "Козырный",
|
||||
model = "models/player/police.mdl",
|
||||
sequence = "pose_ducking_01",
|
||||
description = "Figma дизайнер.",
|
||||
link = "https://steamcommunity.com/profiles/76561199077227396"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id = "helix",
|
||||
title = "Helix",
|
||||
people = {
|
||||
{
|
||||
name = "NutScript",
|
||||
model = "models/player/police.mdl",
|
||||
sequence = "pose_ducking_01",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://github.com/NutScript/NutScript"
|
||||
},
|
||||
{
|
||||
name = "Alex Grist",
|
||||
model = "models/player/police.mdl",
|
||||
sequence = "pose_ducking_01",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://steamcommunity.com/profiles/76561197979205163"
|
||||
},
|
||||
{
|
||||
name = "Igor Radovanovic",
|
||||
model = "models/player/combine_soldier.mdl",
|
||||
sequence = "pose_standing_04",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://steamcommunity.com/profiles/76561197990111113"
|
||||
},
|
||||
{
|
||||
name = "Jaydawg",
|
||||
model = "models/player/combine_soldier_prisonguard.mdl",
|
||||
sequence = "pose_standing_02",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://steamcommunity.com/profiles/76561197970371430"
|
||||
},
|
||||
{
|
||||
name = "nebulous",
|
||||
model = "models/player/combine_super_soldier.mdl",
|
||||
sequence = "pose_standing_01",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://github.com/NebulousCloud"
|
||||
},
|
||||
{
|
||||
name = "Black Tea",
|
||||
model = "models/player/combine_soldier_prisonguard.mdl",
|
||||
sequence = "pose_standing_02",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://steamcommunity.com/profiles/76561197999893894"
|
||||
},
|
||||
{
|
||||
name = "Rain GBizzle",
|
||||
model = "models/player/combine_soldier.mdl",
|
||||
sequence = "pose_standing_04",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://steamcommunity.com/profiles/76561198036111376"
|
||||
},
|
||||
{
|
||||
name = "Luna",
|
||||
model = "models/player/police.mdl",
|
||||
sequence = "pose_ducking_01",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://steamcommunity.com/profiles/76561197988658543"
|
||||
},
|
||||
{
|
||||
name = "Contributors",
|
||||
model = "models/player/police.mdl",
|
||||
sequence = "pose_ducking_01",
|
||||
description = "Спасибо за Helix.",
|
||||
link = "https://github.com/NebulousCloud/helix/graphs/contributors"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function PLUGIN:GetThanksPages()
|
||||
return self.thanksPages or {}
|
||||
end
|
||||
|
||||
function PLUGIN:GetThanksPage(identifier)
|
||||
if not identifier then return end
|
||||
|
||||
for _, page in ipairs(self:GetThanksPages()) do
|
||||
if page.id == identifier then
|
||||
return page
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:GetThanksPerson(pageID, personName)
|
||||
local page = self:GetThanksPage(pageID)
|
||||
if not page then return end
|
||||
|
||||
for _, person in ipairs(page.people or {}) do
|
||||
if person.name == personName then
|
||||
return person
|
||||
end
|
||||
end
|
||||
end
|
||||
667
garrysmod/gamemodes/militaryrp/plugins/f4menu/sv_plugin.lua
Normal file
667
garrysmod/gamemodes/militaryrp/plugins/f4menu/sv_plugin.lua
Normal file
@@ -0,0 +1,667 @@
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
util.AddNetworkString("ix.F4_RequestInfo")
|
||||
util.AddNetworkString("ix.F4_SendInfo")
|
||||
util.AddNetworkString("ix.F4_DonatePurchase")
|
||||
util.AddNetworkString("ix.F4_DonatePurchaseResult")
|
||||
util.AddNetworkString("ixChangeName")
|
||||
util.AddNetworkString("ixF4UpdateName")
|
||||
|
||||
local function GetFactionCounters(factionID, podIndex, specIndex)
|
||||
local factionOnline, samePod, sameSpec = 0, 0, 0
|
||||
|
||||
for _, ply in ipairs(player.GetAll()) do
|
||||
if not IsValid(ply) then continue end
|
||||
if ply:Team() ~= factionID then continue end
|
||||
|
||||
factionOnline = factionOnline + 1
|
||||
|
||||
local char = ply:GetCharacter()
|
||||
if not char then continue end
|
||||
|
||||
if char:GetPodr() == podIndex then
|
||||
samePod = samePod + 1
|
||||
end
|
||||
|
||||
if char:GetSpec() == specIndex then
|
||||
sameSpec = sameSpec + 1
|
||||
end
|
||||
end
|
||||
|
||||
return factionOnline, samePod, sameSpec
|
||||
end
|
||||
|
||||
local function BuildInfoPayload(client)
|
||||
local char = client:GetCharacter()
|
||||
if not char then return end
|
||||
|
||||
local factionID = char:GetFaction()
|
||||
local factionTable = ix.faction.Get(factionID)
|
||||
local podIndex = char:GetPodr()
|
||||
local specIndex = char:GetSpec()
|
||||
local rankIndex = char:GetRank() or 1
|
||||
|
||||
local factionOnline, samePod, sameSpec = GetFactionCounters(factionID, podIndex, specIndex)
|
||||
|
||||
local vehiclesPlugin = ix.plugin.Get("vehicles")
|
||||
local arsenalPlugin = ix.plugin.Get("arsenal")
|
||||
|
||||
local techPoints = 0
|
||||
if vehiclesPlugin and vehiclesPlugin.GetFactionPoints then
|
||||
techPoints = vehiclesPlugin:GetFactionPoints(factionID) or 0
|
||||
end
|
||||
|
||||
local supplyPoints = 0
|
||||
if arsenalPlugin and arsenalPlugin.GetFactionSupply then
|
||||
supplyPoints = arsenalPlugin:GetFactionSupply(factionID) or 0
|
||||
end
|
||||
|
||||
local activeVehicles = 0
|
||||
if vehiclesPlugin and vehiclesPlugin.activeVehicles then
|
||||
for _, data in pairs(vehiclesPlugin.activeVehicles) do
|
||||
if not istable(data) then continue end
|
||||
if data.faction == factionID then
|
||||
activeVehicles = activeVehicles + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local subdivisionData = {
|
||||
index = podIndex,
|
||||
name = "Не назначено",
|
||||
preset = {},
|
||||
specDefault = 1,
|
||||
members = samePod,
|
||||
model = "",
|
||||
skin = 0,
|
||||
bodygroups = {}
|
||||
}
|
||||
|
||||
local specData = {
|
||||
index = specIndex,
|
||||
name = "Не назначено",
|
||||
weapons = {},
|
||||
members = sameSpec,
|
||||
podr = 0
|
||||
}
|
||||
|
||||
local rankData = {
|
||||
index = rankIndex,
|
||||
name = "Без звания"
|
||||
}
|
||||
|
||||
if factionTable then
|
||||
if factionTable.Podr and factionTable.Podr[podIndex] then
|
||||
local unit = factionTable.Podr[podIndex]
|
||||
subdivisionData.name = unit.name or subdivisionData.name
|
||||
subdivisionData.preset = unit.preset or subdivisionData.preset
|
||||
subdivisionData.specDefault = unit.spec_def or subdivisionData.specDefault
|
||||
subdivisionData.model = unit.model or subdivisionData.model
|
||||
subdivisionData.skin = unit.skin or subdivisionData.skin
|
||||
subdivisionData.bodygroups = unit.bodygroups or subdivisionData.bodygroups
|
||||
end
|
||||
|
||||
if factionTable.Spec and factionTable.Spec[specIndex] then
|
||||
local spec = factionTable.Spec[specIndex]
|
||||
specData.name = spec.name or specData.name
|
||||
specData.weapons = spec.weapons or specData.weapons
|
||||
specData.podr = spec.podr or specData.podr
|
||||
end
|
||||
|
||||
if factionTable.Ranks and factionTable.Ranks[rankIndex] then
|
||||
local rank = factionTable.Ranks[rankIndex]
|
||||
rankData.name = rank[1] or rankData.name
|
||||
end
|
||||
end
|
||||
|
||||
local factionColor = nil
|
||||
if factionTable and factionTable.color then
|
||||
factionColor = { r = factionTable.color.r, g = factionTable.color.g, b = factionTable.color.b }
|
||||
end
|
||||
|
||||
local supplyStatus = "Стабильно"
|
||||
local minSupply = 0
|
||||
if arsenalPlugin and arsenalPlugin.config then
|
||||
minSupply = arsenalPlugin.config.minSupply or 0
|
||||
end
|
||||
|
||||
if supplyPoints <= minSupply then
|
||||
supplyStatus = "Критически низко"
|
||||
elseif supplyPoints <= minSupply * 2 and minSupply > 0 then
|
||||
supplyStatus = "Низко"
|
||||
end
|
||||
|
||||
return {
|
||||
timestamp = os.time(),
|
||||
faction = {
|
||||
id = factionID,
|
||||
name = factionTable and factionTable.name or "Неизвестно",
|
||||
description = factionTable and factionTable.description or "",
|
||||
color = factionColor,
|
||||
online = factionOnline,
|
||||
techPoints = techPoints,
|
||||
supplyPoints = supplyPoints,
|
||||
supplyStatus = supplyStatus,
|
||||
activeVehicles = activeVehicles
|
||||
},
|
||||
character = {
|
||||
name = char:GetName(),
|
||||
money = char:GetMoney(),
|
||||
id = char:GetID() or 0,
|
||||
rank = rankData,
|
||||
subdivision = subdivisionData,
|
||||
spec = specData
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
net.Receive("ix.F4_RequestInfo", function(_, client)
|
||||
if not IsValid(client) then return end
|
||||
local payload = BuildInfoPayload(client)
|
||||
if not payload then return end
|
||||
|
||||
net.Start("ix.F4_SendInfo")
|
||||
net.WriteTable(payload)
|
||||
net.Send(client)
|
||||
end)
|
||||
|
||||
local DONATE_PURCHASE_COOLDOWN = 2
|
||||
PLUGIN.donatePurchaseCooldowns = PLUGIN.donatePurchaseCooldowns or {}
|
||||
|
||||
local function GetCooldownKey(client)
|
||||
return client:SteamID64() or client:SteamID() or client:EntIndex()
|
||||
end
|
||||
|
||||
function PLUGIN:GetIGSBalance(client)
|
||||
if not IsValid(client) then return 0 end
|
||||
|
||||
if client.IGSFunds then
|
||||
local ok, funds = pcall(client.IGSFunds, client)
|
||||
if ok and isnumber(funds) then
|
||||
return math.max(math.floor(funds), 0)
|
||||
end
|
||||
end
|
||||
|
||||
if client.GetNetVar then
|
||||
local funds = client:GetNetVar("igsFunds", 0)
|
||||
if isnumber(funds) then
|
||||
return math.max(math.floor(funds), 0)
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function PLUGIN:AdjustIGSBalance(client, amount)
|
||||
if not IsValid(client) then return false, "Игрок недоступен" end
|
||||
amount = tonumber(amount) or 0
|
||||
if amount == 0 then return true end
|
||||
|
||||
if not client.AddIGSFunds then
|
||||
return false, "IGS недоступен"
|
||||
end
|
||||
|
||||
local ok, err = pcall(client.AddIGSFunds, client, amount)
|
||||
if ok then
|
||||
return true
|
||||
end
|
||||
|
||||
return false, err or "Ошибка IGS"
|
||||
end
|
||||
|
||||
function PLUGIN:IsDonateOnCooldown(client)
|
||||
local key = GetCooldownKey(client)
|
||||
local expires = self.donatePurchaseCooldowns[key] or 0
|
||||
if CurTime() < expires then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:ArmDonateCooldown(client)
|
||||
local key = GetCooldownKey(client)
|
||||
self.donatePurchaseCooldowns[key] = CurTime() + DONATE_PURCHASE_COOLDOWN
|
||||
end
|
||||
|
||||
function PLUGIN:CanPurchaseDonateProduct(client, entry)
|
||||
local char = client:GetCharacter()
|
||||
if not char then
|
||||
return false, "Нет активного персонажа"
|
||||
end
|
||||
|
||||
if not entry then
|
||||
return false, "Предложение не найдено"
|
||||
end
|
||||
|
||||
if entry.oneTime then
|
||||
local history = char:GetData("donate_purchases", {})
|
||||
if history[entry.id] then
|
||||
return false, "Этот набор уже был приобретен"
|
||||
end
|
||||
end
|
||||
|
||||
local hookResult, hookMessage = hook.Run("CanPlayerBuyDonateProduct", client, entry)
|
||||
if hookResult == false then
|
||||
return false, hookMessage or "Покупка отклонена"
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function PLUGIN:GrantDonateItems(client, grantData)
|
||||
if not grantData then return end
|
||||
local char = client:GetCharacter()
|
||||
if not char then return end
|
||||
|
||||
if istable(grantData.weapons) and #grantData.weapons > 0 then
|
||||
local owned = char:GetData("donate_weapons", {})
|
||||
local changed
|
||||
for _, class in ipairs(grantData.weapons) do
|
||||
if isstring(class) and not table.HasValue(owned, class) then
|
||||
table.insert(owned, class)
|
||||
changed = true
|
||||
end
|
||||
end
|
||||
if changed then
|
||||
char:SetData("donate_weapons", owned)
|
||||
end
|
||||
end
|
||||
|
||||
if istable(grantData.cosmetics) and #grantData.cosmetics > 0 then
|
||||
local cosmetics = char:GetData("donate_cosmetics", {})
|
||||
for _, cosmeticID in ipairs(grantData.cosmetics) do
|
||||
if isstring(cosmeticID) then
|
||||
cosmetics[cosmeticID] = true
|
||||
end
|
||||
end
|
||||
char:SetData("donate_cosmetics", cosmetics)
|
||||
end
|
||||
|
||||
if istable(grantData.vehicles) and #grantData.vehicles > 0 then
|
||||
local vehicles = char:GetData("donate_vehicles", {})
|
||||
for _, certificate in ipairs(grantData.vehicles) do
|
||||
if isstring(certificate) then
|
||||
vehicles[#vehicles + 1] = certificate
|
||||
end
|
||||
end
|
||||
char:SetData("donate_vehicles", vehicles)
|
||||
end
|
||||
|
||||
if istable(grantData.boosts) and #grantData.boosts > 0 then
|
||||
local calls = char:GetData("donate_support_calls", {})
|
||||
for _, callID in ipairs(grantData.boosts) do
|
||||
calls[#calls + 1] = callID
|
||||
end
|
||||
char:SetData("donate_support_calls", calls)
|
||||
end
|
||||
|
||||
if istable(grantData.items) and #grantData.items > 0 then
|
||||
local pending = char:GetData("donate_items", {})
|
||||
for _, itemID in ipairs(grantData.items) do
|
||||
pending[#pending + 1] = { id = itemID, ts = os.time() }
|
||||
end
|
||||
char:SetData("donate_items", pending)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:ApplyDonateReward(client, entry, mode)
|
||||
local char = client:GetCharacter()
|
||||
if not char then
|
||||
return false, "Нет активного персонажа"
|
||||
end
|
||||
|
||||
local reward = entry.reward
|
||||
if not reward then
|
||||
local hookResult, hookMessage = hook.Run("OnDonateReward", client, entry, mode)
|
||||
if hookResult ~= nil then
|
||||
return hookResult, hookMessage
|
||||
end
|
||||
return false, "Награда не настроена"
|
||||
end
|
||||
|
||||
local rewardType = reward.type
|
||||
|
||||
if rewardType == "privilege" then
|
||||
local tier = reward.tier or entry.id
|
||||
local duration = nil
|
||||
|
||||
if mode == "3month" then
|
||||
duration = os.time() + (90 * 86400) -- 90 дней
|
||||
else
|
||||
duration = os.time() + (30 * 86400) -- 30 дней (1 месяц)
|
||||
end
|
||||
|
||||
local privileges = char:GetData("donate_privileges", {})
|
||||
privileges[tier] = {
|
||||
tier = tier,
|
||||
expires = duration,
|
||||
granted = os.time(),
|
||||
mode = mode or "month"
|
||||
}
|
||||
char:SetData("donate_privileges", privileges)
|
||||
|
||||
-- Применяем группу через SAM если доступно
|
||||
if sam then
|
||||
local groupMap = {
|
||||
vip = "vip",
|
||||
vip_plus = "vip_plus",
|
||||
premium = "premium",
|
||||
sponsor = "sponsor"
|
||||
}
|
||||
local rank = groupMap[tier]
|
||||
if rank then
|
||||
local expireTime = mode == "3month" and os.time() + (90 * 86400) or os.time() + (30 * 86400)
|
||||
sam.player.set_rank(client, rank, expireTime)
|
||||
end
|
||||
end
|
||||
|
||||
local modeText = mode == "3month" and "на 3 месяца" or "на 1 месяц"
|
||||
return true, reward.successMessage or ("Привилегия " .. tier .. " активирована " .. modeText)
|
||||
|
||||
elseif rewardType == "weapon" then
|
||||
local weaponClass = reward.weaponClass or reward.class
|
||||
if not weaponClass then
|
||||
return false, "Класс оружия не указан"
|
||||
end
|
||||
|
||||
-- Добавляем оружие в список донат-оружия персонажа со сроком действия
|
||||
local donateWeapons = char:GetData("donate_weapons_timed", {})
|
||||
if not istable(donateWeapons) then donateWeapons = {} end
|
||||
|
||||
-- Вычисляем срок действия
|
||||
local expireTime
|
||||
if mode == "3month" then
|
||||
expireTime = os.time() + (90 * 86400) -- 90 дней
|
||||
else
|
||||
expireTime = os.time() + (30 * 86400) -- 30 дней
|
||||
end
|
||||
|
||||
-- Добавляем или обновляем срок
|
||||
donateWeapons[weaponClass] = {
|
||||
expires = expireTime,
|
||||
granted = os.time(),
|
||||
mode = mode or "1month"
|
||||
}
|
||||
char:SetData("donate_weapons_timed", donateWeapons)
|
||||
|
||||
local modeText = mode == "3month" and "на 3 месяца" or "на 1 месяц"
|
||||
return true, reward.successMessage or ("Донат-оружие " .. (reward.name or weaponClass) .. " добавлено в ваш арсенал " .. modeText)
|
||||
|
||||
elseif rewardType == "money" then
|
||||
local amount = reward.amount or 0
|
||||
if amount > 0 and char.GiveMoney then
|
||||
char:GiveMoney(math.floor(amount))
|
||||
return true, reward.successMessage or ("Вам начислено " .. amount .. " ₽")
|
||||
end
|
||||
return false, "Ошибка начисления денег"
|
||||
|
||||
elseif rewardType == "voice_chat" then
|
||||
-- Разблокировка голосового чата
|
||||
char:SetData("voice_chat_unlocked", true)
|
||||
|
||||
-- Если есть система SAM, можно добавить флаг
|
||||
if sam then
|
||||
-- Можно добавить специальную группу или флаг для голосового чата
|
||||
end
|
||||
|
||||
return true, reward.successMessage or "Голосовой чат разблокирован!"
|
||||
|
||||
elseif rewardType == "bundle" then
|
||||
if reward.money and reward.money > 0 and char.GiveMoney then
|
||||
char:GiveMoney(math.floor(reward.money))
|
||||
end
|
||||
|
||||
if reward.supply and reward.supply ~= 0 then
|
||||
local arsenal = ix.plugin.Get("arsenal")
|
||||
if arsenal and arsenal.AddFactionSupply then
|
||||
arsenal:AddFactionSupply(client:Team(), reward.supply)
|
||||
end
|
||||
end
|
||||
|
||||
if reward.techPoints and reward.techPoints ~= 0 then
|
||||
local vehicles = ix.plugin.Get("vehicles")
|
||||
if vehicles and vehicles.AddFactionPoints then
|
||||
vehicles:AddFactionPoints(client:Team(), reward.techPoints)
|
||||
end
|
||||
end
|
||||
|
||||
if reward.grantedItems then
|
||||
self:GrantDonateItems(client, reward.grantedItems)
|
||||
end
|
||||
|
||||
return true, reward.successMessage or "Комплект успешно выдан"
|
||||
|
||||
elseif rewardType == "pass" then
|
||||
local tier = reward.tier or entry.id
|
||||
local duration = math.max(1, tonumber(reward.durationDays) or 30) * 86400
|
||||
local passes = char:GetData("donate_passes", {})
|
||||
passes[tier] = {
|
||||
tier = tier,
|
||||
expires = os.time() + duration,
|
||||
bonuses = reward.bonuses or {}
|
||||
}
|
||||
char:SetData("donate_passes", passes)
|
||||
return true, reward.successMessage or "Подписка активирована"
|
||||
elseif rewardType == "booster" then
|
||||
local boosterID = reward.boosterID or entry.id
|
||||
local duration = math.max(1, tonumber(reward.durationHours) or 24) * 3600
|
||||
local boosters = char:GetData("donate_boosters", {})
|
||||
boosters[boosterID] = {
|
||||
expires = os.time() + duration,
|
||||
multiplier = reward.multiplier or 1.0
|
||||
}
|
||||
char:SetData("donate_boosters", boosters)
|
||||
return true, reward.successMessage or "Бустер активирован"
|
||||
elseif rewardType == "case" then
|
||||
local caseID = reward.caseID or entry.id
|
||||
local cases = char:GetData("donate_cases", {})
|
||||
cases[caseID] = (cases[caseID] or 0) + 1
|
||||
char:SetData("donate_cases", cases)
|
||||
return true, reward.successMessage or "Кейс добавлен в коллекцию"
|
||||
elseif rewardType == "cosmetic" then
|
||||
local unlockID = reward.unlockID or entry.id
|
||||
local cosmetics = char:GetData("donate_cosmetics", {})
|
||||
cosmetics[unlockID] = true
|
||||
char:SetData("donate_cosmetics", cosmetics)
|
||||
return true, reward.successMessage or "Косметика разблокирована"
|
||||
end
|
||||
|
||||
local hookResult, hookMessage = hook.Run("OnDonateReward", client, entry)
|
||||
if hookResult ~= nil then
|
||||
return hookResult, hookMessage
|
||||
end
|
||||
|
||||
return false, "Тип награды не поддерживается"
|
||||
end
|
||||
|
||||
function PLUGIN:MarkDonatePurchase(client, entry)
|
||||
local char = client:GetCharacter()
|
||||
if not char then return end
|
||||
|
||||
local history = char:GetData("donate_purchases", {})
|
||||
history[entry.id] = (history[entry.id] or 0) + 1
|
||||
char:SetData("donate_purchases", history)
|
||||
end
|
||||
|
||||
function PLUGIN:SendDonateResult(client, success, message, productID)
|
||||
if not IsValid(client) then return end
|
||||
|
||||
net.Start("ix.F4_DonatePurchaseResult")
|
||||
net.WriteBool(success and true or false)
|
||||
net.WriteString(message or "")
|
||||
net.WriteString(productID or "")
|
||||
net.Send(client)
|
||||
end
|
||||
|
||||
function PLUGIN:HandleDonatePurchase(client, productID, price, mode)
|
||||
local entry = self:GetDonateProduct(productID)
|
||||
local ok, msg = self:CanPurchaseDonateProduct(client, entry)
|
||||
if not ok then
|
||||
return false, msg, entry
|
||||
end
|
||||
|
||||
local actualPrice = price or tonumber(entry and entry.price) or 0
|
||||
if actualPrice <= 0 then
|
||||
return false, "Цена предложения не настроена", entry
|
||||
end
|
||||
|
||||
local funds = self:GetIGSBalance(client)
|
||||
if funds < actualPrice then
|
||||
return false, "Недостаточно средств на балансе", entry
|
||||
end
|
||||
|
||||
local debited, debitError = self:AdjustIGSBalance(client, -actualPrice)
|
||||
if not debited then
|
||||
return false, debitError or "Не удалось списать средства", entry
|
||||
end
|
||||
|
||||
local success, rewardMessage = self:ApplyDonateReward(client, entry, mode)
|
||||
if not success then
|
||||
self:AdjustIGSBalance(client, actualPrice)
|
||||
return false, rewardMessage or "Ошибка выдачи награды", entry
|
||||
end
|
||||
|
||||
self:MarkDonatePurchase(client, entry, mode)
|
||||
hook.Run("PostDonatePurchase", client, entry, actualPrice, mode)
|
||||
|
||||
return true, rewardMessage or "Покупка завершена", entry
|
||||
end
|
||||
|
||||
net.Receive("ix.F4_DonatePurchase", function(_, client)
|
||||
if not IsValid(client) or not client:IsPlayer() then return end
|
||||
|
||||
local productID = net.ReadString() or ""
|
||||
local price = net.ReadUInt(32) or 0
|
||||
local mode = net.ReadString() or "month"
|
||||
|
||||
if productID == "" then return end
|
||||
|
||||
if PLUGIN:IsDonateOnCooldown(client) then
|
||||
PLUGIN:SendDonateResult(client, false, "Слишком частые запросы", productID)
|
||||
return
|
||||
end
|
||||
|
||||
PLUGIN:ArmDonateCooldown(client)
|
||||
local success, message, entry = PLUGIN:HandleDonatePurchase(client, productID, price, mode)
|
||||
|
||||
local entryID = entry and entry.id or productID
|
||||
if success then
|
||||
local priceText = tostring(price)
|
||||
local modeText = mode == "forever" and " (навсегда)" or " (на месяц)"
|
||||
print(string.format("[F4 Donate] %s (%s) купил %s%s за %s", client:Name(), client:SteamID(), entryID, modeText, priceText))
|
||||
else
|
||||
print(string.format("[F4 Donate] Ошибка покупки %s игроком %s: %s", entryID, client:Name(), tostring(message)))
|
||||
end
|
||||
|
||||
PLUGIN:SendDonateResult(client, success, message, entryID)
|
||||
end)
|
||||
-- Admin command to add IGS funds
|
||||
ix.command.Add("GiveIGS", {
|
||||
description = "Выдать IGS средства игроку",
|
||||
CanRun = function(self, client)
|
||||
local userGroup = string.lower(client:GetUserGroup() or "user")
|
||||
return client:IsAdmin() or AdminPrivs[userGroup]
|
||||
end,
|
||||
arguments = {
|
||||
ix.type.player,
|
||||
ix.type.number
|
||||
},
|
||||
OnRun = function(self, client, target, amount)
|
||||
if not IsValid(target) then
|
||||
return "@invalidTarget"
|
||||
end
|
||||
|
||||
amount = math.floor(tonumber(amount) or 0)
|
||||
if amount == 0 then
|
||||
return "Укажите корректную сумму"
|
||||
end
|
||||
|
||||
local success, err = PLUGIN:AdjustIGSBalance(target, amount)
|
||||
if success then
|
||||
local action = amount > 0 and "выдал" or "снял"
|
||||
client:Notify(string.format("Вы %s %d IGS для %s", action, math.abs(amount), target:Name()))
|
||||
target:Notify(string.format("Администратор %s вам %d IGS", action == "выдал" and "выдал" or "снял у вас", math.abs(amount)))
|
||||
|
||||
print(string.format("[IGS Admin] %s (%s) %s %d IGS для %s (%s)",
|
||||
client:Name(), client:SteamID(), action, math.abs(amount), target:Name(), target:SteamID()))
|
||||
return ""
|
||||
else
|
||||
return err or "Ошибка при изменении баланса"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- Admin command to check IGS balance
|
||||
ix.command.Add("CheckIGS", {
|
||||
description = "Проверить IGS баланс игрока",
|
||||
CanRun = function(self, client)
|
||||
local userGroup = string.lower(client:GetUserGroup() or "user")
|
||||
return client:IsAdmin() or AdminPrivs[userGroup]
|
||||
end,
|
||||
arguments = {
|
||||
ix.type.player
|
||||
},
|
||||
OnRun = function(self, client, target)
|
||||
if not IsValid(target) then
|
||||
return "@invalidTarget"
|
||||
end
|
||||
|
||||
local balance = PLUGIN:GetIGSBalance(target)
|
||||
return string.format("Баланс IGS игрока %s: %d руб.", target:Name(), balance)
|
||||
end
|
||||
})
|
||||
|
||||
net.Receive("ixChangeName", function(len, client)
|
||||
if not IsValid(client) then return end
|
||||
|
||||
local character = client:GetCharacter()
|
||||
if not character then return end
|
||||
|
||||
local newName = net.ReadString()
|
||||
if not newName or newName == "" then return end
|
||||
|
||||
if #newName < 3 or #newName > 50 then
|
||||
client:Notify("Имя должно содержать от 3 до 50 символов")
|
||||
return
|
||||
end
|
||||
|
||||
if newName:find("[<>\"\\/]") then
|
||||
client:Notify("Имя содержит недопустимые символы")
|
||||
return
|
||||
end
|
||||
|
||||
local oldName = character:GetName()
|
||||
character:SetName(newName)
|
||||
client:Notify("Ваше имя успешно изменено на: " .. newName)
|
||||
|
||||
net.Start("ixF4UpdateName")
|
||||
net.WriteString(newName)
|
||||
net.Send(client)
|
||||
|
||||
hook.Run("OnCharacterVarChanged", character, "name", oldName, newName)
|
||||
end)
|
||||
|
||||
-- Фикс выдачи донат-оружия IGS в Helix
|
||||
hook.Add("PostPlayerLoadout", "IGS_Helix_WeaponLoadoutFix", function(client)
|
||||
if not IsValid(client) or not IGS then return end
|
||||
|
||||
timer.Simple(1.5, function()
|
||||
if not IsValid(client) or not client:GetCharacter() then return end
|
||||
|
||||
if isfunction(IGS.PlayerLoadout) then
|
||||
IGS.PlayerLoadout(client)
|
||||
end
|
||||
|
||||
if isfunction(IGS.GetItems) and IsValid(client) and client.HasPurchase then
|
||||
for _, ITEM in pairs(IGS.GetItems()) do
|
||||
if not ITEM or not isfunction(ITEM.GetUID) then continue end
|
||||
|
||||
local weaponClass = (isfunction(ITEM.GetWeapon) and ITEM:GetWeapon()) or ITEM.weapon
|
||||
if weaponClass and client:HasPurchase(ITEM:GetUID()) then
|
||||
if not client:HasWeapon(weaponClass) then
|
||||
client:Give(weaponClass)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
Reference in New Issue
Block a user