aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs53
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs206
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs356
-rw-r--r--OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs131
-rw-r--r--OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs157
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs25
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs27
-rw-r--r--OpenSim/Services/FreeswitchService/FreeswitchService.cs8
-rw-r--r--OpenSim/Services/Friends/FriendsService.cs38
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs11
-rw-r--r--OpenSim/Services/HypergridService/HGInstantMessageService.cs349
-rw-r--r--OpenSim/Services/HypergridService/HGInventoryService.cs2
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs252
-rw-r--r--OpenSim/Services/Interfaces/IFriendsService.cs4
-rw-r--r--OpenSim/Services/Interfaces/IHypergridServices.cs (renamed from OpenSim/Services/Interfaces/IGatekeeperService.cs)25
-rw-r--r--OpenSim/Services/Interfaces/IMapImageService.cs (renamed from OpenSim/Services/Interfaces/IMapService.cs)6
-rw-r--r--OpenSim/Services/InventoryService/InventoryService.cs8
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs10
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs14
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs56
-rw-r--r--OpenSim/Services/MapImageService/MapImageService.cs298
21 files changed, 1968 insertions, 68 deletions
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
index 861c475..c5ae0c0 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
@@ -38,7 +38,7 @@ using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base; 38using OpenSim.Server.Base;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41namespace OpenSim.Services.Connectors 41namespace OpenSim.Services.Connectors.Friends
42{ 42{
43 public class FriendsServicesConnector : IFriendsService 43 public class FriendsServicesConnector : IFriendsService
44 { 44 {
@@ -84,7 +84,7 @@ namespace OpenSim.Services.Connectors
84 84
85 85
86 #region IFriendsService 86 #region IFriendsService
87 87
88 public FriendInfo[] GetFriends(UUID PrincipalID) 88 public FriendInfo[] GetFriends(UUID PrincipalID)
89 { 89 {
90 Dictionary<string, object> sendData = new Dictionary<string, object>(); 90 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -92,6 +92,21 @@ namespace OpenSim.Services.Connectors
92 sendData["PRINCIPALID"] = PrincipalID.ToString(); 92 sendData["PRINCIPALID"] = PrincipalID.ToString();
93 sendData["METHOD"] = "getfriends"; 93 sendData["METHOD"] = "getfriends";
94 94
95 return GetFriends(sendData, PrincipalID.ToString());
96 }
97
98 public FriendInfo[] GetFriends(string PrincipalID)
99 {
100 Dictionary<string, object> sendData = new Dictionary<string, object>();
101
102 sendData["PRINCIPALID"] = PrincipalID;
103 sendData["METHOD"] = "getfriends_string";
104
105 return GetFriends(sendData, PrincipalID);
106 }
107
108 protected FriendInfo[] GetFriends(Dictionary<string, object> sendData, string PrincipalID)
109 {
95 string reqString = ServerUtils.BuildQueryString(sendData); 110 string reqString = ServerUtils.BuildQueryString(sendData);
96 111
97 try 112 try
@@ -144,14 +159,10 @@ namespace OpenSim.Services.Connectors
144 159
145 } 160 }
146 161
147 public bool StoreFriend(UUID PrincipalID, string Friend, int flags) 162 public bool StoreFriend(string PrincipalID, string Friend, int flags)
148 { 163 {
149 FriendInfo finfo = new FriendInfo();
150 finfo.PrincipalID = PrincipalID;
151 finfo.Friend = Friend;
152 finfo.MyFlags = flags;
153 164
154 Dictionary<string, object> sendData = finfo.ToKeyValuePairs(); 165 Dictionary<string, object> sendData = ToKeyValuePairs(PrincipalID, Friend, flags);
155 166
156 sendData["METHOD"] = "storefriend"; 167 sendData["METHOD"] = "storefriend";
157 168
@@ -189,6 +200,16 @@ namespace OpenSim.Services.Connectors
189 200
190 } 201 }
191 202
203 public bool Delete(string PrincipalID, string Friend)
204 {
205 Dictionary<string, object> sendData = new Dictionary<string, object>();
206 sendData["PRINCIPALID"] = PrincipalID.ToString();
207 sendData["FRIEND"] = Friend;
208 sendData["METHOD"] = "deletefriend_string";
209
210 return Delete(sendData, PrincipalID, Friend);
211 }
212
192 public bool Delete(UUID PrincipalID, string Friend) 213 public bool Delete(UUID PrincipalID, string Friend)
193 { 214 {
194 Dictionary<string, object> sendData = new Dictionary<string, object>(); 215 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -196,6 +217,11 @@ namespace OpenSim.Services.Connectors
196 sendData["FRIEND"] = Friend; 217 sendData["FRIEND"] = Friend;
197 sendData["METHOD"] = "deletefriend"; 218 sendData["METHOD"] = "deletefriend";
198 219
220 return Delete(sendData, PrincipalID.ToString(), Friend);
221 }
222
223 public bool Delete(Dictionary<string, object> sendData, string PrincipalID, string Friend)
224 {
199 string reply = string.Empty; 225 string reply = string.Empty;
200 try 226 try
201 { 227 {
@@ -230,5 +256,16 @@ namespace OpenSim.Services.Connectors
230 } 256 }
231 257
232 #endregion 258 #endregion
259
260 public Dictionary<string, object> ToKeyValuePairs(string principalID, string friend, int flags)
261 {
262 Dictionary<string, object> result = new Dictionary<string, object>();
263 result["PrincipalID"] = principalID;
264 result["Friend"] = friend;
265 result["MyFlags"] = flags;
266
267 return result;
268 }
269
233 } 270 }
234} \ No newline at end of file 271} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
new file mode 100644
index 0000000..d699f59
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
@@ -0,0 +1,206 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Services.Interfaces;
36using OpenSim.Services.Connectors.Friends;
37using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base;
39using OpenMetaverse;
40
41namespace OpenSim.Services.Connectors.Hypergrid
42{
43 public class HGFriendsServicesConnector
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType);
48
49 private string m_ServerURI = String.Empty;
50 private string m_ServiceKey = String.Empty;
51 private UUID m_SessionID;
52
53 public HGFriendsServicesConnector()
54 {
55 }
56
57 public HGFriendsServicesConnector(string serverURI)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 }
61
62 public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey)
63 {
64 m_ServerURI = serverURI.TrimEnd('/');
65 m_ServiceKey = serviceKey;
66 m_SessionID = sessionID;
67 }
68
69 #region IFriendsService
70
71 public uint GetFriendPerms(UUID PrincipalID, UUID friendID)
72 {
73 Dictionary<string, object> sendData = new Dictionary<string, object>();
74
75 sendData["PRINCIPALID"] = PrincipalID.ToString();
76 sendData["FRIENDID"] = friendID.ToString();
77 sendData["METHOD"] = "getfriendperms";
78 sendData["KEY"] = m_ServiceKey;
79 sendData["SESSIONID"] = m_SessionID.ToString();
80
81 string reqString = ServerUtils.BuildQueryString(sendData);
82
83 try
84 {
85 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
86 m_ServerURI + "/hgfriends",
87 reqString);
88 if (reply != string.Empty)
89 {
90 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
91
92 if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null))
93 {
94 uint perms = 0;
95 uint.TryParse(replyData["Value"].ToString(), out perms);
96 return perms;
97 }
98 else
99 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response",
100 PrincipalID);
101
102 }
103 }
104 catch (Exception e)
105 {
106 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
107 }
108
109 return 0;
110
111 }
112
113 public bool NewFriendship(UUID PrincipalID, string Friend)
114 {
115 FriendInfo finfo = new FriendInfo();
116 finfo.PrincipalID = PrincipalID;
117 finfo.Friend = Friend;
118
119 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
120
121 sendData["METHOD"] = "newfriendship";
122 sendData["KEY"] = m_ServiceKey;
123 sendData["SESSIONID"] = m_SessionID.ToString();
124
125 string reply = string.Empty;
126 try
127 {
128 reply = SynchronousRestFormsRequester.MakeRequest("POST",
129 m_ServerURI + "/hgfriends",
130 ServerUtils.BuildQueryString(sendData));
131 }
132 catch (Exception e)
133 {
134 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
135 return false;
136 }
137
138 if (reply != string.Empty)
139 {
140 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
141
142 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
143 {
144 bool success = false;
145 Boolean.TryParse(replyData["Result"].ToString(), out success);
146 return success;
147 }
148 else
149 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
150 PrincipalID, Friend);
151 }
152 else
153 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply");
154
155 return false;
156
157 }
158
159 public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret)
160 {
161 FriendInfo finfo = new FriendInfo();
162 finfo.PrincipalID = PrincipalID;
163 finfo.Friend = Friend.ToString();
164
165 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
166
167 sendData["METHOD"] = "deletefriendship";
168 sendData["SECRET"] = secret;
169
170 string reply = string.Empty;
171 try
172 {
173 reply = SynchronousRestFormsRequester.MakeRequest("POST",
174 m_ServerURI + "/hgfriends",
175 ServerUtils.BuildQueryString(sendData));
176 }
177 catch (Exception e)
178 {
179 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
180 return false;
181 }
182
183 if (reply != string.Empty)
184 {
185 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
186
187 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
188 {
189 bool success = false;
190 Boolean.TryParse(replyData["Result"].ToString(), out success);
191 return success;
192 }
193 else
194 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response",
195 PrincipalID, Friend);
196 }
197 else
198 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply");
199
200 return false;
201
202 }
203
204 #endregion
205 }
206} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 7ddcfa6..4ce406c 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -51,20 +51,31 @@ namespace OpenSim.Services.Connectors.Hypergrid
51 MethodBase.GetCurrentMethod().DeclaringType); 51 MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 string m_ServerURL; 53 string m_ServerURL;
54 public UserAgentServiceConnector(string url) 54
55 public UserAgentServiceConnector(string url) : this(url, true)
56 {
57 }
58
59 public UserAgentServiceConnector(string url, bool dnsLookup)
55 { 60 {
56 m_ServerURL = url; 61 m_ServerURL = url;
57 // Doing this here, because XML-RPC or mono have some strong ideas about 62
58 // caching DNS translations. 63 if (dnsLookup)
59 try
60 {
61 Uri m_Uri = new Uri(m_ServerURL);
62 IPAddress ip = Util.GetHostFromDNS(m_Uri.Host);
63 m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString()); ;
64 }
65 catch (Exception e)
66 { 64 {
67 m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message); 65 // Doing this here, because XML-RPC or mono have some strong ideas about
66 // caching DNS translations.
67 try
68 {
69 Uri m_Uri = new Uri(m_ServerURL);
70 IPAddress ip = Util.GetHostFromDNS(m_Uri.Host);
71 m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString());
72 if (!m_ServerURL.EndsWith("/"))
73 m_ServerURL += "/";
74 }
75 catch (Exception e)
76 {
77 m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message);
78 }
68 } 79 }
69 m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL); 80 m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL);
70 } 81 }
@@ -400,6 +411,329 @@ namespace OpenSim.Services.Connectors.Hypergrid
400 GetBoolResponse(request, out reason); 411 GetBoolResponse(request, out reason);
401 } 412 }
402 413
414 public List<UUID> StatusNotification(List<string> friends, UUID userID, bool online)
415 {
416 Hashtable hash = new Hashtable();
417 hash["userID"] = userID.ToString();
418 hash["online"] = online.ToString();
419 int i = 0;
420 foreach (string s in friends)
421 {
422 hash["friend_" + i.ToString()] = s;
423 i++;
424 }
425
426 IList paramList = new ArrayList();
427 paramList.Add(hash);
428
429 XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList);
430 string reason = string.Empty;
431
432 // Send and get reply
433 List<UUID> friendsOnline = new List<UUID>();
434 XmlRpcResponse response = null;
435 try
436 {
437 response = request.Send(m_ServerURL, 6000);
438 }
439 catch (Exception e)
440 {
441 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
442 reason = "Exception: " + e.Message;
443 return friendsOnline;
444 }
445
446 if (response.IsFault)
447 {
448 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
449 reason = "XMLRPC Fault";
450 return friendsOnline;
451 }
452
453 hash = (Hashtable)response.Value;
454 //foreach (Object o in hash)
455 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
456 try
457 {
458 if (hash == null)
459 {
460 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
461 reason = "Internal error 1";
462 return friendsOnline;
463 }
464
465 // Here is the actual response
466 foreach (object key in hash.Keys)
467 {
468 if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null)
469 {
470 UUID uuid;
471 if (UUID.TryParse(hash[key].ToString(), out uuid))
472 friendsOnline.Add(uuid);
473 }
474 }
475
476 }
477 catch (Exception e)
478 {
479 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
480 reason = "Exception: " + e.Message;
481 }
482
483 return friendsOnline;
484 }
485
486 public List<UUID> GetOnlineFriends(UUID userID, List<string> friends)
487 {
488 Hashtable hash = new Hashtable();
489 hash["userID"] = userID.ToString();
490 int i = 0;
491 foreach (string s in friends)
492 {
493 hash["friend_" + i.ToString()] = s;
494 i++;
495 }
496
497 IList paramList = new ArrayList();
498 paramList.Add(hash);
499
500 XmlRpcRequest request = new XmlRpcRequest("get_online_friends", paramList);
501 string reason = string.Empty;
502
503 // Send and get reply
504 List<UUID> online = new List<UUID>();
505 XmlRpcResponse response = null;
506 try
507 {
508 response = request.Send(m_ServerURL, 10000);
509 }
510 catch (Exception e)
511 {
512 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
513 reason = "Exception: " + e.Message;
514 return online;
515 }
516
517 if (response.IsFault)
518 {
519 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
520 reason = "XMLRPC Fault";
521 return online;
522 }
523
524 hash = (Hashtable)response.Value;
525 //foreach (Object o in hash)
526 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
527 try
528 {
529 if (hash == null)
530 {
531 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
532 reason = "Internal error 1";
533 return online;
534 }
535
536 // Here is the actual response
537 foreach (object key in hash.Keys)
538 {
539 if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null)
540 {
541 UUID uuid;
542 if (UUID.TryParse(hash[key].ToString(), out uuid))
543 online.Add(uuid);
544 }
545 }
546
547 }
548 catch (Exception e)
549 {
550 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
551 reason = "Exception: " + e.Message;
552 }
553
554 return online;
555 }
556
557 public Dictionary<string, object> GetServerURLs(UUID userID)
558 {
559 Hashtable hash = new Hashtable();
560 hash["userID"] = userID.ToString();
561
562 IList paramList = new ArrayList();
563 paramList.Add(hash);
564
565 XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList);
566 string reason = string.Empty;
567
568 // Send and get reply
569 Dictionary<string, object> serverURLs = new Dictionary<string,object>();
570 XmlRpcResponse response = null;
571 try
572 {
573 response = request.Send(m_ServerURL, 10000);
574 }
575 catch (Exception e)
576 {
577 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
578 reason = "Exception: " + e.Message;
579 return serverURLs;
580 }
581
582 if (response.IsFault)
583 {
584 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
585 reason = "XMLRPC Fault";
586 return serverURLs;
587 }
588
589 hash = (Hashtable)response.Value;
590 //foreach (Object o in hash)
591 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
592 try
593 {
594 if (hash == null)
595 {
596 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
597 reason = "Internal error 1";
598 return serverURLs;
599 }
600
601 // Here is the actual response
602 foreach (object key in hash.Keys)
603 {
604 if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
605 {
606 string serverType = key.ToString().Substring(4); // remove "SRV_"
607 serverURLs.Add(serverType, hash[key].ToString());
608 }
609 }
610
611 }
612 catch (Exception e)
613 {
614 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
615 reason = "Exception: " + e.Message;
616 }
617
618 return serverURLs;
619 }
620
621 public string LocateUser(UUID userID)
622 {
623 Hashtable hash = new Hashtable();
624 hash["userID"] = userID.ToString();
625
626 IList paramList = new ArrayList();
627 paramList.Add(hash);
628
629 XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList);
630 string reason = string.Empty;
631
632 // Send and get reply
633 string url = string.Empty;
634 XmlRpcResponse response = null;
635 try
636 {
637 response = request.Send(m_ServerURL, 10000);
638 }
639 catch (Exception e)
640 {
641 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
642 reason = "Exception: " + e.Message;
643 return url;
644 }
645
646 if (response.IsFault)
647 {
648 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
649 reason = "XMLRPC Fault";
650 return url;
651 }
652
653 hash = (Hashtable)response.Value;
654 //foreach (Object o in hash)
655 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
656 try
657 {
658 if (hash == null)
659 {
660 m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
661 reason = "Internal error 1";
662 return url;
663 }
664
665 // Here's the actual response
666 if (hash.ContainsKey("URL"))
667 url = hash["URL"].ToString();
668
669 }
670 catch (Exception e)
671 {
672 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
673 reason = "Exception: " + e.Message;
674 }
675
676 return url;
677 }
678
679 public string GetUUI(UUID userID, UUID targetUserID)
680 {
681 Hashtable hash = new Hashtable();
682 hash["userID"] = userID.ToString();
683 hash["targetUserID"] = targetUserID.ToString();
684
685 IList paramList = new ArrayList();
686 paramList.Add(hash);
687
688 XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList);
689 string reason = string.Empty;
690
691 // Send and get reply
692 string uui = string.Empty;
693 XmlRpcResponse response = null;
694 try
695 {
696 response = request.Send(m_ServerURL, 10000);
697 }
698 catch (Exception e)
699 {
700 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
701 reason = "Exception: " + e.Message;
702 return uui;
703 }
704
705 if (response.IsFault)
706 {
707 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
708 reason = "XMLRPC Fault";
709 return uui;
710 }
711
712 hash = (Hashtable)response.Value;
713 //foreach (Object o in hash)
714 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
715 try
716 {
717 if (hash == null)
718 {
719 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
720 reason = "Internal error 1";
721 return uui;
722 }
723
724 // Here's the actual response
725 if (hash.ContainsKey("UUI"))
726 uui = hash["UUI"].ToString();
727
728 }
729 catch (Exception e)
730 {
731 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
732 reason = "Exception: " + e.Message;
733 }
734
735 return uui;
736 }
403 737
404 private bool GetBoolResponse(XmlRpcRequest request, out string reason) 738 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
405 { 739 {
diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
new file mode 100644
index 0000000..dbce9f6
--- /dev/null
+++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
@@ -0,0 +1,131 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenMetaverse;
34using Nwc.XmlRpc;
35using log4net;
36
37using OpenSim.Framework;
38
39namespace OpenSim.Services.Connectors.InstantMessage
40{
41 public class InstantMessageServiceConnector
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
46
47 /// <summary>
48 /// This actually does the XMLRPC Request
49 /// </summary>
50 /// <param name="url">URL we pull the data out of to send the request to</param>
51 /// <param name="im">The Instant Message </param>
52 /// <returns>Bool if the message was successfully delivered at the other side.</returns>
53 public static bool SendInstantMessage(string url, GridInstantMessage im)
54 {
55 Hashtable xmlrpcdata = ConvertGridInstantMessageToXMLRPC(im);
56 xmlrpcdata["region_handle"] = 0;
57
58 ArrayList SendParams = new ArrayList();
59 SendParams.Add(xmlrpcdata);
60 XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);
61 try
62 {
63
64 XmlRpcResponse GridResp = GridReq.Send(url, 10000);
65
66 Hashtable responseData = (Hashtable)GridResp.Value;
67
68 if (responseData.ContainsKey("success"))
69 {
70 if ((string)responseData["success"] == "TRUE")
71 {
72 //m_log.DebugFormat("[XXX] Success");
73 return true;
74 }
75 else
76 {
77 //m_log.DebugFormat("[XXX] Fail");
78 return false;
79 }
80 }
81 else
82 {
83 m_log.DebugFormat("[GRID INSTANT MESSAGE]: No response from {0}", url);
84 return false;
85 }
86 }
87 catch (WebException e)
88 {
89 m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond " + e.ToString(), url);
90 }
91
92 return false;
93 }
94
95 /// <summary>
96 /// Takes a GridInstantMessage and converts it into a Hashtable for XMLRPC
97 /// </summary>
98 /// <param name="msg">The GridInstantMessage object</param>
99 /// <returns>Hashtable containing the XMLRPC request</returns>
100 protected static Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg)
101 {
102 Hashtable gim = new Hashtable();
103 gim["from_agent_id"] = msg.fromAgentID.ToString();
104 // Kept for compatibility
105 gim["from_agent_session"] = UUID.Zero.ToString();
106 gim["to_agent_id"] = msg.toAgentID.ToString();
107 gim["im_session_id"] = msg.imSessionID.ToString();
108 gim["timestamp"] = msg.timestamp.ToString();
109 gim["from_agent_name"] = msg.fromAgentName;
110 gim["message"] = msg.message;
111 byte[] dialogdata = new byte[1]; dialogdata[0] = msg.dialog;
112 gim["dialog"] = Convert.ToBase64String(dialogdata, Base64FormattingOptions.None);
113
114 if (msg.fromGroup)
115 gim["from_group"] = "TRUE";
116 else
117 gim["from_group"] = "FALSE";
118 byte[] offlinedata = new byte[1]; offlinedata[0] = msg.offline;
119 gim["offline"] = Convert.ToBase64String(offlinedata, Base64FormattingOptions.None);
120 gim["parent_estate_id"] = msg.ParentEstateID.ToString();
121 gim["position_x"] = msg.Position.X.ToString();
122 gim["position_y"] = msg.Position.Y.ToString();
123 gim["position_z"] = msg.Position.Z.ToString();
124 gim["region_id"] = msg.RegionID.ToString();
125 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None);
126
127 return gim;
128 }
129
130 }
131}
diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs
new file mode 100644
index 0000000..520d639
--- /dev/null
+++ b/OpenSim/Services/Connectors/MapImage/MapImageServiceConnector.cs
@@ -0,0 +1,157 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Reflection;
34
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Communications;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
43
44namespace OpenSim.Services.Connectors
45{
46 public class MapImageServicesConnector : IMapImageService
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(
50 MethodBase.GetCurrentMethod().DeclaringType);
51
52 private string m_ServerURI = String.Empty;
53 private IImprovedAssetCache m_Cache = null;
54
55 public MapImageServicesConnector()
56 {
57 }
58
59 public MapImageServicesConnector(string serverURI)
60 {
61 m_ServerURI = serverURI.TrimEnd('/');
62 }
63
64 public MapImageServicesConnector(IConfigSource source)
65 {
66 Initialise(source);
67 }
68
69 public virtual void Initialise(IConfigSource source)
70 {
71 IConfig config = source.Configs["MapImageService"];
72 if (config == null)
73 {
74 m_log.Error("[MAP IMAGE CONNECTOR]: MapImageService missing");
75 throw new Exception("MapImage connector init error");
76 }
77
78 string serviceURI = config.GetString("MapImageServerURI",
79 String.Empty);
80
81 if (serviceURI == String.Empty)
82 {
83 m_log.Error("[MAP IMAGE CONNECTOR]: No Server URI named in section MapImageService");
84 throw new Exception("MapImage connector init error");
85 }
86 m_ServerURI = serviceURI;
87 m_ServerURI = serviceURI.TrimEnd('/');
88 }
89
90 public bool AddMapTile(int x, int y, byte[] jpgData, out string reason)
91 {
92 reason = string.Empty;
93 int tickstart = Util.EnvironmentTickCount();
94 Dictionary<string, object> sendData = new Dictionary<string, object>();
95 sendData["X"] = x.ToString();
96 sendData["Y"] = y.ToString();
97 sendData["TYPE"] = "image/jpeg";
98 sendData["DATA"] = Convert.ToBase64String(jpgData);
99
100 string reqString = ServerUtils.BuildQueryString(sendData);
101
102 try
103 {
104 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
105 m_ServerURI + "/map",
106 reqString);
107 if (reply != string.Empty)
108 {
109 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
110
111 if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "success"))
112 {
113 return true;
114 }
115 else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure"))
116 {
117 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString());
118 reason = replyData["Message"].ToString();
119 return false;
120 }
121 else if (!replyData.ContainsKey("Result"))
122 {
123 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: reply data does not contain result field");
124 }
125 else
126 {
127 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: unexpected result {0}", replyData["Result"].ToString());
128 reason = "Unexpected result " + replyData["Result"].ToString();
129 }
130
131 }
132 else
133 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: RegisterRegion received null reply");
134 }
135 catch (Exception e)
136 {
137 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
138 }
139 finally
140 {
141 // This just dumps a warning for any operation that takes more than 100 ms
142 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
143 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff);
144 }
145
146 return false;
147
148 }
149
150 public byte[] GetMapTile(string fileName, out string format)
151 {
152 format = string.Empty;
153 new Exception("GetMapTile method not Implemented");
154 return null;
155 }
156 }
157}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
index 6f2d735..7422d94 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -78,6 +78,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
78 78
79 public FriendInfo[] GetFriends(UUID principalID) 79 public FriendInfo[] GetFriends(UUID principalID)
80 { 80 {
81 return GetFriends(principalID.ToString());
82 }
83
84 public FriendInfo[] GetFriends(string principalID)
85 {
81 if (String.IsNullOrEmpty(m_serverUrl)) 86 if (String.IsNullOrEmpty(m_serverUrl))
82 return new FriendInfo[0]; 87 return new FriendInfo[0];
83 88
@@ -95,7 +100,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
95 UUID friendID = friendEntry["Key"].AsUUID(); 100 UUID friendID = friendEntry["Key"].AsUUID();
96 101
97 FriendInfo friend = new FriendInfo(); 102 FriendInfo friend = new FriendInfo();
98 friend.PrincipalID = principalID; 103 if (!UUID.TryParse(principalID, out friend.PrincipalID))
104 {
105 string tmp = string.Empty;
106 if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp, out tmp))
107 // bad record. ignore this entry
108 continue;
109 }
110
99 friend.Friend = friendID.ToString(); 111 friend.Friend = friendID.ToString();
100 friend.MyFlags = friendEntry["Value"].AsInteger(); 112 friend.MyFlags = friendEntry["Value"].AsInteger();
101 friend.TheirFlags = -1; 113 friend.TheirFlags = -1;
@@ -127,7 +139,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
127 return array; 139 return array;
128 } 140 }
129 141
130 public bool StoreFriend(UUID principalID, string friend, int flags) 142 public bool StoreFriend(string principalID, string friend, int flags)
131 { 143 {
132 if (String.IsNullOrEmpty(m_serverUrl)) 144 if (String.IsNullOrEmpty(m_serverUrl))
133 return true; 145 return true;
@@ -152,6 +164,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
152 164
153 public bool Delete(UUID principalID, string friend) 165 public bool Delete(UUID principalID, string friend)
154 { 166 {
167 return Delete(principalID.ToString(), friend);
168 }
169
170 public bool Delete(string principalID, string friend)
171 {
155 if (String.IsNullOrEmpty(m_serverUrl)) 172 if (String.IsNullOrEmpty(m_serverUrl))
156 return true; 173 return true;
157 174
@@ -174,7 +191,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
174 191
175 #endregion IFriendsService 192 #endregion IFriendsService
176 193
177 private OSDArray GetFriended(UUID ownerID) 194 private OSDArray GetFriended(string ownerID)
178 { 195 {
179 NameValueCollection requestArgs = new NameValueCollection 196 NameValueCollection requestArgs = new NameValueCollection
180 { 197 {
@@ -195,7 +212,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
195 } 212 }
196 } 213 }
197 214
198 private OSDArray GetFriendedBy(UUID ownerID) 215 private OSDArray GetFriendedBy(string ownerID)
199 { 216 {
200 NameValueCollection requestArgs = new NameValueCollection 217 NameValueCollection requestArgs = new NameValueCollection
201 { 218 {
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 725c6df..6fb583c 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -103,16 +103,31 @@ namespace OpenSim.Services.Connectors.Simulation
103 args["teleport_flags"] = OSD.FromString(flags.ToString()); 103 args["teleport_flags"] = OSD.FromString(flags.ToString());
104 104
105 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); 105 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000);
106 if (result["Success"].AsBoolean()) 106 bool success = result["success"].AsBoolean();
107 return true; 107 if (success && result.ContainsKey("_Result"))
108 108 {
109 OSDMap data = (OSDMap)result["_Result"];
110
111 reason = data["reason"].AsString();
112 success = data["success"].AsBoolean();
113 return success;
114 }
115
116 // Try the old version, uncompressed
109 result = WebUtil.PostToService(uri, args, 30000); 117 result = WebUtil.PostToService(uri, args, 30000);
110 118
111 if (result["Success"].AsBoolean()) 119 if (result["Success"].AsBoolean())
112 { 120 {
113 m_log.WarnFormat( 121 if (result.ContainsKey("_Result"))
114 "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); 122 {
115 return true; 123 OSDMap data = (OSDMap)result["_Result"];
124
125 reason = data["reason"].AsString();
126 success = data["success"].AsBoolean();
127 m_log.WarnFormat(
128 "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
129 return success;
130 }
116 } 131 }
117 132
118 m_log.WarnFormat( 133 m_log.WarnFormat(
diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs
index c3f1056..201e72f 100644
--- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs
+++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs
@@ -54,10 +54,10 @@ namespace OpenSim.Services.FreeswitchService
54 54
55 Hashtable response = new Hashtable(); 55 Hashtable response = new Hashtable();
56 56
57 foreach (DictionaryEntry item in request) 57// foreach (DictionaryEntry item in request)
58 { 58// {
59// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value); 59//// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value);
60 } 60// }
61 61
62 string requestcontext = (string) request["Hunt-Context"]; 62 string requestcontext = (string) request["Hunt-Context"];
63 response["content_type"] = "text/xml"; 63 response["content_type"] = "text/xml";
diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs
index 3c64ecc..e2033ac 100644
--- a/OpenSim/Services/Friends/FriendsService.cs
+++ b/OpenSim/Services/Friends/FriendsService.cs
@@ -43,17 +43,42 @@ namespace OpenSim.Services.Friends
43 { 43 {
44 } 44 }
45 45
46 public FriendInfo[] GetFriends(UUID PrincipalID) 46 public virtual FriendInfo[] GetFriends(UUID PrincipalID)
47 { 47 {
48 FriendsData[] data = m_Database.GetFriends(PrincipalID); 48 FriendsData[] data = m_Database.GetFriends(PrincipalID);
49 List<FriendInfo> info = new List<FriendInfo>();
50
51 foreach (FriendsData d in data)
52 {
53 FriendInfo i = new FriendInfo();
54
55 i.PrincipalID = new UUID(d.PrincipalID);
56 i.Friend = d.Friend;
57 i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
58 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
59
60 info.Add(i);
61 }
62
63 return info.ToArray();
64 }
49 65
66 public virtual FriendInfo[] GetFriends(string PrincipalID)
67 {
68 FriendsData[] data = m_Database.GetFriends(PrincipalID);
50 List<FriendInfo> info = new List<FriendInfo>(); 69 List<FriendInfo> info = new List<FriendInfo>();
51 70
52 foreach (FriendsData d in data) 71 foreach (FriendsData d in data)
53 { 72 {
54 FriendInfo i = new FriendInfo(); 73 FriendInfo i = new FriendInfo();
55 74
56 i.PrincipalID = d.PrincipalID; 75 if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID))
76 {
77 string tmp = string.Empty;
78 if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp, out tmp))
79 // bad record. ignore this entry
80 continue;
81 }
57 i.Friend = d.Friend; 82 i.Friend = d.Friend;
58 i.MyFlags = Convert.ToInt32(d.Data["Flags"]); 83 i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
59 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]); 84 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
@@ -64,7 +89,7 @@ namespace OpenSim.Services.Friends
64 return info.ToArray(); 89 return info.ToArray();
65 } 90 }
66 91
67 public bool StoreFriend(UUID PrincipalID, string Friend, int flags) 92 public virtual bool StoreFriend(string PrincipalID, string Friend, int flags)
68 { 93 {
69 FriendsData d = new FriendsData(); 94 FriendsData d = new FriendsData();
70 95
@@ -76,7 +101,12 @@ namespace OpenSim.Services.Friends
76 return m_Database.Store(d); 101 return m_Database.Store(d);
77 } 102 }
78 103
79 public bool Delete(UUID PrincipalID, string Friend) 104 public bool Delete(string principalID, string friend)
105 {
106 return m_Database.Delete(principalID, friend);
107 }
108
109 public virtual bool Delete(UUID PrincipalID, string Friend)
80 { 110 {
81 return m_Database.Delete(PrincipalID, Friend); 111 return m_Database.Delete(PrincipalID, Friend);
82 } 112 }
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
index b226971..6d63748 100644
--- a/OpenSim/Services/GridService/HypergridLinker.cs
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -327,10 +327,13 @@ namespace OpenSim.Services.GridService
327 else 327 else
328 regInfo.RegionName = externalName; 328 regInfo.RegionName = externalName;
329 329
330 m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName); 330 m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
331 331
332 // Get the map image 332 // Get the map image
333 regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory); 333 regInfo.TerrainImage = GetMapImage(regionID, imageURL);
334
335 // Store the origin's coordinates somewhere
336 regInfo.RegionSecret = handle.ToString();
334 337
335 AddHyperlinkRegion(regInfo, handle); 338 AddHyperlinkRegion(regInfo, handle);
336 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID); 339 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID);
@@ -427,6 +430,10 @@ namespace OpenSim.Services.GridService
427 m_Database.Delete(regionID); 430 m_Database.Delete(regionID);
428 } 431 }
429 432
433 public UUID GetMapImage(UUID regionID, string imageURL)
434 {
435 return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
436 }
430 #endregion 437 #endregion
431 438
432 439
diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
new file mode 100644
index 0000000..ded589d
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
@@ -0,0 +1,349 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends;
35using OpenSim.Services.Connectors.Hypergrid;
36using OpenSim.Services.Interfaces;
37using OpenSim.Services.Connectors.InstantMessage;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenSim.Server.Base;
40using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
41
42using OpenMetaverse;
43using log4net;
44using Nini.Config;
45
46namespace OpenSim.Services.HypergridService
47{
48 /// <summary>
49 /// Inter-grid IM
50 /// </summary>
51 public class HGInstantMessageService : IInstantMessage
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56
57 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours
58
59 static bool m_Initialized = false;
60
61 protected static IGridService m_GridService;
62 protected static IPresenceService m_PresenceService;
63 protected static IUserAgentService m_UserAgentService;
64
65 protected static IInstantMessageSimConnector m_IMSimConnector;
66
67 protected static Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
68 private static ExpiringCache<UUID, GridRegion> m_RegionCache;
69
70 private static string m_RestURL;
71 private static bool m_ForwardOfflineGroupMessages;
72 private static bool m_InGatekeeper;
73
74 public HGInstantMessageService(IConfigSource config)
75 : this(config, null)
76 {
77 }
78
79 public HGInstantMessageService(IConfigSource config, IInstantMessageSimConnector imConnector)
80 {
81 if (imConnector != null)
82 m_IMSimConnector = imConnector;
83
84 if (!m_Initialized)
85 {
86 m_Initialized = true;
87
88 IConfig serverConfig = config.Configs["HGInstantMessageService"];
89 if (serverConfig == null)
90 throw new Exception(String.Format("No section HGInstantMessageService in config file"));
91
92 string gridService = serverConfig.GetString("GridService", String.Empty);
93 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
94 string userAgentService = serverConfig.GetString("UserAgentService", String.Empty);
95 m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false);
96 m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper);
97
98
99 if (gridService == string.Empty || presenceService == string.Empty)
100 throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function."));
101
102 Object[] args = new Object[] { config };
103 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
104 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
105 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args);
106
107 m_RegionCache = new ExpiringCache<UUID, GridRegion>();
108
109 IConfig cnf = config.Configs["Messaging"];
110 if (cnf == null)
111 {
112 return;
113 }
114
115 m_RestURL = cnf.GetString("OfflineMessageURL", string.Empty);
116 m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", false);
117
118 }
119 }
120
121 public bool IncomingInstantMessage(GridInstantMessage im)
122 {
123 m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID);
124 UUID toAgentID = new UUID(im.toAgentID);
125
126 bool success = false;
127 if (m_IMSimConnector != null)
128 {
129 //m_log.DebugFormat("[XXX] SendIMToRegion local im connector");
130 success = m_IMSimConnector.SendInstantMessage(im);
131 }
132 else
133 {
134 success = TrySendInstantMessage(im, "", true, false);
135 }
136
137 if (!success && m_InGatekeeper) // we do this only in the Gatekeeper IM service
138 UndeliveredMessage(im);
139
140 return success;
141 }
142
143 public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner)
144 {
145 m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url);
146 if (url != string.Empty)
147 return TrySendInstantMessage(im, url, true, foreigner);
148 else
149 {
150 PresenceInfo upd = new PresenceInfo();
151 upd.RegionID = UUID.Zero;
152 return TrySendInstantMessage(im, upd, true, foreigner);
153 }
154
155 }
156
157 protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime, bool foreigner)
158 {
159 UUID toAgentID = new UUID(im.toAgentID);
160
161 PresenceInfo upd = null;
162 string url = string.Empty;
163
164 bool lookupAgent = false;
165
166 lock (m_UserLocationMap)
167 {
168 if (m_UserLocationMap.ContainsKey(toAgentID))
169 {
170 object o = m_UserLocationMap[toAgentID];
171 if (o is PresenceInfo)
172 upd = (PresenceInfo)o;
173 else if (o is string)
174 url = (string)o;
175
176 // We need to compare the current location with the previous
177 // or the recursive loop will never end because it will never try to lookup the agent again
178 if (!firstTime)
179 {
180 lookupAgent = true;
181 upd = null;
182 }
183 }
184 else
185 {
186 lookupAgent = true;
187 }
188 }
189
190 //m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no"));
191
192 // Are we needing to look-up an agent?
193 if (lookupAgent)
194 {
195 // Non-cached user agent lookup.
196 PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { toAgentID.ToString() });
197 if (presences != null && presences.Length > 0)
198 {
199 foreach (PresenceInfo p in presences)
200 {
201 if (p.RegionID != UUID.Zero)
202 {
203 //m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID);
204 upd = p;
205 break;
206 }
207 }
208 }
209
210 if (upd == null && !foreigner)
211 {
212 // Let's check with the UAS if the user is elsewhere
213 m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service");
214 url = m_UserAgentService.LocateUser(toAgentID);
215 }
216
217 // check if we've tried this before..
218 // This is one way to end the recursive loop
219 //
220 if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) ||
221 (previousLocation is string && upd == null && previousLocation.Equals(url))))
222 {
223 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
224 m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url);
225
226 return false;
227 }
228 }
229
230 if (upd != null)
231 {
232 // ok, the user is around somewhere. Let's send back the reply with "success"
233 // even though the IM may still fail. Just don't keep the caller waiting for
234 // the entire time we're trying to deliver the IM
235 return SendIMToRegion(upd, im, toAgentID, foreigner);
236 }
237 else if (url != string.Empty)
238 {
239 // ok, the user is around somewhere. Let's send back the reply with "success"
240 // even though the IM may still fail. Just don't keep the caller waiting for
241 // the entire time we're trying to deliver the IM
242 return ForwardIMToGrid(url, im, toAgentID, foreigner);
243 }
244 else if (firstTime && previousLocation is string && (string)previousLocation != string.Empty)
245 {
246 return ForwardIMToGrid((string)previousLocation, im, toAgentID, foreigner);
247 }
248 else
249 m_log.DebugFormat("[HG IM SERVICE]: Unable to locate user {0}", toAgentID);
250 return false;
251 }
252
253 bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID, bool foreigner)
254 {
255 bool imresult = false;
256 GridRegion reginfo = null;
257 if (!m_RegionCache.TryGetValue(upd.RegionID, out reginfo))
258 {
259 reginfo = m_GridService.GetRegionByUUID(UUID.Zero /*!!!*/, upd.RegionID);
260 if (reginfo != null)
261 m_RegionCache.AddOrUpdate(upd.RegionID, reginfo, CACHE_EXPIRATION_SECONDS);
262 }
263
264 if (reginfo != null)
265 {
266 imresult = InstantMessageServiceConnector.SendInstantMessage(reginfo.ServerURI, im);
267 }
268 else
269 {
270 m_log.DebugFormat("[HG IM SERVICE]: Failed to deliver message to {0}", reginfo.ServerURI);
271 return false;
272 }
273
274 if (imresult)
275 {
276 // IM delivery successful, so store the Agent's location in our local cache.
277 lock (m_UserLocationMap)
278 {
279 if (m_UserLocationMap.ContainsKey(toAgentID))
280 {
281 m_UserLocationMap[toAgentID] = upd;
282 }
283 else
284 {
285 m_UserLocationMap.Add(toAgentID, upd);
286 }
287 }
288 return true;
289 }
290 else
291 {
292 // try again, but lookup user this time.
293 // Warning, this must call the Async version
294 // of this method or we'll be making thousands of threads
295 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
296 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
297
298 // This is recursive!!!!!
299 return TrySendInstantMessage(im, upd, false, foreigner);
300 }
301 }
302
303 bool ForwardIMToGrid(string url, GridInstantMessage im, UUID toAgentID, bool foreigner)
304 {
305 if (InstantMessageServiceConnector.SendInstantMessage(url, im))
306 {
307 // IM delivery successful, so store the Agent's location in our local cache.
308 lock (m_UserLocationMap)
309 {
310 if (m_UserLocationMap.ContainsKey(toAgentID))
311 {
312 m_UserLocationMap[toAgentID] = url;
313 }
314 else
315 {
316 m_UserLocationMap.Add(toAgentID, url);
317 }
318 }
319
320 return true;
321 }
322 else
323 {
324 // try again, but lookup user this time.
325
326 // This is recursive!!!!!
327 return TrySendInstantMessage(im, url, false, foreigner);
328 }
329
330 }
331
332 private bool UndeliveredMessage(GridInstantMessage im)
333 {
334 if (m_RestURL != string.Empty && (im.offline != 0)
335 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
336 {
337 m_log.DebugFormat("[HG IM SERVICE]: Message saved");
338 return SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
339 "POST", m_RestURL + "/SaveMessage/", im);
340
341 }
342
343 else
344 {
345 return false;
346 }
347 }
348 }
349}
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
index 9ee1ae4..4eb61ba 100644
--- a/OpenSim/Services/HypergridService/HGInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -134,6 +134,7 @@ namespace OpenSim.Services.HypergridService
134 134
135 public override InventoryFolderBase GetRootFolder(UUID principalID) 135 public override InventoryFolderBase GetRootFolder(UUID principalID)
136 { 136 {
137 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
137 // Warp! Root folder for travelers 138 // Warp! Root folder for travelers
138 XInventoryFolder[] folders = m_Database.GetFolders( 139 XInventoryFolder[] folders = m_Database.GetFolders(
139 new string[] { "agentID", "folderName"}, 140 new string[] { "agentID", "folderName"},
@@ -171,6 +172,7 @@ namespace OpenSim.Services.HypergridService
171 172
172 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 173 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
173 { 174 {
175 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
174 return GetRootFolder(principalID); 176 return GetRootFolder(principalID);
175 } 177 }
176 178
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 09e785f..ac53583 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -31,10 +31,12 @@ using System.Net;
31using System.Reflection; 31using System.Reflection;
32 32
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends;
34using OpenSim.Services.Connectors.Hypergrid; 35using OpenSim.Services.Connectors.Hypergrid;
35using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
36using GridRegion = OpenSim.Services.Interfaces.GridRegion; 37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37using OpenSim.Server.Base; 38using OpenSim.Server.Base;
39using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38 40
39using OpenMetaverse; 41using OpenMetaverse;
40using log4net; 42using log4net;
@@ -63,19 +65,35 @@ namespace OpenSim.Services.HypergridService
63 protected static IGridService m_GridService; 65 protected static IGridService m_GridService;
64 protected static GatekeeperServiceConnector m_GatekeeperConnector; 66 protected static GatekeeperServiceConnector m_GatekeeperConnector;
65 protected static IGatekeeperService m_GatekeeperService; 67 protected static IGatekeeperService m_GatekeeperService;
68 protected static IFriendsService m_FriendsService;
69 protected static IPresenceService m_PresenceService;
70 protected static IUserAccountService m_UserAccountService;
71 protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule
72 protected static FriendsSimConnector m_FriendsSimConnector; // grid
66 73
67 protected static string m_GridName; 74 protected static string m_GridName;
68 75
69 protected static bool m_BypassClientVerification; 76 protected static bool m_BypassClientVerification;
70 77
71 public UserAgentService(IConfigSource config) 78 public UserAgentService(IConfigSource config) : this(config, null)
72 { 79 {
80 }
81
82 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
83 {
84 // Let's set this always, because we don't know the sequence
85 // of instantiations
86 if (friendsConnector != null)
87 m_FriendsLocalSimConnector = friendsConnector;
88
73 if (!m_Initialized) 89 if (!m_Initialized)
74 { 90 {
75 m_Initialized = true; 91 m_Initialized = true;
76 92
77 m_log.DebugFormat("[HOME USERS SECURITY]: Starting..."); 93 m_log.DebugFormat("[HOME USERS SECURITY]: Starting...");
78 94
95 m_FriendsSimConnector = new FriendsSimConnector();
96
79 IConfig serverConfig = config.Configs["UserAgentService"]; 97 IConfig serverConfig = config.Configs["UserAgentService"];
80 if (serverConfig == null) 98 if (serverConfig == null)
81 throw new Exception(String.Format("No section UserAgentService in config file")); 99 throw new Exception(String.Format("No section UserAgentService in config file"));
@@ -83,6 +101,9 @@ namespace OpenSim.Services.HypergridService
83 string gridService = serverConfig.GetString("GridService", String.Empty); 101 string gridService = serverConfig.GetString("GridService", String.Empty);
84 string gridUserService = serverConfig.GetString("GridUserService", String.Empty); 102 string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
85 string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty); 103 string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty);
104 string friendsService = serverConfig.GetString("FriendsService", String.Empty);
105 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
106 string userAccountService = serverConfig.GetString("UserAccountService", String.Empty);
86 107
87 m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false); 108 m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false);
88 109
@@ -94,6 +115,9 @@ namespace OpenSim.Services.HypergridService
94 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args); 115 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
95 m_GatekeeperConnector = new GatekeeperServiceConnector(); 116 m_GatekeeperConnector = new GatekeeperServiceConnector();
96 m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args); 117 m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args);
118 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(friendsService, args);
119 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
120 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args);
97 121
98 m_GridName = serverConfig.GetString("ExternalName", string.Empty); 122 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
99 if (m_GridName == string.Empty) 123 if (m_GridName == string.Empty)
@@ -155,12 +179,17 @@ namespace OpenSim.Services.HypergridService
155 string myExternalIP = string.Empty; 179 string myExternalIP = string.Empty;
156 string gridName = gatekeeper.ServerURI; 180 string gridName = gatekeeper.ServerURI;
157 181
158 m_log.DebugFormat("[USER AGENT SERVICE]: m_grid - {0}, gn - {1}", m_GridName, gridName); 182 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName);
159 183
160 if (m_GridName == gridName) 184 if (m_GridName == gridName)
161 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); 185 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
162 else 186 else
187 {
163 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason); 188 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
189 if (success)
190 // Report them as nowhere
191 m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero);
192 }
164 193
165 if (!success) 194 if (!success)
166 { 195 {
@@ -169,7 +198,12 @@ namespace OpenSim.Services.HypergridService
169 198
170 // restore the old travel info 199 // restore the old travel info
171 lock (m_TravelingAgents) 200 lock (m_TravelingAgents)
172 m_TravelingAgents[agentCircuit.SessionID] = old; 201 {
202 if (old == null)
203 m_TravelingAgents.Remove(agentCircuit.SessionID);
204 else
205 m_TravelingAgents[agentCircuit.SessionID] = old;
206 }
173 207
174 return false; 208 return false;
175 } 209 }
@@ -179,6 +213,7 @@ namespace OpenSim.Services.HypergridService
179 if (clientIP != null) 213 if (clientIP != null)
180 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString(); 214 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString();
181 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; 215 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
216
182 return true; 217 return true;
183 } 218 }
184 219
@@ -289,6 +324,213 @@ namespace OpenSim.Services.HypergridService
289 return false; 324 return false;
290 } 325 }
291 326
327 public List<UUID> StatusNotification(List<string> friends, UUID foreignUserID, bool online)
328 {
329 if (m_FriendsService == null || m_PresenceService == null)
330 {
331 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
332 return new List<UUID>();
333 }
334
335 List<UUID> localFriendsOnline = new List<UUID>();
336
337 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);
338
339 // First, let's double check that the reported friends are, indeed, friends of that user
340 // And let's check that the secret matches
341 List<string> usersToBeNotified = new List<string>();
342 foreach (string uui in friends)
343 {
344 UUID localUserID;
345 string secret = string.Empty, tmp = string.Empty;
346 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
347 {
348 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
349 foreach (FriendInfo finfo in friendInfos)
350 {
351 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret))
352 {
353 // great!
354 usersToBeNotified.Add(localUserID.ToString());
355 }
356 }
357 }
358 }
359
360 // Now, let's send the notifications
361 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);
362
363 // First, let's send notifications to local users who are online in the home grid
364 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
365 if (friendSessions != null && friendSessions.Length > 0)
366 {
367 PresenceInfo friendSession = null;
368 foreach (PresenceInfo pinfo in friendSessions)
369 if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents
370 {
371 friendSession = pinfo;
372 break;
373 }
374
375 if (friendSession != null)
376 {
377 ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
378 usersToBeNotified.Remove(friendSession.UserID.ToString());
379 UUID id;
380 if (UUID.TryParse(friendSession.UserID, out id))
381 localFriendsOnline.Add(id);
382
383 }
384 }
385
386 // Lastly, let's notify the rest who may be online somewhere else
387 foreach (string user in usersToBeNotified)
388 {
389 UUID id = new UUID(user);
390 if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName)
391 {
392 string url = m_TravelingAgents[id].GridExternalName;
393 // forward
394 m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
395 }
396 }
397
398 // and finally, let's send the online friends
399 if (online)
400 {
401 return localFriendsOnline;
402 }
403 else
404 return new List<UUID>();
405 }
406
407 protected void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online)
408 {
409 UUID userID;
410 if (UUID.TryParse(user, out userID))
411 {
412 if (m_FriendsLocalSimConnector != null)
413 {
414 m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline"));
415 m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online);
416 }
417 else
418 {
419 GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID);
420 if (region != null)
421 {
422 m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline"));
423 m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID, online);
424 }
425 }
426 }
427 }
428
429 public List<UUID> GetOnlineFriends(UUID foreignUserID, List<string> friends)
430 {
431 List<UUID> online = new List<UUID>();
432
433 if (m_FriendsService == null || m_PresenceService == null)
434 {
435 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
436 return online;
437 }
438
439 m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);
440
441 // First, let's double check that the reported friends are, indeed, friends of that user
442 // And let's check that the secret matches and the rights
443 List<string> usersToBeNotified = new List<string>();
444 foreach (string uui in friends)
445 {
446 UUID localUserID;
447 string secret = string.Empty, tmp = string.Empty;
448 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
449 {
450 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
451 foreach (FriendInfo finfo in friendInfos)
452 {
453 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) &&
454 (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
455 {
456 // great!
457 usersToBeNotified.Add(localUserID.ToString());
458 }
459 }
460 }
461 }
462
463 // Now, let's find out their status
464 m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);
465
466 // First, let's send notifications to local users who are online in the home grid
467 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
468 if (friendSessions != null && friendSessions.Length > 0)
469 {
470 foreach (PresenceInfo pi in friendSessions)
471 {
472 UUID presenceID;
473 if (UUID.TryParse(pi.UserID, out presenceID))
474 online.Add(presenceID);
475 }
476 }
477
478 return online;
479 }
480
481 public Dictionary<string, object> GetServerURLs(UUID userID)
482 {
483 if (m_UserAccountService == null)
484 {
485 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing");
486 return new Dictionary<string, object>();
487 }
488 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
489 if (account != null)
490 return account.ServiceURLs;
491
492 return new Dictionary<string, object>();
493 }
494
495 public string LocateUser(UUID userID)
496 {
497 foreach (TravelingAgentInfo t in m_TravelingAgents.Values)
498 {
499 if (t == null)
500 {
501 m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis");
502 continue;
503 }
504 if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName))
505 return t.GridExternalName;
506 }
507
508 return string.Empty;
509 }
510
511 public string GetUUI(UUID userID, UUID targetUserID)
512 {
513 // Let's see if it's a local user
514 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID);
515 if (account != null)
516 return targetUserID.ToString() + ";" + m_GridName + ";" + account.FirstName + " " + account.LastName ;
517
518 // Let's try the list of friends
519 FriendInfo[] friends = m_FriendsService.GetFriends(userID);
520 if (friends != null && friends.Length > 0)
521 {
522 foreach (FriendInfo f in friends)
523 if (f.Friend.StartsWith(targetUserID.ToString()))
524 {
525 // Let's remove the secret
526 UUID id; string tmp = string.Empty, secret = string.Empty;
527 if (Util.ParseUniversalUserIdentifier(f.Friend, out id, out tmp, out tmp, out tmp, out secret))
528 return f.Friend.Replace(secret, "0");
529 }
530 }
531
532 return string.Empty;
533 }
292 } 534 }
293 535
294 class TravelingAgentInfo 536 class TravelingAgentInfo
diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs
index 0ddd5e5..1664f3b 100644
--- a/OpenSim/Services/Interfaces/IFriendsService.cs
+++ b/OpenSim/Services/Interfaces/IFriendsService.cs
@@ -74,7 +74,9 @@ namespace OpenSim.Services.Interfaces
74 public interface IFriendsService 74 public interface IFriendsService
75 { 75 {
76 FriendInfo[] GetFriends(UUID PrincipalID); 76 FriendInfo[] GetFriends(UUID PrincipalID);
77 bool StoreFriend(UUID PrincipalID, string Friend, int flags); 77 FriendInfo[] GetFriends(string PrincipalID);
78 bool StoreFriend(string PrincipalID, string Friend, int flags);
78 bool Delete(UUID PrincipalID, string Friend); 79 bool Delete(UUID PrincipalID, string Friend);
80 bool Delete(string PrincipalID, string Friend);
79 } 81 }
80} 82}
diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index aac8293..220caef 100644
--- a/OpenSim/Services/Interfaces/IGatekeeperService.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -54,9 +54,34 @@ namespace OpenSim.Services.Interfaces
54 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); 54 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
55 void LogoutAgent(UUID userID, UUID sessionID); 55 void LogoutAgent(UUID userID, UUID sessionID);
56 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); 56 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
57 Dictionary<string, object> GetServerURLs(UUID userID);
58
59 string LocateUser(UUID userID);
60 // Tries to get the universal user identifier for the targetUserId
61 // on behalf of the userID
62 string GetUUI(UUID userID, UUID targetUserID);
63
64 // Returns the local friends online
65 List<UUID> StatusNotification(List<string> friends, UUID userID, bool online);
66 //List<UUID> GetOnlineFriends(UUID userID, List<string> friends);
57 67
58 bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); 68 bool AgentIsComingHome(UUID sessionID, string thisGridExternalName);
59 bool VerifyAgent(UUID sessionID, string token); 69 bool VerifyAgent(UUID sessionID, string token);
60 bool VerifyClient(UUID sessionID, string reportedIP); 70 bool VerifyClient(UUID sessionID, string reportedIP);
61 } 71 }
72
73 public interface IInstantMessage
74 {
75 bool IncomingInstantMessage(GridInstantMessage im);
76 bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner);
77 }
78 public interface IFriendsSimConnector
79 {
80 bool StatusNotify(UUID userID, UUID friendID, bool online);
81 }
82
83 public interface IInstantMessageSimConnector
84 {
85 bool SendInstantMessage(GridInstantMessage im);
86 }
62} 87}
diff --git a/OpenSim/Services/Interfaces/IMapService.cs b/OpenSim/Services/Interfaces/IMapImageService.cs
index c70f484..a7b2cf1 100644
--- a/OpenSim/Services/Interfaces/IMapService.cs
+++ b/OpenSim/Services/Interfaces/IMapImageService.cs
@@ -31,8 +31,10 @@ using OpenMetaverse;
31 31
32namespace OpenSim.Services.Interfaces 32namespace OpenSim.Services.Interfaces
33{ 33{
34 public interface IMapService 34 public interface IMapImageService
35 { 35 {
36 List<MapBlockData> GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY); 36 //List<MapBlockData> GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY);
37 bool AddMapTile(int x, int y, byte[] imageData, out string reason);
38 byte[] GetMapTile(string fileName, out string format);
37 } 39 }
38} 40}
diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs
index e543337..73dd06a 100644
--- a/OpenSim/Services/InventoryService/InventoryService.cs
+++ b/OpenSim/Services/InventoryService/InventoryService.cs
@@ -340,6 +340,9 @@ namespace OpenSim.Services.InventoryService
340 List<InventoryItemBase> itemsList = new List<InventoryItemBase>(); 340 List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
341 341
342 itemsList.AddRange(m_Database.getInventoryInFolder(folderID)); 342 itemsList.AddRange(m_Database.getInventoryInFolder(folderID));
343
344// m_log.DebugFormat(
345// "[INVENTORY SERVICE]: Found {0} items in folder {1} for {2}", itemsList.Count, folderID, userID);
343 346
344 return itemsList; 347 return itemsList;
345 } 348 }
@@ -385,8 +388,9 @@ namespace OpenSim.Services.InventoryService
385 // See IInventoryServices 388 // See IInventoryServices
386 public virtual bool AddItem(InventoryItemBase item) 389 public virtual bool AddItem(InventoryItemBase item)
387 { 390 {
388 m_log.DebugFormat( 391// m_log.DebugFormat(
389 "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); 392// "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}",
393// item.Name, item.ID, item.Folder, item.Owner);
390 394
391 m_Database.addInventoryItem(item); 395 m_Database.addInventoryItem(item);
392 396
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 58c59eb..eeab67a 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
40{ 40{
41 public class XInventoryService : ServiceBase, IInventoryService 41 public class XInventoryService : ServiceBase, IInventoryService
42 { 42 {
43// private static readonly ILog m_log = 43 //private static readonly ILog m_log =
44// LogManager.GetLogger( 44 // LogManager.GetLogger(
45// MethodBase.GetCurrentMethod().DeclaringType); 45 // MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 protected IXInventoryData m_Database; 47 protected IXInventoryData m_Database;
48 protected bool m_AllowDelete = true; 48 protected bool m_AllowDelete = true;
@@ -385,8 +385,8 @@ namespace OpenSim.Services.InventoryService
385 385
386 public virtual bool AddItem(InventoryItemBase item) 386 public virtual bool AddItem(InventoryItemBase item)
387 { 387 {
388// m_log.DebugFormat( 388 //m_log.DebugFormat(
389// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); 389 // "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
390 390
391 return m_Database.StoreItem(ConvertFromOpenSim(item)); 391 return m_Database.StoreItem(ConvertFromOpenSim(item));
392 } 392 }
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index f8868f5..82acfbc 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -627,7 +627,19 @@ namespace OpenSim.Services.LLLoginService
627 if (finfo.TheirFlags == -1) 627 if (finfo.TheirFlags == -1)
628 continue; 628 continue;
629 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend); 629 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
630 buddyitem.BuddyID = finfo.Friend; 630 // finfo.Friend may not be a simple uuid
631 UUID friendID = UUID.Zero;
632 if (UUID.TryParse(finfo.Friend, out friendID))
633 buddyitem.BuddyID = finfo.Friend;
634 else
635 {
636 string tmp;
637 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
638 buddyitem.BuddyID = friendID.ToString();
639 else
640 // junk entry
641 continue;
642 }
631 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags; 643 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
632 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags; 644 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
633 buddylistreturn.AddNewBuddy(buddyitem); 645 buddylistreturn.AddNewBuddy(buddyitem);
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index ffed15e..e7dd15e 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -112,6 +112,14 @@ namespace OpenSim.Services.LLLoginService
112 m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); 112 m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
113 m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); 113 m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty);
114 114
115 // Clean up some of these vars
116 if (m_MapTileURL != String.Empty)
117 {
118 m_MapTileURL = m_MapTileURL.Trim();
119 if (!m_MapTileURL.EndsWith("/"))
120 m_MapTileURL = m_MapTileURL + "/";
121 }
122
115 // These are required; the others aren't 123 // These are required; the others aren't
116 if (accountService == string.Empty || authService == string.Empty) 124 if (accountService == string.Empty || authService == string.Empty)
117 throw new Exception("LoginService is missing service specifications"); 125 throw new Exception("LoginService is missing service specifications");
@@ -523,6 +531,7 @@ namespace OpenSim.Services.LLLoginService
523 // free uri form 531 // free uri form
524 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34 532 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
525 where = "url"; 533 where = "url";
534 GridRegion region = null;
526 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$"); 535 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
527 Match uriMatch = reURI.Match(startLocation); 536 Match uriMatch = reURI.Match(startLocation);
528 if (uriMatch == null) 537 if (uriMatch == null)
@@ -553,8 +562,18 @@ namespace OpenSim.Services.LLLoginService
553 } 562 }
554 else 563 else
555 { 564 {
556 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation); 565 m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
557 return null; 566 region = FindAlternativeRegion(scopeID);
567 if (region != null)
568 {
569 where = "safe";
570 return region;
571 }
572 else
573 {
574 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions and no alternative found.", startLocation);
575 return null;
576 }
558 } 577 }
559 } 578 }
560 return regions[0]; 579 return regions[0];
@@ -582,7 +601,8 @@ namespace OpenSim.Services.LLLoginService
582 if (parts.Length > 1) 601 if (parts.Length > 1)
583 UInt32.TryParse(parts[1], out port); 602 UInt32.TryParse(parts[1], out port);
584 603
585 GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper); 604// GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
605 region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
586 return region; 606 return region;
587 } 607 }
588 } 608 }
@@ -811,16 +831,13 @@ namespace OpenSim.Services.LLLoginService
811 // Old style: get the service keys from the DB 831 // Old style: get the service keys from the DB
812 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) 832 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs)
813 { 833 {
814 if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty)) 834 if (kvp.Value != null)
815 {
816 aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty);
817 }
818 else
819 { 835 {
820 aCircuit.ServiceURLs[kvp.Key] = kvp.Value; 836 aCircuit.ServiceURLs[kvp.Key] = kvp.Value;
837
838 if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/"))
839 aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/";
821 } 840 }
822 if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/"))
823 aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/";
824 } 841 }
825 842
826 // New style: service keys start with SRV_; override the previous 843 // New style: service keys start with SRV_; override the previous
@@ -828,16 +845,29 @@ namespace OpenSim.Services.LLLoginService
828 845
829 if (keys.Length > 0) 846 if (keys.Length > 0)
830 { 847 {
848 bool newUrls = false;
831 IEnumerable<string> serviceKeys = keys.Where(value => value.StartsWith("SRV_")); 849 IEnumerable<string> serviceKeys = keys.Where(value => value.StartsWith("SRV_"));
832 foreach (string serviceKey in serviceKeys) 850 foreach (string serviceKey in serviceKeys)
833 { 851 {
834 string keyName = serviceKey.Replace("SRV_", ""); 852 string keyName = serviceKey.Replace("SRV_", "");
835 aCircuit.ServiceURLs[keyName] = m_LoginServerConfig.GetString(serviceKey, string.Empty); 853 string keyValue = m_LoginServerConfig.GetString(serviceKey, string.Empty);
836 if (!aCircuit.ServiceURLs[keyName].ToString().EndsWith("/")) 854 if (!keyValue.EndsWith("/"))
837 aCircuit.ServiceURLs[keyName] = aCircuit.ServiceURLs[keyName] + "/"; 855 keyValue = keyValue + "/";
856
857 if (!account.ServiceURLs.ContainsKey(keyName) || (account.ServiceURLs.ContainsKey(keyName) && account.ServiceURLs[keyName] != keyValue))
858 {
859 account.ServiceURLs[keyName] = keyValue;
860 newUrls = true;
861 }
862 aCircuit.ServiceURLs[keyName] = keyValue;
838 863
839 m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]); 864 m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]);
840 } 865 }
866
867 // The grid operator decided to override the defaults in the
868 // [LoginService] configuration. Let's store the correct ones.
869 if (newUrls)
870 m_UserAccountService.StoreUserAccount(account);
841 } 871 }
842 872
843 } 873 }
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs
new file mode 100644
index 0000000..7e7391c
--- /dev/null
+++ b/OpenSim/Services/MapImageService/MapImageService.cs
@@ -0,0 +1,298 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The design of this map service is based on SimianGrid's PHP-based
28 * map service. See this URL for the original PHP version:
29 * https://github.com/openmetaversefoundation/simiangrid/
30 */
31
32using System;
33using System.Collections.Generic;
34using System.Drawing;
35using System.Drawing.Imaging;
36using System.IO;
37using System.Net;
38using System.Reflection;
39
40using Nini.Config;
41using log4net;
42using OpenMetaverse;
43
44using OpenSim.Framework;
45using OpenSim.Framework.Console;
46using OpenSim.Services.Interfaces;
47
48
49namespace OpenSim.Services.MapImageService
50{
51 public class MapImageService : IMapImageService
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56
57 private const int ZOOM_LEVELS = 8;
58 private const int IMAGE_WIDTH = 256;
59 private const int HALF_WIDTH = 128;
60 private const int JPEG_QUALITY = 80;
61
62 private static string m_TilesStoragePath = "maptiles";
63
64 private static object m_Sync = new object();
65 private static bool m_Initialized = false;
66 private static string m_WaterTileFile = string.Empty;
67 private static Color m_Watercolor = Color.FromArgb(29, 71, 95);
68
69 public MapImageService(IConfigSource config)
70 {
71 if (!m_Initialized)
72 {
73 m_Initialized = true;
74 m_log.Debug("[MAP IMAGE SERVICE]: Starting MapImage service");
75
76 IConfig serviceConfig = config.Configs["MapImageService"];
77 if (serviceConfig != null)
78 {
79 m_TilesStoragePath = serviceConfig.GetString("TilesStoragePath", m_TilesStoragePath);
80 if (!Directory.Exists(m_TilesStoragePath))
81 Directory.CreateDirectory(m_TilesStoragePath);
82
83
84 m_WaterTileFile = Path.Combine(m_TilesStoragePath, "water.jpg");
85 if (!File.Exists(m_WaterTileFile))
86 {
87 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH);
88 FillImage(waterTile, m_Watercolor);
89 waterTile.Save(m_WaterTileFile);
90 }
91 }
92 }
93 }
94
95 #region IMapImageService
96
97 public bool AddMapTile(int x, int y, byte[] imageData, out string reason)
98 {
99 reason = string.Empty;
100 string fileName = GetFileName(1, x, y);
101
102 lock (m_Sync)
103 {
104 try
105 {
106 using (FileStream f = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write))
107 f.Write(imageData, 0, imageData.Length);
108 }
109 catch (Exception e)
110 {
111 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save image file {0}: {1}", fileName, e);
112 reason = e.Message;
113 return false;
114 }
115
116 // Also save in png format?
117
118 // Stitch seven more aggregate tiles together
119 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
120 {
121 // Calculate the width (in full resolution tiles) and bottom-left
122 // corner of the current zoom level
123 int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
124 int x1 = x - (x % width);
125 int y1 = y - (y % width);
126
127 if (!CreateTile(zoomLevel, x1, y1))
128 {
129 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0} at zoom level {1}", fileName, zoomLevel);
130 reason = string.Format("Map tile at zoom level {0} failed", zoomLevel);
131 return false;
132 }
133 }
134 }
135
136 return true;
137 }
138
139 public byte[] GetMapTile(string fileName, out string format)
140 {
141 format = ".jpg";
142 string fullName = Path.Combine(m_TilesStoragePath, fileName);
143 if (File.Exists(fullName))
144 {
145 format = Path.GetExtension(fileName).ToLower();
146 //m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format);
147 return File.ReadAllBytes(fullName);
148 }
149 else if (File.Exists(m_WaterTileFile))
150 {
151 return File.ReadAllBytes(m_WaterTileFile);
152 }
153 else
154 {
155 m_log.DebugFormat("[MAP IMAGE SERVICE]: unable to get file {0}", fileName);
156 return new byte[0];
157 }
158 }
159
160 #endregion
161
162
163 private string GetFileName(uint zoomLevel, int x, int y)
164 {
165 string extension = "jpg";
166 return Path.Combine(m_TilesStoragePath, string.Format("map-{0}-{1}-{2}-objects.{3}", zoomLevel, x, y, extension));
167 }
168
169 private Bitmap GetInputTileImage(string fileName)
170 {
171 try
172 {
173 if (File.Exists(fileName))
174 return new Bitmap(fileName);
175 }
176 catch (Exception e)
177 {
178 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e);
179 }
180
181 return null;
182 }
183
184 private Bitmap GetOutputTileImage(string fileName)
185 {
186 try
187 {
188 if (File.Exists(fileName))
189 return new Bitmap(fileName);
190
191 else
192 {
193 // Create a new output tile with a transparent background
194 Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH, PixelFormat.Format24bppRgb);
195 bm.MakeTransparent();
196 return bm;
197 }
198 }
199 catch (Exception e)
200 {
201 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e);
202 }
203
204 return null;
205 }
206
207 private bool CreateTile(uint zoomLevel, int x, int y)
208 {
209 m_log.DebugFormat("[MAP IMAGE SERVICE]: Create tile for {0} {1}, zoom {2}", x, y, zoomLevel);
210 int prevWidth = (int)Math.Pow(2, (double)zoomLevel - 2);
211 int thisWidth = (int)Math.Pow(2, (double)zoomLevel - 1);
212
213 // Convert x and y to the bottom left tile for this zoom level
214 int xIn = x - (x % prevWidth);
215 int yIn = y - (y % prevWidth);
216
217 // Convert x and y to the bottom left tile for the next zoom level
218 int xOut = x - (x % thisWidth);
219 int yOut = y - (y % thisWidth);
220
221 // Try to open the four input tiles from the previous zoom level
222 Bitmap inputBL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn));
223 Bitmap inputBR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn));
224 Bitmap inputTL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn + prevWidth));
225 Bitmap inputTR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn + prevWidth));
226
227 // Open the output tile (current zoom level)
228 string outputFile = GetFileName(zoomLevel, xOut, yOut);
229 Bitmap output = GetOutputTileImage(outputFile);
230 if (output == null)
231 return false;
232 FillImage(output, m_Watercolor);
233
234 if (inputBL != null)
235 {
236 ImageCopyResampled(output, inputBL, 0, HALF_WIDTH, 0, 0);
237 inputBL.Dispose();
238 }
239 if (inputBR != null)
240 {
241 ImageCopyResampled(output, inputBR, HALF_WIDTH, HALF_WIDTH, 0, 0);
242 inputBR.Dispose();
243 }
244 if (inputTL != null)
245 {
246 ImageCopyResampled(output, inputTL, 0, 0, 0, 0);
247 inputTL.Dispose();
248 }
249 if (inputTR != null)
250 {
251 ImageCopyResampled(output, inputTR, HALF_WIDTH, 0, 0, 0);
252 inputTR.Dispose();
253 }
254
255 // Write the modified output
256 try
257 {
258 using (Bitmap final = new Bitmap(output))
259 {
260 output.Dispose();
261 final.Save(outputFile, ImageFormat.Jpeg);
262 }
263 }
264 catch (Exception e)
265 {
266 m_log.WarnFormat("[MAP IMAGE SERVICE]: Oops on saving {0} {1}", outputFile, e);
267 }
268
269 // Save also as png?
270
271 return true;
272 }
273
274 #region Image utilities
275
276 private void FillImage(Bitmap bm, Color c)
277 {
278 for (int x = 0; x < bm.Width; x++)
279 for (int y = 0; y < bm.Height; y++)
280 bm.SetPixel(x, y, c);
281 }
282
283 private void ImageCopyResampled(Bitmap output, Bitmap input, int destX, int destY, int srcX, int srcY)
284 {
285 int resamplingRateX = 2; // (input.Width - srcX) / (output.Width - destX);
286 int resamplingRateY = 2; // (input.Height - srcY) / (output.Height - destY);
287
288 for (int x = destX; x < destX + HALF_WIDTH; x++)
289 for (int y = destY; y < destY + HALF_WIDTH; y++)
290 {
291 Color p = input.GetPixel(srcX + (x - destX) * resamplingRateX, srcY + (y - destY) * resamplingRateY);
292 output.SetPixel(x, y, p);
293 }
294 }
295
296 #endregion
297 }
298}