Best way to create a "M1 Cycle"

i have the animations setup and stuff, and currently im attempting to use animationevents to determined when the animation reaches a point and to create the hitbox at this point then dissolve it either at another point or at the animation end

Furthermore this method first has client call to server then server creates the connections to detect this stuff then returns status to client whether it should go through with playing the animation

Code Regarding above

Server:

local function default_weapon_swing(Player, Character, ValidAnimations, MaxCycle, IdToCycle, SwingCD, StartStates, EndStates, CancelStates)
	local Humanoid : Humanoid = Character:FindFirstChildWhichIsA("Humanoid")
	local Animator : Animator = Humanoid:FindFirstChildWhichIsA("Animator")
	
	local Connection_1 = nil
	local Connection_2 = nil
	local Connection_3 = nil
	local Connection_4 = nil
	local Connection_5 = nil
	local Connection_6 = nil
	
	local FoundConnections = false
	local HumanoidCurrentCycle = Character.Humanoid:GetAttribute("M1Cycle")
	local M1CDT = Character.Humanoid:GetAttribute("M1CDT")
	local M1CD = Character.Humanoid:GetAttribute("M1CD")
	
	for iter, CancelableState in ipairs(CancelStates) do
		if Humanoid:GetAttribute(CancelableState) then
			return false
		end
	end
	
	if M1CD and M1CDT then
		if os.clock() - M1CDT < M1CD then
			return false
		end
	end
	
	local StateList = {}
	for iter, StartingState in ipairs(StartStates) do
		local ID = states.AddState(Character, StartingState, -1, 0, false)
		StateList[StartingState] = ID
	end

	local function CleanConnections()
		local ConnectionList = {Connection_1, Connection_2, Connection_3, Connection_4, Connection_5, Connection_6}

		for iteration, Connection : RBXScriptConnection in ipairs(ConnectionList) do
			if Connection then
				Connection:Disconnect()
			end
		end
	end

	local function DamageEnd()
		--print("Damage Ended...")
	end
	
	local function CycleSwitch()
		local CycleNum = HumanoidCurrentCycle + 1
		CycleNum = if CycleNum <= MaxCycle then CycleNum else 1

		Character.Humanoid:SetAttribute("M1Cycle", CycleNum)
	end

	local function DamageStart()
		--print("Damage Started...")
	end

	local function DissolveStates()
		for StateName, StateID in pairs(StateList) do
			states.DestroyState(Character, StateName, StateID)
		end
	end
	
	Connection_1 = Animator.AnimationPlayed:Connect(function(AnimationTrack)
		print("Detected Animation")
		local ValidCheck = false
		
		for iteration_1, AnimationID in ipairs(ValidAnimations) do
			local Check1 = AnimationTrack.Animation.AnimationId == "rbxassetid://" .. AnimationID
			local Check2 = IdToCycle[(HumanoidCurrentCycle)] == AnimationID
			
			if Check1 and Check2 then
				ValidCheck = true
				break
			end
		end
		
		if not ValidCheck then
			CleanConnections()
			DissolveStates()
			return false
		end
		
		Humanoid:SetAttribute("M1CDT", os.clock())
		Humanoid:SetAttribute("M1CD", AnimationTrack.Length)
		
		Connection_2 = AnimationTrack:GetMarkerReachedSignal("SwingDamageStart"):Connect(function()
			print("Detected Event")
			local SwingEnded = false
			local Cleaned = false
			
			FoundConnections = true
			DamageStart()
			CycleSwitch()
			
			Connection_3 = AnimationTrack.Stopped:Connect(function()
				print("Found1")
				if not SwingEnded then
					DamageEnd()
				end
				
				CleanConnections()
				DissolveStates()
				Cleaned = true
			end)
			
			Connection_4 = AnimationTrack:GetMarkerReachedSignal("SwingDamageEnd"):Connect(function()
				print("Found2")
				SwingEnded = true
				DamageEnd()
				
				Cleaned = true
			end)
			
			Connection_5 = AnimationTrack:GetMarkerReachedSignal("EndAnimFunction"):Connect(function()
				print("Found3")
				CleanConnections()
				DissolveStates()
				
				Cleaned = true
			end)
			
			task.wait(AnimationTrack.Length + 0.3)
			if not Cleaned then
				print("Found4")
				CleanConnections()
				DissolveStates()
			end
		end)
		
		Connection_6 = AnimationTrack.Stopped:Connect(function()
			if not FoundConnections then
				CleanConnections()
				DissolveStates()
			end
		end)
	end)
	
	return true
end

Client [In a function]:

local Successful = game.ReplicatedStorage.Events_1.RequestUsage:InvokeServer(WhoAmI)

local AnimOrder = {
	"SwordSlash1",
	"SwordSlash2",
	"SwordSlash1",
	"SwordFinish"
}

if Successful then
	local Animator = require(Character:FindFirstChild("CharacterMain"):FindFirstChild("AnimationClient"))
	local AnimatorCharacter = Character.Humanoid.Animator

	Animator.PlayAnimation(AnimOrder[Character.Humanoid:GetAttribute("M1Cycle")])
end

Anyways what im wondering is that if my current method is the “best way” to create a M1 Cycle or if theres better ways that games use

Not too confident in my way as it seems to bug quite often and easily (Could just be bad coding on my part)