diff --git a/MCGalaxy/Chat/Chat.cs b/MCGalaxy/Chat/Chat.cs index e801b1de2..7f9c42bf5 100644 --- a/MCGalaxy/Chat/Chat.cs +++ b/MCGalaxy/Chat/Chat.cs @@ -14,6 +14,7 @@ permissions and limitations under the Licenses. */ using System; using System.Text; +using System.Collections.Generic; using MCGalaxy.Commands; using MCGalaxy.Events.ServerEvents; @@ -238,5 +239,57 @@ namespace MCGalaxy { isCommand = true; return text.Substring(1); } + + public class PersistentMessage { + public enum Priority { Lowest, Low, Default, High, Highest } + + public string message; + public Priority priority; + public PersistentMessage(string message, Priority priority) { + this.message = message; this.priority = priority; + } + + /// + /// Returns false if no persistent message was handled, otherwise true. + /// + internal static bool Handle(Player p, CpeMessageType type, string message, Priority priority) { + if (!IsPersistent(type)) return false; + if (!p.fields.ContainsKey(type)) { + p.fields[type] = new List(); + } + var field = p.fields[type]; + + PersistentMessage thisMsg = null; + foreach (var persMsg in field) { //Find an existing message with same priority + if (persMsg.priority == priority) { thisMsg = persMsg; break; } + } + + if (string.IsNullOrEmpty(message)) { //Clearing the message case + if (thisMsg == null) { return true; } //No message exists with this priority, meaning no action needs to be taken when clearing it + field.Remove(thisMsg); + PersistentMessage highestRemainingMsg = null; + foreach (var persMsg in field) { + if (highestRemainingMsg == null || persMsg.priority > highestRemainingMsg.priority) { highestRemainingMsg = persMsg; } + } + if (highestRemainingMsg == null) { p.Session.SendMessage(type, ""); return true; } //No messages remain, clear field and quit + + p.Session.SendMessage(type, highestRemainingMsg.message); //reveal highest remaining message + return true; + } + + + if (thisMsg == null) { thisMsg = new PersistentMessage(message, priority); field.Add(thisMsg); } else { thisMsg.message = message; } + + foreach (var persMsg in field) { + if (persMsg.priority > priority) { return true; } //If any other message in this field has higher priority, do not send to client + } + p.Session.SendMessage(type, message); + return true; + } + static bool IsPersistent(CpeMessageType type) { + return type == CpeMessageType.Status1 || type == CpeMessageType.Status2 || type == CpeMessageType.Status3 || + type == CpeMessageType.BottomRight1 || type == CpeMessageType.BottomRight2 || type == CpeMessageType.BottomRight3; + } + } } } diff --git a/MCGalaxy/Network/Player.Networking.cs b/MCGalaxy/Network/Player.Networking.cs index 3e1be11a0..b683e6642 100644 --- a/MCGalaxy/Network/Player.Networking.cs +++ b/MCGalaxy/Network/Player.Networking.cs @@ -55,14 +55,15 @@ namespace MCGalaxy Logger.LogError(e); } } - - public void SendCpeMessage(CpeMessageType type, string message) { + + public void SendCpeMessage(CpeMessageType type, string message, Chat.PersistentMessage.Priority priority = Chat.PersistentMessage.Priority.Default) { if (type != CpeMessageType.Normal && !Supports(CpeExt.MessageTypes)) { - if (type == CpeMessageType.Announcement) type = CpeMessageType.Normal; + if (type >= CpeMessageType.Announcement) type = CpeMessageType.Normal; else return; } message = Chat.Format(message, this); + if (Chat.PersistentMessage.Handle(this, type, message, priority)) { return; } Session.SendMessage(type, message); } diff --git a/MCGalaxy/Player/Player.Fields.cs b/MCGalaxy/Player/Player.Fields.cs index b489f0e82..a0bc16bdc 100644 --- a/MCGalaxy/Player/Player.Fields.cs +++ b/MCGalaxy/Player/Player.Fields.cs @@ -31,6 +31,7 @@ namespace MCGalaxy { public PlayerIgnores Ignores = new PlayerIgnores(); public static string lastMSG = ""; + internal Dictionary> fields = new Dictionary>(); public Zone ZoneIn; //TpA