2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2014, 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;
36 using Radegast.Netcom;
38 using OpenMetaverse.StructuredData;
42 public class IMTextManager
44 public bool DingOnAllIncoming = false;
46 RadegastInstance instance;
47 RadegastNetcom netcom { get { return instance.Netcom; } }
48 ITextPrinter textPrinter;
49 IMTextManagerType Type;
52 bool AutoResponseSent = false;
57 public IMTextManager(RadegastInstance instance, ITextPrinter textPrinter, IMTextManagerType type, UUID sessionID, string sessionName)
59 this.sessionID = sessionID;
60 this.sessionName = sessionName;
61 this.textPrinter = textPrinter;
62 this.textBuffer = new ArrayList();
65 this.instance = instance;
72 private void InitializeConfig()
74 Settings s = instance.GlobalSettings;
76 if (s["im_timestamps"].Type == OSDType.Unknown)
77 s["im_timestamps"] = OSD.FromBoolean(true);
79 showTimestamps = s["im_timestamps"].AsBoolean();
81 s.OnSettingChanged += new Settings.SettingChangedCallback(s_OnSettingChanged);
84 void s_OnSettingChanged(object sender, SettingsEventArgs e)
86 if (e.Key == "im_timestamps" && e.Value != null)
88 showTimestamps = e.Value.AsBoolean();
93 private void AddNetcomEvents()
95 netcom.InstantMessageReceived += new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
96 netcom.InstantMessageSent += new EventHandler<InstantMessageSentEventArgs>(netcom_InstantMessageSent);
99 private void RemoveNetcomEvents()
101 netcom.InstantMessageReceived -= netcom_InstantMessageReceived;
102 netcom.InstantMessageSent -= netcom_InstantMessageSent;
105 private void netcom_InstantMessageSent(object sender, InstantMessageSentEventArgs e)
107 if (e.SessionID != sessionID) return;
113 private void netcom_InstantMessageReceived(object sender, InstantMessageEventArgs e)
115 if (e.IM.IMSessionID != sessionID) return;
116 if (e.IM.Dialog == InstantMessageDialog.StartTyping ||
117 e.IM.Dialog == InstantMessageDialog.StopTyping)
120 if (instance.Client.Self.MuteList.Find(me => me.Type == MuteType.Resident && me.ID == e.IM.FromAgentID) != null)
129 public void ProcessIM(object e)
131 if (e is InstantMessageEventArgs)
132 this.ProcessIncomingIM((InstantMessageEventArgs)e);
133 else if (e is InstantMessageSentEventArgs)
134 this.ProcessOutgoingIM((InstantMessageSentEventArgs)e);
137 private void ProcessOutgoingIM(InstantMessageSentEventArgs e)
139 PrintIM(e.Timestamp, netcom.LoginOptions.FullName, instance.Client.Self.AgentID, e.Message);
142 private void ProcessIncomingIM(InstantMessageEventArgs e)
144 string msg = e.IM.Message;
146 if (instance.RLV.RestictionActive("recvim", e.IM.FromAgentID.ToString()))
148 msg = "*** IM blocked by your viewer";
150 if (Type == IMTextManagerType.Agent)
152 instance.Client.Self.InstantMessage(instance.Client.Self.Name,
154 "*** The Resident you messaged is prevented from reading your instant messages at the moment, please try again later.",
156 InstantMessageDialog.BusyAutoResponse,
157 InstantMessageOnline.Offline,
158 instance.Client.Self.RelativePosition,
159 instance.Client.Network.CurrentSim.ID,
164 if (DingOnAllIncoming)
166 instance.MediaManager.PlayUISound(UISounds.IM);
168 PrintIM(DateTime.Now, instance.Names.Get(e.IM.FromAgentID, e.IM.FromAgentName), e.IM.FromAgentID, msg);
170 if (!AutoResponseSent && Type == IMTextManagerType.Agent && e.IM.FromAgentID != UUID.Zero && e.IM.FromAgentName != "Second Life")
172 bool autoRespond = false;
173 AutoResponseType art = (AutoResponseType)instance.GlobalSettings["auto_response_type"].AsInteger();
177 case AutoResponseType.WhenBusy: autoRespond = instance.State.IsBusy; break;
178 case AutoResponseType.WhenFromNonFriend: autoRespond = !instance.Client.Friends.FriendList.ContainsKey(e.IM.FromAgentID); break;
179 case AutoResponseType.Always: autoRespond = true; break;
184 AutoResponseSent = true;
185 instance.Client.Self.InstantMessage(instance.Client.Self.Name,
187 instance.GlobalSettings["auto_response_text"].AsString(),
189 InstantMessageDialog.BusyAutoResponse,
190 InstantMessageOnline.Online,
191 instance.Client.Self.RelativePosition,
192 instance.Client.Network.CurrentSim.ID,
195 PrintIM(DateTime.Now, instance.Client.Self.Name, instance.Client.Self.AgentID, instance.GlobalSettings["auto_response_text"].AsString());
200 public void DisplayNotification(string message)
202 if (instance.MainForm.InvokeRequired)
204 instance.MainForm.Invoke(new System.Windows.Forms.MethodInvoker(() => DisplayNotification(message)));
210 textPrinter.ForeColor = SystemColors.GrayText;
211 textPrinter.PrintText(DateTime.Now.ToString("[HH:mm] "));
214 textPrinter.ForeColor = Color.DarkCyan;
215 instance.LogClientMessage(sessionName + ".txt", message);
216 textPrinter.PrintTextLine(message);
219 private void PrintIM(DateTime timestamp, string fromName, UUID fromID, string message)
223 textPrinter.ForeColor = SystemColors.GrayText;
224 textPrinter.PrintText(timestamp.ToString("[HH:mm] "));
227 textPrinter.ForeColor = SystemColors.WindowText;
229 if (instance.GlobalSettings["av_name_link"])
231 textPrinter.InsertLink(fromName, string.Format("secondlife:///app/agent/{0}/about", fromID));
235 textPrinter.PrintText(fromName);
238 StringBuilder sb = new StringBuilder();
240 if (message.StartsWith("/me "))
242 sb.Append(message.Substring(3));
250 instance.LogClientMessage(sessionName + ".txt", fromName + sb.ToString());
251 textPrinter.PrintTextLine(sb.ToString());
254 public static string ReadEndTokens(string path, Int64 numberOfTokens, Encoding encoding, string tokenSeparator)
257 int sizeOfChar = encoding.GetByteCount("\n");
258 byte[] buffer = encoding.GetBytes(tokenSeparator);
261 using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
263 Int64 tokenCount = 0;
264 Int64 endPosition = fs.Length / sizeOfChar;
266 for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar)
268 fs.Seek(-position, SeekOrigin.End);
269 fs.Read(buffer, 0, buffer.Length);
271 if (encoding.GetString(buffer) == tokenSeparator)
274 if (tokenCount == numberOfTokens)
276 byte[] returnBuffer = new byte[fs.Length - fs.Position];
277 fs.Read(returnBuffer, 0, returnBuffer.Length);
278 return encoding.GetString(returnBuffer);
283 // handle case where number of tokens in file is less than numberOfTokens
284 fs.Seek(0, SeekOrigin.Begin);
285 buffer = new byte[fs.Length];
286 fs.Read(buffer, 0, buffer.Length);
287 return encoding.GetString(buffer);
291 private void PrintLastLog()
293 string last = string.Empty;
296 last = IMTextManager.ReadEndTokens(instance.ChatFileName(sessionName + ".txt"), 20, Encoding.UTF8, Environment.NewLine);
300 if (string.IsNullOrEmpty(last))
305 string[] lines = last.Split(Environment.NewLine.ToCharArray());
306 for (int i = 0; i < lines.Length; i++)
308 string msg = lines[i].Trim();
309 if (!string.IsNullOrEmpty(msg))
311 textPrinter.PrintTextLine(msg, SystemColors.GrayText);
315 textPrinter.PrintTextLine("====", SystemColors.GrayText);
318 public void ReprintAllText()
320 textPrinter.ClearText();
322 foreach (object obj in textBuffer)
326 public void ClearInternalBuffer()
331 public void CleanUp()
333 RemoveNetcomEvents();
341 public ITextPrinter TextPrinter
343 get { return textPrinter; }
344 set { textPrinter = value; }
347 public bool ShowTimestamps
349 get { return showTimestamps; }
350 set { showTimestamps = value; }
353 public UUID SessionID
355 get { return sessionID; }
356 set { sessionID = value; }
360 public enum IMTextManagerType