Skip to content

Instantly share code, notes, and snippets.

@AMD-NICK
Last active June 23, 2023 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AMD-NICK/0fc6a36f87e0232e5d1a9dd60b864e18 to your computer and use it in GitHub Desktop.
Save AMD-NICK/0fc6a36f87e0232e5d1a9dd60b864e18 to your computer and use it in GitHub Desktop.
Функции получения покупок или транзакций https://gm-donate.net сквозь лимиты. Собирает данные, пока выполняется условие (например, все)

Примеры использования кода, приведенного выше

Собираем 100 покупок игрока

Пример может собрать меньше покупок (если их меньше у игрока), либо больше из-за проскальзывания

co_igs_query_while("/purchases/get", {
	sid    = "76561198071463189",
	limit  = 10,
}, function(fetched_results)
	local need_more = #fetched_results < 100
	return need_more
end, function(fetched_results)
	print("#fetched_results", #fetched_results)
end)

Собираем транзакции игрока, сделанные за последние 90 дней

Оно соберет больше транзакций, чем нужно, поэтому финальный результат мы дополнительно фильтруем

co_igs_query_while("/transactions/get", {
	sid    = "76561198071463189",
	limit  = 10,
}, function(fetched_results)
	local oldest_tx = fetched_results[#fetched_results]
	local days_ago  = (os.time() - oldest_tx.Time) / 60 / 60 / 24

	local need_more = days_ago < 90
	return need_more
end, function(fetched_results)
	local filtered = {}
	for _, tx in ipairs(fetched_results) do
		local days_ago = (os.time() - tx.Time) / 60 / 60 / 24
		print("Транзакция сделана дней назад:", days_ago)
		if days_ago <= 90 then
			table.insert(filtered, tx)
		end
	end

	print("#filtered", #filtered)
end)

Подсчет суммы всех транзакций игрока

co_igs_query_while("/transactions/get", {
	sid    = "76561198071463189",
	limit  = 100, -- за 1 запрос
}, function()
	return true -- запрашиваем все до конца, без тормозов
end, function(fetched_results)
	local total_charges = 0
	for _, tx in ipairs(fetched_results) do
		-- Пополнение
		if tx.Note and tx.Note:StartWith("A: ") then
			total_charges = total_charges + tx.Sum
		end
	end
	print("Всего у игрока", #fetched_results, "транзакций. Он пополнил счет за все время на", total_charges, "валюты")
end)

Перенос всех активных покупок сервера на другой сервер (не проект)

local server_id_from = IGS.SERVERS:ID()
local server_id_to   = 3

-- Запрос всех активных покупок с текущего сервера
co_igs_query_while("/purchases/get", {
	limit = 100,
	only_active = 1,
	s = server_id_from,
	-- sid = "",
}, function(fetched_results)
	return true
end, function(all_active_purchases)
	print("#all_active_purchases", #all_active_purchases)

	for i, purch in ipairs(all_active_purchases) do
		local days_left = purch.Expire and math.ceil((purch.Expire - os.time()) / (60 * 60 * 24)) or nil
		IGS.StorePurchase(purch.SteamID, purch.Item, days_left, server_id_to, function(new_db_id)
			print("Покупка перенесена. Новый ид:", new_db_id, "осталось:", #all_active_purchases - i)
		end)
	end
end)

Если проект сторонний (не локальный), то вставить этот "костыль" перед кодом сверху, заменив ID и ключ проекта на реальные

IGS.C.ProjectKey_TG = IGS.C.ProjectKey_TG or IGS.C.ProjectKey
IGS.C.ProjectID_TG  = IGS.C.ProjectID_TG  or IGS.C.ProjectID

IGS.C.ProjectID  = 0
IGS.C.ProjectKey = ""
-- Раньше здесь был опубликован другой вариант, но
-- https://vk.com/id202626327 предложил красивый вариант с корутинами,
-- под который я адаптировал все функции
local function co_igs_query(method, params)
local co = coroutine.running()
IGS.Query(method, params, function(result) coroutine.resume(co, result) end)
return coroutine.yield()
end
-- Для функций, где есть параметры limit и offset
-- в fwhile(fetched_results) return false будет означать "хватит делать запросы"
-- например, можно получать данные до определенного числа, либо определенное количество, либо же все (return true)
local function co_igs_query_while(method, params, fNeedMore, fAllPicked)
coroutine.wrap(function()
local fetched_results = {}
while true do
params.offset = #fetched_results
params.limit = params.limit or 127
local res = co_igs_query(method, params)
table.Add(fetched_results, res)
if #res < params.limit or not fNeedMore(fetched_results) then
break
end
end
fAllPicked(fetched_results)
end)()
end
-- Примеры отдельно
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment