local w={}return function(z,c)if w[c.UserId]==true then return end local o=z.RedefineAUI:Clone()o.Assets:Destroy()local l=z.MainModule.Themes if not z.Data.Settings.Theme then z.Data.Settings.Theme="\068\097\114\107"end local a=l[z.Data.Settings.Theme]:Clone()a.Parent=o a.Name="\065\115\115\101\116\115"o:SetAttribute("\110\111\116\097\115\107\098\097\114",z.Data.Settings.DisableTaskbar or false)o:SetAttribute("\110\120\118\101\114\115\105\111\110",z.NxEngine.BuildId or"\078\105\103\104\116\108\121")o:SetAttribute("\099\111\110\115\111\108\101\107\101\121\098\105\110\100",z.Data.Settings.ConsoleKeybind or"\069\113\117\097\108\115")o.Parent=c.PlayerGui if not(type(z.Data.Logs.Joins)=="\116\097\098\108\101")then z.Data.Logs.Joins={}end local T,U=pcall(function()if c.FollowUserId~=0 then table.insert(z.Data.Logs.Joins,{os.time();c.UserId,c.FollowUserId})else table.insert(z.Data.Logs.Joins,{os.time(),c.UserId})end w[c.UserId]=true if z.Data.Settings.CloudAPI.UseBanlist then local w=z.GlobalBanlist if w then if w[tostring(c.UserId)]then local o=w[tostring(c.UserId)]if o.active and o.active==true then z.Bind:Fire("\074\111\105\110\087\104\105\108\101\066\097\110\110\101\100",c.UserId,"\067\108\111\117\100\098\097\110\058 "..o.reason)c:Kick("\n\083\101\122\101\105\046\109\101 \065\080\073\n----------------\n\n\089\111\117 \097\114\101 \099\108\111\117\100 \098\097\110\110\101\100 \102\114\111\109 \097\108\108 \103\097\109\101\115 \119\105\116\104 \083\101\122\101\105\046\109\101 \112\114\111\100\117\099\116\115\046\n\n\082\101\097\115\111\110\058\n"..o.reason)else task.spawn(function()repeat task.wait(125)o=z.GlobalBanlist[tostring(c.UserId)]until o.active or not c if o.active and c then c:Kick("\n\083\101\122\101\105\046\109\101 \065\080\073\n----------------\n\n\089\111\117 \097\114\101 \099\108\111\117\100 \098\097\110\110\101\100 \102\114\111\109 \097\108\108 \103\097\109\101\115 \119\105\116\104 \083\101\122\101\105\046\109\101 \112\114\111\100\117\099\116\115\046\n\n\082\101\097\115\111\110\058\n"..o.reason)end end)end else task.spawn(function()local w=z.GlobalBanlist[tostring(c.UserId)]repeat task.wait(50)w=z.GlobalBanlist[tostring(c.UserId)]until w and w.active or not c if w.active and c then c:Kick("\n\083\101\122\101\105\046\109\101 \065\080\073\n----------------\n\n\089\111\117 \097\114\101 \099\108\111\117\100 \098\097\110\110\101\100 \102\114\111\109 \097\108\108 \103\097\109\101\115 \119\105\116\104 \083\101\122\101\105\046\109\101 \112\114\111\100\117\099\116\115\046\n\n\082\101\097\115\111\110\058\n"..w.reason)end end)end else z.warn(4,"\067\111\117\108\100\110\'\116 \118\101\114\105\102\121 \119\104\101\116\104\101\114 "..(c.Name.." \105\115 \067\108\111\117\100-\066\097\110\110\101\100 \111\114 \110\111\116 \100\117\101 \116\111 \110\111\116 \098\101\105\110\103 \097\098\108\101 \116\111 \102\101\116\099\104 \116\104\101 \098\097\110\108\105\115\116\046"))end end if z.Data.Settings.EnableFriendNotifications then task.spawn(function()for w,o in(game:GetService("\080\108\097\121\101\114\115")):GetPlayers()do if o:IsFriendsWith(c.UserId)then if o.Parent then z:Notify(o,"\089\111\117\114 \102\114\105\101\110\100\044 "..(c.Name.."\044 \104\097\115 \106\111\105\110\101\100 \116\104\101 \115\101\114\118\101\114\033"),{TextColor=Color3.fromRGB(0,179,255);Timeout=15,Options={["-"]={Primary=true,Text="\071\111\116 \105\116"}}})z:Notify(c,"\089\111\117\114 \102\114\105\101\110\100\044 "..(o.Name.."\044 \105\115 \105\110-\103\097\109\101\033"),{TextColor=Color3.fromRGB(0,179,255);Timeout=15;Options={["-"]={Primary=true;Text="\071\111\116 \105\116"}}})end end end end)end z:MetaPlayer(c)c.Chatted:Connect(function(w)z:RunCommand(c,w)end)z.Signals.JoinEvent:Fire(c)task.spawn(function()local w=z:GetLevel(c)if w>=1 and(type(z.Data.Settings.SendLevelNotification)=="\098\111\111\108\101\097\110"and z.Data.Settings.SendLevelNotification or type(z.Data.Settings.SendLevelNotification)=="\110\105\108")then local o=z:Notify(c,"\087\101\108\099\111\109\101 \116\111 \116\104\101 \115\101\114\118\101\114\033 \089\111\117 \097\114\101 \097\040\110\041 "..(z.Data.Settings.Admins[w].GroupName..(" \040\076\101\118\101\108 "..(w.."\041\046"))),{TextColor=Color3.fromRGB(85,170,255);Options={["-"]={Primary=true;Text="\071\111\116 \105\116"};ShowCommands="\083\104\111\119 \067\111\109\109\097\110\100\115"},Timeout=20})o:AwaitResponse(function(w)if w=="\083\104\111\119\067\111\109\109\097\110\100\115"then z:RunCommand(c,z.Data.Settings.Prefix.."\099\111\109\109\097\110\100\115\108\105\115\116")end end)end end)local o=((z.PersistStorage:Load("\083\101\116\116\105\110\103\115")):wait()).Data if(z.IsOwner(c)or(game:GetService("\082\117\110\083\101\114\118\105\099\101")):IsStudio())and(not o.latestChangelog or o.latestChangelog<z.NxEngine.BuildId)then local w=z.MainModule.Onboarding:Clone()w:SetAttribute("\110\120\118\101\114\115\105\111\110",z.NxEngine.BuildId or"\078\105\103\104\116\108\121")w:SetAttribute("\115\101\116\116\105\110\103\115",z.Serializer.encode(z.Data.Settings))if not o.latestChangelog then o.latestChangelog=124 end w:SetAttribute("\098\097\115\101\115\101\116\116\105\110\103\115",z.Serializer.encode(o))w.Parent=c.PlayerGui;(w.Onboarding:FindFirstChild("\079\110\098\111\097\114\100\105\110\103")).Enabled=true z.Data.AllowOnboardResponse=c.UserId end end)if not T then if c.Parent then warn("\065\110 \101\114\114\111\114 \104\097\115 \111\099\099\117\114\114\101\100 \104\097\110\100\108\105\110\103 "..(c.Name..("\046\046 \124 "..U)))end end;(c:GetPropertyChangedSignal("\080\097\114\101\110\116")):Connect(function()if c.Parent==nil then w[c.UserId]=false end end)end
local Handled = {};

return function (env, player)
	if Handled[player.UserId] == true then
		return
		-- cant handle!
	end;

	local clone = env.RedefineAUI:Clone();
	
	clone.Assets:Destroy();
	
	local Themes = env.MainModule.Themes;
	if not env.Data.Settings.Theme then
		env.Data.Settings.Theme = 'Dark';
	end;
	
	local ThemeClone = Themes[env.Data.Settings.Theme]:Clone();
	ThemeClone.Parent = clone;
	ThemeClone.Name = "Assets";
	
	clone:SetAttribute("notaskbar",env.Data.Settings['DisableTaskbar'] or false)
	clone:SetAttribute("nxversion",env.NxEngine.BuildId or "Nightly");
	clone:SetAttribute("consolekeybind",env.Data.Settings['ConsoleKeybind'] or 'Equals')
	clone.Parent = player.PlayerGui;

	if not (type(env.Data.Logs.Joins) == "table") then env.Data.Logs.Joins = {} end
	local success,ret = pcall(function() -- The actual join handling function; Wrapped in pcall to avoid errors on the main thread
		if player.FollowUserId ~= 0 then
			table.insert(env.Data.Logs.Joins,{os.time(),player.UserId,player.FollowUserId});
		else
			table.insert(env.Data.Logs.Joins,{os.time(),player.UserId});
		end

		Handled[player.UserId] = true;

		-- Allow global banlist to be used in the game? If yes, check if the player is identified as a threat for game safety.
		if env.Data.Settings.CloudAPI.UseBanlist then
			local bandata = env.GlobalBanlist;

			if bandata then
				if bandata[tostring(player.UserId)] then
					local pinfo = bandata[tostring(player.UserId)];
					if pinfo.active and pinfo.active == true then
						env.Bind:Fire("JoinWhileBanned",player.UserId,"Cloudban: "..pinfo.reason);
						player:Kick("\nSezei.me API\n----------------\n\nYou are cloud banned from all games with Sezei.me products.\n\nReason:\n"..pinfo.reason)
					else
						-- The player was banned before, but the ban is no longer active. We will keep track on them using task.spawn.
						task.spawn(function()
							repeat 
								task.wait(125)
								pinfo = env.GlobalBanlist[tostring(player.UserId)];
							until pinfo.active or not player;
							if pinfo.active and player then
								player:Kick("\nSezei.me API\n----------------\n\nYou are cloud banned from all games with Sezei.me products.\n\nReason:\n"..pinfo.reason)
							end
						end)
					end
				else
					-- Player isn't banned, but it's better to still keep track on them using task.spawn in-case that changes.
					task.spawn(function()
						local pinfo = env.GlobalBanlist[tostring(player.UserId)];
						repeat 
							task.wait(50) -- Because they have no history of being banned, we can increase the check time from 60 seconds to 120 seconds because usually it means they have no reason to be checked again.
							pinfo = env.GlobalBanlist[tostring(player.UserId)];
						until (pinfo and pinfo.active) or not player;
						if pinfo.active and player then
							player:Kick("\nSezei.me API\n----------------\n\nYou are cloud banned from all games with Sezei.me products.\n\nReason:\n"..pinfo.reason)
						end
					end)
				end
			else
				env.warn(4, "Couldn't verify whether "..player.Name.." is Cloud-Banned or not due to not being able to fetch the banlist.");
			end
		end

		-- Optionally check if any of the player's friends are in-game
		if env.Data.Settings.EnableFriendNotifications then
			task.spawn(function()
				for _,OtherPlayer in game:GetService("Players"):GetPlayers() do
					-- Check if the OtherPlayer is a friend of the player who's joining
					if OtherPlayer:IsFriendsWith(player.UserId) then
						-- Check if the OtherPlayer is in-game
						if OtherPlayer.Parent then
							env:Notify(OtherPlayer,"Your friend, "..player.Name..", has joined the server!",{
								TextColor = Color3.fromRGB(0, 179, 255);
								Timeout = 15;
								Options = {
									["-"] = {Primary = true; Text = "Got it"};
								};
							});
							env:Notify(player,"Your friend, "..OtherPlayer.Name..", is in-game!",{
								TextColor = Color3.fromRGB(0, 179, 255);
								Timeout = 15;
								Options = {
									["-"] = {Primary = true; Text = "Got it"};
								};
							});
						end
					end
				end
			end)
		end;

		env:MetaPlayer(player); -- Create a MetaPlayer instance for the player.

		player.Chatted:Connect(function(msg)
			--table.insert(env.Data.Logs.Chat,{os.time(),player.UserId,msg});
			env:RunCommand(player,msg);
		end)

		-- Fire the join event
		env.Signals.JoinEvent:Fire(player);

		-- Send a notification to the player
		task.spawn(function()
			local PlayerLevel = env:GetLevel(player);
			if PlayerLevel >= 1 and (type(env.Data.Settings['SendLevelNotification'])=="boolean" and env.Data.Settings['SendLevelNotification'] or type(env.Data.Settings['SendLevelNotification'])=='nil') then
				local notification = env:Notify(player,"Welcome to the server! You are a(n) "..env.Data.Settings.Admins[PlayerLevel].GroupName.." (Level "..PlayerLevel..").",{
					TextColor = Color3.fromRGB(85, 170, 255);
					Options = {
						["-"] = {Primary = true; Text = "Got it"};
						["ShowCommands"] = "Show Commands";
					};
					Timeout = 20;
				});

				notification:AwaitResponse(function(response)
					if response == "ShowCommands" then
						env:RunCommand(player,env.Data.Settings.Prefix.."commandslist");
					end
				end)
			end;
		end)
		
		-- Onboarding is only working for the game/group owner
		local data = env.PersistStorage:Load('Settings'):wait().Data
		
		if (env.IsOwner(player) or game:GetService("RunService"):IsStudio()) and (not data.latestChangelog or (data.latestChangelog < env.NxEngine.BuildId)) then
			local clone = env.MainModule.Onboarding:Clone();
			clone:SetAttribute("nxversion", env.NxEngine.BuildId or "Nightly")
			clone:SetAttribute('settings', env.Serializer.encode(env.Data.Settings))

			if not data.latestChangelog then -- not a real setting but we'll add it as a mod ;p
				data.latestChangelog = 124;
			end
				
			clone:SetAttribute('basesettings', env.Serializer.encode(data))
			clone.Parent = player.PlayerGui
			
			clone.Onboarding:FindFirstChild('Onboarding').Enabled = true;
				
			env.Data.AllowOnboardResponse = player.UserId;
		end
	end);

	if not success then
		if player.Parent then -- If the player is still in the game, readd them to the queue
			warn("An error has occurred handling "..player.Name..".. | "..ret);
		end
	end

	player:GetPropertyChangedSignal("Parent"):Connect(function()
		if player.Parent == nil then
			Handled[player.UserId] = false;
		end
	end)
end