aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/InstantMessage
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 14:54:35 +0100
committerUbitUmarov2015-09-01 14:54:35 +0100
commit371c9dd2af01a2e7422ec901ee1f80757284a78c (patch)
tree058d2a513cacb12efcce0c0df0ae14ad135dbfe2 /OpenSim/Region/CoreModules/Avatar/InstantMessage
parentremove lixo (diff)
parentdont change camera on crossings (diff)
downloadopensim-SC_OLD-371c9dd2af01a2e7422ec901ee1f80757284a78c.zip
opensim-SC_OLD-371c9dd2af01a2e7422ec901ee1f80757284a78c.tar.gz
opensim-SC_OLD-371c9dd2af01a2e7422ec901ee1f80757284a78c.tar.bz2
opensim-SC_OLD-371c9dd2af01a2e7422ec901ee1f80757284a78c.tar.xz
bad merge?
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/InstantMessage')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs67
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs113
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs112
3 files changed, 249 insertions, 43 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index c33a296..55e30a0 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -27,6 +27,7 @@
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using System.Timers;
30using log4net; 31using log4net;
31using Mono.Addins; 32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
@@ -44,6 +45,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
44 private static readonly ILog m_log = LogManager.GetLogger( 45 private static readonly ILog m_log = LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
46 47
48 private Timer m_logTimer = new Timer(10000);
49 private List<GridInstantMessage> m_logData = new List<GridInstantMessage>();
50 private string m_restUrl;
51
47 /// <value> 52 /// <value>
48 /// Is this module enabled? 53 /// Is this module enabled?
49 /// </value> 54 /// </value>
@@ -63,9 +68,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
63 "InstantMessageModule", "InstantMessageModule") != 68 "InstantMessageModule", "InstantMessageModule") !=
64 "InstantMessageModule") 69 "InstantMessageModule")
65 return; 70 return;
71 m_restUrl = config.Configs["Messaging"].GetString("LogURL", String.Empty);
66 } 72 }
67 73
68 m_enabled = true; 74 m_enabled = true;
75 m_logTimer.AutoReset = false;
76 m_logTimer.Elapsed += LogTimerElapsed;
69 } 77 }
70 78
71 public void AddRegion(Scene scene) 79 public void AddRegion(Scene scene)
@@ -150,6 +158,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
150 { 158 {
151 byte dialog = im.dialog; 159 byte dialog = im.dialog;
152 160
161 if (client != null && dialog == (byte)InstantMessageDialog.MessageFromAgent)
162 LogInstantMesssage(im);
163
153 if (dialog != (byte)InstantMessageDialog.MessageFromAgent 164 if (dialog != (byte)InstantMessageDialog.MessageFromAgent
154 && dialog != (byte)InstantMessageDialog.StartTyping 165 && dialog != (byte)InstantMessageDialog.StartTyping
155 && dialog != (byte)InstantMessageDialog.StopTyping 166 && dialog != (byte)InstantMessageDialog.StopTyping
@@ -159,6 +170,32 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
159 return; 170 return;
160 } 171 }
161 172
173 //DateTime dt = DateTime.UtcNow;
174
175 // Ticks from UtcNow, but make it look like local. Evil, huh?
176 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
177
178 //try
179 //{
180 // // Convert that to the PST timezone
181 // TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
182 // dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
183 //}
184 //catch
185 //{
186 // //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
187 //}
188
189 //// And make it look local again to fool the unix time util
190 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
191
192 // If client is null, this message comes from storage and IS offline
193 if (client != null)
194 im.offline = 0;
195
196 if (im.offline == 0)
197 im.timestamp = (uint)Util.UnixTimeSinceEpoch();
198
162 if (m_TransferModule != null) 199 if (m_TransferModule != null)
163 { 200 {
164 if (client != null) 201 if (client != null)
@@ -202,5 +239,35 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
202 // 239 //
203 OnInstantMessage(null, msg); 240 OnInstantMessage(null, msg);
204 } 241 }
242
243 private void LogInstantMesssage(GridInstantMessage im)
244 {
245 if (m_logData.Count < 20)
246 {
247 // Restart the log write timer
248 m_logTimer.Stop();
249 }
250 if (!m_logTimer.Enabled)
251 m_logTimer.Start();
252
253 lock (m_logData)
254 {
255 m_logData.Add(im);
256 }
257 }
258
259 private void LogTimerElapsed(object source, ElapsedEventArgs e)
260 {
261 lock (m_logData)
262 {
263 if (m_restUrl != String.Empty && m_logData.Count > 0)
264 {
265 bool success = SynchronousRestObjectRequester.MakeRequest<List<GridInstantMessage>, bool>("POST", m_restUrl + "/LogMessages/", m_logData);
266 if (!success)
267 m_log.ErrorFormat("[INSTANT MESSAGE]: Failed to save log data");
268 }
269 m_logData.Clear();
270 }
271 }
205 } 272 }
206} 273}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 2462ff8..5573c94 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private bool m_Enabled = false; 52 private bool m_Enabled = false;
53 protected string m_MessageKey = String.Empty;
53 protected List<Scene> m_Scenes = new List<Scene>(); 54 protected List<Scene> m_Scenes = new List<Scene>();
54 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); 55 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
55 56
@@ -69,14 +70,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
69 public virtual void Initialise(IConfigSource config) 70 public virtual void Initialise(IConfigSource config)
70 { 71 {
71 IConfig cnf = config.Configs["Messaging"]; 72 IConfig cnf = config.Configs["Messaging"];
72 if (cnf != null && cnf.GetString( 73 if (cnf != null)
73 "MessageTransferModule", "MessageTransferModule") !=
74 "MessageTransferModule")
75 { 74 {
76 m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); 75 if (cnf.GetString("MessageTransferModule",
77 return; 76 "MessageTransferModule") != "MessageTransferModule")
78 } 77 {
78 return;
79 }
79 80
81 m_MessageKey = cnf.GetString("MessageKey", String.Empty);
82 }
83 m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
80 m_Enabled = true; 84 m_Enabled = true;
81 } 85 }
82 86
@@ -135,6 +139,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
135 { 139 {
136 UUID toAgentID = new UUID(im.toAgentID); 140 UUID toAgentID = new UUID(im.toAgentID);
137 141
142 if (toAgentID == UUID.Zero)
143 return;
144
138 // Try root avatar only first 145 // Try root avatar only first
139 foreach (Scene scene in m_Scenes) 146 foreach (Scene scene in m_Scenes)
140 { 147 {
@@ -249,6 +256,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
249 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 256 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
250 && requestData.ContainsKey("binary_bucket")) 257 && requestData.ContainsKey("binary_bucket"))
251 { 258 {
259 if (m_MessageKey != String.Empty)
260 {
261 XmlRpcResponse error_resp = new XmlRpcResponse();
262 Hashtable error_respdata = new Hashtable();
263 error_respdata["success"] = "FALSE";
264 error_resp.Value = error_respdata;
265
266 if (!requestData.Contains("message_key"))
267 return error_resp;
268 if (m_MessageKey != (string)requestData["message_key"])
269 return error_resp;
270 }
271
252 // Do the easy way of validating the UUIDs 272 // Do the easy way of validating the UUIDs
253 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 273 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
254 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 274 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -425,34 +445,89 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
425 return resp; 445 return resp;
426 } 446 }
427 447
448<<<<<<< HEAD
428 /// <summary> 449 /// <summary>
429 /// delegate for sending a grid instant message asynchronously 450 /// delegate for sending a grid instant message asynchronously
430 /// </summary> 451 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); 452 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
453=======
454 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
455>>>>>>> avn/ubitvar
432 456
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 457 private class GIM {
434 { 458 public GridInstantMessage im;
435 GridInstantMessageDelegate icon = 459 public MessageResultNotification result;
436 (GridInstantMessageDelegate)iar.AsyncState; 460 };
437 icon.EndInvoke(iar);
438 }
439 461
462 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
463 private int numInstantMessageThreads = 0;
440 464
441 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 465 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
442 { 466 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 467 lock (pendingInstantMessages) {
468 if (numInstantMessageThreads >= 4) {
469 GIM gim = new GIM();
470 gim.im = im;
471 gim.result = result;
472 pendingInstantMessages.Enqueue(gim);
473 } else {
474 ++ numInstantMessageThreads;
475 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
476 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
477 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
478 }
479 }
480 }
444 481
482<<<<<<< HEAD
445 d.BeginInvoke(im, result, GridInstantMessageCompleted, d); 483 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
484=======
485 private void GridInstantMessageCompleted(IAsyncResult iar)
486 {
487 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
488 d.EndInvoke(iar);
489>>>>>>> avn/ubitvar
446 } 490 }
447 491
448 /// <summary> 492 /// <summary>
449 /// Internal SendGridInstantMessage over XMLRPC method. 493 /// Internal SendGridInstantMessage over XMLRPC method.
450 /// </summary> 494 /// </summary>
495<<<<<<< HEAD
451 /// <remarks> 496 /// <remarks>
452 /// This is called from within a dedicated thread. 497 /// This is called from within a dedicated thread.
453 /// </remarks> 498 /// </remarks>
454 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result) 499 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
500=======
501 /// <param name="prevRegionHandle">
502 /// Pass in 0 the first time this method is called. It will be called recursively with the last
503 /// regionhandle tried
504 /// </param>
505 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
506>>>>>>> avn/ubitvar
455 { 507 {
508 GIM gim;
509 do {
510 try {
511 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
512 } catch (Exception e) {
513 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
514 }
515 lock (pendingInstantMessages) {
516 if (pendingInstantMessages.Count > 0) {
517 gim = pendingInstantMessages.Dequeue();
518 im = gim.im;
519 result = gim.result;
520 } else {
521 gim = null;
522 -- numInstantMessageThreads;
523 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
524 }
525 }
526 } while (gim != null);
527 }
528 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
529 {
530
456 UUID toAgentID = new UUID(im.toAgentID); 531 UUID toAgentID = new UUID(im.toAgentID);
457 UUID regionID; 532 UUID regionID;
458 bool needToLookupAgent; 533 bool needToLookupAgent;
@@ -494,6 +569,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
494 break; 569 break;
495 } 570 }
496 571
572<<<<<<< HEAD
497 // Try to send the message to the agent via the retrieved region. 573 // Try to send the message to the agent via the retrieved region.
498 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 574 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
499 msgdata["region_handle"] = 0; 575 msgdata["region_handle"] = 0;
@@ -501,6 +577,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
501 577
502 // If the message delivery was successful, then cache the entry. 578 // If the message delivery was successful, then cache the entry.
503 if (imresult) 579 if (imresult)
580=======
581 if (upd != null)
582 {
583 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
584 upd.RegionID);
585 if (reginfo != null)
586>>>>>>> avn/ubitvar
504 { 587 {
505 lock (m_UserRegionMap) 588 lock (m_UserRegionMap)
506 { 589 {
@@ -622,6 +705,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
622 gim["position_z"] = msg.Position.Z.ToString(); 705 gim["position_z"] = msg.Position.Z.ToString();
623 gim["region_id"] = new UUID(msg.RegionID).ToString(); 706 gim["region_id"] = new UUID(msg.RegionID).ToString();
624 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 707 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
708 if (m_MessageKey != String.Empty)
709 gim["message_key"] = m_MessageKey;
625 return gim; 710 return gim;
626 } 711 }
627 712
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index c75920d..76023bd 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -40,6 +40,13 @@ using OpenSim.Region.Framework.Scenes;
40 40
41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
42{ 42{
43 public struct SendReply
44 {
45 public bool Success;
46 public string Message;
47 public int Disposition;
48 }
49
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OfflineMessageModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OfflineMessageModule")]
44 public class OfflineMessageModule : ISharedRegionModule 51 public class OfflineMessageModule : ISharedRegionModule
45 { 52 {
@@ -50,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
50 private string m_RestURL = String.Empty; 57 private string m_RestURL = String.Empty;
51 IMessageTransferModule m_TransferModule = null; 58 IMessageTransferModule m_TransferModule = null;
52 private bool m_ForwardOfflineGroupMessages = true; 59 private bool m_ForwardOfflineGroupMessages = true;
60 private Dictionary<IClientAPI, List<UUID>> m_repliesSent= new Dictionary<IClientAPI, List<UUID>>();
53 61
54 public void Initialise(IConfigSource config) 62 public void Initialise(IConfigSource config)
55 { 63 {
@@ -169,11 +177,21 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
169 private void OnNewClient(IClientAPI client) 177 private void OnNewClient(IClientAPI client)
170 { 178 {
171 client.OnRetrieveInstantMessages += RetrieveInstantMessages; 179 client.OnRetrieveInstantMessages += RetrieveInstantMessages;
180 client.OnLogout += OnClientLoggedOut;
181 }
182
183 public void OnClientLoggedOut(IClientAPI client)
184 {
185 m_repliesSent.Remove(client);
172 } 186 }
173 187
174 private void RetrieveInstantMessages(IClientAPI client) 188 private void RetrieveInstantMessages(IClientAPI client)
175 { 189 {
176 if (m_RestURL != "") 190 if (m_RestURL == String.Empty)
191 {
192 return;
193 }
194 else
177 { 195 {
178 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); 196 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
179 197
@@ -181,28 +199,28 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
181 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>( 199 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
182 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 200 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
183 201
184 if (msglist == null) 202 if (msglist != null)
185 { 203 {
186 m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list."); 204 foreach (GridInstantMessage im in msglist)
187 return;
188 }
189
190 foreach (GridInstantMessage im in msglist)
191 {
192 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
193 // send it directly or else the item will be given twice
194 client.SendInstantMessage(im);
195 else
196 { 205 {
197 // Send through scene event manager so all modules get a chance 206 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
198 // to look at this message before it gets delivered. 207 // send it directly or else the item will be given twice
199 // 208 client.SendInstantMessage(im);
200 // Needed for proper state management for stored group 209 else
201 // invitations 210 {
202 // 211 // Send through scene event manager so all modules get a chance
203 Scene s = FindScene(client.AgentId); 212 // to look at this message before it gets delivered.
204 if (s != null) 213 //
205 s.EventManager.TriggerIncomingInstantMessage(im); 214 // Needed for proper state management for stored group
215 // invitations
216 //
217
218 im.offline = 1;
219
220 Scene s = FindScene(client.AgentId);
221 if (s != null)
222 s.EventManager.TriggerIncomingInstantMessage(im);
223 }
206 } 224 }
207 } 225 }
208 } 226 }
@@ -214,11 +232,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
214 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 232 im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
215 im.dialog != (byte)InstantMessageDialog.GroupNotice && 233 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
216 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 234 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
217 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 235 im.dialog != (byte)InstantMessageDialog.InventoryOffered &&
236 im.dialog != (byte)InstantMessageDialog.TaskInventoryOffered)
218 { 237 {
219 return; 238 return;
220 } 239 }
221 240
241<<<<<<< HEAD
222 if (!m_ForwardOfflineGroupMessages) 242 if (!m_ForwardOfflineGroupMessages)
223 { 243 {
224 if (im.dialog == (byte)InstantMessageDialog.GroupNotice || 244 if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
@@ -228,6 +248,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
228 248
229 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 249 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
230 "POST", m_RestURL+"/SaveMessage/", im, 10000); 250 "POST", m_RestURL+"/SaveMessage/", im, 10000);
251=======
252 Scene scene = FindScene(new UUID(im.fromAgentID));
253 if (scene == null)
254 scene = m_SceneList[0];
255
256 SendReply reply = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, SendReply>(
257 "POST", m_RestURL+"/SaveMessage/?scope=" +
258 scene.RegionInfo.ScopeID.ToString(), im);
259>>>>>>> avn/ubitvar
231 260
232 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 261 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
233 { 262 {
@@ -235,13 +264,38 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
235 if (client == null) 264 if (client == null)
236 return; 265 return;
237 266
238 client.SendInstantMessage(new GridInstantMessage( 267 if (reply.Message == String.Empty)
239 null, new UUID(im.toAgentID), 268 reply.Message = "User is not logged in. " + (reply.Success ? "Message saved." : "Message not saved");
240 "System", new UUID(im.fromAgentID), 269
241 (byte)InstantMessageDialog.MessageFromAgent, 270 bool sendReply = true;
242 "User is not logged in. "+ 271
243 (success ? "Message saved." : "Message not saved"), 272 switch (reply.Disposition)
244 false, new Vector3())); 273 {
274 case 0: // Normal
275 break;
276 case 1: // Only once per user
277 if (m_repliesSent.ContainsKey(client) && m_repliesSent[client].Contains(new UUID(im.toAgentID)))
278 {
279 sendReply = false;
280 }
281 else
282 {
283 if (!m_repliesSent.ContainsKey(client))
284 m_repliesSent[client] = new List<UUID>();
285 m_repliesSent[client].Add(new UUID(im.toAgentID));
286 }
287 break;
288 }
289
290 if (sendReply)
291 {
292 client.SendInstantMessage(new GridInstantMessage(
293 null, new UUID(im.toAgentID),
294 "System", new UUID(im.fromAgentID),
295 (byte)InstantMessageDialog.MessageFromAgent,
296 reply.Message,
297 false, new Vector3()));
298 }
245 } 299 }
246 } 300 }
247 } 301 }