///////////////////////////////////////////////////////////////////////// // // www.ultima.smoce.net // Name: WorldSave modif. // ///////////////////////////////////////////////////////////////////////// using System; using System.Timers; using Phoenix.Communication.Packets; namespace Phoenix.Plugins { public class WorldSave { private DateTime lastSave = DateTime.MinValue; private Timer timer; private static DefaultPublicEvent worldSaving = new DefaultPublicEvent(); public WorldSave() { WorldSaving += (s, e) => OnSave(); timer = new Timer(TimeSpan.FromHours(2.5).TotalMilliseconds); timer.Elapsed += timer_Elapsed; } public static event EventHandler WorldSaving { add { worldSaving.AddHandler(value); } remove { worldSaving.RemoveHandler(value); } } [ServerMessageHandler(0x1C)] public CallbackResult OnAsciiSpeech(byte[] data, CallbackResult state) { AsciiSpeech speech = new AsciiSpeech(data); if (speech.Name != "System" || speech.Text != "World save has been initiated.") return CallbackResult.Normal; worldSaving.BeginInvoke(null, EventArgs.Empty); return CallbackResult.Eat; } private void timer_Elapsed(object sender, ElapsedEventArgs e) { UO.Print(0x0434, "Warning: World Save bude za 2 hodiny.n"); timer.Stop(); timer.Start(); } private void OnSave() { bool firstSave = lastSave == DateTime.MinValue ? true : false; string str = firstSave ? "(Prvni od prihlaseni)" : "(Posledni pred {0})"; UO.Print(0x0564, "!!!WORLD SAVE!!!n" + str, LongTime(DateTime.Now.Subtract(lastSave))); if (!firstSave) timer.Interval = DateTime.Now.Subtract(lastSave).Subtract(TimeSpan.FromMinutes(10)).TotalMilliseconds; lastSave = DateTime.Now; WaitForPing(); UO.Print(0x0573,"World Save trval {0}.", ShortTime(DateTime.Now.Subtract(lastSave))); } private string LongTime(TimeSpan time) { return string.Format("{0}h {1}m {2}.{3:D3}s", time.Hours, time.Minutes, time.Seconds, time.Milliseconds); } private string ShortTime(TimeSpan time) { return string.Format(time.TotalMinutes > 1 ? "{0}m {1}.{2:D3}s" : "{1}.{2:D3}s", time.Minutes, time.Seconds, time.Milliseconds); } private void WaitForPing() { using (PingMessageWaiter waiter = new PingMessageWaiter()) { Core.SendToServer(new byte[] { 0x73, 0x7F }); waiter.Wait(1000 * 60 * 5); } } private class PingMessageWaiter : ServerMessageWaiter { public PingMessageWaiter() : base(0x73) { } protected override CallbackResult EventHandler(byte[] data, CallbackResult state) { if (data[1] != 0x7F) return CallbackResult.Normal; waiter.Set(); return CallbackResult.Eat; } } } }