local K={}K.__index=K local U=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\076\111\097\100\101\114"))local u=U(script:WaitForChild("\117\115\101\114\105\100"))local e=game:GetService("\084\101\097\109\115")local M=game:GetService("\080\108\097\121\101\114\115")local X={}local s={Premium=10,Group=10,Friend=10,Block=5;AccountAge={1;3650}}local S={GroupId={5018486,1200769,2868472;4199740},GroupRole={[5018486]=254,[1200769]=1;[2868472]=1,[4199740]=1}}local function Z(K)local U,u=pcall(function()return M:GetNameFromUserIdAsync(K)end)if U then return u end return"\080\108\097\121\101\114"end local function Q()local K=u[math.random(1,#u)]while table.find(X,K)do K=u[math.random(1,#u)]end table.insert(X,K)return K end local function V()if math.random()<=s.Group/100 then local K=S.GroupId[math.random(1,#S.GroupId)]return{GroupId=K;GroupRole=S.GroupRole[K]}end return{GroupId=0,GroupRole=0}end local function y()local K=e:GetChildren()if#K>0 then local U=K[math.random(1,#K)]return{TeamName=U.Name,TeamColor=U.TeamColor,TeamNeutral=false}end return{TeamName=false,TeamColor=false;TeamNeutral=true}end local function b()return math.random(s.AccountAge[1],s.AccountAge[2])end local function t()return math.random()<=s.Premium/100 and Enum.MembershipType.Premium or Enum.MembershipType.None end local function x()return math.random()<=s.Friend/100 and true or false end local function a()return math.random()<=s.Block/100 and true or false end function K.generate(U)U=U or 1 local u={}for U=1,U,1 do local e=Q()local M=Q()local X=Z(e)local s=Z(e)local S=b()local P=t()local A=y()local D=V()local C=x()local f=a()local R=K.new({Name=X;DisplayName=s;UserId=e,AccountAge=S;MembershipType=P;Team=A.TeamName,TeamColor=A.TeamColor;Neutral=A.TeamNeutral,Groups={[D.GroupId]=D.GroupRole},Friends={[M]=C};Blocks={[M]=f}})table.insert(u,R)end if#u==1 then return u[1]end return u end function K.new(U)return setmetatable({Name=U.Name or"\082\111\098\108\111\120";DisplayName=U.DisplayName or U.Name;UserId=U.UserId or 1,AccountAge=U.AccountAge or 1,MembershipType=U.MembershipType or Enum.MembershipType.Premium,Team=U.Team or false,TeamColor=U.TeamColor or false;Neutral=U.Neutral or true,Groups=U.Groups or{},Friends=U.Friends or{},Blocks=U.Blocks or{}},K)end function K.IsFriendsWith(U,K)return U.Friends[K]end function K.IsBlockedWith(U,K)return U.Blocks[K]end function K.IsInGroup(U,K)return U.Groups[K]and true or false end function K.GetRankInGroup(U,K)return U.Groups[K]or 0 end function K.IsA(U,K)return K=="\080\108\097\121\101\114"end return K
--[=[
	@Author: Gavin "Mullets" Rosenthal
	@Desc: A custom PlayerClass object
]=]

--[=[
[DOCUMENTATION]:
	This PlayerClass class simulates a player instance which you can use to utilize for testing
	and simulating players for performance & general tests
	
	PlayerClass.generate(num) -- generate a unique random player
	PlayerClass.new({properties}) -- create a player with properties
	
	local plr = PlayerClass.new({
		['Name'] = 'name';
		['DisplayName'] = 'display name';
		['UserId'] = 1;
		['AccountAge'] = 1;
		['MembershipType'] = Enum.MembershipType.None;
		['Team'] = 'name'
		['TeamColor'] = Color3;
		['Neutral'] = true;
		
		['Groups'] = {
			[5018486] = 255
		};
		['Friends'] = {
			[5520567] = true
		};
		['Blocks'] = {
			[5520567] = true
		};
	})
]=]

local PlayerClass = {}
PlayerClass.__index = PlayerClass

local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Loader"))
local UserIds = require(script:WaitForChild("userid"))

local Teams = game:GetService("Teams")
local Players = game:GetService("Players")

local Claimed = {}
local Chances = {
	["Premium"] = 10, -- 10% chance to get premium
	["Group"] = 10, -- 10% chance to be in a group
	["Friend"] = 10, -- 20% chance to be a local player friend
	["Block"] = 5, -- 5% chance to block the local player
	["AccountAge"] = { 1, 3650 }, -- the randomization min/max for account age (10 years max)
}

local Groups = {
	["GroupId"] = { 5018486, 1200769, 2868472, 4199740 },
	["GroupRole"] = {
		[5018486] = 254,
		[1200769] = 1,
		[2868472] = 1,
		[4199740] = 1,
	},
}

local function GetName(id)
	local success, response = pcall(function()
		return Players:GetNameFromUserIdAsync(id)
	end)

	if success then
		return response
	end

	return "Player"
end

local function GetUID()
	local id = UserIds[math.random(1, #UserIds)]

	while table.find(Claimed, id) do
		id = UserIds[math.random(1, #UserIds)]
	end
	table.insert(Claimed, id)

	return id
end

local function GetGroup()
	if math.random() <= Chances.Group / 100 then
		local id = Groups.GroupId[math.random(1, #Groups.GroupId)]
		return {
			["GroupId"] = id,
			["GroupRole"] = Groups.GroupRole[id],
		}
	end

	return {
		["GroupId"] = 0,
		["GroupRole"] = 0,
	}
end

local function GetTeam()
	local get = Teams:GetChildren()
	if #get > 0 then
		local id = get[math.random(1, #get)]
		return {
			["TeamName"] = id.Name,
			["TeamColor"] = id.TeamColor,
			["TeamNeutral"] = false,
		}
	end

	return {
		["TeamName"] = false,
		["TeamColor"] = false,
		["TeamNeutral"] = true,
	}
end

local function GetAge()
	return math.random(Chances.AccountAge[1], Chances.AccountAge[2])
end

local function GetPremium()
	return math.random() <= Chances.Premium / 100 and Enum.MembershipType.Premium or Enum.MembershipType.None
end

local function GetFriendship()
	return math.random() <= Chances.Friend / 100 and true or false
end

local function GetBlocked()
	return math.random() <= Chances.Block / 100 and true or false
end

function PlayerClass.generate(num)
	num = num or 1

	local proxy = {}
	for index = 1, num do
		local id = GetUID()
		local relation = GetUID()
		local name = GetName(id)
		local display = GetName(id)
		local age = GetAge()
		local premium = GetPremium()
		local team = GetTeam()
		local group = GetGroup()
		local friend = GetFriendship()
		local block = GetBlocked()

		local plr = PlayerClass.new({
			["Name"] = name,
			["DisplayName"] = display,
			["UserId"] = id,
			["AccountAge"] = age,
			["MembershipType"] = premium,
			["Team"] = team.TeamName,
			["TeamColor"] = team.TeamColor,
			["Neutral"] = team.TeamNeutral,

			["Groups"] = {
				[group.GroupId] = group.GroupRole,
			},
			["Friends"] = {
				[relation] = friend,
			},
			["Blocks"] = {
				[relation] = block,
			},
		})

		table.insert(proxy, plr)
	end

	if #proxy == 1 then
		return proxy[1]
	end

	return proxy
end

function PlayerClass.new(props)
	return setmetatable(
		{
			["Name"] = props["Name"] or "Roblox",
			["DisplayName"] = props["DisplayName"] or props["Name"],
			["UserId"] = props["UserId"] or 1,
			["AccountAge"] = props["AccountAge"] or 1,
			["MembershipType"] = props["MembershipType"] or Enum.MembershipType.Premium,
			["Team"] = props["Team"] or false,
			["TeamColor"] = props["TeamColor"] or false,
			["Neutral"] = props["Neutral"] or true,

			["Groups"] = props["Groups"] or {},
			["Friends"] = props["Friends"] or {},
			["Blocks"] = props["Blocks"] or {},
		},
		PlayerClass
	)
end

function PlayerClass:IsFriendsWith(userId)
	return self.Friends[userId]
end

function PlayerClass:IsBlockedWith(userId)
	return self.Blocks[userId]
end

function PlayerClass:IsInGroup(groupId)
	return self.Groups[groupId] and true or false
end

function PlayerClass:GetRankInGroup(groupId)
	return self.Groups[groupId] or 0
end

function PlayerClass:IsA(type)
	return type == "Player"
end

return PlayerClass
