local X=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local Y=game:GetService("\077\097\114\107\101\116\112\108\097\099\101\083\101\114\118\105\099\101")local w=game:GetService("\080\108\097\121\101\114\115")local A=game:GetService("\082\117\110\083\101\114\118\105\099\101")local e=X.AvatarEditor local J=require(e.Shared.Settings)local P=require(e.Shared.Util.Promise)local i=J.FILTER_USERS local D={}local function G(X,Y)assert(typeof(Y)=="\110\105\108"or typeof(Y)=="\110\117\109\098\101\114","\114\101\113\117\105\114\101\100\082\097\110\107 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114 \111\114 \110\105\108")return function(w)assert(w:IsA("\080\108\097\121\101\114"),"\105\110\073\110\071\114\111\117\112 \110\101\101\100\115 \116\111 \098\101 \097 \080\108\097\121\101\114")return(P.new(function(A,e)local J,P=pcall(function()if Y then return w:GetRankInGroup(X)>Y else return w:IsInGroup(X)end end)if J then A(P)else e(P)end end)):catch(warn)end end if J.ALLOWED_USERS.Groups then for X,Y in ipairs(J.ALLOWED_USERS.Groups)do Y.IsInGroup=G(Y.GroupId,Y.Rank)end end local function I(X)assert(typeof(X)=="\110\117\109\098\101\114","\114\101\113\117\105\114\101\100\082\097\110\107 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114 \111\114 \110\105\108")return function(w)assert(w:IsA("\080\108\097\121\101\114"),"\105\110\073\110\071\114\111\117\112 \110\101\101\100\115 \116\111 \098\101 \097 \080\108\097\121\101\114")return(P.new(function(A,e)local J,P=pcall(function()return Y:UserOwnsGamePassAsync(w.UserId,X)end)if J then A(P)else e(P)end end)):catch(warn)end end if J.ALLOWED_USERS.GamePasses then for X,Y in ipairs(J.ALLOWED_USERS.GamePasses)do Y.UserOwnsGamePass=I(Y.GamePassId)Y.Owners={}end end local function x(X,Y,e)print(e)if not e then return end if J.ALLOWED_USERS.GamePasses then for e,J in ipairs(J.ALLOWED_USERS.GamePasses)do if J.GamePassId==Y then print("\099\097\099\104\105\110\103")if A:IsClient()and w.LocalPlayer==X then table.insert(J.Owners,w.LocalPlayer)else table.insert(J.Owners,X)end break end end end end Y.PromptGamePassPurchaseFinished:Connect(x)local function Q(X)if J.ALLOWED_USERS.GamePasses then for Y,w in ipairs(J.ALLOWED_USERS.GamePasses)do local A=table.find(w.Owners,X)if A then table.remove(w.Owners,A)end end end end if A:IsServer()then w.PlayerRemoving:Connect(Q)end function D.CanUse(Y,X)if i==false then return true end if table.find(J.ALLOWED_USERS.Players,X.UserId)then return true end if J.ALLOWED_USERS.Groups then for Y,w in ipairs(J.ALLOWED_USERS.Groups)do if(w.IsInGroup(X)):expect()then return true end end end if J.ALLOWED_USERS.GamePasses then for Y,w in ipairs(J.ALLOWED_USERS.GamePasses)do if table.find(w.Owners,X)then print("\102\114\111\109 \099\097\099\104\101")return true end if(w.UserOwnsGamePass(X)):expect()then print("\102\105\114\115\116 \116\105\109\101")table.insert(w.Owners,X)return true end end end return false end return D
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Marketplace = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local Run = game:GetService("RunService")

local AvatarEditor = ReplicatedStorage.AvatarEditor
local Settings = require(AvatarEditor.Shared.Settings)
local Promise = require(AvatarEditor.Shared.Util.Promise)

local filterUsers = Settings.FILTER_USERS

local module = {}


local function makeIsInGroup(groupId, requiredRank)
	assert(typeof(requiredRank) == "nil" or typeof(requiredRank) == "number", "requiredRank must be a number or nil")
	
	return function(player)
		assert(player:IsA("Player"), "inInGroup needs to be a Player")
		
		return Promise.new(function(resolve, reject)
			local success, result = pcall(function()
				if requiredRank then
					return player:GetRankInGroup(groupId) > requiredRank
				else
					return player:IsInGroup(groupId)
				end
			end)
			if success then
				resolve(result)
			else
				reject(result)
			end
		end):catch(warn)
	end
end

if Settings.ALLOWED_USERS.Groups then
	for i, group in ipairs(Settings.ALLOWED_USERS.Groups) do
		group.IsInGroup = makeIsInGroup(group.GroupId, group.Rank)
	end
end


local function makeUserOwnsGamepass(gamePassId)
	assert(typeof(gamePassId) == "number", "requiredRank must be a number or nil")
	
	return function(player)
		assert(player:IsA("Player"), "inInGroup needs to be a Player")
		
		return Promise.new(function(resolve, reject)
			local success, result = pcall(function()
				return Marketplace:UserOwnsGamePassAsync(player.UserId, gamePassId)
			end)
			if success then
				resolve(result)
			else
				reject(result)
			end
		end):catch(warn)
	end
end

if Settings.ALLOWED_USERS.GamePasses then
	for i, gamepass in ipairs(Settings.ALLOWED_USERS.GamePasses) do
		gamepass.UserOwnsGamePass = makeUserOwnsGamepass(gamepass.GamePassId)
		gamepass.Owners = {}
	end
end


local function promptGamePassPurchaseFinished(player, gamePassId, wasPurchased) print(wasPurchased)
	if not wasPurchased then
		return
	end
	if Settings.ALLOWED_USERS.GamePasses then
		for i, gamepass in ipairs(Settings.ALLOWED_USERS.GamePasses) do
			if gamepass.GamePassId == gamePassId then print("caching")
				if Run:IsClient() and Players.LocalPlayer == player then
					table.insert(gamepass.Owners, Players.LocalPlayer)
				else
					table.insert(gamepass.Owners, player)
				end
				break
			end
		end
	end
end

Marketplace.PromptGamePassPurchaseFinished:Connect(promptGamePassPurchaseFinished)


local function playerRemoving(player)
	if Settings.ALLOWED_USERS.GamePasses then
		for i, gamepass in ipairs(Settings.ALLOWED_USERS.GamePasses) do
			local index = table.find(gamepass.Owners, player)
			if index then
				table.remove(gamepass.Owners, index)
			end
		end
	end
end

if Run:IsServer() then
	Players.PlayerRemoving:Connect(playerRemoving)
end


function module:CanUse(player)
	if filterUsers == false then
		return true
	end
	
	if table.find(Settings.ALLOWED_USERS.Players, player.UserId) then
		return true
	end
	
	if Settings.ALLOWED_USERS.Groups then
		for i, group in ipairs(Settings.ALLOWED_USERS.Groups) do
			if group.IsInGroup(player):expect() then
				return true
			end
		end
	end
	
	if Settings.ALLOWED_USERS.GamePasses then
		for i, gamepass in ipairs(Settings.ALLOWED_USERS.GamePasses) do
			if table.find(gamepass.Owners, player) then print("from cache")
				return true
			end
			if gamepass.UserOwnsGamePass(player):expect() then print("first time")
				table.insert(gamepass.Owners, player)
				return true
			end
		end
	end
	
	return false
end

return module
