Did I make this too complicated?

It’s supposed to be a relatively simple concept, a /handto script that allows a player to give someone else the tool they’re currently holding, yet somehow it’s almost 200 lines? Did I overcomplicate this, and if so how could I make this better? Performance tips would also be appreciated.

--txciove
local playerService = game:GetService("Players")

local constantsModule = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("constantsModule"))
local foodItemGiverModule = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("foodItemGiver"))


local serverStorage = game:GetService("ServerStorage")
local textChatService = game:GetService("TextChatService")
local runService = game:GetService("RunService")

local generalChannel = textChatService:WaitForChild("TextChannels"):WaitForChild("RBXGeneral")

local incomingHandToEvent = game:GetService("ReplicatedStorage"):WaitForChild("remoteEvents"):WaitForChild("incomingHandTo")
local handToResponseEvent = game:GetService("ReplicatedStorage"):WaitForChild("remoteEvents"):WaitForChild("handToResponse")

local occuringHandtos = {}

local function canPlayerRunCommand(playerTalking : Player) : boolean -- checks if the player can use the command
	if playerTalking:GetRankInGroup(constantsModule.groupId) >= 40 then
		print("player is authorized to use command")
		return true
	end

	return true
end

local function isStringValidCommand(stringToCheck : string) : boolean -- checks if the message starts with /handto
	local splitString = string.split(stringToCheck," ")

	if splitString[1] == "/handto" then
		print("string is valid")
		return true
	else
		warn("string is not valid")
		return false
	end
end

local function returnToolFromName(toolName) -- returns the tool instance from a string
	print(toolName)
	return serverStorage.foodItems:FindFirstChild(toolName)
end

local function findToolBeingHeld(player : Player) : boolean -- finds the tool being held by a specific player
	local tool = player.Character:FindFirstChildWhichIsA("Tool")

	if tool and returnToolFromName(tool.Name) then
		print("Found tool!")
		return tool
	else
		warn("Couldn't find tool.")
		return false
	end
end

local function findToolInPlayer(player : Player, toolName : string) -- finds the tool inside the player (backpack or character)
	if player.Character:FindFirstChild(toolName) then
		return player.Character:FindFirstChild(toolName) 
	end

	if player.Backpack:FindFirstChild(toolName) then
		return player.Backpack:FindFirstChild(toolName) 
	end

	return nil
end

local function findPlayer(queryString : string) -- finds a player using a string
	if queryString == nil then return end
	queryString = string.lower(queryString)

	for index, player in playerService:GetPlayers() do
		local searchString = string.sub(player.Name, 1, string.len(queryString))

		if string.lower(searchString) == queryString then 
			print("Found player!")
			return player
		end

		searchString = string.sub(player.DisplayName, 1, string.len(queryString))

		if string.lower(searchString) == queryString then 
			print("Found player!")
			return player
		end
	end

	return nil
end

local function registerHandto(playerRegistering : Player, playerTarget : Player, Item : string) -- stores information of the handto
	print("Registering handout")
	table.insert(occuringHandtos, {playerRegistering, playerTarget, Item})

	local tool = findToolInPlayer(playerRegistering, Item)

	if tool then
		tool:Remove()
	end
end

local function isPlayerInvovledInHandto(playerToSearchFor) -- looks for a players handto information
	for index, information in occuringHandtos do
		if information[1] == playerToSearchFor or information[2] == playerToSearchFor then
			print("Found relevent handto information!")
			return index
		end
	end

	warn("Could not find relevent handto information!")
	return nil
end

local function carryOutHandout(index : number) -- executes the handto
	print("Carrying out handout")
	if occuringHandtos[index][1] ~= nil and occuringHandtos[index][2] ~= nil and returnToolFromName(occuringHandtos[index][3]) then		
		foodItemGiverModule.giveItem(occuringHandtos[index][2],occuringHandtos[index][3])
	end

	table.remove(occuringHandtos, index)
end

local function cancelHandout(index : number) -- cancels it
	print("Cancelling handout")
	if occuringHandtos[index][1] ~= nil and returnToolFromName(occuringHandtos[index][3]) then
		foodItemGiverModule.giveItem(occuringHandtos[index][1],occuringHandtos[index][3])
	end

	table.remove(occuringHandtos, index)
end

playerService.PlayerAdded:Connect(function(player) -- (doesn't work in normal test mode, have to start a local server for it to run)
	if canPlayerRunCommand(player) then

		player.Chatted:Connect(function(messsage)
			if isStringValidCommand(messsage) then
				local targetPlayer = findPlayer(string.split(messsage," ")[2])
				local tool = findToolBeingHeld(player)

				if not tool then return end

				if targetPlayer ~= nil and not isPlayerInvovledInHandto(targetPlayer) then
					incomingHandToEvent:FireClient(targetPlayer, {player, tool.Name})
					registerHandto(player, targetPlayer, tool.Name)
				end
			end
		end)

	end
end)

handToResponseEvent.OnServerEvent:Connect(function(playerWhoFired, response) -- handles handto target response
	print("response recieved")
	if response == true then
		local index = isPlayerInvovledInHandto(playerWhoFired)

		if index then
			carryOutHandout(index)
		end
	else
		local index = isPlayerInvovledInHandto(playerWhoFired)

		if index then
			cancelHandout(index)
		end
	end
end)


generalChannel.ShouldDeliverCallback = function(textChatMessage, textSource) -- if the command is a valid /handto command, doesn't display it for users
	print(textChatMessage.Text)
	if canPlayerRunCommand(playerService:GetPlayerByUserId(textSource.UserId)) and isStringValidCommand(textChatMessage.Text) then
		return false
	else
		return true
	end
end

1 Like

I can’t review all of this at the moment, but from what I can tell you’re already sorta complicating it by using your own string detection system instead of TextCommands. I’ll reply later when I’m able to read all of this although it may be a while lol

4 Likes

I actually forgot that the new chat service comes with built in chat commands lmao, thanks tho

3 Likes