Commands yield shortly before executing + lag inducing

Hello, people of DevForums!
I’ve been encountering an ongoing problem with my admin commands module recently, it seems to lag whenever someone uses it!

Not only does the main script’s usage % rise drastically, the player may also tend to lose the ability to speak for a long period of time, until the chat with their command finally goes through. This has found itself to be very troublesome, and I can’t seem to find the source of the issue considering that I made no relevant changes before this became a problem.

I believe it has something to do with either the either the p.Chatted function and/or the command handler itself. Thankfully though, my module is completely open sourced, allowing you guys to see the whole thing!

Here’s the whole Main Script, excluding the giant logo comment at the top!

--Setup time!
require(script.VA_Commons:WaitForChild("Commons"))() 
--These two are the main reason why there is a bunch of underlined stuff, but it all still works!
require(script.VA_Commons:WaitForChild("Functions"))()
local Colors =					require(script.VA_Commons.BrickColors)
local ScriptsFolder = 			script:WaitForChild("Scripts")::Folder
local PropsFolder = 			script:WaitForChild("Props")::Folder
local GuisFolder = 				script:WaitForChild("Guis")::Folder
local CmdCategories = 			script:WaitForChild("CmdCategories")::Folder
local DefaultCommands = 		script:WaitForChild("VA_DefaultCommands")::ModuleScript
local isNewestVersion = 		(script:GetAttribute("NewestVersion") or false)::boolean
local runService = 				serv.RunService::RunService
local ms = 						serv.MessagingService::MessagingService
local rs = 						serv.ReplicatedStorage::ReplicatedStorage
local ds = 						serv.DataStoreService::DataStoreService
local mps = 					serv.MarketplaceService::MarketplaceService
local gs = 						serv.GroupService::GroupService
local ts = 						serv.TweenService::TweenService
local us = 						serv.UserService::UserService
local plrs = 					serv.Players::Players
local is = 						serv.InsertService::InsertService
local ch = 						serv.Chat::Chat
local starterplr = 				serv.StarterPlayer::StarterPlayer
local sss = 					serv.ServerScriptService::ServerScriptService
local localPlayerHandler = 		Clone(ScriptsFolder:WaitForChild("LocalPlayerHandler"),{Parent = starterplr.StarterPlayerScripts, Enabled = true})::LocalScript
local localCharacterHandler = 	Clone(ScriptsFolder:WaitForChild("LocalCharacterHandler"),{Parent = starterplr.StarterCharacterScripts, Enabled = true})::LocalScript
local antiExploitMobile =		Clone(ScriptsFolder:WaitForChild("AntiExploitMobile"),{Parent = rs, Enabled = true})::LocalScript
local partyHandler =			Clone(ScriptsFolder:WaitForChild("VA_PartyHandler"),{Parent = workspace, Enabled = true})::Script
local MainGui = 				Clone(GuisFolder:WaitForChild("VintageAdminGUI"))
local VA_Version = 				Clone(script:WaitForChild("VA_Version"),{Parent = rs})
--^ What a nice set of variables, I love variables.

local isStudio = 				runService:IsStudio()
local isClient = 				not isStudio
local isPrivate =				game.PrivateServerId ~= ""

local isMainPlace = 			game.GameId == 3954110342 --If the script is being used in the testing place, it won't run moderation commands for mods!
local Settings = 				require(rs:WaitForChild("VA_Settings")) --There is no debug for this, so if your settings are broken, we'll be broken!

if Settings[13] == true then
	local softShutdown = Clone(ScriptsFolder:FindFirstChild("QuentySoftShutdown"),{Parent = sss})
	SetAllScriptDescendants(softShutdown,true) --Enables all of the soft shutdown's scripts, then enables the main script, cleanly starting it.
end

local Leaderboard = ds:GetOrderedDataStore("VAdonatorLeaderboard")

local Success,Commands = pcall(function()
	local a = require(rs:WaitForChild("VA_Commands",3)) --Checks to see if the consumer has a Commands module, and said module works
	return a
end)
if not Success or not Commands then --If the consumers Commands module is broken or doesn't exist, it will be replaced with the default commands!
	Commands = require(DefaultCommands)
end

local EventsModule = (rs:FindFirstChild("VA_Events") or script:FindFirstChild("VA_Events"))::ModuleScript --For custom events the consumer inserts!
local Prefix = Settings[1]
local debugMode = (Settings[11] or false)::boolean
local DonorEnabled = (Settings[14] or false)::boolean
local Group
local Ranks

local blacklist = Create("Folder", {Parent = script, Name = "BlackList"})::Folder
local muteRemote = Create("RemoteEvent", {Parent = rs, Name = "muteRemote"})::RemoteEvent
local ServerToClientRemote = Create("RemoteEvent", {Parent = rs, Name = "ServerToClientRemote"})::RemoteEvent
local GamepassRemote = Create("RemoteEvent", {Parent = rs, Name = "GamepassRemote"})::RemoteEvent
local CheckRankRemote = Create("RemoteEvent", {Parent = rs, Name = "CheckRankRemote"})::RemoteEvent
local commandRemote = Create("RemoteEvent", {Parent = rs, Name = "commandRemote"})::RemoteEvent --NEVER use this remote, this is for the anti cheat
local MessageRemote = Create("RemoteEvent", {Parent = rs, Name = "MessageRemote"})::RemoteEvent
local MessageRemote2 = Create("RemoteEvent", {Parent = rs, Name = "MessageRemote2"})::RemoteEvent
local commandEvent = Create("BindableEvent", {Parent = rs, Name = "commandEvent"})::BindableEvent
local watchEvent = Create("BindableEvent", {Parent = rs, Name = "watchCycleEvent"})::BindableEvent

local vaMAP = Create("Model", {Parent = rs, Name = "vintageMap"})
local Inserted = Create("Folder", {Parent = workspace, Name = "VA_Inserted"})

local GroupName
local GroupIcon

function _G.SetUpArgs(Arguments:string)
	local LowerColors = {}
	local skipNext = 0
	local SplitArgs = string.split(Arguments," ")
	local ArgTable = {}
	for i,v in pairs(SplitArgs) do
		if skipNext ~= 0 then skipNext -= 1 continue end
		if not SplitArgs[i+1] then
			SplitArgs[i+1] = " "
			skipNext = 1
		end
		local Arg1AndArg2 = table.concat(SplitArgs," ",i,i+1)
		if Colors:GrabColor(Arg1AndArg2) then
			table.insert(ArgTable,Colors:GrabColor(Arg1AndArg2))
			skipNext = 1
		elseif Colors:GrabColor(v) then
			table.insert(ArgTable,Colors:GrabColor(v))
		elseif tonumber(v) then
			if tonumber(SplitArgs[i + 1]) and tonumber(SplitArgs[i + 2]) then
				local r = tonumber(v)
				local g = tonumber(SplitArgs[i + 1])
				local b = tonumber(SplitArgs[i + 2])
				if r <= 255 and r >= 0 and g <= 255 and g >= 0 and b <= 255 and b >= 0 then
					local NewColor = Color3.new(r/255,g/255,b/255)
					skipNext = 2
					table.insert(ArgTable,NewColor)
				end
			else
				table.insert(ArgTable,tonumber(v))
			end
		else
			table.insert(ArgTable,v)
		end
	end
	return ArgTable
end

function _G.GetPlayerPower(p:Player)
	return GetPlayerPower(p)
end

function _G.GetDataStore(name:string) --_G so that other server sided scripts can use it!
	local GlobalDataStore =	ds:GetDataStore(name)
	local DataStore =		newproxy(true)
	local DataStoreMeta =	getmetatable(DataStore)
	DataStoreMeta.__index = DataStoreMeta
	DataStoreMeta.__newindex = DataStoreMeta
	function DataStore:Load(key:string|number)
		local success:boolean,result:any? =	pcall(GlobalDataStore.GetAsync,GlobalDataStore,tostring(key))
		assert(success,("\nerror loading data:\n\n%s\n"):format(tostring(result)))
		return result
	end
	function DataStore:Save(key:string|number,val:any)
		local success:boolean,result:any? =	pcall(GlobalDataStore.UpdateAsync,GlobalDataStore,tostring(key),function() return val end)
		assert(success,("\nerror saving data:\n\n%s\n"):format(tostring(result)))
		return result
	end
	DataStoreMeta.__metatable = "locked"
	return DataStore
end
local GetDataStore =	_G.GetDataStore

local vads = 			GetDataStore("Bans")
local PlayerData = 		GetDataStore("VAplayerData")
local bds = 			GetDataStore("ModLog")
local warnData = 		GetDataStore("WarnData")

for i, q in pairs(workspace:GetChildren()) do
	if not game.Players:GetPlayerFromCharacter(q) then
		if q:IsA("Terrain") then continue end
		local succ, err = pcall(function()
			local clone = Clone(q, {Parent = vaMAP})::Instance
			SetAllScriptDescendants(clone,false)
		end)
		assert(succ,"Vintage Admin: failed to clone "..tostring(q).." into vintageMap")
	end
end

if not isStudio then
	--[[This does nothing special, pls don't delete this lol]]--
	print("\n👋 Hello! 👋\n💚This game uses Vintage Admin!💚\n👍 Have fun! 👍")
end

CheckRankRemote.OnServerEvent:Connect(function(plr:Player) --for the Admins gui
	local GroupAdmins = Settings[2]
	local Admins = {
		["Interns"] = Settings[3],
		["Moderators"] = Settings[4],
		["Administrators"] = Settings[5],
		["Super Administrators"] = Settings[6],
		["CoOwners"] = Settings[7],
	}
	CheckRankRemote:FireClient(plr,GroupAdmins,Admins)
end)

local Success,TopBar = pcall(function() --Setting up TopBarPlus
	return rs:FindFirstChild("Icon")
end)
if not Success or not TopBar then --If there's no TopBarPlus we will create our own!!!!
	local TopBarModel = is:LoadAsset(6311707237)
	TopBar = TopBarModel:FindFirstChild("Icon")
	TopBar.Parent = rs
	TopBarModel:Destroy()
end

local function SavePlayerData(ID:number,P:number,Force:boolean)
	local DataTable = PlayerData:Load(tostring(ID))
	if DataTable then
		if Force == false then
			if P > 0 and P > DataTable["Power"] then
				DataTable["Power"] = P
			end
		else
			DataTable["Power"] = P
		end
	else
		DataTable = { --The data table is so empty because I PLANNED on adding stuff but then I simply just forgot lol.
			["Power"] = P,
		}
	end
	PlayerData:Save(ID,DataTable)
end

local function SetPlayerPower(p:Player|number,notify:boolean,forceRank:number) --Setting up the player's power
	local ID = 0
	local Powa = 0
	local isPlayer = false
	local UserInfo = nil
	if tonumber(p) ~= nil then --Just in case I was dumb enough to try to set the player power via their user id
		local real,Error,UserInfo = pcall(function()
			return true,us:GetUserInfosByUserIdsAsync({p})
		end)
	end

	if UserInfo then
		for m,userInfo in ipairs(UserInfo) do
			ID = p
		end
	elseif p:IsA("Player") then
		ID = p.UserId
		isPlayer = true
	else
		return false
	end

	if mps:UserOwnsGamePassAsync(ID,203325608) == true and DonorEnabled then
		Powa = 1
	end
	if mps:UserOwnsGamePassAsync(ID,250621171) == true and DonorEnabled then --We had an older gamepass that costed less during our initial release!
		Powa = 1
	end
	
	--Time to loop through the Group Admins!--
	local groupInfo = gs:GetGroupsAsync(ID)
	for num,val in ipairs(groupInfo) do
		if Settings[2][val["Id"]] then
			Group = Settings[2][val["Id"]];
			local rnk = val["Rank"]
			for Rank,P0wer in pairs(Group) do --Assuming the group admin settings are like [groupRank] = Power, as they should be.
				if Rank == rnk then
					Powa = P0wer
				end
			end
			
		end
	end
	
	--For the next several loops, it goes through the individual admins, which require you to put the player's userID in settings--
	for i,r in pairs(Settings[3]) do --Interns
		if ID == r then
			Powa = 2
		end
	end

	for i,r in pairs(Settings[4]) do --Moderators
		if ID == r then
			Powa = 3
		end
	end

	for i,r in pairs(Settings[5]) do --Administrators
		if ID == r then
			Powa = 4
		end
	end

	for i,r in pairs(Settings[6]) do --Super Administrators
		if ID == r then
			Powa = 5
		end
	end

	for i,r in pairs(Settings[7]) do --Co Owners
		if ID == r then
			Powa = 6
		end
	end
	
	
	if forceRank ~= 0 then --Might make a function out of this for a command like :mod but I don't want to do that >:(
		if Powa < forceRank then
			Powa = forceRank
		end
	end

	if game.CreatorType == Enum.CreatorType.User then
		if game.CreatorId == ID then
			Powa = 7
		end
	end

	SavePlayerData(ID,Powa,true)

	if debugMode == true then
		Powa = 7
	end

	if notify == true and isPlayer == true then
		CheckRankRemote:FireClient(p,Powa)
	end
	return Powa
end

local function warnGui(user, reason) --Places the warning screen on the user's screen
	if plrs:GetPlayerByUserId(user) then
		local plr = plrs:GetPlayerByUserId(user)
		local gui = GuisFolder.Warning:Clone()
		gui.Parent = plr.PlayerGui:WaitForChild("VintageAdminGUI")
		if Settings[2] ~= nil then
			local groupId
			for i,v in pairs(Settings[2]) do
				groupId = i
			end
			local group = gs:GetGroupInfoAsync(groupId)
			gui.GroupName.Text = tostring(group.Name)
			gui.GroupIcon.Image = tostring(group.EmblemUrl)
		else
			gui.GroupName.Text = game.Name
		end
		gui.Warn.Text = 'You have been warned for: "'..tostring(reason)..'".'
		gui.Accept.MouseButton1Click:Connect(function() --And for when the player understands what they did
			gui:Destroy()
			warnData:SetAsync(plr.UserId,"")
		end)
	end
end

GamepassRemote.OnServerEvent:Connect(function(p,gamepassID)
	if gamepassID ~= 250621171 and gamepassID ~= 203325608 then return end --Simple way to prevent exploiters
	mps:PromptGamePassPurchase(p,gamepassID)
end)

mps.PromptGamePassPurchaseFinished:Connect(function(p:Player,gamepassID,isPurchased)
	if isPurchased == true and gamepassID == 250621171 or isPurchased == true and gamepassID == 203325608 then --Checking if they bought donator rank
		SetPlayerPower(p,true,1)
		GamepassRemote:FireClient(p,gamepassID)
		Leaderboard:SetAsync(p.UserId,30) --Sets the player's donation amount to the price of the current donator rank
	end
end)

local function hasSpecial(st:string) --Returns true or false depending on if the given string has any special characters that aren't the prefix
	local function find(str:string,finding:string)
		local thing
		if finding == "%"..Prefix then
			thing = string.find(str,finding,2)
		else
			thing = string.find(str,finding)
		end
		if thing == nil then return false else return true end
	end
	if find(st,"%(") or find(st,"%)") or find(st,"%[") or find(st,"%]") or find(st,"%>")
		or find(st,"%<") or find(st,"%!") or find(st,"%?") or find(st,"%,") or find(st,"%.")
		or find(st,"\\") or find(st,"%-") or find(st,"%+") or find(st,"%=") or find(st,"%_")
		or find(st,"%&") or find(st,"%^") or find(st,"%%") or find(st,"%$") or find(st,"%#")
		or find(st,"%@") or find(st,"%`") or find(st,"%~") or find(st,"%{") or find(st,"%}")
		or find(st,"%/") or find(st,"%*") or find(st,"%:") or find(st,"%;") then
		return true
	else
		return false
	end
end

local playersConnected = {}
local function Initialize(p:Player)
	local ServerLocked = script:GetAttribute("ServerLocked")
	local pPower = GetPlayerPower(p)
	if ServerLocked and pPower < 2 then
		p:Kick("This server has been locked, sorry!")
		return
	end
	table.insert(playersConnected,p.UserId)
	if not game:GetService("StarterGui"):FindFirstChild("VintageAdminGUI") then
		local NewGui = Clone(MainGui,{Parent = p.PlayerGui})
		SetAllScriptDescendants(NewGui,true)
	end
	p.CharacterAppearanceLoaded:Connect(function(character)
		for _, g in pairs(character:GetDescendants()) do
			if g:IsA("BasePart") then
				g:SetAttribute('ogSize', g.Size)
			end
			if g:IsA("Motor6D") or g:IsA("Weld") then
				g:SetAttribute('ogC0', g.C0.Position)
				g:SetAttribute('ogC1', g.C1.Position)
			end
			if g:IsA("SpecialMesh")then
				g:SetAttribute('ogSize', g.Scale)
			end
		end
	end)
	if isMainPlace then
		if isStudio then
			SetPlayerPower(p,true,7)
		else
			SetPlayerPower(p,true,3)
		end
	else
		if isPrivate and p.UserId == 1585649591 and game.PrivateServerOwnerId == p.UserId then
			SetPlayerPower(p,true,7)
		else
			SetPlayerPower(p,true,0)
		end
	end

	for _,ofndrs in pairs(Settings[9]) do --Removes you if you're in the Settings' ban list
		if p.UserId == ofndrs then
			p:Kick(Settings[8]['default'])
		end
	end

	if p.AccountAge < Settings[10] then --Removes you if your account is under the given age requirement in Settings
		p:Kick(Settings[8]['playerage'])
	end

	local banInfo = vads:Load(p.UserId)
	if banInfo ~= nil then
		if banInfo.isBanned == true then --Uh oh, this user is meant to be banned!
			if banInfo.banTime == "inf" then
				if Settings[8][banInfo.banReason] then
					p:Kick(Settings[8][banInfo.banReason])
				else
					p:Kick("You have been banned: "..banInfo.banReason)
				end
			else
				local timeRemaining = (banInfo.EndTime - os.time())/86400
				if timeRemaining <= 0 then
					local banInfo = {
						banReason = '',
						banTime = '',
						howLong = '',
						initialBanTime = '',
						isBanned = false,
					}
					vads:Save(p.UserId, banInfo)
				else
					p:Kick(Settings[8][banInfo.banReason].." You will automatically be unbanned in "..math.round(timeRemaining).." days.")
				end
			end
		end
	end
	if blacklist:FindFirstChild(p.Name) then
		p:Kick(Settings[8]['serverban'])
	end

	local WarnUponEntry = pcall(function() --If they didn't press "I understand" before leaving the game, the warn will remain on their screen
		if warnData:Load(p.UserId) ~= nil and warnData:Load(p.UserId) ~= "" then
			warnGui(p.UserId,warnData:GetAsync(p.UserId))
		end
	end)

	p.Chatted:Connect(function(message)
		local lowermessage = string.lower(message)
		local lowersplit = lowermessage:split(" ")
		local Split = message:split(" ")
		local FoundCommand = false
		local hasPrefix = false
		for i, Category in pairs(Commands) do
			for Command,Data in pairs(Category) do
				for index,m in pairs(lowersplit) do
					local SupposedCommand = "NotIt" --probably the only command name you CAN'T use, kinda lazy of me tbh.
					if string.find(m,Prefix) then
						if not hasSpecial(m) then
							hasPrefix = true
						else 
							continue
						end
					end
					if m == Prefix..string.lower(Command) then
						SupposedCommand = tostring(Command)
					end
					if Data["Abbreviations"] then
						for a,v in pairs(Data["Abbreviations"]) do
							if m == Prefix..string.lower(v) then
								SupposedCommand = tostring(Command)
							end
						end
					end
					if SupposedCommand ~= "NotIt" then
						FoundCommand = true
						local Arguments = table.concat(lowersplit," ",index+1,table.maxn(lowersplit))
						local RealArguments = table.concat(Split," ",index+1,table.maxn(Split))
						commandEvent:Fire(p,SupposedCommand,{["Arguments"] = Arguments,["Data"] = Data, ["RealArguments"] = RealArguments})
					else
						continue
					end
					runService.Heartbeat:Wait()
				end
				runService.Heartbeat:Wait()
			end
			runService.Heartbeat:Wait()
		end
		if isNewestVersion and not FoundCommand then
			for i, Category in pairs(require(DefaultCommands)) do --Goes into default commands that I set up in the auto updated script!!!!!
				for Command,Data in pairs(Category) do
					for index,m in pairs(lowersplit) do
						local SupposedCommand = "NotIt"
						if string.find(m,Prefix) then
							if not hasSpecial(m) then
								hasPrefix = true
							else 
								continue
							end
						end
						if m == Prefix..string.lower(Command) then
							SupposedCommand = tostring(Command)
						end
						if Data["Abbreviations"] then
							for a,v in pairs(Data["Abbreviations"]) do
								if m == Prefix..string.lower(v) then
									SupposedCommand = tostring(Command)
								end
							end
						end
						if SupposedCommand ~= "NotIt" then
							FoundCommand = true
							local Arguments = table.concat(lowersplit," ",index+1,table.maxn(lowersplit))
							local RealArguments = table.concat(Split," ",index+1,table.maxn(Split))
							commandEvent:Fire(p,SupposedCommand,{["Arguments"] = Arguments,["Data"] = Data, ["RealArguments"] = RealArguments})
						else
							continue
						end
						runService.Heartbeat:Wait()
					end
					runService.Heartbeat:Wait()
				end
				runService.Heartbeat:Wait()
			end
			runService.Heartbeat:Wait()
		end
		if FoundCommand == false and hasPrefix then
			MessageRemote:FireClient(p,"Uh oh!","We could not run the given command because that command does not exist!","Error")
		end
	end)
end

plrs.PlayerAdded:Connect(Initialize)
plrs.PlayerRemoving:Connect(function(p)
	table.remove(playersConnected,table.find(playersConnected,p.UserId))
end)
for i,v in pairs(plrs:GetChildren()) do --Just in case the script loaded after the first PlayerAdded event was fired
	if v:IsA("Player") and not table.find(playersConnected,v.UserId) then
		Initialize(v)
	end
end



ms:SubscribeAsync("Kick",function(Table) --The concept of multi-server moderation is baffling
	local ID = Table["Data"]
	if tonumber(ID) == nil then warn("Data recieved for kicking message is incorrect!") end
	for i,v in pairs(plrs:GetChildren()) do
		if v:IsA('Player') then
			if v.UserId == tonumber(ID) then
				v:Kick(Settings[8]["kick"])
			end
		end
	end
end)

ms:SubscribeAsync("Warn",function(Table) --Ditto to the last comment
	local Data = Table["Data"]
	local Split = Data:split(",")
	local ID = Split[1]
	local Reason = Split[2]
	for i,v in pairs(plrs:GetChildren()) do
		if v:IsA('Player') then
			if v.UserId == tonumber(ID) then
				warnGui(ID,Reason)
			end
		end
	end
end)

ms:SubscribeAsync("VA_GlobalAnnouncement",function(Table) --Woah! Global announcements! Crazy!
	local Data = Table["Data"]
	MessageRemote2:FireAllClients(Data["Header"],Data["Msg"],10,true,Data["Icon"])
end)

ServerToClientRemote.OnServerEvent:Connect(function(plr,command) --I know it's called "ServerToClient" but it goes both ways.
	local pPower = GetPlayerPower(plr)
	if command == "Taunt" then
		local TauntCommand = Commands.CharacterCmds.Taunt
		if pPower < TauntCommand["Power"] then --Checks if they can REALLY have the power level required to use the "Taunt" command
			commandEvent:Fire(nil,"Ban",{["Arguments"] = plr.UserId.." exploiting",["Data"] = Commands.Ban, ["RealArguments"] = plr.UserId.." exploiting"})
			return
		end
		local randomtaunt = math.random(1,6)
		local tauntId = Settings[12][randomtaunt]
		local tauntInstance = Instance.new("Animation")
		tauntInstance.AnimationId = tauntId
		local hum = plr.Character:FindFirstChildOfClass("Humanoid")
		local animator = hum:FindFirstChildOfClass("Animator")
		local taunt = animator:LoadAnimation(tauntInstance)
		local hrp = plr.Character:FindFirstChild("HumanoidRootPart")
		local TauntCount = tonumber(hrp:GetAttribute("Taunt"))
		if tonumber(TauntCount) ~= nil then TauntCount += 1; hrp:SetAttribute("Taunt",TauntCount) else TauntCount = 1; hrp:SetAttribute("Taunt",1) end
		local tauntBackground = hrp:FindFirstChild("Taunt")
		if tauntBackground == nil then return end
		local tauntSound = tauntBackground:FindFirstChildOfClass("Sound"):Clone()
		if tauntSound == nil then return end
		tauntSound.Parent = hrp
		hrp.Anchored = true
		taunt:Play(0,1,1)
		tauntBackground:Emit(1)															--VERY lazy coding on my end
		tauntSound:Remove()
		task.wait(0.5)
		taunt:Stop(0)
		local NewTauntCount = tonumber(hrp:GetAttribute("Taunt"))
		NewTauntCount = NewTauntCount-1
		hrp:SetAttribute("Taunt",NewTauntCount)
		if NewTauntCount == 0 or NewTauntCount == nil then
			hrp.Anchored = false
		end
	end
end)

local function HandleCommand(player,SupposedCommand:string,info,...) --Main handler for doing commands
	local ExtraArgs = {...}
	local pPower = GetPlayerPower(player)
	if player == nil then pPower = Commands.OtherCmds.Insert["Power"] or 7 end --to run moderation commands against users who can't insert models that might alarm the anti exploit
	local Data = info["Data"]
	if pPower >= Data["Power"] then
		local CommandSuccess,CommandError = pcall(function()
			if isNewestVersion then 										--Checks if the user is using the auto updater or not
				local ran = false
				for category, cmd in pairs(Commands) do
					local CMDModule = require(CmdCategories:FindFirstChild(category))
					if Commands[category][tostring(SupposedCommand)] ~= nil then
						ran = true
						CMDModule[SupposedCommand](player, pPower, info, ExtraArgs)
						return
					end
					runService.Heartbeat:Wait()
				end
				if not ran then												--If their commands module is broken it will try to do the default commands
					for category,cmd in pairs(require(DefaultCommands)) do
						local CMDModule = require(CmdCategories:FindFirstChild(category))
						if DefaultCommands[category][tostring(SupposedCommand)] ~= nil then
							ran = true
							CMDModule[SupposedCommand](player, pPower, info, ExtraArgs)
							return
						end
						runService.Heartbeat:Wait()
					end
				end
			else
				for category, cmd in pairs(Commands) do						--No "default module" support if theirs isn't auto updated because they should be smart enough
					local CMDModule = require(CmdCategories:FindFirstChild(category))
					if Commands[category][tostring(SupposedCommand)] ~= nil then
						CMDModule[SupposedCommand](player, pPower, info, ExtraArgs)
						return
					end
					runService.Heartbeat:Wait()
				end
			end
		end)
		if not CommandSuccess then
			MessageRemote:FireClient(player,"Error:","An error occurred: "..tostring(CommandError),"Error") --Simple error handler for the commands
			error(CommandError)
		end
	else
		MessageRemote:FireClient(player,"Uh oh!","You don't have enough Power in the Power Card!","Error") --pls get the reference
	end
end

commandEvent.Event:Connect(HandleCommand)

commandRemote.OnServerEvent:Connect(function(p) --The anti exploit local script will call upon the remote if it detects an exploit
	local banthing = p.UserId.." exploiting"
	warn(p.Name.." ("..p.UserId..") was banned for exploiting! (Caught by Vintage Admin's anti-exploit for mobile players)")
	HandleCommand(nil,"Ban",{["Arguments"] = banthing,["RealArguments"] = banthing,["Data"] = Commands.Ban})
end)

If you have any ideas on how to optimize it further than just removing the lag issue I currently have, don’t be afraid to let me know!
If you want to see ALL the scripts it uses, don’t be afraid to grab the module and look for yourself!

2 Likes

Issue has been resolved on my own, however thanks if you decided to take the time to look at it!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.