Yes, this is not a large forum so if you make four posts in a two hour period you might get lonely XD
I'm going to respond to your posts one by one. It might be more work in the long run because you might have solved some problems, but I don't think I can keep all of your posts in my head at once

Prepare yourselves for a very long post...
I mentioned it in my code. Basically when I had RunConsoleCommand("ulx asay", "I'm not AFK.")
it gives me the error: "RunConsoleCommand: Command has invalid characters! (ulx asay (' '))
--The first parameter of this function should contain only the command, the second parameter should contain arguments."
That's the issue I'm having. It's saying that the first param should only have the command, and I think it's confusing "ulx" and "asay" as two different variables accidentally put into the first variable. Do you know why this is?
In the source engine commands are not allowed to contain spaces. Technically "ulx" is a command, and "asay" is an argument. You want to do RunConsoleCommand( "ulx", "asay", "I'm", "not", "AFK." ).
Also, is what you mean here just putting everything in the code I have above (except the whole ulx stuff at the bottom) into the client file?
Should I move all that code into the cl_cc_cafk.lua and then in the sh use the ULib.clientRPC() command to simulate a clientside command activated on the serverside?
Yes
Also, another question, which file do I put the ULib.clientRPC() util in?
I already answered this in a way, but just to clarify: you want to call ULib.clientRPC() in the shared file (CustomCommands\lua\ulx\modules\sh\sh_cc_cafk.lua).
I now have in the cl_cc_cafk.lua file this code: -snipped code-
What do I then put in the sh file? Do I need to AddCSLua?
You just want to create a ULX command that runs ulx.cafk() via ULib.clientRPC(). You do not need to use AddCSLua, as ULX will automatically include the client files if they're in
<addon>/lua/ulx/modules/cl/.
Ok I just tried something else. I'm getting the error: -snipped error-
when I'm trying to use this code: -snipped code-
I feel like I'm doing something wrong with the LocalPlayer() but I don't know.
It's always a good idea to check the
wiki page for a function.
team.GetName shows us that this function accepts one argument, a teamIndex. You only use Player:function() notation when the function needs a reference to a player. team.GetName() does not. I'm not sure what you were attempting to do with the LocalPlayer():, but if you had removed that I believe it would have worked (or at least fixed that specific error).
Nevermind, found a much easier way to do it. TTT has it's own set of variables for spectator, so I used the following code and it worked: -snipped code-
Of course, now I need to make it into a command so that it isn't activated instantly, and so that it doesn't do it to everyone, and so that it only activates when called upon... what I want it to do is have a timer after the !cafk command appears, so that if the timer gets to a certain duration before the button is clicked, they are put into spectator.
Looping through all the players and running console commands on them is an extremely inefficient way of doing this. I don't know the specifics, as it's been a while since I messed with TTT, but I believe there is a function in TTT to force someone to the spectator team. Check out the
TTT website, it might give you some information on how to. If not, hopefully someone else here has experience. You could also go sorting through TTT's code, though it is quite a lot.
Ah man I feel like I'm the only one posting here now. :/
Never fear, roast is here!

Having an issue though, I understand what it means but I'm not entirely sure how to fix it.
-snipped error-
-snipped code-
I know what the error means. The second argument in ulx.command should be the function name of the command, but there is no function command in that file since it's in the cl file as it uses vgui which is clientside only. What do I need to put there to have it reference to the client function that I have (-snipped code-)
as I can't have that in the shared folder because vgui.Create can't be used via the server.
In other words, you mentioned earlier a ULib.clientRPC() function, I'm confused how to use it.
Okay, so what you want to do is create a new command. To refresh your memory, it's in this format:
local CATEGORY_NAME = "My Category"
local function ulx.mycommand( calling_ply, myArg1, myArg2 )
--my code to be run when the command is called
end
local mycommand = ulx.command( CATEGORY_NAME, "ulx mycommand", ulx.mycommand, "!mycommand" ) --the third argument here must be a shared function, most likely the function you defined above.
mycommand:addParam{ type=ULib.cmds.PlayerArg } --just an example
mycommand:addParam{ type=ULib.cmds.StringArg } --just an example
mycommand:defaultAccess( ULib.ACESS_SUPERADMIN ) --just an example
mycommand:help( "My help text!" )
You're trying to mix in the client-side function with the command registration. You don't want to do that. All you want is a simple command with a body that runs ULib.clientRPC().
In your case, your body would probably just look like this:
ULib.clientRPC( target_ply, "ulx.cafk" )
I recommend renaming your client-side function to something more descriptive, like "ulx.afkMenu". That way your actual command can be called ulx.cafk. Basically just remove the body of your original code and slap a ULib.clientRPC in there:
------------------------------ Check AFK ------------------------------
function ulx.cafk()
--put ULib.clientRPC here
end
local cafk = ulx.command( CATEGORY_NAME, "ulx cafk", ulx.cafk, "!cafk" )
cafk:defaultAccess( ULib.ACCESS_ADMIN )
cafk:help( "Checks if a player is currently AFK." )
Again, apologies for the humongous post. Hope it helped in some way.