diff --git a/Commands/other/CmdTp.cs b/Commands/other/CmdTp.cs index ac1467b02..04968cf02 100644 --- a/Commands/other/CmdTp.cs +++ b/Commands/other/CmdTp.cs @@ -59,7 +59,7 @@ namespace MCGalaxy.Commands { ushort[] pos = bot != null ? bot.pos : target.pos; byte[] rot = bot != null ? bot.rot : target.rot; p.BlockUntilLoad(10); //Wait for player to spawn in new map - p.SendOwnHeadPos(pos[0], pos[1], pos[2], rot[0], 0); + p.SendOwnHeadPos(pos[0], pos[1], pos[2], rot[0], rot[1]); } static bool CheckPlayer(Player p, Player target) { diff --git a/Server/Extra/Scheduler.cs b/Server/Extra/Scheduler.cs index 365bafa0b..e62d9672f 100644 --- a/Server/Extra/Scheduler.cs +++ b/Server/Extra/Scheduler.cs @@ -35,25 +35,35 @@ namespace MCGalaxy { } /// Queues an action that is asynchronously executed one time, as soon as possible. - public void QueueOnce(Action callback) { - EnqueueTask(new SchedulerTask(obj => callback(), null, TimeSpan.Zero, false)); + public SchedulerTask QueueOnce(Action callback) { + return EnqueueTask(new SchedulerTask(obj => callback(), null, TimeSpan.Zero, false)); } /// Queues an action that is asynchronously executed one time, after a certain delay. - public void QueueOnce(Action callback, object state, TimeSpan delay) { - EnqueueTask(new SchedulerTask(callback, state, delay, false)); + public SchedulerTask QueueOnce(Action callback, object state, TimeSpan delay) { + return EnqueueTask(new SchedulerTask(callback, state, delay, false)); } - /// Queues an action that is asynchronously executed repeatedly, after a certain delay. - public void QueueRepeat(Action callback, object state, TimeSpan delay) { - EnqueueTask(new SchedulerTask(callback, state, delay, true)); + /// Queues an action that is asynchronously executed repeatedly, after a certain delay. + public SchedulerTask QueueRepeat(Action callback, object state, TimeSpan delay) { + return EnqueueTask(new SchedulerTask(callback, state, delay, true)); } - void EnqueueTask(SchedulerTask task) { + /// Cancels a task if it is in the tasks list. + /// Does not cancel the task if it is currently executing. + public bool Cancel(SchedulerTask task) { + lock (taskLock) { + return tasks.Remove(task); + } + } + + + SchedulerTask EnqueueTask(SchedulerTask task) { lock (taskLock) { tasks.Add(task); handle.Set(); } + return task; } void Loop() { @@ -68,11 +78,8 @@ namespace MCGalaxy { SchedulerTask GetNextTask() { DateTime now = DateTime.UtcNow; lock (taskLock) { - for (int i = 0; i < tasks.Count; i++) { - SchedulerTask task = tasks[i]; - if (task.NextRun < now) { - tasks.RemoveAt(i); return task; - } + foreach (SchedulerTask task in tasks) { + if (task.NextRun < now) return task; } } return null; @@ -84,11 +91,13 @@ namespace MCGalaxy { } catch (Exception ex) { MCGalaxy.Server.ErrorLog(ex); } - if (!task.Repeating) return; - task.NextRun = DateTime.UtcNow.Add(task.Delay); - lock (taskLock) - tasks.Add(task); + if (task.Repeating) { + task.NextRun = DateTime.UtcNow.Add(task.Delay); + } else { + lock (taskLock) + tasks.Remove(task); + } } int GetWaitTime() { @@ -96,9 +105,8 @@ namespace MCGalaxy { DateTime now = DateTime.UtcNow; lock (taskLock) { - for (int i = 0; i < tasks.Count; i++) { - SchedulerTask task = tasks[i]; - int remaining = (int)(task.NextRun - now).TotalMilliseconds; + foreach (SchedulerTask task in tasks) { + int remaining = (int)(task.NextRun - now).TotalMilliseconds; // minimum wait time is 10 milliseconds remaining = Math.Max(10, remaining); wait = Math.Min(wait, remaining); @@ -121,7 +129,7 @@ namespace MCGalaxy { /// Whether this task should continue repeating. public bool Repeating; - public SchedulerTask(Action callback, object state, + public SchedulerTask(Action callback, object state, TimeSpan delay, bool repeating) { Callback = callback; State = state;