using System; using System.Collections; using System.IO; using Server; using Server.Commands; using Server.HuePickers; using Server.Gumps; using Knives.Utils; namespace Knives.Chat3 { public enum ChatStyle { Global, Regional } public class Channel { private static ArrayList s_Channels = new ArrayList(); public static ArrayList Channels { get{ return s_Channels; } } public static void Register(Channel c) { foreach (string str in c.Commands) CommandSystem.Register(str, AccessLevel.Player, new CommandEventHandler(ChannelCommand)); } public static Channel GetByName(string str) { foreach (Channel c in s_Channels) if (c.Name == str) return c; return null; } private static void ChannelCommand(CommandEventArgs args) { foreach (Channel c in s_Channels) foreach (string str in c.Commands) if (str == args.Command) { c.OnChat(args.Mobile, args.ArgString); return; } } public static void AddCommand(string str) { CommandSystem.Register(str, AccessLevel.Player, new CommandEventHandler(ChannelCommand)); } public static void RemoveCommand(string str) { CommandSystem.Entries.Remove(str); } public static void Save() { if (!Directory.Exists("Saves/Chat/")) Directory.CreateDirectory("Saves/Chat/"); GenericWriter writer = new BinaryFileWriter(Path.Combine("Saves/Chat/", "Channels34.bin"), true); writer.Write(0); // version ArrayList list = new ArrayList(); foreach (Channel c in s_Channels) if (c.Mod) list.Add(c); writer.Write(list.Count); foreach (Channel c in list) c.Save(writer); writer.Close(); } public static void Load() { if ( !File.Exists( Path.Combine( "Saves/Chat/", "Channels34.bin" ) ) ) return; using (FileStream bin = new FileStream(Path.Combine("Saves/Chat/", "Channels34.bin"), FileMode.Open, FileAccess.Read, FileShare.Read)) { GenericReader reader = new BinaryFileReader(new BinaryReader(bin)); int version = reader.ReadInt(); int count = reader.ReadInt(); Channel c; for (int i = 0; i < count; ++i) { c = new Channel(""); c.Load(reader); } } } #region Class Definitions private string c_Name; private ArrayList c_Commands; private int c_DefaultC; private ChatStyle c_Style; private bool c_Mod, c_ToIrc, c_NewChars; public string Name { get { return c_Name; } set { c_Name = value; } } public ArrayList Commands { get { return c_Commands; } } public int DefaultC { get { return c_DefaultC; } set { c_DefaultC = value; } } public ChatStyle Style { get { return c_Style; } set { c_Style = value; } } public bool Mod { get { return c_Mod; } set { c_Mod = value; } } public bool ToIrc { get { return c_ToIrc; } set { c_ToIrc = value; } } public bool NewChars { get { return c_NewChars; } set { c_NewChars = value; } } #endregion #region Constructors public Channel( string name ) { c_Name = name; c_Commands = new ArrayList(); c_DefaultC = 0x47E; s_Channels.Add(this); } #endregion #region Methods public virtual string NameFor(Mobile m) { if (c_Style == ChatStyle.Regional && m.Region != null && m.Region.Name != "") return c_Name + " (" + m.Region.Name + ")"; return c_Name; } public virtual bool CanChat(Mobile m, bool say) { if (Data.GetData(m).Banned) { if (say) m.SendMessage(Data.GetData(m).SystemC, General.Local(33)); return false; } if (c_Style == ChatStyle.Regional && (m.Region == null || m.Region.Name == "")) { if (say) m.SendMessage(Data.GetData(m).SystemC, General.Local(35)); return false; } return true; } private void OnChat(object o) { if (!(o is object[])) return; object[] obj = (object[])o; if (obj.Length != 2 || !(obj[0] is Mobile) || !(obj[1] is string)) return; OnChat((Mobile)obj[0], obj[1].ToString(), false); } public virtual void OnChat(Mobile m, string msg) { OnChat(m, msg, true); } public virtual void OnChat(Mobile m, string msg, bool spam) { if (msg == null || msg == "") { if( Data.GetData(m).Channels.Contains(c_Name)) Data.GetData(m).CurrentChannel = this; ChannelGump.SendTo(m); return; } if (!CanChat(m, true)) return; msg = Filter.FilterText(m, msg); if (!CanChat(m, false)) return; if (!Data.GetData(m).Channels.Contains(c_Name)) { m.SendMessage(Data.GetData(m).SystemC, General.Local(34)); return; } if (!TrackSpam.LogSpam(m, "Chat", TimeSpan.FromSeconds(Data.ChatSpam))) { if (spam) m.SendMessage(Data.GetData(m).SystemC, General.Local(97)); Timer.DelayCall(TimeSpan.FromSeconds(4), new TimerStateCallback(OnChat), new object[] { m, msg }); return; } Broadcast(m, msg); if (c_ToIrc && IrcConnection.Connection.Connected) IrcConnection.Connection.SendUserMessage(m, "(" + c_Name + ") " + msg); } protected virtual void Broadcast(Mobile m, string msg) { foreach (Data data in Data.Datas.Values) { if (data.Channels.Contains(c_Name) && !data.Ignores.Contains(m)) { if (c_Style == ChatStyle.Regional && data.Mobile.Region != m.Region) continue; data.Mobile.SendMessage(m.AccessLevel == AccessLevel.Player ? data.ColorFor(this) : Data.GetData(m).StaffC, String.Format("<{0}{1}> {2}: {3}", c_Name, (c_Style == ChatStyle.Regional && m.Region != null ? "-" + m.Region.Name : ""), m.Name, msg)); } else if (data.Mobile.AccessLevel >= m.AccessLevel && ((data.GlobalC && !data.GIgnores.Contains(m)) || data.GListens.Contains(m))) data.Mobile.SendMessage(data.GlobalCC, String.Format("(Global) <{0}{1}> {2}: {3}", c_Name, (c_Style == ChatStyle.Regional && m.Region != null ? "-" + m.Region.Name : ""), m.Name, msg )); } } public virtual void GumpOptions( GumpPlus g, int x, int y ) { int oldY = y; g.AddHtml(x, y + 10, 300, 21, HTML.White + "
" + c_Name + " " + General.Local(40), false, false); string txt = HTML.White + General.Local(42) + ":"; foreach (string str in Data.GetData(g.Owner).CurrentChannel.Commands) txt += " " + str; g.AddHtml(x + 30, y += 30, 170, 21, txt, false, false); g.AddHtml(x + 130, y += 25, 120, 21, HTML.White + c_Name + " " + General.Local(49), false, false); g.AddImage(x + 100, y, 0x2342, Data.GetData(g.Owner).ColorFor(this)); g.AddButton(x + 104, y + 4, 0x2716, 0x2716, "Channel Color", new TimerStateCallback(ChannelColor), g); g.Entries.Insert( 0, new GumpBackground(x, oldY, 300, y-oldY+40, 0x1400)); } public virtual ArrayList BuildList(Mobile m) { ArrayList list = new ArrayList(); foreach (Data data in Data.Datas.Values) { if (m.AccessLevel < data.Mobile.AccessLevel && !Data.ShowStaff) continue; if (!data.Channels.Contains(c_Name)) continue; if (data.Status == OnlineStatus.Hidden && data.Mobile.AccessLevel >= m.AccessLevel) continue; list.Add(data.Mobile); } return list; } private void ChannelColor(object o) { if (!(o is GumpPlus)) return; ((GumpPlus)o).Owner.SendHuePicker(new InternalPicker((GumpPlus)o, this)); } private void Save(GenericWriter writer) { writer.Write(0); // Version writer.Write(c_Name); writer.Write((int)c_Style); writer.Write(c_ToIrc); writer.Write(c_NewChars); writer.Write(c_Commands.Count); foreach (string str in c_Commands) writer.Write(str); } private void Load(GenericReader reader) { int version = reader.ReadInt(); c_Name = reader.ReadString(); c_Style = (ChatStyle)reader.ReadInt(); c_ToIrc = reader.ReadBool(); c_NewChars = reader.ReadBool(); int count = reader.ReadInt(); for (int i = 0; i < count; ++i) c_Commands.Add(reader.ReadString()); foreach (string str in c_Commands) AddCommand(str); c_Mod = true; } #endregion #region Internal Classes protected class InternalPicker : HuePicker { private GumpPlus c_Gump; private Channel c_Chan; public InternalPicker(GumpPlus g, Channel c) : base(0x1018) { c_Gump = g; c_Chan = c; } public override void OnResponse(int hue) { Data.GetData(c_Gump.Owner).ChannelColors[c_Chan.Name] = hue; c_Gump.NewGump(); } } #endregion } }