Указание времени истечения услуги в минутах

Не помню, кто просил этот скрипт, но я написал его и не тестировал.

Расширение добавляет метод :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)

Отпишите кто-нибудь, если будете тестировать