so you currently have only one Player rotativoPlayer in your EventsHandler class so that's wrong, if you want something to happen to multiple players, you either need to store all of those players in a global-like context (so change rotativoPlayer to a List<Player> and add to it OnPlayerJoinedetc...) or run your action on each player (in your case starting a new timer in OnPlayerJoined) I also think you should use MEC coroutines instead of timers (if you cant find the MEC namespace, reference Assembly-CSharp-firstpass).
I personally would start a coroutine in OnServerWaitingForPlayers and store it in EventsHandler as a static CoroutineHandle to make OnServerWaitingForPlayers only create the coroutine if it doesnt exist already. Then in OnPlayerJoined add to a static List<Player> in EventsHandler (make sure the list defaults to a value like [] or new()) which is then referenced in the coroutine, which checks if the round is started, kills itself if so, and then make the coroutine iterate every 5 seconds, and make that coroutine modify a static string in EventsHandler, and make it so in OnPlayerJoined, players get a hint that has your positions and font size etc... but no Text, instead it will have an AutoText that goes to the static string in EventsHandler after checking the round hasnt started, meaning when your coroutine changes that string, every hint will automatically update to it (and changing the hints SyncSpeed will change how fast it updates). You dont ever need to remove this hint or anything btw, if you make sure you dont duplicate coroutines across rounds and control everything properly, it should be pretty simple.
An example of the AutoText for the hint is:
AutoText = _ => Round.IsRoundStarted ? string.Empty : EventsHandler.HintValue,
where EventsHandler.HintValue is the static string I mentioned earlier. I hope this helps! Maybe ChatGPT can help you understand what I tried to communicate