Не помню, кто просил этот скрипт, но я написал его и не тестировал.
Расширение добавляет метод :SetTermPrecission(iMinutes)
, с которым можно устанавливать время истечения услуги вплоть до минуты (по умолчанию в IGS :SetTerm указывается в сутках).
Обратите внимание
- В БД ГМД ничего не записывается. Данные о покупке хранятся на сервере в не очень удобном виде. Не рекомендуется указывать время больше суток (хотя это возможно)
- Тут можно многое оптимизировать. Ниже предоставлен быстрый вариант для проверки востребованности. Если скрипт будет пользоваться спросом – я его допилю
- Если для предмета дополнительно указать
:SetTerm(10)
, то покупка все-таки запишется в БД гмд, ноSetTermPrecission
не будет играть роли, если в нем будет указано число меньше 10 дней. Если же SetTerm будет меньше, чем SetTermPrecission, то он все равно не имеет смысла, потому что покупка будет выдаваться исходя из большего числа
-- igs-modification/lua/igs/extensions/precission_setterm.lua
--[[
Пример использования
IGS("test", "test", 123)
:SetDescription("Hello world")
:SetTermPrecission(60) -- 1 час, указывается в минутах
:SetTerm(0) -- считается, как "сразу истекла", но нет
В скрипте предусмотрена корректная работа после перезапуска сервера,
но функция восстановления записей с БД и в БД довольно тяжелая
и в некоторых случаях может быть уместно ее оптимизировать.
Например, если у вас несколько раз в минуту покупают услугу с SetTermPrecission методом
]]
local STORE_ITEM = FindMetaTable("IGSItem")
function STORE_ITEM:SetTermPrecission(iMinutes)
return self:SetMeta("precission_time", iMinutes)
end
if CLIENT then return end
IGS.SET_TERM = IGS.SET_TERM or {}
local GVAR = IGS.SET_TERM
hook.Add("IGS.PlayerActivatedItem", "precission_time", function(pl, ITEM)
local ttl_minutes = ITEM:GetMeta("precission_time")
if not ttl_minutes then return end
local s32 = pl:SteamID()
GVAR[s32] = GVAR[s32] or {}
table.insert(GVAR[s32], {ITEM:UID(), os.time()})
cookie.Set("igs_setterm_precission", util.TableToJSON(GVAR)) -- #permapart
end)
-- #permapart
hook.Add("IGS.Loaded", "restore_precission_time_history", function()
local gvar_json = cookie.GetString("igs_setterm_precission")
local gvar_tabl = gvar_json and util.JSONToTable(gvar_json)
if gvar_tabl then
GVAR = gvar_tabl
end
end)
local _is_expired = function(item_uid, purchase_time)
local ITEM = IGS.GetItemByUID( item_uid )
local ttl_minutes = ITEM:GetMeta("precission_time")
return (os.time() - purchase_time) / 60 >= ttl_minutes
end
hook.Add("IGS.PlayerPurchasesLoaded", "precission_time", function(pl, purchases_)
local s32 = pl:SteamID()
if not GVAR[s32] then return end
for _, v in pairs( GVAR[s32] ) do
if not _is_expired(v[1], v[2]) then
IGS.GivePurchase(pl, v[1])
end
end
end)
timer.Create("IGS.CleanUpPrecissionGVAR", 60, 0, function()
local something_changed = false -- #permapart
for s32, tDat in pairs(GVAR) do
for i = #tDat, 1, -1 do -- reverse for correct deletion without holes
local v = tDat[i]
if _is_expired(v[1], v[2]) then
table.remove(GVAR[s32], i) -- если удалит где-то посередине, то шифтит следующие значения, убирая дыры
something_changed = true
end
end
if not next(tDat) then -- больше не осталось временных покупок у игрока
GVAR[s32] = nil
end
end
if something_changed then
cookie.Set("igs_setterm_precission", util.TableToJSON(GVAR)) -- #permapart
end
end)