OSDN Git Service

Update year in copyright header
[radegast/radegast.git] / Radegast / Core / ChatTextManager.cs
1 // 
2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2011, Radegast Development Team
4 // All rights reserved.
5 // 
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 
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.
17 // 
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.
28 //
29 // $Id$
30 //
31 using System;
32 using System.Collections.Generic;
33 using System.Drawing;
34 using System.Text;
35 using Radegast.Netcom;
36 using OpenMetaverse;
37 using OpenMetaverse.StructuredData;
38
39 namespace Radegast
40 {
41     public class ChatTextManager : IDisposable
42     {
43         private RadegastInstance instance;
44         private RadegastNetcom netcom { get { return instance.Netcom; } }
45         private GridClient client { get { return instance.Client; } }
46         private ITextPrinter textPrinter;
47
48         private List<ChatBufferItem> textBuffer;
49
50         private bool showTimestamps;
51
52         public ChatTextManager(RadegastInstance instance, ITextPrinter textPrinter)
53         {
54             this.textPrinter = textPrinter;
55             this.textBuffer = new List<ChatBufferItem>();
56
57             this.instance = instance;
58             InitializeConfig();
59
60             // Callbacks
61             netcom.ChatReceived += new EventHandler<ChatEventArgs>(netcom_ChatReceived);
62             netcom.ChatSent += new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
63             netcom.AlertMessageReceived += new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
64         }
65
66         public void Dispose()
67         {
68             netcom.ChatReceived -= new EventHandler<ChatEventArgs>(netcom_ChatReceived);
69             netcom.ChatSent -= new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
70             netcom.AlertMessageReceived -= new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
71         }
72
73         private void InitializeConfig()
74         {
75             Settings s = instance.GlobalSettings;
76
77             if (s["chat_timestamps"].Type == OSDType.Unknown)
78                 s["chat_timestamps"] = OSD.FromBoolean(true);
79
80             showTimestamps = s["chat_timestamps"].AsBoolean();
81
82             s.OnSettingChanged += new Settings.SettingChangedCallback(s_OnSettingChanged);
83         }
84
85         void s_OnSettingChanged(object sender, SettingsEventArgs e)
86         {
87             if (e.Key == "chat_timestamps" && e.Value != null)
88             {
89                 showTimestamps = e.Value.AsBoolean();
90                 ReprintAllText();
91             }
92         }
93
94         private void netcom_ChatSent(object sender, ChatSentEventArgs e)
95         {
96             if (e.Channel == 0) return;
97
98             ProcessOutgoingChat(e);
99         }
100
101         private void netcom_AlertMessageReceived(object sender, AlertMessageEventArgs e)
102         {
103             if (e.Message.ToLower().Contains("autopilot canceled")) return; //workaround the stupid autopilot alerts
104
105             ChatBufferItem item = new ChatBufferItem(
106                 DateTime.Now, "Alert message: " + e.Message, ChatBufferTextStyle.Alert);
107
108             ProcessBufferItem(item, true);
109         }
110
111         private void netcom_ChatReceived(object sender, ChatEventArgs e)
112         {
113             ProcessIncomingChat(e);
114         }
115
116         public void PrintStartupMessage()
117         {
118             ChatBufferItem title = new ChatBufferItem(
119                 DateTime.Now, Properties.Resources.RadegastTitle + "." + RadegastBuild.CurrentRev, ChatBufferTextStyle.StartupTitle);
120
121             ChatBufferItem ready = new ChatBufferItem(
122                 DateTime.Now, "Ready.", ChatBufferTextStyle.StatusBlue);
123
124             ProcessBufferItem(title, true);
125             ProcessBufferItem(ready, true);
126         }
127
128         private Object SyncChat = new Object();
129
130         public void ProcessBufferItem(ChatBufferItem item, bool addToBuffer)
131         {
132             lock (SyncChat)
133             {
134                 instance.LogClientMessage("chat.txt", item.Text);
135                 if (addToBuffer) textBuffer.Add(item);
136
137                 if (showTimestamps)
138                 {
139                     textPrinter.ForeColor = SystemColors.GrayText;
140                     textPrinter.PrintText(item.Timestamp.ToString("[HH:mm] "));
141                 }
142
143                 switch (item.Style)
144                 {
145                     case ChatBufferTextStyle.Normal:
146                         textPrinter.ForeColor = SystemColors.WindowText;
147                         break;
148
149                     case ChatBufferTextStyle.StatusBlue:
150                         textPrinter.ForeColor = Color.Blue;
151                         break;
152
153                     case ChatBufferTextStyle.StatusDarkBlue:
154                         textPrinter.ForeColor = Color.DarkBlue;
155                         break;
156
157                     case ChatBufferTextStyle.LindenChat:
158                         textPrinter.ForeColor = Color.DarkGreen;
159                         break;
160
161                     case ChatBufferTextStyle.ObjectChat:
162                         textPrinter.ForeColor = Color.DarkCyan;
163                         break;
164
165                     case ChatBufferTextStyle.StartupTitle:
166                         textPrinter.ForeColor = SystemColors.WindowText;
167                         textPrinter.Font = new Font(textPrinter.Font, FontStyle.Bold);
168                         break;
169
170                     case ChatBufferTextStyle.Alert:
171                         textPrinter.ForeColor = Color.DarkRed;
172                         break;
173
174                     case ChatBufferTextStyle.Error:
175                         textPrinter.ForeColor = Color.Red;
176                         break;
177
178                     case ChatBufferTextStyle.OwnerSay:
179                         textPrinter.ForeColor = Color.FromArgb(255, 180, 150, 0);
180                         break;
181                 }
182
183                 textPrinter.PrintTextLine(item.Text);
184             }
185         }
186
187         //Used only for non-public chat
188         private void ProcessOutgoingChat(ChatSentEventArgs e)
189         {
190             StringBuilder sb = new StringBuilder();
191
192             sb.AppendFormat("(channel {0}) {1}", e.Channel, client.Self.Name);
193
194             switch (e.Type)
195             {
196                 case ChatType.Normal:
197                     sb.Append(": ");
198                     break;
199
200                 case ChatType.Whisper:
201                     sb.Append(" whisper: ");
202                     break;
203
204                 case ChatType.Shout:
205                     sb.Append(" shout: ");
206                     break;
207             }
208
209             sb.Append(e.Message);
210
211             ChatBufferItem item = new ChatBufferItem(
212                 DateTime.Now, sb.ToString(), ChatBufferTextStyle.StatusDarkBlue);
213
214             ProcessBufferItem(item, true);
215
216             sb = null;
217         }
218
219         private void ProcessIncomingChat(ChatEventArgs e)
220         {
221             if (string.IsNullOrEmpty(e.Message)) return;
222
223             if (instance.RLV.Enabled && e.Message.StartsWith("@"))
224             {
225                 instance.RLV.TryProcessCMD(e);
226 #if !DEBUG
227                 return;
228 #endif
229             }
230
231             StringBuilder sb = new StringBuilder();
232             // if (e.SourceType == ChatSourceType.Object) {
233             //    sb.Append(e.Position + " ");
234             // }
235             if (e.SourceType == ChatSourceType.Agent)
236             {
237                 sb.Append(instance.Names.Get(e.SourceID, e.FromName));
238             }
239             else
240             {
241                 sb.Append(e.FromName);
242             }
243
244             bool isEmote = e.Message.StartsWith("/me ");
245
246             if (!isEmote)
247             {
248                 switch (e.Type)
249                 {
250
251                     case ChatType.Whisper:
252                         sb.Append(" whispers");
253                         break;
254
255                     case ChatType.Shout:
256                         sb.Append(" shouts");
257                         break;
258                 }
259             }
260
261             if (isEmote)
262             {
263                 if (e.SourceType == ChatSourceType.Agent && instance.RLV.RestictionActive("recvemote", e.SourceID.ToString()))
264                     sb.Append(" ...");
265                 else
266                     sb.Append(e.Message.Substring(3));
267             }
268             else
269             {
270                 sb.Append(": ");
271                 if (e.SourceType == ChatSourceType.Agent && !e.Message.StartsWith("/") && instance.RLV.RestictionActive("recvchat", e.SourceID.ToString()))
272                     sb.Append("...");
273                 else
274                     sb.Append(e.Message);
275             }
276
277             ChatBufferItem item = new ChatBufferItem();
278             item.Timestamp = DateTime.Now;
279             item.Text = sb.ToString();
280
281             switch (e.SourceType)
282             {
283                 case ChatSourceType.Agent:
284                     item.Style =
285                         (e.FromName.EndsWith("Linden") ?
286                         ChatBufferTextStyle.LindenChat : ChatBufferTextStyle.Normal);
287                     break;
288
289                 case ChatSourceType.Object:
290                     if (e.Type == ChatType.OwnerSay)
291                     {
292                         item.Style = ChatBufferTextStyle.OwnerSay;
293                     }
294                     else
295                     {
296                         item.Style = ChatBufferTextStyle.ObjectChat;
297                     }
298                     break;
299             }
300
301             ProcessBufferItem(item, true);
302             sb = null;
303         }
304
305         public void ReprintAllText()
306         {
307             textPrinter.ClearText();
308
309             foreach (ChatBufferItem item in textBuffer)
310             {
311                 ProcessBufferItem(item, false);
312             }
313         }
314
315         public void ClearInternalBuffer()
316         {
317             textBuffer.Clear();
318         }
319
320         public ITextPrinter TextPrinter
321         {
322             get { return textPrinter; }
323             set { textPrinter = value; }
324         }
325     }
326 }