Delaying code execution without locking thread?Solved
ZeTioZ
Hi I wanted to make a little script that wait for an answer of the player for like 60 seconds. I was thinking of making a simple incrementing variable in a while loop which will check if he whether or not answered. And so, I would like to make the loop to wait a second before incrementing the variable and if the incrementing variable is  "60" then just exit the loop and assume that the player didn't answered. But I don't know how to make this timer without sleeping the thread :/ any suggestion ?
MrBlue

Hello, best way you could do this is to store the date and time at the start and then check when the player answers if the 60 seconds have passed or not.
Another way would be with timers. https://umod.org/documentation/api/timers

ZeTioZ
Original Poster
Wow nice thanks you I didn't thought about looking on the umod api !I'll use that ;)

Merged post

I've tried the timer, it does delay the execution of the code in the timer but it doesn't delay the function the timer is in :/

private bool Answered(PlayerSession sender){var playerName = sender.Identity.Name;if (PlayerSave.ContainsKey(playerName)){var Awnsered = PlayerSave[playerName].Awnsered;timer.Repeat(1f, 60, () =>{hurt.SendChatMessage(sender, "", "TRY");if (Awnsered != 3){return;}});if(Awnsered == 1){return true;}if(Awnsered == 2){return false;}return false;}else{return false;}}​// Returns false and then 60 times "TRY" each one delayed by 1 second

It will always return false because the function run the timer like an other function and don't delay itself so the player doesn't have the time to answer

 

Wulf
uMod Admin
Take a look at my Babel Chat plugin which uses Action<> callbacks.
ZeTioZ
Original Poster
5c2d88ae4ea06.jpg Wulf
Take a look at my Babel Chat plugin which uses Action<> callbacks.

Gonna look at it ^^

EDIT: Not really what I was looking for, I'm looking for something like that

command
    var = 1
    check every second if var != 1 60 times
    if var != 1 and var = 2 => return true;
    if var != 1 and var = 3 => return false;
    if var still = 1 after the 60 times then return false;


//To change the var he use the chat

on chat
    if var = 1
        if message = "yes" => var = 2 => return false //To cancel the message from being send to the chat
        if message = "no" => var = 3 => return false
ZeTioZ
Original Poster
ZeTioZ

Gonna look at it ^^

EDIT: Not really what I was looking for, I'm looking for something like that

command var = 1 check every second if var != 1 60 times if var != 1 and var = 2 => return true; if var != 1 and var = 3 => return false; if var still = 1 after the 60 times then return false;//To change the var he use the chaton chat if var = 1 if message = "yes" => var = 2 => return false //To cancel the message from being send to the chat if message = "no" => var = 3 => return false

At the moment I use the suggestion of MrBlue by using the dates and checking the difference but it's not a realtime response so if anyone knows how to delay the code execution it would be very nice :)

klauz24

timer.Repeat(1f, 60, () =>
{
    // Checks every second during 1 minute if something's happening
});


Merged post

To delay the execution just run checks, if it's not what you want, return until it matches what you need
MrBlue

If you could explain what you are trying to do exacly, we might be able to help you better.
I'm pretty sure you can't stop the excecution of the code without locking up the whole server so we might be able to help you make it work in another way.

ZeTioZ
Original Poster
5bee9f4b73cc8.png MrBlue

If you could explain what you are trying to do exacly, we might be able to help you better.
I'm pretty sure you can't stop the excecution of the code without locking up the whole server so we might be able to help you make it work in another way.

I'm trying to make the server wait for 1 minutes the answer of the player before doing something. Like "Do you want to be teleported ?" and the player has 60 seconds to answer "yes" or "no" and if he doesn't answer the default answer is "no" but if I can't delay the code execution then I can't make the server wait for the answer and locking the server is not a good options because then the player could not answer and other player would be locked too.

ZeTioZ
Original Poster
ZeTioZ

At the moment I use the suggestion of MrBlue by using the dates and checking the difference but it's not a realtime response so if anyone knows how to delay the code execution it would be very nice :)

The problem with the timer function is that it's executed like an other function and it doesn't delay the function execution it is in. The function read the timer and pass throught like a simple line, and the timer execute himself independently from the function it is in.
MrBlue

Okay, what about this...
-Player does the teleport requests
-Player is asked are you sure? (yes/no)
-Add player to a dictionary called PendingTeleports <PlayerSession, PlayerSession> (Second playersession is the player to teleport to or whatever)
-Timer is set for 60 seconds
--When the timer runs out, send a message to the player saying they didn't reply and that the teleport is canceled
--Remove player from PendingTeleports

Then use the OnPlayerChat hook or a ChatCommand with the yes/no
-When the player activates it (by typing yes/no or calling the command)
-Check if the PendingTeleports list contains the player
--If yes, do the teleport
--If no, tell the player that there is no teleport pending



Merged post

I can make a proof of concept if you need...
ZeTioZ
Original Poster
5bee9f4b73cc8.png MrBlue

Okay, what about this...
-Player does the teleport requests
-Player is asked are you sure? (yes/no)
-Add player to a dictionary called PendingTeleports (Second playersession is the player to teleport to or whatever)
-Timer is set for 60 seconds
--When the timer runs out, send a message to the player saying they didn't reply and that the teleport is canceled
--Remove player from PendingTeleports

Then use the OnPlayerChat hook or a ChatCommand with the yes/no
-When the player activates it (by typing yes/no or calling the command)
-Check if the PendingTeleports list contains the player
--If yes, do the teleport
--If no, tell the player that there is no teleport pending

Not a bad Idea, but then I would have to make each time a custom pending for each action which need a delay, that wouldn't be really optimized, but for now that could fit my needs, gonna try it ^^ Thanks for all your answers and helps by the way !

MrBlue

This is perfectly fine if it comes down to optimizing, locking up the server to wait for a response isn't xD

ZeTioZ
Original Poster
5bee9f4b73cc8.png MrBlue

This is perfectly fine if it comes down to optimizing, locking up the server to wait for a response isn't xD

Yes surely far better then locking xD
ZeTioZ
Original Poster
5bee9f4b73cc8.png MrBlue

Okay, what about this...
-Player does the teleport requests
-Player is asked are you sure? (yes/no)
-Add player to a dictionary called PendingTeleports (Second playersession is the player to teleport to or whatever)
-Timer is set for 60 seconds
--When the timer runs out, send a message to the player saying they didn't reply and that the teleport is canceled
--Remove player from PendingTeleports

Then use the OnPlayerChat hook or a ChatCommand with the yes/no
-When the player activates it (by typing yes/no or calling the command)
-Check if the PendingTeleports list contains the player
--If yes, do the teleport
--If no, tell the player that there is no teleport pending



Merged post

I can make a proof of concept if you need...

I tryed to make something like your idea with no success x) could you show me the concept ? Thanks ^^
I don't understand the "When the timer runs out" how do I get it ? Should I place an incremental variable inside the timer and check if the variable is at 60 and then send the message or there is an actual method to get the end of the timer ?

EDIT: After some changed, I got this to work but as I said, the problem would be that I would have to make everytime a new delayer for each function I want to delay to get an answer :/

        IDictionary varToCheck = new Dictionary();
		private void CodeDelayer(PlayerSession sender, int delayInSeconds)
		{
			if(!varToCheck.ContainsKey(sender)) varToCheck[sender] = 2;
            else if(varToCheck.ContainsKey(sender)) { hurt.SendChatMessage(sender, "", logo + "You're already pending an answer"); return; }
			int i = 0;
			timer.Repeat(1f, delayInSeconds, () =>
			{
				if (!varToCheck.ContainsKey(sender)) return;
				if (varToCheck[sender] == 1)
				{
					//Do Stuff Yes
					hurt.SendChatMessage(sender, "", logo + "Accepted");
					varToCheck.Remove(sender);
					return;
				}
				else if (varToCheck[sender] == 0)
				{
					//Do Stuff No
					hurt.SendChatMessage(sender, "", logo + "Refused");
					varToCheck.Remove(sender);
					return;
				}
				else
				{
					i++;
					if(i == delayInSeconds)
					{
					    //Do Stuff No
						hurt.SendChatMessage(sender, "", logo + "You didn't answered in time. Default answer is no.");
						varToCheck.Remove(sender);
						return;
					}
				}
			});
		}