2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2012, Radegast Development Team
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 // * Neither the name of the application "Radegast", nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 using System.Collections.Generic;
35 using Radegast.Netcom;
37 using OpenMetaverse.StructuredData;
41 public class ChatTextManager : IDisposable
43 public event EventHandler<ChatLineAddedArgs> ChatLineAdded;
45 private RadegastInstance instance;
46 private RadegastNetcom netcom { get { return instance.Netcom; } }
47 private GridClient client { get { return instance.Client; } }
48 private ITextPrinter textPrinter;
50 private List<ChatBufferItem> textBuffer;
52 private bool showTimestamps;
54 public ChatTextManager(RadegastInstance instance, ITextPrinter textPrinter)
56 this.textPrinter = textPrinter;
57 this.textBuffer = new List<ChatBufferItem>();
59 this.instance = instance;
63 netcom.ChatReceived += new EventHandler<ChatEventArgs>(netcom_ChatReceived);
64 netcom.ChatSent += new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
65 netcom.AlertMessageReceived += new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
70 netcom.ChatReceived -= new EventHandler<ChatEventArgs>(netcom_ChatReceived);
71 netcom.ChatSent -= new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
72 netcom.AlertMessageReceived -= new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
75 private void InitializeConfig()
77 Settings s = instance.GlobalSettings;
79 if (s["chat_timestamps"].Type == OSDType.Unknown)
80 s["chat_timestamps"] = OSD.FromBoolean(true);
82 showTimestamps = s["chat_timestamps"].AsBoolean();
84 s.OnSettingChanged += new Settings.SettingChangedCallback(s_OnSettingChanged);
87 void s_OnSettingChanged(object sender, SettingsEventArgs e)
89 if (e.Key == "chat_timestamps" && e.Value != null)
91 showTimestamps = e.Value.AsBoolean();
96 private void netcom_ChatSent(object sender, ChatSentEventArgs e)
98 if (e.Channel == 0) return;
100 ProcessOutgoingChat(e);
103 private void netcom_AlertMessageReceived(object sender, AlertMessageEventArgs e)
105 if (e.Message.ToLower().Contains("autopilot canceled")) return; //workaround the stupid autopilot alerts
107 ChatBufferItem item = new ChatBufferItem(
108 DateTime.Now, "Alert message", UUID.Zero, ": " + e.Message, ChatBufferTextStyle.Alert);
110 ProcessBufferItem(item, true);
113 private void netcom_ChatReceived(object sender, ChatEventArgs e)
115 ProcessIncomingChat(e);
118 public void PrintStartupMessage()
120 ChatBufferItem title = new ChatBufferItem(
121 DateTime.Now, "", UUID.Zero, Properties.Resources.RadegastTitle + "." + RadegastBuild.CurrentRev, ChatBufferTextStyle.StartupTitle);
123 ChatBufferItem ready = new ChatBufferItem(
124 DateTime.Now, "", UUID.Zero, "Ready.", ChatBufferTextStyle.StatusBlue);
126 ProcessBufferItem(title, true);
127 ProcessBufferItem(ready, true);
130 private Object SyncChat = new Object();
132 public void ProcessBufferItem(ChatBufferItem item, bool addToBuffer)
134 if (ChatLineAdded != null)
136 ChatLineAdded(this, new ChatLineAddedArgs(item));
141 instance.LogClientMessage("chat.txt", item.From + item.Text);
142 if (addToBuffer) textBuffer.Add(item);
146 textPrinter.ForeColor = SystemColors.GrayText;
147 textPrinter.PrintText(item.Timestamp.ToString("[HH:mm] "));
152 case ChatBufferTextStyle.Normal:
153 textPrinter.ForeColor = SystemColors.WindowText;
156 case ChatBufferTextStyle.StatusBlue:
157 textPrinter.ForeColor = Color.Blue;
160 case ChatBufferTextStyle.StatusDarkBlue:
161 textPrinter.ForeColor = Color.DarkBlue;
164 case ChatBufferTextStyle.LindenChat:
165 textPrinter.ForeColor = Color.DarkGreen;
168 case ChatBufferTextStyle.ObjectChat:
169 textPrinter.ForeColor = Color.DarkCyan;
172 case ChatBufferTextStyle.StartupTitle:
173 textPrinter.ForeColor = SystemColors.WindowText;
174 textPrinter.Font = new Font(textPrinter.Font, FontStyle.Bold);
177 case ChatBufferTextStyle.Alert:
178 textPrinter.ForeColor = Color.DarkRed;
181 case ChatBufferTextStyle.Error:
182 textPrinter.ForeColor = Color.Red;
185 case ChatBufferTextStyle.OwnerSay:
186 textPrinter.ForeColor = Color.FromArgb(255, 180, 150, 0);
190 if (item.Style == ChatBufferTextStyle.Normal && item.ID != UUID.Zero && instance.GlobalSettings["av_name_link"])
192 textPrinter.InsertLink(item.From, string.Format("secondlife:///app/agent/{0}/about", item.ID));
193 textPrinter.PrintTextLine(item.Text);
197 textPrinter.PrintTextLine(item.From + item.Text);
202 //Used only for non-public chat
203 private void ProcessOutgoingChat(ChatSentEventArgs e)
205 StringBuilder sb = new StringBuilder();
209 case ChatType.Normal:
213 case ChatType.Whisper:
214 sb.Append(" whisper: ");
218 sb.Append(" shout: ");
222 sb.Append(e.Message);
224 ChatBufferItem item = new ChatBufferItem(
225 DateTime.Now, string.Format("(channel {0}) {1}", e.Channel, client.Self.Name), client.Self.AgentID, sb.ToString(), ChatBufferTextStyle.StatusDarkBlue);
227 ProcessBufferItem(item, true);
232 private void ProcessIncomingChat(ChatEventArgs e)
234 if (string.IsNullOrEmpty(e.Message)) return;
236 // Check if the sender agent is muted
237 if (e.SourceType == ChatSourceType.Agent &&
238 null != client.Self.MuteList.Find(me => me.Type == MuteType.Resident && me.ID == e.SourceID)
241 // Check if sender object is muted
242 if (e.SourceType == ChatSourceType.Object &&
243 null != client.Self.MuteList.Find(me =>
244 (me.Type == MuteType.Resident && me.ID == e.OwnerID) // Owner muted
245 || (me.Type == MuteType.Object && me.ID == e.SourceID) // Object muted by ID
246 || (me.Type == MuteType.ByName && me.Name == e.FromName) // Object muted by name
249 if (instance.RLV.Enabled && e.Message.StartsWith("@"))
251 instance.RLV.TryProcessCMD(e);
257 ChatBufferItem item = new ChatBufferItem();
258 item.ID = e.SourceID;
260 StringBuilder sb = new StringBuilder();
262 if (e.SourceType == ChatSourceType.Agent)
264 item.From = instance.Names.Get(e.SourceID, e.FromName);
268 item.From = e.FromName;
271 bool isEmote = e.Message.ToLower().StartsWith("/me ");
278 case ChatType.Whisper:
279 sb.Append(" whispers");
283 sb.Append(" shouts");
290 if (e.SourceType == ChatSourceType.Agent && instance.RLV.RestictionActive("recvemote", e.SourceID.ToString()))
293 sb.Append(e.Message.Substring(3));
298 if (e.SourceType == ChatSourceType.Agent && !e.Message.StartsWith("/") && instance.RLV.RestictionActive("recvchat", e.SourceID.ToString()))
301 sb.Append(e.Message);
304 item.Timestamp = DateTime.Now;
305 item.Text = sb.ToString();
307 switch (e.SourceType)
309 case ChatSourceType.Agent:
311 (e.FromName.EndsWith("Linden") ?
312 ChatBufferTextStyle.LindenChat : ChatBufferTextStyle.Normal);
315 case ChatSourceType.Object:
316 if (e.Type == ChatType.OwnerSay)
318 item.Style = ChatBufferTextStyle.OwnerSay;
322 item.Style = ChatBufferTextStyle.ObjectChat;
327 ProcessBufferItem(item, true);
328 instance.TabConsole.Tabs["chat"].Highlight();
333 public void ReprintAllText()
335 textPrinter.ClearText();
337 foreach (ChatBufferItem item in textBuffer)
339 ProcessBufferItem(item, false);
343 public void ClearInternalBuffer()
348 public ITextPrinter TextPrinter
350 get { return textPrinter; }
351 set { textPrinter = value; }
355 public class ChatLineAddedArgs : EventArgs
357 ChatBufferItem mItem;
358 public ChatBufferItem Item { get { return mItem; } }
360 public ChatLineAddedArgs(ChatBufferItem item)