aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-11-25 15:19:00 +0000
committerJustin Clarke Casey2008-11-25 15:19:00 +0000
commite187972377c19bdd85093677c4c54034e4f9196e (patch)
treecc1bb5f003628b018b823eafc9ee0a67f98df31c /OpenSim/Region
parent* Adding some virtual hooks and making some privaets protected for great just... (diff)
downloadopensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.zip
opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.tar.gz
opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.tar.bz2
opensim-SC_OLD-e187972377c19bdd85093677c4c54034e4f9196e.tar.xz
* Apply http://opensimulator.org/mantis/view.php?id=2640
* This is Diva's hypergrid patch, as perviously discussed on the opensim-dev mailing list * Applied some minor prebuild.xml jiggling to resolve a dependency issue * Thanks Diva!
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Application/Application.cs10
-rw-r--r--OpenSim/Region/Application/HGOpenSimNode.cs184
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGCommunicationsGridMode.cs82
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGCommunicationsStandalone.cs59
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGGridServices.cs1294
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGGridServicesGridMode.cs285
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs928
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs451
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGUserServices.cs267
-rw-r--r--OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs199
-rw-r--r--OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs315
-rw-r--r--OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs178
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs377
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs152
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs78
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs263
16 files changed, 5121 insertions, 1 deletions
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 09d821f..c891549 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -76,11 +76,13 @@ namespace OpenSim
76 configSource.AddSwitch("Startup", "gridmode"); 76 configSource.AddSwitch("Startup", "gridmode");
77 configSource.AddSwitch("Startup", "physics"); 77 configSource.AddSwitch("Startup", "physics");
78 configSource.AddSwitch("Startup", "useexecutepath"); 78 configSource.AddSwitch("Startup", "useexecutepath");
79 configSource.AddSwitch("Startup", "hypergrid");
79 80
80 configSource.AddConfig("StandAlone"); 81 configSource.AddConfig("StandAlone");
81 configSource.AddConfig("Network"); 82 configSource.AddConfig("Network");
82 83
83 bool background = configSource.Configs["Startup"].GetBoolean("background", false); 84 bool background = configSource.Configs["Startup"].GetBoolean("background", false);
85 bool hgrid = configSource.Configs["Startup"].GetBoolean("hypergrid", false);
84 86
85 if (background) 87 if (background)
86 { 88 {
@@ -89,13 +91,19 @@ namespace OpenSim
89 } 91 }
90 else 92 else
91 { 93 {
92 OpenSimBase sim = new OpenSim(configSource); 94 OpenSimBase sim = null;
95 if (hgrid)
96 sim = new HGOpenSimNode(configSource);
97 else
98 sim = new OpenSim(configSource);
99
93 sim.Startup(); 100 sim.Startup();
94 101
95 while (true) 102 while (true)
96 { 103 {
97 MainConsole.Instance.Prompt(); 104 MainConsole.Instance.Prompt();
98 } 105 }
106
99 } 107 }
100 } 108 }
101 109
diff --git a/OpenSim/Region/Application/HGOpenSimNode.cs b/OpenSim/Region/Application/HGOpenSimNode.cs
new file mode 100644
index 0000000..8bb93a6
--- /dev/null
+++ b/OpenSim/Region/Application/HGOpenSimNode.cs
@@ -0,0 +1,184 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.IO;
5using System.Net;
6using System.Reflection;
7using log4net;
8using Nini.Config;
9using OpenSim.Framework;
10using OpenSim.Framework.Console;
11using OpenSim.Framework.Servers;
12using OpenSim.Framework.Statistics;
13using OpenSim.Region.ClientStack;
14using OpenSim.Framework.Communications;
15using OpenSim.Framework.Communications.Cache;
16using OpenSim.Region.Communications.Local;
17using OpenSim.Region.Communications.Hypergrid;
18using OpenSim.Region.Environment;
19using OpenSim.Region.Environment.Interfaces;
20using OpenSim.Region.Environment.Scenes;
21using OpenSim.Region.Environment.Scenes.Hypergrid;
22
23using Timer = System.Timers.Timer;
24
25namespace OpenSim
26{
27 public class HGOpenSimNode : OpenSim
28 {
29 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
30 private IHyperlink HGServices = null;
31
32 public HGOpenSimNode(IConfigSource configSource) : base(configSource)
33 {
34 }
35
36
37 /// <summary>
38 /// Performs initialisation of the scene, such as loading configuration from disk.
39 /// </summary>
40 protected override void StartupSpecific()
41 {
42 m_log.Info("====================================================================");
43 m_log.Info("=================== STARTING HYPERGRID NODE ========================");
44 m_log.Info("====================================================================");
45
46 base.StartupSpecific();
47 }
48
49
50 protected override void InitialiseStandaloneServices(LibraryRootFolder libraryRootFolder)
51 {
52 // Standalone mode
53
54 HGInventoryService inventoryService = new HGInventoryService(m_networkServersInfo.InventoryURL, null, false);
55 inventoryService.AddPlugin(m_configSettings.StandaloneInventoryPlugin, m_configSettings.StandaloneInventorySource);
56
57 LocalUserServices userService =
58 new LocalUserServices(m_networkServersInfo, m_networkServersInfo.DefaultHomeLocX,
59 m_networkServersInfo.DefaultHomeLocY, inventoryService);
60 userService.AddPlugin(m_configSettings.StandaloneUserPlugin, m_configSettings.StandaloneUserSource);
61
62 //LocalBackEndServices backendService = new LocalBackEndServices();
63 HGGridServicesStandalone gridService = new HGGridServicesStandalone(m_networkServersInfo, m_httpServer, m_assetCache, m_sceneManager);
64
65 LocalLoginService loginService =
66 new LocalLoginService(
67 userService, m_configSettings.StandaloneWelcomeMessage, inventoryService, gridService.LocalBackend, m_networkServersInfo,
68 m_configSettings.StandaloneAuthenticate, libraryRootFolder);
69
70
71 m_commsManager = new HGCommunicationsStandalone(m_networkServersInfo, m_httpServer, m_assetCache,
72 userService, userService, inventoryService, gridService, gridService, userService, libraryRootFolder, m_configSettings.DumpAssetsToFile);
73
74 inventoryService.UserProfileCache = m_commsManager.UserProfileCacheService;
75 HGServices = gridService;
76
77 // set up XMLRPC handler for client's initial login request message
78 m_httpServer.AddXmlRPCHandler("login_to_simulator", loginService.XmlRpcLoginMethod);
79
80 // provides the web form login
81 m_httpServer.AddHTTPHandler("login", loginService.ProcessHTMLLogin);
82
83 // Provides the LLSD login
84 m_httpServer.SetDefaultLLSDHandler(loginService.LLSDLoginMethod);
85
86 // provide grid info
87 // m_gridInfoService = new GridInfoService(m_config.Source.Configs["Startup"].GetString("inifile", Path.Combine(Util.configDir(), "OpenSim.ini")));
88 m_gridInfoService = new GridInfoService(m_config.Source);
89 m_httpServer.AddXmlRPCHandler("get_grid_info", m_gridInfoService.XmlRpcGridInfoMethod);
90 m_httpServer.AddStreamHandler(new RestStreamHandler("GET", "/get_grid_info", m_gridInfoService.RestGetGridInfoMethod));
91 }
92
93 protected override void InitialiseGridServices(LibraryRootFolder libraryRootFolder)
94 {
95 m_commsManager = new HGCommunicationsGridMode(m_networkServersInfo, m_httpServer, m_assetCache, m_sceneManager, libraryRootFolder);
96
97 HGServices = ((HGCommunicationsGridMode)m_commsManager).HGServices;
98
99 m_httpServer.AddStreamHandler(new SimStatusHandler());
100 }
101
102 protected override Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager,
103 AgentCircuitManager circuitManager)
104 {
105 HGSceneCommunicationService sceneGridService = new HGSceneCommunicationService(m_commsManager, HGServices);
106 return
107 new HGScene(regionInfo, circuitManager, m_commsManager, sceneGridService, m_assetCache,
108 storageManager, m_httpServer,
109 m_moduleLoader, m_configSettings.DumpAssetsToFile, m_configSettings.PhysicalPrim, m_configSettings.See_into_region_from_neighbor, m_config.Source,
110 m_version);
111 }
112
113 public override void RunCmd(string command, string[] cmdparams)
114 {
115 if (command.Equals("link-region"))
116 {
117 // link-region <Xloc> <Yloc> <HostName> <HttpPort> <LocalName>
118 if (cmdparams.Length < 4)
119 {
120 LinkRegionCmdUsage();
121 return;
122 }
123
124 RegionInfo regInfo = new RegionInfo();
125 uint xloc, yloc;
126 uint externalPort;
127 try
128 {
129 xloc = Convert.ToUInt32(cmdparams[0]);
130 yloc = Convert.ToUInt32(cmdparams[1]);
131 externalPort = Convert.ToUInt32(cmdparams[3]);
132 //internalPort = Convert.ToUInt32(cmdparams[4]);
133 //remotingPort = Convert.ToUInt32(cmdparams[5]);
134 }
135 catch (Exception e)
136 {
137 m_log.Warn("[HGrid] Wrong format for link-region command: " + e.Message);
138 LinkRegionCmdUsage();
139 return;
140 }
141 regInfo.RegionLocX = xloc;
142 regInfo.RegionLocY = yloc;
143 regInfo.ExternalHostName = cmdparams[2];
144 regInfo.HttpPort = externalPort;
145 //regInfo.RemotingPort = remotingPort;
146 try
147 {
148 regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0);
149 }
150 catch (Exception e)
151 {
152 m_log.Warn("[HGrid] Wrong format for link-region command: " + e.Message);
153 LinkRegionCmdUsage();
154 return;
155 }
156 regInfo.RemotingAddress = regInfo.ExternalEndPoint.Address.ToString();
157
158 // Finally, link it
159 try
160 {
161 m_sceneManager.CurrentOrFirstScene.CommsManager.GridService.RegisterRegion(regInfo);
162 }
163 catch (Exception e)
164 {
165 m_log.Warn("[HGrid] Unable to link region: " + e.StackTrace);
166 }
167 if (cmdparams.Length >= 5)
168 {
169 regInfo.RegionName = "";
170 for (int i = 4; i < cmdparams.Length; i++)
171 regInfo.RegionName += cmdparams[i] + " ";
172 }
173 }
174
175 base.RunCmd(command, cmdparams);
176
177 }
178
179 private void LinkRegionCmdUsage()
180 {
181 Console.WriteLine("Usage: link-region <Xloc> <Yloc> <HostName> <HttpPort> [<LocalName>]");
182 }
183 }
184}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGCommunicationsGridMode.cs b/OpenSim/Region/Communications/Hypergrid/HGCommunicationsGridMode.cs
new file mode 100644
index 0000000..9672df3
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGCommunicationsGridMode.cs
@@ -0,0 +1,82 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28using System.Reflection;
29
30using log4net;
31
32using OpenSim.Framework;
33using OpenSim.Framework.Communications;
34using OpenSim.Framework.Communications.Cache;
35using OpenSim.Region.Communications.OGS1;
36using OpenSim.Framework.Servers;
37using OpenSim.Region.Environment.Scenes;
38
39namespace OpenSim.Region.Communications.Hypergrid
40{
41 public class HGCommunicationsGridMode : CommunicationsManager // CommunicationsOGS1
42 {
43 private static readonly ILog m_log
44 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 IHyperlink m_osw = null;
47 public IHyperlink HGServices
48 {
49 get { return m_osw; }
50 }
51
52 public HGCommunicationsGridMode(
53 NetworkServersInfo serversInfo, BaseHttpServer httpServer,
54 AssetCache assetCache, SceneManager sman, LibraryRootFolder libraryRootFolder)
55 : base(serversInfo, httpServer, assetCache, false, libraryRootFolder)
56 {
57
58 // From constructor at CommunicationsOGS1
59 HGGridServices gridInterComms = new HGGridServicesGridMode(serversInfo, httpServer, assetCache, sman, m_userProfileCacheService);
60 m_gridService = gridInterComms;
61 m_interRegion = gridInterComms;
62 m_osw = gridInterComms;
63
64 // The HG InventoryService always uses secure handlers
65 HGInventoryService invService = new HGInventoryService(serversInfo.InventoryURL, this.m_userProfileCacheService, true);
66 AddSecureInventoryService(invService);
67 m_defaultInventoryHost = invService.Host;
68 if (SecureInventoryService != null)
69 m_log.Info("[HG] SecureInventoryService.");
70 else
71 m_log.Info("[HG] Non-secureInventoryService.");
72
73
74 HGUserServices userServices = new HGUserServices(this);
75 m_userService = userServices;
76 m_messageService = userServices;
77 m_avatarService = (IAvatarService)m_userService;
78
79 }
80
81 }
82}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGCommunicationsStandalone.cs b/OpenSim/Region/Communications/Hypergrid/HGCommunicationsStandalone.cs
new file mode 100644
index 0000000..2868b77
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGCommunicationsStandalone.cs
@@ -0,0 +1,59 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29
30using OpenSim.Framework;
31using OpenSim.Framework.Communications;
32using OpenSim.Framework.Communications.Cache;
33using OpenSim.Region.Communications.Local;
34using OpenSim.Framework.Servers;
35
36namespace OpenSim.Region.Communications.Hypergrid
37{
38 public class HGCommunicationsStandalone : CommunicationsLocal
39 {
40 public HGCommunicationsStandalone(
41 NetworkServersInfo serversInfo,
42 BaseHttpServer httpServer,
43 AssetCache assetCache,
44 IUserService userService,
45 IUserServiceAdmin userServiceAdmin,
46 LocalInventoryService inventoryService,
47 IInterRegionCommunications interRegionService,
48 HGGridServices gridService, IMessagingService messageService, LibraryRootFolder libraryRootFolder, bool dumpAssetsToFile)
49 : base(serversInfo, httpServer, assetCache, userService, userServiceAdmin, inventoryService, interRegionService, gridService, messageService, libraryRootFolder, dumpAssetsToFile)
50 {
51 gridService.UserProfileCache = m_userProfileCacheService;
52 m_assetCache = assetCache;
53 // Let's swap to always be secure access to inventory
54 AddSecureInventoryService((ISecureInventoryService)inventoryService);
55 m_inventoryServices = null;
56 }
57
58 }
59}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs
new file mode 100644
index 0000000..5433e41
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGGridServices.cs
@@ -0,0 +1,1294 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29
30using System;
31using System.Collections;
32using System.Collections.Generic;
33using System.Drawing;
34using System.Drawing.Drawing2D;
35using System.Drawing.Imaging;
36using System.IO;
37using System.Net;
38using System.Net.Sockets;
39using System.Reflection;
40using System.Runtime.Remoting;
41using System.Runtime.Remoting.Channels;
42using System.Runtime.Remoting.Channels.Tcp;
43using System.Security.Authentication;
44using System.Threading;
45using OpenMetaverse;
46using OpenMetaverse.Imaging;
47using log4net;
48using Nwc.XmlRpc;
49using OpenSim.Framework;
50using OpenSim.Framework.Communications;
51using OpenSim.Framework.Communications.Cache;
52using OpenSim.Framework.Servers;
53using OpenSim.Region.Communications.Local;
54using OpenSim.Region.Communications.OGS1;
55using OpenSim.Region.Environment.Modules.Framework;
56using OpenSim.Region.Environment.Scenes;
57using OpenSim.Region.Interfaces;
58
59namespace OpenSim.Region.Communications.Hypergrid
60{
61 /// <summary>
62 /// This class encapsulates the main hypergrid functions related to creating and managing
63 /// hyperlinks, as well as processing all the inter-region comms between a region and
64 /// an hyperlinked region.
65 /// </summary>
66 public class HGGridServices : IGridServices, IInterRegionCommunications, IHyperlink
67 {
68 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
69
70
71 public BaseHttpServer httpListener;
72 public NetworkServersInfo serversInfo;
73 public BaseHttpServer httpServer;
74
75 protected List<RegionInfo> m_regionsOnInstance = new List<RegionInfo>();
76
77 // Hyperlink regions are hyperlinks on the map
78 protected List<RegionInfo> m_hyperlinkRegions = new List<RegionInfo>();
79
80 // Known regions are home regions of visiting foreign users.
81 // They are not on the map as static hyperlinks. They are dynamic hyperlinks, they go away when
82 // the visitor goes away. They are mapped to X=0 on the map.
83 // This is key-ed on agent ID
84 protected Dictionary<UUID, RegionInfo> m_knownRegions = new Dictionary<UUID, RegionInfo>();
85
86 protected AssetCache m_assetcache;
87 protected UserProfileCacheService m_userProfileCache;
88 protected SceneManager m_sceneman;
89
90 private Dictionary<string, string> m_queuedGridSettings = new Dictionary<string, string>();
91
92 public virtual string gdebugRegionName
93 {
94 get { return "Override me"; }
95 set { ; }
96 }
97
98 public string rdebugRegionName
99 {
100 get { return _rdebugRegionName; }
101 set { _rdebugRegionName = value; }
102 }
103 private string _rdebugRegionName = String.Empty;
104
105 public virtual bool RegionLoginsEnabled
106 {
107 get { return true; }
108 set { ; }
109 }
110
111 public UserProfileCacheService UserProfileCache
112 {
113 set { m_userProfileCache = value; }
114 }
115
116 /// <summary>
117 /// Contructor. Adds "expect_hg_user" and "check" xmlrpc method handlers
118 /// </summary>
119 /// <param name="servers_info"></param>
120 /// <param name="httpServe"></param>
121 public HGGridServices(NetworkServersInfo servers_info, BaseHttpServer httpServe, AssetCache asscache, SceneManager sman)
122 {
123 serversInfo = servers_info;
124 httpServer = httpServe;
125 m_assetcache = asscache;
126 m_sceneman = sman;
127
128 httpServer.AddXmlRPCHandler("link_region", LinkRegionRequest);
129 httpServer.AddXmlRPCHandler("expect_hg_user", ExpectHGUser);
130
131 HGNetworkServersInfo.Init(servers_info.AssetURL, servers_info.InventoryURL, servers_info.UserURL);
132 }
133
134 // see IGridServices
135 public virtual RegionCommsListener RegisterRegion(RegionInfo regionInfo)
136 {
137 // Region doesn't exist here. Trying to link remote region
138
139 m_log.Info("[HGrid]: Linking remote region " + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort );
140 regionInfo.RegionID = LinkRegion(regionInfo); // UUID.Random();
141 if (!regionInfo.RegionID.Equals(UUID.Zero))
142 {
143 m_hyperlinkRegions.Add(regionInfo);
144 m_log.Info("[HGrid]: Successfully linked to region_uuid " + regionInfo.RegionID);
145
146 //Try get the map image
147 GetMapImage(regionInfo);
148 }
149 else
150 {
151 m_log.Info("[HGrid]: No such region " + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "(" + regionInfo.InternalEndPoint.Port + ")");
152 }
153 // Note that these remote regions aren't registered in localBackend, so return null, no local listeners
154 return null;
155 }
156
157 // see IGridServices
158 public virtual bool DeregisterRegion(RegionInfo regionInfo)
159 {
160 if (m_hyperlinkRegions.Contains(regionInfo))
161 {
162 m_hyperlinkRegions.Remove(regionInfo);
163 return true;
164 }
165 foreach (KeyValuePair<UUID, RegionInfo> kvp in m_knownRegions)
166 {
167 if (kvp.Value == regionInfo)
168 {
169 m_knownRegions.Remove(kvp.Key);
170 return true;
171 }
172 }
173 return false;
174 }
175
176 public virtual Dictionary<string, string> GetGridSettings()
177 {
178 Dictionary<string, string> returnGridSettings = new Dictionary<string, string>();
179 lock (m_queuedGridSettings)
180 {
181 foreach (string Dictkey in m_queuedGridSettings.Keys)
182 {
183 returnGridSettings.Add(Dictkey, m_queuedGridSettings[Dictkey]);
184 }
185
186 m_queuedGridSettings.Clear();
187 }
188
189 return returnGridSettings;
190 }
191
192 // see IGridServices
193 public virtual List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
194 {
195 List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
196 foreach (RegionInfo reg in m_hyperlinkRegions)
197 {
198 if (reg.RegionLocX != x || reg.RegionLocY != y)
199 {
200 //Console.WriteLine("CommsManager- RequestNeighbours() - found a different region in list, checking location");
201 if ((reg.RegionLocX > (x - 2)) && (reg.RegionLocX < (x + 2)))
202 {
203 if ((reg.RegionLocY > (y - 2)) && (reg.RegionLocY < (y + 2)))
204 {
205 neighbours.Add(reg);
206 }
207 }
208 }
209 }
210
211 return neighbours;
212 }
213
214 /// <summary>
215 /// Request information about a region.
216 /// </summary>
217 /// <param name="regionHandle"></param>
218 /// <returns>
219 /// null on a failure to contact or get a response from the grid server
220 /// FIXME: Might be nicer to return a proper exception here since we could inform the client more about the
221 /// nature of the faiulre.
222 /// </returns>
223 public virtual RegionInfo RequestNeighbourInfo(UUID Region_UUID)
224 {
225 foreach (RegionInfo info in m_hyperlinkRegions)
226 {
227 if (info.RegionID == Region_UUID) return info;
228 }
229
230 // I don't trust region uuids to be unique...
231 //foreach (RegionInfo info in m_knownRegions.Values)
232 //{
233 // if (info.RegionID == Region_UUID) return info;
234 //}
235
236 return null;
237 }
238
239 /// <summary>
240 /// Request information about a region.
241 /// </summary>
242 /// <param name="regionHandle"></param>
243 /// <returns></returns>
244 public virtual RegionInfo RequestNeighbourInfo(ulong regionHandle)
245 {
246 //Console.WriteLine("RequestNeighbourInfo for " + regionHandle);
247 foreach (RegionInfo info in m_hyperlinkRegions)
248 {
249 //Console.WriteLine(" .. " + info.RegionHandle);
250 if (info.RegionHandle == regionHandle) return info;
251 }
252
253 foreach (RegionInfo info in m_knownRegions.Values)
254 {
255 if (info.RegionHandle == regionHandle)
256 {
257 //Console.WriteLine("XXX------ Found known region " + info.RegionHandle);
258 return info;
259 }
260 }
261
262 return null;
263 }
264
265 public virtual RegionInfo RequestClosestRegion(string regionName)
266 {
267 foreach (RegionInfo info in m_hyperlinkRegions)
268 {
269 if (info.RegionName == regionName) return info;
270 }
271
272 return null;
273 }
274
275 /// <summary>
276 ///
277 /// </summary>
278 /// <param name="minX"></param>
279 /// <param name="minY"></param>
280 /// <param name="maxX"></param>
281 /// <param name="maxY"></param>
282 /// <returns></returns>
283 public virtual List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
284 {
285 List<MapBlockData> neighbours = new List<MapBlockData>();
286
287 foreach (RegionInfo regInfo in m_hyperlinkRegions)
288 {
289 if (((regInfo.RegionLocX >= minX) && (regInfo.RegionLocX <= maxX)) &&
290 ((regInfo.RegionLocY >= minY) && (regInfo.RegionLocY <= maxY)))
291 {
292 MapBlockData map = new MapBlockData();
293 map.Name = regInfo.RegionName;
294 map.X = (ushort)regInfo.RegionLocX;
295 map.Y = (ushort)regInfo.RegionLocY;
296 map.WaterHeight = (byte)regInfo.RegionSettings.WaterHeight;
297 map.MapImageId = regInfo.RegionSettings.TerrainImageID;
298// Console.WriteLine("ImgID: " + map.MapImageId);
299 map.Agents = 1;
300 map.RegionFlags = 72458694;
301 map.Access = 13;
302 neighbours.Add(map);
303 }
304 }
305
306 return neighbours;
307 }
308
309
310 protected virtual void GetMapImage(RegionInfo info)
311 {
312 try
313 {
314 string regionimage = "regionImage" + info.RegionID.ToString();
315 regionimage = regionimage.Replace("-", "");
316
317 WebClient c = new WebClient();
318 string uri = "http://" + info.ExternalHostName + ":" + info.HttpPort + "/index.php?method=" + regionimage;
319 //Console.WriteLine("JPEG: " + uri);
320 c.DownloadFile(uri, info.RegionID.ToString() + ".jpg");
321 Bitmap m = new Bitmap(info.RegionID.ToString() + ".jpg");
322 //Console.WriteLine("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
323 byte[] imageData = OpenJPEG.EncodeFromImage(m, true);
324 AssetBase ass = new AssetBase(UUID.Random(), "region " + info.RegionID.ToString());
325 info.RegionSettings.TerrainImageID = ass.FullID;
326 ass.Type = (int)AssetType.Texture;
327 ass.Temporary = false;
328 //imageData.CopyTo(ass.Data, 0);
329 ass.Data = imageData;
330 m_assetcache.AddAsset(ass);
331
332 }
333 catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
334 {
335 Console.WriteLine("Failed getting/storing map image: " + e);
336 }
337 }
338
339 // A little ugly, since this code is exactly the same as OSG1's, and we're already
340 // calling that for when the region in in grid mode... (for the grid regions)
341 //
342 public virtual LandData RequestLandData (ulong regionHandle, uint x, uint y)
343 {
344 m_log.DebugFormat("[HGrid]: requests land data in {0}, at {1}, {2}",
345 regionHandle, x, y);
346
347 // Remote region
348
349 Hashtable hash = new Hashtable();
350 hash["region_handle"] = regionHandle.ToString();
351 hash["x"] = x.ToString();
352 hash["y"] = y.ToString();
353
354 IList paramList = new ArrayList();
355 paramList.Add(hash);
356 LandData landData = null;
357
358 try
359 {
360 RegionInfo info = RequestNeighbourInfo(regionHandle);
361 if (info != null) // just to be sure
362 {
363 XmlRpcRequest request = new XmlRpcRequest("land_data", paramList);
364 string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
365 XmlRpcResponse response = request.Send(uri, 10000);
366 if (response.IsFault)
367 {
368 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
369 }
370 else
371 {
372 hash = (Hashtable)response.Value;
373 try
374 {
375 landData = new LandData();
376 landData.AABBMax = Vector3.Parse((string)hash["AABBMax"]);
377 landData.AABBMin = Vector3.Parse((string)hash["AABBMin"]);
378 landData.Area = Convert.ToInt32(hash["Area"]);
379 landData.AuctionID = Convert.ToUInt32(hash["AuctionID"]);
380 landData.Description = (string)hash["Description"];
381 landData.Flags = Convert.ToUInt32(hash["Flags"]);
382 landData.GlobalID = new UUID((string)hash["GlobalID"]);
383 landData.Name = (string)hash["Name"];
384 landData.OwnerID = new UUID((string)hash["OwnerID"]);
385 landData.SalePrice = Convert.ToInt32(hash["SalePrice"]);
386 landData.SnapshotID = new UUID((string)hash["SnapshotID"]);
387 landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]);
388 m_log.DebugFormat("[HGrid]: Got land data for parcel {0}", landData.Name);
389 }
390 catch (Exception e)
391 {
392 m_log.Error("[HGrid]: Got exception while parsing land-data:", e);
393 }
394 }
395 }
396 else m_log.WarnFormat("[HGrid]: Couldn't find region with handle {0}", regionHandle);
397 }
398 catch (Exception e)
399 {
400 m_log.ErrorFormat("[HGrid]: Couldn't contact region {0}: {1}", regionHandle, e);
401 }
402
403 return landData;
404 }
405
406 // Grid Request Processing
407 public virtual List<RegionInfo> RequestNamedRegions (string name, int maxNumber)
408 {
409 List<RegionInfo> infos = new List<RegionInfo>();
410 foreach (RegionInfo info in m_hyperlinkRegions)
411 {
412 if (info.RegionName.ToLower().Contains(name))
413 {
414 infos.Add(info);
415 }
416 }
417 return infos;
418 }
419
420
421 private UUID LinkRegion(RegionInfo info)
422 {
423 UUID uuid = UUID.Zero;
424
425 Hashtable hash = new Hashtable();
426 hash["region_name"] = info.RegionName;
427
428 IList paramList = new ArrayList();
429 paramList.Add(hash);
430
431 XmlRpcRequest request = new XmlRpcRequest("link_region", paramList);
432 string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
433 m_log.Debug("[HGrid]: Linking to " + uri);
434 XmlRpcResponse response = request.Send(uri, 10000);
435 if (response.IsFault)
436 {
437 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
438 }
439 else
440 {
441 hash = (Hashtable)response.Value;
442 //foreach (Object o in hash)
443 // Console.WriteLine(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
444 try
445 {
446 UUID.TryParse((string)hash["uuid"], out uuid);
447 info.RegionID = uuid;
448 if ((string)hash["handle"] != null)
449 {
450 info.regionSecret = (string)hash["handle"];
451 //Console.WriteLine(">> HERE: " + info.regionSecret);
452 }
453 if (hash["region_image"] != null)
454 {
455 UUID img = UUID.Zero;
456 UUID.TryParse((string)hash["region_image"], out img);
457 info.RegionSettings.TerrainImageID = img;
458 }
459 if (hash["region_name"] != null)
460 {
461 info.RegionName = (string)hash["region_name"];
462 }
463 if (hash["internal_port"] != null)
464 {
465 int port = Convert.ToInt32((string)hash["internal_port"]);
466 info.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
467 //Console.WriteLine(">> " + info.InternalEndPoint.ToString());
468 }
469 if (hash["remoting_port"] != null)
470 {
471 info.RemotingPort = Convert.ToUInt32(hash["remoting_port"]);
472 //Console.WriteLine(">> " + info.RemotingPort);
473 }
474
475 }
476 catch (Exception e)
477 {
478 m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace);
479 }
480 }
481 return uuid;
482 }
483
484 /// <summary>
485 /// Someone wants to link to us
486 /// </summary>
487 /// <param name="request"></param>
488 /// <returns></returns>
489 public XmlRpcResponse LinkRegionRequest(XmlRpcRequest request)
490 {
491 Hashtable requestData = (Hashtable)request.Params[0];
492 //string host = (string)requestData["host"];
493 //string portstr = (string)requestData["port"];
494 string name = (string)requestData["region_name"];
495
496 m_log.DebugFormat("[HGrid]: Hyperlink request");
497
498
499 RegionInfo regInfo = null;
500 foreach (RegionInfo r in m_regionsOnInstance)
501 {
502 if ((r.RegionName != null) && (name != null) && (r.RegionName.ToLower() == name.ToLower()))
503 {
504 regInfo = r;
505 break;
506 }
507 }
508
509 if (regInfo == null)
510 regInfo = m_regionsOnInstance[0]; // Send out the first region
511
512 Hashtable hash = new Hashtable();
513 hash["uuid"] = regInfo.RegionID.ToString();
514 hash["handle"] = regInfo.RegionHandle.ToString();
515 //Console.WriteLine(">> Here " + regInfo.RegionHandle);
516 hash["region_image"] = regInfo.RegionSettings.TerrainImageID.ToString();
517 hash["region_name"] = regInfo.RegionName;
518 hash["internal_port"] = regInfo.InternalEndPoint.Port.ToString();
519 hash["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString();
520 //Console.WriteLine(">> Here: " + regInfo.InternalEndPoint.Port);
521
522
523 XmlRpcResponse response = new XmlRpcResponse();
524 response.Value = hash;
525 return response;
526 }
527
528 public bool InformRegionOfUser(RegionInfo regInfo, AgentCircuitData agentData)
529 {
530 ulong regionHandle = regInfo.RegionHandle;
531 try
532 {
533 regionHandle = Convert.ToUInt64(regInfo.regionSecret);
534 m_log.Info("[HGrid]: InformRegionOfUser: Remote hyperlinked region " + regInfo.regionSecret);
535 }
536 catch
537 {
538 m_log.Info("[HGrid]: InformRegionOfUser: Local grid region " + regInfo.regionSecret);
539 }
540
541 string capsPath = agentData.CapsPath;
542 Hashtable loginParams = new Hashtable();
543 loginParams["session_id"] = agentData.SessionID.ToString();
544 loginParams["secure_session_id"] = agentData.SecureSessionID.ToString();
545
546 loginParams["firstname"] = agentData.firstname;
547 loginParams["lastname"] = agentData.lastname;
548
549 loginParams["agent_id"] = agentData.AgentID.ToString();
550 loginParams["circuit_code"] = agentData.circuitcode.ToString();
551 loginParams["startpos_x"] = agentData.startpos.X.ToString();
552 loginParams["startpos_y"] = agentData.startpos.Y.ToString();
553 loginParams["startpos_z"] = agentData.startpos.Z.ToString();
554 loginParams["caps_path"] = capsPath;
555
556 CachedUserInfo u = m_userProfileCache.GetUserDetails(agentData.AgentID);
557 if (u != null && u.UserProfile != null)
558 {
559 loginParams["region_uuid"] = u.UserProfile.HomeRegionID.ToString(); // This seems to be always Zero
560 //Console.WriteLine(" --------- Home Region UUID -------");
561 //Console.WriteLine(" >> " + loginParams["region_uuid"] + " <<");
562 //Console.WriteLine(" --------- ---------------- -------");
563
564 string serverURI = "";
565 if (u.UserProfile is ForeignUserProfileData)
566 serverURI = HGNetworkServersInfo.ServerURI(((ForeignUserProfileData)u.UserProfile).UserServerURI);
567 loginParams["userserver_id"] = (serverURI == "") || (serverURI == null) ? HGNetworkServersInfo.Singleton.LocalUserServerURI : serverURI;
568
569 serverURI = HGNetworkServersInfo.ServerURI(u.UserProfile.UserAssetURI);
570 loginParams["assetserver_id"] = (serverURI == "") || (serverURI == null) ? HGNetworkServersInfo.Singleton.LocalAssetServerURI : serverURI;
571
572 serverURI = HGNetworkServersInfo.ServerURI(u.UserProfile.UserInventoryURI);
573 loginParams["inventoryserver_id"] = (serverURI == "") || (serverURI == null) ? HGNetworkServersInfo.Singleton.LocalInventoryServerURI : serverURI;
574
575 loginParams["root_folder_id"] = u.UserProfile.RootInventoryFolderID;
576
577 RegionInfo rinfo = RequestNeighbourInfo(u.UserProfile.HomeRegion);
578 if (rinfo != null)
579 {
580 loginParams["internal_port"] = rinfo.InternalEndPoint.Port.ToString();
581 if (!IsLocalUser(u))
582 {
583 loginParams["regionhandle"] = rinfo.regionSecret; // user.CurrentAgent.Handle.ToString();
584 //Console.WriteLine("XXX--- informregionofuser (foreign user) here handle: " + rinfo.regionSecret);
585
586 loginParams["home_address"] = ((ForeignUserProfileData)(u.UserProfile)).UserHomeAddress;
587 loginParams["home_port"] = ((ForeignUserProfileData)(u.UserProfile)).UserHomePort;
588 loginParams["home_remoting"] = ((ForeignUserProfileData)(u.UserProfile)).UserHomeRemotingPort;
589 }
590 else
591 {
592 //Console.WriteLine("XXX--- informregionofuser (local user) here handle: " + rinfo.regionSecret);
593
594 //// local user about to jump out, let's process the name
595 // On second thoughts, let's not do this for the *user*; let's only do it for the *agent*
596 //loginParams["firstname"] = agentData.firstname + "." + agentData.lastname;
597 //loginParams["lastname"] = serversInfo.UserURL;
598
599 // local user, first time out. let's ask the grid about this user's home region
600 loginParams["regionhandle"] = u.UserProfile.HomeRegion.ToString(); // user.CurrentAgent.Handle.ToString();
601
602 loginParams["home_address"] = rinfo.ExternalHostName;
603 Console.WriteLine(" --------- Home Address -------");
604 Console.WriteLine(" >> " + loginParams["home_address"] + " <<");
605 Console.WriteLine(" --------- ------------ -------");
606 loginParams["home_port"] = rinfo.HttpPort.ToString();
607 loginParams["home_remoting"] = NetworkServersInfo.RemotingListenerPort.ToString(); ;
608 }
609 }
610 else
611 {
612 m_log.Warn("[HGrid]: User's home region info not found: " + u.UserProfile.HomeRegionX + ", " + u.UserProfile.HomeRegionY);
613 }
614 }
615
616 ArrayList SendParams = new ArrayList();
617 SendParams.Add(loginParams);
618
619 // Send
620 string uri = "http://" + regInfo.ExternalHostName + ":" + regInfo.HttpPort + "/";
621 //Console.WriteLine("XXX uri: " + uri);
622 XmlRpcRequest request = new XmlRpcRequest("expect_hg_user", SendParams);
623 XmlRpcResponse reply = request.Send(uri, 6000);
624
625 if (!reply.IsFault)
626 {
627 bool responseSuccess = true;
628 if (reply.Value != null)
629 {
630 Hashtable resp = (Hashtable)reply.Value;
631 if (resp.ContainsKey("success"))
632 {
633 if ((string)resp["success"] == "FALSE")
634 {
635 responseSuccess = false;
636 }
637 }
638 }
639 if (responseSuccess)
640 {
641 m_log.Info("[HGrid]: Successfully informed remote region about user " + agentData.AgentID);
642 return true;
643 }
644 else
645 {
646 m_log.ErrorFormat("[HGrid]: Region responded that it is not available to receive clients");
647 return false;
648 }
649 }
650 else
651 {
652 m_log.ErrorFormat("[HGrid]: XmlRpc request to region failed with message {0}, code {1} ", reply.FaultString, reply.FaultCode);
653 return false;
654 }
655 }
656
657
658 /// <summary>
659 /// Received from other HGrid nodes when a user wants to teleport here. This call allows
660 /// the region to prepare for direct communication from the client. Sends back an empty
661 /// xmlrpc response on completion.
662 /// This is somewhat similar to OGS1's ExpectUser, but with the additional task of
663 /// registering the user in the local user cache.
664 /// </summary>
665 /// <param name="request"></param>
666 /// <returns></returns>
667 public XmlRpcResponse ExpectHGUser(XmlRpcRequest request)
668 {
669 Hashtable requestData = (Hashtable)request.Params[0];
670 ForeignUserProfileData userData = new ForeignUserProfileData();
671
672 userData.FirstName = (string)requestData["firstname"];
673 userData.SurName = (string)requestData["lastname"];
674 userData.ID = new UUID((string)requestData["agent_id"]);
675 userData.HomeLocation = new Vector3((float)Convert.ToDecimal((string)requestData["startpos_x"]),
676 (float)Convert.ToDecimal((string)requestData["startpos_y"]),
677 (float)Convert.ToDecimal((string)requestData["startpos_z"]));
678
679 userData.UserServerURI = (string)requestData["userserver_id"];
680 userData.UserAssetURI = (string)requestData["assetserver_id"];
681 userData.UserInventoryURI = (string)requestData["inventoryserver_id"];
682
683 UUID rootID = UUID.Zero;
684 UUID.TryParse((string)requestData["root_folder_id"], out rootID);
685 userData.RootInventoryFolderID = rootID;
686
687 UUID uuid = UUID.Zero;
688 UUID.TryParse((string)requestData["region_uuid"], out uuid);
689 userData.HomeRegionID = uuid; // not quite comfortable about this...
690 ulong userRegionHandle = Convert.ToUInt64((string)requestData["regionhandle"]);
691 //userData.HomeRegion = userRegionHandle;
692 userData.UserHomeAddress = (string)requestData["home_address"];
693 userData.UserHomePort = (string)requestData["home_port"];
694 int userhomeinternalport = Convert.ToInt32((string)requestData["internal_port"]);
695 userData.UserHomeRemotingPort = (string)requestData["home_remoting"];
696
697
698 m_log.DebugFormat("[HGrid]: Told by user service to prepare for a connection from {0} {1} {2}",
699 userData.FirstName, userData.SurName, userData.ID);
700 m_log.Debug("[HGrid]: home_address: " + userData.UserHomeAddress +
701 "; home_port: " + userData.UserHomePort + "; remoting: " + userData.UserHomeRemotingPort);
702
703
704 XmlRpcResponse resp = new XmlRpcResponse();
705
706 if (!RegionLoginsEnabled)
707 {
708 m_log.InfoFormat(
709 "[HGrid]: Denying access for user {0} {1} because region login is currently disabled",
710 userData.FirstName, userData.SurName);
711
712 Hashtable respdata = new Hashtable();
713 respdata["success"] = "FALSE";
714 respdata["reason"] = "region login currently disabled";
715 resp.Value = respdata;
716 }
717 else
718 {
719 RegionInfo[] regions = m_regionsOnInstance.ToArray();
720 //bool banned = false;
721 // Just check one region. We assume they all belong to the same estate.
722 if ((regions.Length > 0) && (regions[0].EstateSettings.IsBanned(userData.ID)))
723 {
724 m_log.InfoFormat(
725 "[HGrid]: Denying access for user {0} {1} because user is banned",
726 userData.FirstName, userData.SurName);
727
728 Hashtable respdata = new Hashtable();
729 respdata["success"] = "FALSE";
730 respdata["reason"] = "banned";
731 resp.Value = respdata;
732 }
733 else
734 {
735 // Finally, everything looks ok
736 //Console.WriteLine("XXX---- EVERYTHING OK ---XXX");
737
738 // Nope, let's do it only for the *agent*
739 //// 0 - Switch name if necessary
740 //if (IsComingHome(userData))
741 //{
742 // string[] parts = userData.FirstName.Split( new char[] {'.'});
743 // if (parts.Length >= 1)
744 // userData.FirstName = parts[0];
745 // if (parts.Length == 2)
746 // userData.SurName = parts[1];
747 // else
748 // m_log.Warn("[HGrid]: Something fishy with user " + userData.FirstName + userData.SurName);
749
750 // m_log.Info("[HGrid]: Welcome home, " + userData.FirstName + " " + userData.SurName);
751 //}
752
753 // 1 - Preload the user data
754 m_userProfileCache.PreloadUserCache(userData.ID, userData);
755
756 // 2 - Load the region info into list of known regions
757 RegionInfo rinfo = new RegionInfo();
758 rinfo.RegionID = userData.HomeRegionID;
759 rinfo.ExternalHostName = userData.UserHomeAddress;
760 rinfo.HttpPort = Convert.ToUInt32(userData.UserHomePort);
761 rinfo.RemotingPort = Convert.ToUInt32(userData.UserHomeRemotingPort);
762 rinfo.RegionID = userData.HomeRegionID;
763 // X=0 on the map
764 rinfo.RegionLocX = 0;
765 rinfo.RegionLocY = (uint)m_knownRegions.Count;
766 rinfo.regionSecret = userRegionHandle.ToString();
767 //Console.WriteLine("XXX--- Here: handle = " + rinfo.regionSecret);
768 try
769 {
770 rinfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)userhomeinternalport);
771 }
772 catch (Exception e)
773 {
774 m_log.Warn("[HGrid]: Exception while constructing internal endpoint: " + e);
775 }
776 rinfo.RemotingAddress = rinfo.ExternalEndPoint.Address.ToString(); //userData.UserHomeAddress;
777
778 if (!IsComingHome(userData))
779 {
780 // Change the user's home region here!!!
781 userData.HomeRegion = rinfo.RegionHandle;
782 }
783
784 if (!m_knownRegions.ContainsKey(userData.ID))
785 m_knownRegions.Add(userData.ID, rinfo);
786 else
787 // just update it. The previous one was left there when the user departed
788 m_knownRegions[userData.ID] = rinfo;
789
790 // 3 - Send the reply
791 Hashtable respdata = new Hashtable();
792 respdata["success"] = "TRUE";
793 resp.Value = respdata;
794
795 DumpUserData(userData);
796 DumpRegionData(rinfo);
797 }
798 }
799
800 return resp;
801 }
802
803 #region IInterRegionCommunications interface
804
805 public virtual bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId) { return false; }
806 public virtual bool AcknowledgePrimCrossed(ulong regionHandle, UUID primID) { return false; }
807 public virtual bool CheckRegion(string address, uint port) { return false; }
808 public virtual bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) { return false; }
809
810 public virtual bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying) {
811 // Remote region
812 RegionInfo regInfo = null;
813 ulong remoteHandle = 0;
814 try
815 {
816 regInfo = RequestNeighbourInfo(regionHandle);
817 if (regInfo != null)
818 {
819 try
820 {
821 remoteHandle = Convert.ToUInt64(regInfo.regionSecret);
822 }
823 catch
824 {
825 m_log.Warn("[HGrid]: Invalid remote region with handle " + regInfo.regionSecret);
826 return false;
827 }
828 //Console.WriteLine("XXX---- Sending Expectavatarcrossing into : " + remoteHandle);
829
830 bool retValue = false;
831 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
832 typeof(OGS1InterRegionRemoting),
833 "tcp://" + regInfo.RemotingAddress +
834 ":" + regInfo.RemotingPort +
835 "/InterRegions");
836
837 if (remObject != null)
838 {
839 retValue =
840 remObject.ExpectAvatarCrossing(remoteHandle, agentID.Guid, new sLLVector3(position),
841 isFlying);
842 }
843 else
844 {
845 m_log.Warn("[HGrid]: Remoting object not found");
846 }
847 remObject = null;
848
849 return retValue;
850 }
851 //TODO need to see if we know about where this region is and use .net remoting
852 // to inform it.
853 //NoteDeadRegion(regionHandle);
854 return false;
855 }
856 catch (RemotingException e)
857 {
858// NoteDeadRegion(regionHandle);
859
860 m_log.WarnFormat(
861 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
862 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
863 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
864
865 return false;
866 }
867 catch
868 {
869// NoteDeadRegion(regionHandle);
870 return false;
871 }
872
873 }
874
875 public virtual bool ExpectPrimCrossing(ulong regionHandle, UUID primID, Vector3 position, bool isFlying) { return false; }
876
877 public virtual bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
878 {
879 // If we're here, it's because regionHandle is a remote, non-grided region
880 m_log.Info("[HGrid]: InformRegionOfChildAgent for " + regionHandle);
881
882 RegionInfo regInfo = GetHyperlinkRegion(regionHandle);
883 if (regInfo == null)
884 return false;
885
886 ulong realHandle = regionHandle;
887
888 CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(agentData.AgentID);
889 if ((uinfo == null) || !IsGoingHome(uinfo, regInfo))
890 {
891 m_log.Info("[HGrid]: User seems to be going to foreign region " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
892 if (!InformRegionOfUser(regInfo, agentData))
893 {
894 m_log.Warn("[HGrid]: Could not inform remote region of transferring user.");
895 return false;
896 }
897 }
898 else
899 m_log.Info("[HGrid]: User seems to be going home " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
900
901 try
902 {
903 // ... and then
904
905 m_log.Debug("[HGrid]: Region is hyperlink.");
906 bool retValue = false;
907 try
908 {
909 regionHandle = Convert.ToUInt64(regInfo.regionSecret);
910 }
911 catch (Exception)
912 {
913 m_log.Warn("[HGrid]: Invalid hyperlink region.");
914 return false;
915 }
916
917 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
918 typeof(OGS1InterRegionRemoting),
919 "tcp://" + regInfo.RemotingAddress +
920 ":" + regInfo.RemotingPort +
921 "/InterRegions");
922
923 if (remObject != null)
924 {
925 sAgentCircuitData sag = new sAgentCircuitData(agentData);
926 // May need to change agent's name
927 if (IsLocalUser(uinfo))
928 {
929 sag.firstname = agentData.firstname + "." + agentData.lastname;
930 sag.lastname = serversInfo.UserURL; //HGNetworkServersInfo.Singleton.LocalUserServerURI;
931 }
932 retValue = remObject.InformRegionOfChildAgent(regionHandle, sag);
933 }
934 else
935 {
936 m_log.Warn("[HGrid]: remoting object not found");
937 }
938 remObject = null;
939 m_log.Info("[HGrid]: tried to InformRegionOfChildAgent for " +
940 agentData.firstname + " " + agentData.lastname + " and got " +
941 retValue.ToString());
942
943 // Remove the info from this region
944 if (m_knownRegions.ContainsKey(uinfo.UserProfile.ID))
945 m_knownRegions.Remove(uinfo.UserProfile.ID);
946
947 return retValue;
948 }
949 catch (RemotingException e)
950 {
951 //NoteDeadRegion(regionHandle);
952
953 m_log.WarnFormat(
954 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
955 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
956 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
957
958 return false;
959 }
960 catch (SocketException e)
961 {
962 //NoteDeadRegion(regionHandle);
963
964 m_log.WarnFormat(
965 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
966 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
967 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
968
969 return false;
970 }
971 catch (InvalidCredentialException e)
972 {
973 //NoteDeadRegion(regionHandle);
974
975 m_log.WarnFormat(
976 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
977 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
978 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
979
980 return false;
981 }
982 catch (AuthenticationException e)
983 {
984 //NoteDeadRegion(regionHandle);
985
986 m_log.WarnFormat(
987 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
988 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
989 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
990
991 return false;
992 }
993 catch (Exception e)
994 {
995 //NoteDeadRegion(regionHandle);
996
997 if (regInfo != null)
998 {
999 m_log.WarnFormat(
1000 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
1001 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
1002 }
1003 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
1004
1005 return false;
1006 }
1007
1008
1009 }
1010
1011 public virtual bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod) { return false; }
1012
1013 public virtual bool RegionUp(SerializableRegionInfo region, ulong regionhandle) {
1014
1015 ulong realHandle = FindRegionHandle(regionhandle);
1016
1017 if (realHandle == regionhandle) // something wrong, not remote region
1018 return false;
1019
1020 SerializableRegionInfo regInfo = null;
1021 try
1022 {
1023 // You may ask why this is in here...
1024 // The region asking the grid services about itself..
1025 // And, surprisingly, the reason is.. it doesn't know
1026 // it's own remoting port! How special.
1027 RegionUpData regiondata = new RegionUpData(region.RegionLocX, region.RegionLocY, region.ExternalHostName, region.InternalEndPoint.Port);
1028
1029 region = new SerializableRegionInfo(RequestNeighbourInfo(realHandle));
1030 region.RemotingAddress = region.ExternalHostName;
1031 region.RemotingPort = NetworkServersInfo.RemotingListenerPort;
1032 region.HttpPort = serversInfo.HttpListenerPort;
1033
1034 regInfo = new SerializableRegionInfo(RequestNeighbourInfo(regionhandle));
1035 if (regInfo != null)
1036 {
1037 // If we're not trying to remote to ourselves.
1038 if (regInfo.RemotingAddress != region.RemotingAddress && region.RemotingAddress != null)
1039 {
1040 //don't want to be creating a new link to the remote instance every time like we are here
1041 bool retValue = false;
1042
1043 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
1044 typeof(OGS1InterRegionRemoting),
1045 "tcp://" +
1046 regInfo.RemotingAddress +
1047 ":" + regInfo.RemotingPort +
1048 "/InterRegions");
1049
1050 if (remObject != null)
1051 {
1052 retValue = remObject.RegionUp(regiondata, realHandle);
1053 }
1054 else
1055 {
1056 m_log.Warn("[HGrid]: remoting object not found");
1057 }
1058 remObject = null;
1059
1060 m_log.Info(
1061 "[HGrid]: tried to inform region I'm up");
1062
1063 return retValue;
1064 }
1065 else
1066 {
1067 // We're trying to inform ourselves via remoting.
1068 // This is here because we're looping over the listeners before we get here.
1069 // Odd but it should work.
1070 return true;
1071 }
1072 }
1073
1074 return false;
1075 }
1076 catch (RemotingException e)
1077 {
1078 m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region using tcp://" +
1079 regInfo.RemotingAddress +
1080 ":" + regInfo.RemotingPort +
1081 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
1082 " - Is this neighbor up?");
1083 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
1084 return false;
1085 }
1086 catch (SocketException e)
1087 {
1088 m_log.Warn("[HGrid]: Socket Error: Unable to connect to adjacent region using tcp://" +
1089 regInfo.RemotingAddress +
1090 ":" + regInfo.RemotingPort +
1091 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
1092 " - Is this neighbor up?");
1093 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
1094 return false;
1095 }
1096 catch (InvalidCredentialException e)
1097 {
1098 m_log.Warn("[HGrid]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
1099 regInfo.RemotingAddress +
1100 ":" + regInfo.RemotingPort +
1101 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
1102 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
1103 return false;
1104 }
1105 catch (AuthenticationException e)
1106 {
1107 m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region using tcp://" +
1108 regInfo.RemotingAddress +
1109 ":" + regInfo.RemotingPort +
1110 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
1111 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
1112 return false;
1113 }
1114 catch (Exception e)
1115 {
1116 m_log.Debug(e.ToString());
1117 return false;
1118 }
1119
1120 }
1121
1122 public virtual bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID) { return false; }
1123
1124 public virtual List<UUID> InformFriendsInOtherRegion(UUID agentId, ulong destRegionHandle, List<UUID> friends, bool online)
1125 {
1126 return new List<UUID>();
1127 }
1128
1129 public virtual bool TriggerTerminateFriend(ulong regionHandle, UUID agentID, UUID exFriendID)
1130 {
1131 return true;
1132 }
1133
1134
1135 #endregion
1136
1137 #region Methods triggered by calls from external instances
1138
1139 /// <summary>
1140 ///
1141 /// </summary>
1142 /// <param name="regionHandle"></param>
1143 /// <param name="agentData"></param>
1144 /// <returns></returns>
1145 protected bool HGIncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
1146 {
1147 CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(agentData.AgentID);
1148 if ((uinfo != null) && (uinfo.UserProfile != null) &&
1149 (IsLocalUser(uinfo) || !(uinfo.UserProfile is ForeignUserProfileData)))
1150 {
1151 //Console.WriteLine("---------------> Local User!");
1152 string[] parts = agentData.firstname.Split(new char[] { '.' });
1153 if (parts.Length == 2)
1154 {
1155 agentData.firstname = parts[0];
1156 agentData.lastname = parts[1];
1157 }
1158 }
1159 //else
1160 // Console.WriteLine("---------------> Foreign User!");
1161 return true;
1162 }
1163 #endregion
1164
1165
1166 #region IHyperGrid interface
1167
1168 public virtual bool IsHyperlinkRegion(ulong ihandle)
1169 {
1170 if (GetHyperlinkRegion(ihandle) == null)
1171 return false;
1172 else
1173 return true;
1174 }
1175
1176 public virtual RegionInfo GetHyperlinkRegion(ulong ihandle)
1177 {
1178 foreach (RegionInfo info in m_hyperlinkRegions)
1179 {
1180 if (info.RegionHandle == ihandle)
1181 return info;
1182 }
1183
1184 foreach (RegionInfo info in m_knownRegions.Values)
1185 {
1186 if (info.RegionHandle == ihandle)
1187 return info;
1188 }
1189
1190 return null;
1191 }
1192
1193 public virtual ulong FindRegionHandle(ulong ihandle)
1194 {
1195 long ohandle = -1;
1196 List<RegionInfo> rlist = new List<RegionInfo>(m_hyperlinkRegions);
1197 rlist.AddRange(m_knownRegions.Values);
1198 foreach (RegionInfo info in rlist)
1199 {
1200 if (info.RegionHandle == ihandle)
1201 {
1202 try
1203 {
1204 ohandle = Convert.ToInt64(info.regionSecret);
1205 m_log.Info("[HGrid] remote region " + ohandle);
1206 }
1207 catch
1208 {
1209 m_log.Error("[HGrid] Could not convert secret for " + ihandle + " (" + info.regionSecret + ")");
1210 }
1211 break;
1212 }
1213 }
1214 return ohandle < 0 ? ihandle : (ulong)ohandle;
1215 }
1216 #endregion
1217
1218 #region Misc
1219
1220 protected bool IsComingHome(ForeignUserProfileData userData)
1221 {
1222 return (userData.UserServerURI == HGNetworkServersInfo.Singleton.LocalUserServerURI);
1223 }
1224
1225 protected bool IsGoingHome(CachedUserInfo uinfo, RegionInfo rinfo)
1226 {
1227 if (uinfo.UserProfile == null)
1228 return false;
1229
1230 string userUserServerURI = String.Empty;
1231 if (uinfo.UserProfile is ForeignUserProfileData)
1232 {
1233 userUserServerURI = HGNetworkServersInfo.ServerURI(((ForeignUserProfileData)uinfo.UserProfile).UserServerURI);
1234 }
1235
1236 return ((uinfo.UserProfile.HomeRegionID == rinfo.RegionID) &&
1237 (userUserServerURI != HGNetworkServersInfo.Singleton.LocalUserServerURI));
1238 }
1239
1240 protected bool IsLocalUser(CachedUserInfo uinfo)
1241 {
1242 if (uinfo == null)
1243 return true;
1244
1245 if (uinfo.UserProfile is ForeignUserProfileData)
1246 return HGNetworkServersInfo.Singleton.IsLocalUser(((ForeignUserProfileData)uinfo.UserProfile).UserServerURI);
1247 else
1248 return true;
1249
1250 }
1251
1252 protected bool IsLocalRegion(ulong handle)
1253 {
1254 foreach (RegionInfo reg in m_regionsOnInstance)
1255 if (reg.RegionHandle == handle)
1256 return true;
1257 return false;
1258 }
1259
1260 private void DumpUserData(ForeignUserProfileData userData)
1261 {
1262 Console.WriteLine(" ------------ User Data Dump ----------");
1263 Console.WriteLine(" >> Name: " + userData.FirstName + " " + userData.SurName);
1264 Console.WriteLine(" >> HomeID: " + userData.HomeRegionID);
1265 Console.WriteLine(" >> HomeHandle: " + userData.HomeRegion);
1266 Console.WriteLine(" >> HomeX: " + userData.HomeRegionX);
1267 Console.WriteLine(" >> HomeY: " + userData.HomeRegionY);
1268 Console.WriteLine(" >> UserServer: " + userData.UserServerURI);
1269 Console.WriteLine(" >> InvServer: " + userData.UserInventoryURI);
1270 Console.WriteLine(" >> AssetServer: " + userData.UserAssetURI);
1271 Console.WriteLine(" ------------ -------------- ----------");
1272 }
1273
1274 private void DumpRegionData(RegionInfo rinfo)
1275 {
1276 Console.WriteLine(" ------------ Region Data Dump ----------");
1277 Console.WriteLine(" >> handle: " + rinfo.RegionHandle);
1278 Console.WriteLine(" >> coords: " + rinfo.RegionLocX + ", " + rinfo.RegionLocY);
1279 Console.WriteLine(" >> secret: " + rinfo.regionSecret);
1280 Console.WriteLine(" >> remoting address: " + rinfo.RemotingAddress);
1281 Console.WriteLine(" >> remoting port: " + rinfo.RemotingPort);
1282 Console.WriteLine(" >> external host name: " + rinfo.ExternalHostName);
1283 Console.WriteLine(" >> http port: " + rinfo.HttpPort);
1284 Console.WriteLine(" >> external EP address: " + rinfo.ExternalEndPoint.Address);
1285 Console.WriteLine(" >> external EP port: " + rinfo.ExternalEndPoint.Port);
1286 Console.WriteLine(" ------------ -------------- ----------");
1287 }
1288
1289
1290 #endregion
1291
1292
1293 }
1294}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServicesGridMode.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServicesGridMode.cs
new file mode 100644
index 0000000..23258df
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGGridServicesGridMode.cs
@@ -0,0 +1,285 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections.Generic;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35using OpenSim.Framework.Communications.Cache;
36using OpenSim.Framework.Servers;
37using OpenSim.Region.Communications.OGS1;
38using OpenSim.Region.Environment.Scenes;
39
40using OpenMetaverse;
41
42using log4net;
43
44namespace OpenSim.Region.Communications.Hypergrid
45{
46 public class HGGridServicesGridMode : HGGridServices
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 /// <summary>
51 /// Encapsulate remote backend services for manipulation of grid regions
52 /// </summary>
53 private OGS1GridServices m_remoteBackend = null;
54
55 public OGS1GridServices RemoteBackend
56 {
57 get { return m_remoteBackend; }
58 }
59
60
61 public override string gdebugRegionName
62 {
63 get { return m_remoteBackend.gdebugRegionName; }
64 set { m_remoteBackend.gdebugRegionName = value; }
65 }
66
67 public override bool RegionLoginsEnabled
68 {
69 get { return m_remoteBackend.RegionLoginsEnabled; }
70 set { m_remoteBackend.RegionLoginsEnabled = value; }
71 }
72
73 public HGGridServicesGridMode(NetworkServersInfo servers_info, BaseHttpServer httpServe,
74 AssetCache asscache, SceneManager sman, UserProfileCacheService userv)
75 : base(servers_info, httpServe, asscache, sman)
76 {
77 m_remoteBackend = new OGS1GridServices(servers_info, httpServe);
78 // Let's deregister this, so we can handle it here first
79 InterRegionSingleton.Instance.OnChildAgent -= m_remoteBackend.IncomingChildAgent;
80 InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent;
81 m_userProfileCache = userv;
82 }
83
84 #region IGridServices interface
85
86 public override RegionCommsListener RegisterRegion(RegionInfo regionInfo)
87 {
88 if (!regionInfo.RegionID.Equals(UUID.Zero))
89 {
90 m_regionsOnInstance.Add(regionInfo);
91 return m_remoteBackend.RegisterRegion(regionInfo);
92 }
93 else
94 return base.RegisterRegion(regionInfo);
95 }
96
97 public override bool DeregisterRegion(RegionInfo regionInfo)
98 {
99 bool success = m_remoteBackend.DeregisterRegion(regionInfo);
100 if (!success)
101 success = base.DeregisterRegion(regionInfo);
102 return success;
103 }
104
105 public override List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
106 {
107 List<SimpleRegionInfo> neighbours = m_remoteBackend.RequestNeighbours(x, y);
108 List<SimpleRegionInfo> remotes = base.RequestNeighbours(x, y);
109 neighbours.AddRange(remotes);
110
111 return neighbours;
112 }
113
114 public override RegionInfo RequestNeighbourInfo(UUID Region_UUID)
115 {
116 RegionInfo info = m_remoteBackend.RequestNeighbourInfo(Region_UUID);
117 if (info == null)
118 info = base.RequestNeighbourInfo(Region_UUID);
119 return info;
120 }
121
122 public override RegionInfo RequestNeighbourInfo(ulong regionHandle)
123 {
124 RegionInfo info = m_remoteBackend.RequestNeighbourInfo(regionHandle);
125 if (info == null)
126 info = base.RequestNeighbourInfo(regionHandle);
127 return info;
128 }
129
130 public override RegionInfo RequestClosestRegion(string regionName)
131 {
132 RegionInfo info = m_remoteBackend.RequestClosestRegion(regionName);
133 if (info == null)
134 info = base.RequestClosestRegion(regionName);
135 return info;
136 }
137
138 public override List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
139 {
140 List<MapBlockData> neighbours = m_remoteBackend.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
141 List<MapBlockData> remotes = base.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
142 neighbours.AddRange(remotes);
143
144 return neighbours;
145 }
146
147 public override LandData RequestLandData(ulong regionHandle, uint x, uint y)
148 {
149 LandData land = m_remoteBackend.RequestLandData(regionHandle, x, y);
150 if (land == null)
151 land = base.RequestLandData(regionHandle, x, y);
152 return land;
153 }
154
155 public override List<RegionInfo> RequestNamedRegions(string name, int maxNumber)
156 {
157 List<RegionInfo> infos = m_remoteBackend.RequestNamedRegions(name, maxNumber);
158 List<RegionInfo> remotes = base.RequestNamedRegions(name, maxNumber);
159 infos.AddRange(remotes);
160 return infos;
161 }
162
163 #endregion
164
165 #region IInterRegionCommunications interface
166
167 public override bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId)
168 {
169 return m_remoteBackend.AcknowledgeAgentCrossed(regionHandle, agentId);
170 }
171
172 public override bool AcknowledgePrimCrossed(ulong regionHandle, UUID primID)
173 {
174 return m_remoteBackend.AcknowledgePrimCrossed(regionHandle, primID);
175 }
176
177 public override bool CheckRegion(string address, uint port)
178 {
179 return m_remoteBackend.CheckRegion(address, port);
180 }
181
182 public override bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
183 {
184 return m_remoteBackend.ChildAgentUpdate(regionHandle, cAgentData);
185 }
186
187 public override bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
188 {
189 if (base.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying))
190 return true;
191 return m_remoteBackend.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
192 }
193
194 public override bool ExpectPrimCrossing(ulong regionHandle, UUID primID, Vector3 position, bool isFlying)
195 {
196 return m_remoteBackend.ExpectPrimCrossing(regionHandle, primID, position, isFlying);
197 }
198
199 public override bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
200 {
201 CachedUserInfo user = m_userProfileCache.GetUserDetails(agentData.AgentID);
202
203 if (IsLocalUser(user))
204 {
205 Console.WriteLine("XXX Home User XXX");
206 if (IsHyperlinkRegion(regionHandle))
207 {
208 Console.WriteLine("XXX Going Hyperlink XXX");
209 return base.InformRegionOfChildAgent(regionHandle, agentData);
210 }
211 else
212 {
213 // non-hypergrid case
214 Console.WriteLine("XXX Going local-grid region XXX");
215 return m_remoteBackend.InformRegionOfChildAgent(regionHandle, agentData);
216 }
217 }
218
219 // Foregin users
220 Console.WriteLine("XXX Foreign User XXX");
221 if (IsLocalRegion(regionHandle)) // regions on the same instance
222 {
223 Console.WriteLine("XXX Going onInstance region XXX");
224 return m_remoteBackend.InformRegionOfChildAgent(regionHandle, agentData);
225 }
226
227 if (IsHyperlinkRegion(regionHandle)) // hyperlinked regions
228 {
229 Console.WriteLine("XXX Going Hyperlink XXX");
230 return base.InformRegionOfChildAgent(regionHandle, agentData);
231 }
232 else
233 {
234 // foreign user going to a non-local region on the same grid
235 // We need to inform that region about this user before
236 // proceeding to the normal backend process.
237 Console.WriteLine("XXX Going local-grid region XXX");
238 RegionInfo regInfo = RequestNeighbourInfo(regionHandle);
239 if (regInfo != null)
240 InformRegionOfUser(regInfo, agentData);
241 return m_remoteBackend.InformRegionOfChildAgent(regionHandle, agentData);
242 }
243
244 }
245
246 public override bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod)
247 {
248 return m_remoteBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod);
249 }
250
251 public override bool RegionUp(SerializableRegionInfo region, ulong regionhandle)
252 {
253 if (m_remoteBackend.RegionUp(region, regionhandle))
254 return true;
255 return base.RegionUp(region, regionhandle);
256 }
257
258 public override bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
259 {
260 return m_remoteBackend.TellRegionToCloseChildConnection(regionHandle, agentID);
261 }
262
263
264 #endregion
265
266 #region Methods triggered by calls from external instances
267
268 /// <summary>
269 ///
270 /// </summary>
271 /// <param name="regionHandle"></param>
272 /// <param name="agentData"></param>
273 /// <returns></returns>
274 public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
275 {
276 HGIncomingChildAgent(regionHandle, agentData);
277
278 m_log.Info("[HGrid]: Incoming HGrid Agent " + agentData.firstname + " " + agentData.lastname);
279
280 return m_remoteBackend.IncomingChildAgent(regionHandle, agentData);
281 }
282 #endregion
283
284 }
285}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs
new file mode 100644
index 0000000..4dc26e0
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs
@@ -0,0 +1,928 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Net.Sockets;
33using System.Reflection;
34using System.Runtime.Remoting;
35using System.Runtime.Remoting.Channels;
36using System.Runtime.Remoting.Channels.Tcp;
37using System.Security.Authentication;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Cache;
42using OpenSim.Framework.Servers;
43using OpenSim.Region.Communications.Local;
44using OpenSim.Region.Communications.OGS1;
45using OpenSim.Region.Environment.Scenes;
46
47using OpenMetaverse;
48using Nwc.XmlRpc;
49using log4net;
50
51namespace OpenSim.Region.Communications.Hypergrid
52{
53 public class HGGridServicesStandalone : HGGridServices
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 /// <summary>
58 /// Encapsulate local backend services for manipulation of local regions
59 /// </summary>
60 protected LocalBackEndServices m_localBackend = new LocalBackEndServices();
61
62 private Dictionary<ulong, int> m_deadRegionCache = new Dictionary<ulong, int>();
63
64 public LocalBackEndServices LocalBackend
65 {
66 get { return m_localBackend; }
67 }
68
69 public override string gdebugRegionName
70 {
71 get { return m_localBackend.gdebugRegionName; }
72 set { m_localBackend.gdebugRegionName = value; }
73 }
74
75 public override bool RegionLoginsEnabled
76 {
77 get { return m_localBackend.RegionLoginsEnabled; }
78 set { m_localBackend.RegionLoginsEnabled = value; }
79 }
80
81
82 public HGGridServicesStandalone(NetworkServersInfo servers_info, BaseHttpServer httpServe, AssetCache asscache, SceneManager sman)
83 : base(servers_info, httpServe, asscache, sman)
84 {
85 //Respond to Grid Services requests
86 httpServer.AddXmlRPCHandler("logoff_user", LogOffUser);
87 httpServer.AddXmlRPCHandler("check", PingCheckReply);
88 httpServer.AddXmlRPCHandler("land_data", LandData);
89
90 StartRemoting();
91 }
92
93 #region IGridServices interface
94
95 public override RegionCommsListener RegisterRegion(RegionInfo regionInfo)
96 {
97 if (!regionInfo.RegionID.Equals(UUID.Zero))
98 {
99 m_regionsOnInstance.Add(regionInfo);
100 return m_localBackend.RegisterRegion(regionInfo);
101 }
102 else
103 return base.RegisterRegion(regionInfo);
104
105 }
106
107 public override bool DeregisterRegion(RegionInfo regionInfo)
108 {
109 bool success = m_localBackend.DeregisterRegion(regionInfo);
110 if (!success)
111 success = base.DeregisterRegion(regionInfo);
112 return success;
113 }
114
115 public override List<SimpleRegionInfo> RequestNeighbours(uint x, uint y)
116 {
117 List<SimpleRegionInfo> neighbours = m_localBackend.RequestNeighbours(x, y);
118 List<SimpleRegionInfo> remotes = base.RequestNeighbours(x, y);
119 neighbours.AddRange(remotes);
120
121 return neighbours;
122 }
123
124 public override RegionInfo RequestNeighbourInfo(UUID Region_UUID)
125 {
126 RegionInfo info = m_localBackend.RequestNeighbourInfo(Region_UUID);
127 if (info == null)
128 info = base.RequestNeighbourInfo(Region_UUID);
129 return info;
130 }
131
132 public override RegionInfo RequestNeighbourInfo(ulong regionHandle)
133 {
134 RegionInfo info = m_localBackend.RequestNeighbourInfo(regionHandle);
135 //m_log.Info("[HGrid] Request neighbor info, local backend returned " + info);
136 if (info == null)
137 info = base.RequestNeighbourInfo(regionHandle);
138 return info;
139 }
140
141 public override RegionInfo RequestClosestRegion(string regionName)
142 {
143 RegionInfo info = m_localBackend.RequestClosestRegion(regionName);
144 if (info == null)
145 info = base.RequestClosestRegion(regionName);
146 return info;
147 }
148
149 public override List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
150 {
151 //m_log.Info("[HGrid] Request map blocks " + minX + "-" + minY + "-" + maxX + "-" + maxY);
152 List<MapBlockData> neighbours = m_localBackend.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
153 List<MapBlockData> remotes = base.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
154 neighbours.AddRange(remotes);
155
156 return neighbours;
157 }
158
159 public override LandData RequestLandData(ulong regionHandle, uint x, uint y)
160 {
161 LandData land = m_localBackend.RequestLandData(regionHandle, x, y);
162 if (land == null)
163 land = base.RequestLandData(regionHandle, x, y);
164 return land;
165 }
166
167 public override List<RegionInfo> RequestNamedRegions(string name, int maxNumber)
168 {
169 List<RegionInfo> infos = m_localBackend.RequestNamedRegions(name, maxNumber);
170 List<RegionInfo> remotes = base.RequestNamedRegions(name, maxNumber);
171 infos.AddRange(remotes);
172 return infos;
173 }
174
175 #endregion
176
177 #region XML Request Handlers
178
179 /// <summary>
180 /// A ping / version check
181 /// </summary>
182 /// <param name="request"></param>
183 /// <returns></returns>
184 public virtual XmlRpcResponse PingCheckReply(XmlRpcRequest request)
185 {
186 XmlRpcResponse response = new XmlRpcResponse();
187
188 Hashtable respData = new Hashtable();
189 respData["online"] = "true";
190
191 m_localBackend.PingCheckReply(respData);
192
193 response.Value = respData;
194
195 return response;
196 }
197
198
199 // Grid Request Processing
200 /// <summary>
201 /// Ooops, our Agent must be dead if we're getting this request!
202 /// </summary>
203 /// <param name="request"></param>
204 /// <returns></returns>
205 public XmlRpcResponse LogOffUser(XmlRpcRequest request)
206 {
207 m_log.Debug("[HGrid]: LogOff User Called");
208
209 Hashtable requestData = (Hashtable)request.Params[0];
210 string message = (string)requestData["message"];
211 UUID agentID = UUID.Zero;
212 UUID RegionSecret = UUID.Zero;
213 UUID.TryParse((string)requestData["agent_id"], out agentID);
214 UUID.TryParse((string)requestData["region_secret"], out RegionSecret);
215
216 ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]);
217
218 m_localBackend.TriggerLogOffUser(regionHandle, agentID, RegionSecret, message);
219
220 return new XmlRpcResponse();
221 }
222
223 /// <summary>
224 /// Someone asked us about parcel-information
225 /// </summary>
226 /// <param name="request"></param>
227 /// <returns></returns>
228 public XmlRpcResponse LandData(XmlRpcRequest request)
229 {
230 Hashtable requestData = (Hashtable)request.Params[0];
231 ulong regionHandle = Convert.ToUInt64(requestData["region_handle"]);
232 uint x = Convert.ToUInt32(requestData["x"]);
233 uint y = Convert.ToUInt32(requestData["y"]);
234 m_log.DebugFormat("[HGrid]: Got XML reqeuest for land data at {0}, {1} in region {2}", x, y, regionHandle);
235
236 LandData landData = m_localBackend.RequestLandData(regionHandle, x, y);
237 Hashtable hash = new Hashtable();
238 if (landData != null)
239 {
240 // for now, only push out the data we need for answering a ParcelInfoReqeust
241 hash["AABBMax"] = landData.AABBMax.ToString();
242 hash["AABBMin"] = landData.AABBMin.ToString();
243 hash["Area"] = landData.Area.ToString();
244 hash["AuctionID"] = landData.AuctionID.ToString();
245 hash["Description"] = landData.Description;
246 hash["Flags"] = landData.Flags.ToString();
247 hash["GlobalID"] = landData.GlobalID.ToString();
248 hash["Name"] = landData.Name;
249 hash["OwnerID"] = landData.OwnerID.ToString();
250 hash["SalePrice"] = landData.SalePrice.ToString();
251 hash["SnapshotID"] = landData.SnapshotID.ToString();
252 hash["UserLocation"] = landData.UserLocation.ToString();
253 }
254
255 XmlRpcResponse response = new XmlRpcResponse();
256 response.Value = hash;
257 return response;
258 }
259
260 #endregion
261
262 #region Remoting
263
264 /// <summary>
265 /// Start listening for .net remoting calls from other regions.
266 /// </summary>
267 private void StartRemoting()
268 {
269 m_log.Info("[HGrid]: Start remoting...");
270 TcpChannel ch;
271 try
272 {
273 ch = new TcpChannel((int)NetworkServersInfo.RemotingListenerPort);
274 ChannelServices.RegisterChannel(ch, false); // Disabled security as Mono doesn't support this.
275 }
276 catch (Exception ex)
277 {
278 m_log.Error("[HGrid]: Exception while attempting to listen on TCP port " + (int)NetworkServersInfo.RemotingListenerPort + ".");
279 throw (ex);
280 }
281
282 WellKnownServiceTypeEntry wellType =
283 new WellKnownServiceTypeEntry(typeof(OGS1InterRegionRemoting), "InterRegions",
284 WellKnownObjectMode.Singleton);
285 RemotingConfiguration.RegisterWellKnownServiceType(wellType);
286 InterRegionSingleton.Instance.OnArrival += TriggerExpectAvatarCrossing;
287 InterRegionSingleton.Instance.OnChildAgent += IncomingChildAgent;
288 InterRegionSingleton.Instance.OnPrimGroupArrival += IncomingPrim;
289 InterRegionSingleton.Instance.OnPrimGroupNear += TriggerExpectPrimCrossing;
290 InterRegionSingleton.Instance.OnRegionUp += TriggerRegionUp;
291 InterRegionSingleton.Instance.OnChildAgentUpdate += TriggerChildAgentUpdate;
292 InterRegionSingleton.Instance.OnTellRegionToCloseChildConnection += TriggerTellRegionToCloseChildConnection;
293 }
294
295
296 #endregion
297
298 #region IInterRegionCommunications interface (Methods called by regions in this instance)
299
300 public override bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
301 {
302 int failures = 0;
303 lock (m_deadRegionCache)
304 {
305 if (m_deadRegionCache.ContainsKey(regionHandle))
306 {
307 failures = m_deadRegionCache[regionHandle];
308 }
309 }
310 if (failures <= 3)
311 {
312 RegionInfo regInfo = null;
313 try
314 {
315 if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData))
316 {
317 return true;
318 }
319
320 regInfo = RequestNeighbourInfo(regionHandle);
321 if (regInfo != null)
322 {
323 //don't want to be creating a new link to the remote instance every time like we are here
324 bool retValue = false;
325
326
327 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
328 typeof(OGS1InterRegionRemoting),
329 "tcp://" + regInfo.RemotingAddress +
330 ":" + regInfo.RemotingPort +
331 "/InterRegions");
332
333 if (remObject != null)
334 {
335 retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData);
336 }
337 else
338 {
339 m_log.Warn("[HGrid]: remoting object not found");
340 }
341 remObject = null;
342
343 return retValue;
344 }
345 NoteDeadRegion(regionHandle);
346
347 return false;
348 }
349 catch (RemotingException e)
350 {
351 NoteDeadRegion(regionHandle);
352
353 m_log.WarnFormat(
354 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
355 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
356 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
357
358 return false;
359 }
360 catch (SocketException e)
361 {
362 NoteDeadRegion(regionHandle);
363
364 m_log.WarnFormat(
365 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
366 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
367 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
368
369 return false;
370 }
371 catch (InvalidCredentialException e)
372 {
373 NoteDeadRegion(regionHandle);
374
375 m_log.WarnFormat(
376 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
377 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
378 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
379
380 return false;
381 }
382 catch (AuthenticationException e)
383 {
384 NoteDeadRegion(regionHandle);
385
386 m_log.WarnFormat(
387 "[HGrid]: Remoting Error: Unable to connect to adjacent region: {0} {1},{2}",
388 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
389 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
390
391 return false;
392 }
393 catch (Exception e)
394 {
395 NoteDeadRegion(regionHandle);
396
397 m_log.WarnFormat("[HGrid]: Unable to connect to adjacent region: {0} {1},{2}",
398 regInfo.RegionName, regInfo.RegionLocX, regInfo.RegionLocY);
399 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
400
401 return false;
402 }
403 }
404 else
405 {
406 //m_log.Info("[INTERREGION]: Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString());
407 return false;
408 }
409 }
410
411 /// <summary>
412 /// Inform a region that a child agent will be on the way from a client.
413 /// </summary>
414 /// <param name="regionHandle"></param>
415 /// <param name="agentData"></param>
416 /// <returns></returns>
417 public override bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData)
418 {
419
420 if (m_localBackend.InformRegionOfChildAgent(regionHandle, agentData))
421 {
422 return true;
423 }
424 return base.InformRegionOfChildAgent(regionHandle, agentData);
425 }
426
427 // UGLY!
428 public override bool RegionUp(SerializableRegionInfo region, ulong regionhandle)
429 {
430 if (m_localBackend.RegionUp(region, regionhandle))
431 return true;
432 return base.RegionUp(region, regionhandle);
433 }
434
435 /// <summary>
436 ///
437 /// </summary>
438 /// <param name="regionHandle"></param>
439 /// <param name="agentData"></param>
440 /// <returns></returns>
441 public override bool InformRegionOfPrimCrossing(ulong regionHandle, UUID primID, string objData, int XMLMethod)
442 {
443 int failures = 0;
444 lock (m_deadRegionCache)
445 {
446 if (m_deadRegionCache.ContainsKey(regionHandle))
447 {
448 failures = m_deadRegionCache[regionHandle];
449 }
450 }
451 if (failures <= 1)
452 {
453 RegionInfo regInfo = null;
454 try
455 {
456 if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData, XMLMethod))
457 {
458 return true;
459 }
460
461 regInfo = RequestNeighbourInfo(regionHandle);
462 if (regInfo != null)
463 {
464 //don't want to be creating a new link to the remote instance every time like we are here
465 bool retValue = false;
466
467 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
468 typeof(OGS1InterRegionRemoting),
469 "tcp://" + regInfo.RemotingAddress +
470 ":" + regInfo.RemotingPort +
471 "/InterRegions");
472
473 if (remObject != null)
474 {
475 retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod);
476 }
477 else
478 {
479 m_log.Warn("[HGrid]: Remoting object not found");
480 }
481 remObject = null;
482
483 return retValue;
484 }
485 NoteDeadRegion(regionHandle);
486 return false;
487 }
488 catch (RemotingException e)
489 {
490 NoteDeadRegion(regionHandle);
491 m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
492 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
493 return false;
494 }
495 catch (SocketException e)
496 {
497 NoteDeadRegion(regionHandle);
498 m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
499 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
500 return false;
501 }
502 catch (InvalidCredentialException e)
503 {
504 NoteDeadRegion(regionHandle);
505 m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
506 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
507 return false;
508 }
509 catch (AuthenticationException e)
510 {
511 NoteDeadRegion(regionHandle);
512 m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
513 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
514 return false;
515 }
516 catch (Exception e)
517 {
518 NoteDeadRegion(regionHandle);
519 m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
520 m_log.DebugFormat("[HGrid]: {0}", e);
521 return false;
522 }
523 }
524 else
525 {
526 return false;
527 }
528 }
529
530 /// <summary>
531 ///
532 /// </summary>
533 /// <param name="regionHandle"></param>
534 /// <param name="agentID"></param>
535 /// <param name="position"></param>
536 /// <returns></returns>
537 public override bool ExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
538 {
539
540 RegionInfo[] regions = m_regionsOnInstance.ToArray();
541 bool banned = false;
542 bool localregion = false;
543
544 for (int i = 0; i < regions.Length; i++)
545 {
546 if (regions[i] != null)
547 {
548 if (regions[i].RegionHandle == regionHandle)
549 {
550 localregion = true;
551 if (regions[i].EstateSettings.IsBanned(agentID))
552 {
553 banned = true;
554 break;
555 }
556 }
557 }
558 }
559
560 if (banned)
561 return false;
562 if (localregion)
563 return m_localBackend.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
564
565 return base.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
566
567 }
568
569 public override bool ExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical)
570 {
571 RegionInfo regInfo = null;
572 try
573 {
574 if (m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical))
575 {
576 return true;
577 }
578
579 regInfo = RequestNeighbourInfo(regionHandle);
580 if (regInfo != null)
581 {
582 bool retValue = false;
583 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
584 typeof(OGS1InterRegionRemoting),
585 "tcp://" + regInfo.RemotingAddress +
586 ":" + regInfo.RemotingPort +
587 "/InterRegions");
588
589 if (remObject != null)
590 {
591 retValue =
592 remObject.ExpectAvatarCrossing(regionHandle, agentID.Guid, new sLLVector3(position),
593 isPhysical);
594 }
595 else
596 {
597 m_log.Warn("[HGrid]: Remoting object not found");
598 }
599 remObject = null;
600
601 return retValue;
602 }
603 //TODO need to see if we know about where this region is and use .net remoting
604 // to inform it.
605 NoteDeadRegion(regionHandle);
606 return false;
607 }
608 catch (RemotingException e)
609 {
610 NoteDeadRegion(regionHandle);
611 m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
612 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
613 return false;
614 }
615 catch (SocketException e)
616 {
617 NoteDeadRegion(regionHandle);
618 m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region: " + regionHandle);
619 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
620 return false;
621 }
622 catch (InvalidCredentialException e)
623 {
624 NoteDeadRegion(regionHandle);
625 m_log.Warn("[HGrid]: Invalid Credential Exception: Invalid Credentials : " + regionHandle);
626 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
627 return false;
628 }
629 catch (AuthenticationException e)
630 {
631 NoteDeadRegion(regionHandle);
632 m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region: " + regionHandle);
633 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
634 return false;
635 }
636 catch (Exception e)
637 {
638 NoteDeadRegion(regionHandle);
639 m_log.Warn("[HGrid]: Unknown exception: Unable to connect to adjacent region: " + regionHandle);
640 m_log.DebugFormat("[HGrid]: {0}", e);
641 return false;
642 }
643 }
644
645 public override bool TellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
646 {
647 RegionInfo regInfo = null;
648 try
649 {
650 if (m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID))
651 {
652 return true;
653 }
654
655 regInfo = RequestNeighbourInfo(regionHandle);
656 if (regInfo != null)
657 {
658 // bool retValue = false;
659 OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
660 typeof(OGS1InterRegionRemoting),
661 "tcp://" + regInfo.RemotingAddress +
662 ":" + regInfo.RemotingPort +
663 "/InterRegions");
664
665 if (remObject != null)
666 {
667 // retValue =
668 remObject.TellRegionToCloseChildConnection(regionHandle, agentID.Guid);
669 }
670 else
671 {
672 m_log.Warn("[HGrid]: Remoting object not found");
673 }
674 remObject = null;
675
676 return true;
677 }
678 //TODO need to see if we know about where this region is and use .net remoting
679 // to inform it.
680 NoteDeadRegion(regionHandle);
681 return false;
682 }
683 catch (RemotingException)
684 {
685 NoteDeadRegion(regionHandle);
686 m_log.Warn("[HGrid]: Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName +
687 " " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
688 //m_log.Debug(e.ToString());
689 return false;
690 }
691 catch (SocketException e)
692 {
693 NoteDeadRegion(regionHandle);
694 m_log.Warn("[HGridS]: Socket Error: Unable to connect to adjacent region using tcp://" +
695 regInfo.RemotingAddress +
696 ":" + regInfo.RemotingPort +
697 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY +
698 " - Is this neighbor up?");
699 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
700 return false;
701 }
702 catch (InvalidCredentialException e)
703 {
704 NoteDeadRegion(regionHandle);
705 m_log.Warn("[HGrid]: Invalid Credentials: Unable to connect to adjacent region using tcp://" +
706 regInfo.RemotingAddress +
707 ":" + regInfo.RemotingPort +
708 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
709 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
710 return false;
711 }
712 catch (AuthenticationException e)
713 {
714 NoteDeadRegion(regionHandle);
715 m_log.Warn("[HGrid]: Authentication exception: Unable to connect to adjacent region using tcp://" +
716 regInfo.RemotingAddress +
717 ":" + regInfo.RemotingPort +
718 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
719 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
720 return false;
721 }
722 catch (WebException e)
723 {
724 NoteDeadRegion(regionHandle);
725 m_log.Warn("[HGrid]: WebException exception: Unable to connect to adjacent region using tcp://" +
726 regInfo.RemotingAddress +
727 ":" + regInfo.RemotingPort +
728 "/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY);
729 m_log.DebugFormat("[HGrid]: {0} {1}", e.Source, e.Message);
730 return false;
731 }
732 catch (Exception e)
733 {
734 NoteDeadRegion(regionHandle);
735 // This line errors with a Null Reference Exception.. Why? @.@
736 //m_log.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress +
737 // ":" + regInfo.RemotingPort +
738 //"/InterRegions - @ " + regInfo.RegionLocX + "," + regInfo.RegionLocY + " - This is likely caused by an incompatibility in the protocol between this sim and that one");
739 m_log.DebugFormat("[HGrid]: {0}", e);
740 return false;
741 }
742 }
743
744 public override bool AcknowledgeAgentCrossed(ulong regionHandle, UUID agentId)
745 {
746 return m_localBackend.AcknowledgeAgentCrossed(regionHandle, agentId);
747 }
748
749 public override bool AcknowledgePrimCrossed(ulong regionHandle, UUID primId)
750 {
751 return m_localBackend.AcknowledgePrimCrossed(regionHandle, primId);
752 }
753
754 #endregion
755
756 #region Methods triggered by calls from external instances
757
758 /// <summary>
759 ///
760 /// </summary>
761 /// <param name="regionHandle"></param>
762 /// <param name="agentData"></param>
763 /// <returns></returns>
764 public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData)
765 {
766 HGIncomingChildAgent(regionHandle, agentData);
767
768 m_log.Info("[HGrid]: " + gdebugRegionName + ": Incoming HGrid Agent " + agentData.firstname + " " + agentData.lastname);
769
770 return m_localBackend.IncomingChildAgent(regionHandle, agentData);
771 }
772
773 public bool TriggerRegionUp(RegionUpData regionData, ulong regionhandle)
774 {
775 m_log.Info(
776 "[HGrid]: " +
777 m_localBackend._gdebugRegionName + "Incoming HGrid RegionUpReport: " + "(" + regionData.X +
778 "," + regionData.Y + "). Giving this region a fresh set of 'dead' tries");
779
780 RegionInfo nRegionInfo = new RegionInfo();
781 nRegionInfo.SetEndPoint("127.0.0.1", regionData.PORT);
782 nRegionInfo.ExternalHostName = regionData.IPADDR;
783 nRegionInfo.RegionLocX = regionData.X;
784 nRegionInfo.RegionLocY = regionData.Y;
785
786 lock (m_deadRegionCache)
787 {
788 if (m_deadRegionCache.ContainsKey(nRegionInfo.RegionHandle))
789 {
790 m_deadRegionCache.Remove(nRegionInfo.RegionHandle);
791 }
792 }
793
794 return m_localBackend.TriggerRegionUp(nRegionInfo, regionhandle);
795 }
796
797 public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
798 {
799 //m_log.Info("[INTER]: Incoming HGrid Child Agent Data Update");
800
801 return m_localBackend.TriggerChildAgentUpdate(regionHandle, cAgentData);
802 }
803
804 /// <summary>
805 ///
806 /// </summary>
807 /// <param name="regionHandle"></param>
808 /// <param name="agentData"></param>
809 /// <returns></returns>
810 public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod)
811 {
812 m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod);
813
814 return true;
815 }
816
817 /// <summary>
818 ///
819 /// </summary>
820 /// <param name="regionHandle"></param>
821 /// <param name="agentID"></param>
822 /// <param name="position"></param>
823 /// <returns></returns>
824 public bool TriggerExpectAvatarCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
825 {
826 return m_localBackend.TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying);
827 }
828
829 public bool TriggerExpectPrimCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isPhysical)
830 {
831 return m_localBackend.TriggerExpectPrimCrossing(regionHandle, agentID, position, isPhysical);
832 }
833
834 public bool TriggerTellRegionToCloseChildConnection(ulong regionHandle, UUID agentID)
835 {
836 return m_localBackend.TriggerTellRegionToCloseChildConnection(regionHandle, agentID);
837 }
838
839 int timeOut = 10; //10 seconds
840 /// <summary>
841 /// Check that a region is available for TCP comms. This is necessary for .NET remoting between regions.
842 /// </summary>
843 /// <param name="address"></param>
844 /// <param name="port"></param>
845 /// <param name="retry"></param>
846 /// <returns></returns>
847 public bool CheckRegion(string address, uint port, bool retry)
848 {
849 bool available = false;
850 bool timed_out = true;
851
852 IPAddress ia;
853 IPAddress.TryParse(address, out ia);
854 IPEndPoint m_EndPoint = new IPEndPoint(ia, (int)port);
855
856 AsyncCallback callback = delegate(IAsyncResult iar)
857 {
858 Socket s = (Socket)iar.AsyncState;
859 try
860 {
861 s.EndConnect(iar);
862 available = true;
863 timed_out = false;
864 }
865 catch (Exception e)
866 {
867 m_log.DebugFormat(
868 "[HGrid]: Callback EndConnect exception: {0}:{1}", e.Message, e.StackTrace);
869 }
870
871 s.Close();
872 };
873
874 try
875 {
876 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
877 IAsyncResult ar = socket.BeginConnect(m_EndPoint, callback, socket);
878 ar.AsyncWaitHandle.WaitOne(timeOut * 1000, false);
879 }
880 catch (Exception e)
881 {
882 m_log.DebugFormat(
883 "[HGrid]: CheckRegion Socket Setup exception: {0}:{1}", e.Message, e.StackTrace);
884
885 return false;
886 }
887
888 if (timed_out)
889 {
890 m_log.DebugFormat(
891 "[HGrid]: socket [{0}] timed out ({1}) waiting to obtain a connection.",
892 m_EndPoint, timeOut * 1000);
893
894 if (retry)
895 {
896 return CheckRegion(address, port, false);
897 }
898 }
899
900 return available;
901 }
902
903 public override bool CheckRegion(string address, uint port)
904 {
905 return CheckRegion(address, port, true);
906 }
907
908 public void NoteDeadRegion(ulong regionhandle)
909 {
910 lock (m_deadRegionCache)
911 {
912 if (m_deadRegionCache.ContainsKey(regionhandle))
913 {
914 m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1;
915 }
916 else
917 {
918 m_deadRegionCache.Add(regionhandle, 1);
919 }
920 }
921
922 }
923
924 #endregion
925
926
927 }
928}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs b/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs
new file mode 100644
index 0000000..9ef040b
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs
@@ -0,0 +1,451 @@
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 OpenSim 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;
32using OpenMetaverse;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Communications.Cache;
37using OpenSim.Framework.Servers;
38using OpenSim.Framework.Statistics;
39using OpenSim.Region.Communications.Local;
40
41namespace OpenSim.Region.Communications.Hypergrid
42{
43 public class HGInventoryService : LocalInventoryService, ISecureInventoryService
44 {
45 private static readonly ILog m_log
46 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private string _inventoryServerUrl;
49 private Uri m_Uri;
50 private UserProfileCacheService m_userProfileCache;
51 private bool m_gridmode = false;
52
53 private Dictionary<UUID, InventoryReceiptCallback> m_RequestingInventory
54 = new Dictionary<UUID, InventoryReceiptCallback>();
55
56 public UserProfileCacheService UserProfileCache
57 {
58 set { m_userProfileCache = value; }
59 }
60
61 public HGInventoryService(string inventoryServerUrl, UserProfileCacheService userProfileCacheService, bool gridmode)
62 {
63 _inventoryServerUrl = HGNetworkServersInfo.ServerURI(inventoryServerUrl);
64 m_Uri = new Uri(_inventoryServerUrl);
65 m_userProfileCache = userProfileCacheService;
66 m_gridmode = gridmode;
67 }
68
69 #region ISecureInventoryService Members
70
71 public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback)
72 {
73 if (IsLocalStandaloneUser(userID))
74 {
75 base.RequestInventoryForUser(userID, callback);
76 return;
77 }
78
79 // grid/hypergrid mode
80 if (!m_RequestingInventory.ContainsKey(userID))
81 {
82 m_RequestingInventory.Add(userID, callback);
83
84 try
85 {
86 string invServer = GetUserInventoryURI(userID);
87 m_log.InfoFormat(
88 "[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})",
89 /*_inventoryServerUrl*/ invServer, userID, userID.Guid);
90
91
92 RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
93 = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
94 requester.ResponseCallback = InventoryResponse;
95
96 requester.BeginPostObject(invServer + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString());
97
98 //Test(userID.Guid);
99
100 //RestObjectPosterResponse<InventoryCollection> requester
101 // = new RestObjectPosterResponse<InventoryCollection>();
102 //requester.ResponseCallback = InventoryResponse;
103
104 //requester.BeginPostObject<Guid>(/*_inventoryServerUrl*/ invServer + "/GetInventory/", userID.Guid);
105
106 //RestClient cli = new RestClient(invServer + "/GetInventory/" + userID.Guid);
107 //Stream reply = cli.Request();
108 }
109 catch (WebException e)
110 {
111 if (StatsManager.SimExtraStats != null)
112 StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
113
114 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Request inventory operation failed, {0} {1}",
115 e.Source, e.Message);
116 }
117 }
118 else
119 {
120 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID);
121 }
122
123 }
124
125 /// <summary>
126 /// Add a new folder to the user's inventory
127 /// </summary>
128 /// <param name="folder"></param>
129 /// <returns>true if the folder was successfully added</returns>
130 public bool AddFolder(InventoryFolderBase folder, UUID session_id)
131 {
132 if (IsLocalStandaloneUser(folder.Owner))
133 {
134 return base.AddFolder(folder);
135 }
136
137 try
138 {
139 string invServ = GetUserInventoryURI(folder.Owner);
140
141 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
142 "POST", invServ + "/NewFolder/", folder, session_id.ToString(), folder.Owner.ToString());
143 }
144 catch (WebException e)
145 {
146 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Add new inventory folder operation failed, {0} {1}",
147 e.Source, e.Message);
148 }
149
150 return false;
151
152 }
153
154 /// <summary>
155 /// Update a folder in the user's inventory
156 /// </summary>
157 /// <param name="folder"></param>
158 /// <returns>true if the folder was successfully updated</returns>
159 public bool UpdateFolder(InventoryFolderBase folder, UUID session_id)
160 {
161 if (IsLocalStandaloneUser(folder.Owner))
162 {
163 return base.UpdateFolder(folder);
164 }
165 try
166 {
167 string invServ = GetUserInventoryURI(folder.Owner);
168
169 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
170 "POST", invServ + "/UpdateFolder/", folder, session_id.ToString(), folder.Owner.ToString());
171 }
172 catch (WebException e)
173 {
174 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Update inventory folder operation failed, {0} {1}",
175 e.Source, e.Message);
176 }
177
178 return false;
179
180 }
181
182 /// <summary>
183 /// Move an inventory folder to a new location
184 /// </summary>
185 /// <param name="folder">A folder containing the details of the new location</param>
186 /// <returns>true if the folder was successfully moved</returns>
187 public bool MoveFolder(InventoryFolderBase folder, UUID session_id)
188 {
189 if (IsLocalStandaloneUser(folder.Owner))
190 {
191 return base.MoveFolder(folder);
192 }
193
194 try
195 {
196 string invServ = GetUserInventoryURI(folder.Owner);
197
198 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
199 "POST", invServ + "/MoveFolder/", folder, session_id.ToString(), folder.Owner.ToString());
200 }
201 catch (WebException e)
202 {
203 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Move inventory folder operation failed, {0} {1}",
204 e.Source, e.Message);
205 }
206
207 return false;
208 }
209
210 /// <summary>
211 /// Purge an inventory folder of all its items and subfolders.
212 /// </summary>
213 /// <param name="folder"></param>
214 /// <returns>true if the folder was successfully purged</returns>
215 public bool PurgeFolder(InventoryFolderBase folder, UUID session_id)
216 {
217 if (IsLocalStandaloneUser(folder.Owner))
218 {
219 return base.PurgeFolder(folder);
220 }
221
222 try
223 {
224 string invServ = GetUserInventoryURI(folder.Owner);
225
226 return SynchronousRestSessionObjectPoster<InventoryFolderBase, bool>.BeginPostObject(
227 "POST", invServ + "/PurgeFolder/", folder, session_id.ToString(), folder.Owner.ToString());
228 }
229 catch (WebException e)
230 {
231 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Move inventory folder operation failed, {0} {1}",
232 e.Source, e.Message);
233 }
234
235 return false;
236 }
237
238 /// <summary>
239 /// Add a new item to the user's inventory
240 /// </summary>
241 /// <param name="item"></param>
242 /// <returns>true if the item was successfully added</returns>
243 public bool AddItem(InventoryItemBase item, UUID session_id)
244 {
245 if (IsLocalStandaloneUser(item.Owner))
246 {
247 return base.AddItem(item);
248 }
249
250 try
251 {
252 string invServ = GetUserInventoryURI(item.Owner);
253
254 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
255 "POST", invServ + "/NewItem/", item, session_id.ToString(), item.Owner.ToString());
256 }
257 catch (WebException e)
258 {
259 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Add new inventory item operation failed, {0} {1}",
260 e.Source, e.Message);
261 }
262
263 return false;
264 }
265
266 /// <summary>
267 /// Update an item in the user's inventory
268 /// </summary>
269 /// <param name="item"></param>
270 /// <returns>true if the item was successfully updated</returns>
271 public bool UpdateItem(InventoryItemBase item, UUID session_id)
272 {
273 if (IsLocalStandaloneUser(item.Owner))
274 {
275 return base.UpdateItem(item);
276 }
277
278 try
279 {
280 string invServ = GetUserInventoryURI(item.Owner);
281 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
282 "POST", invServ + "/NewItem/", item, session_id.ToString(), item.Owner.ToString());
283 }
284 catch (WebException e)
285 {
286 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Update new inventory item operation failed, {0} {1}",
287 e.Source, e.Message);
288 }
289
290 return false;
291 }
292
293 /// <summary>
294 /// Delete an item from the user's inventory
295 /// </summary>
296 /// <param name="item"></param>
297 /// <returns>true if the item was successfully deleted</returns>
298 public bool DeleteItem(InventoryItemBase item, UUID session_id)
299 {
300 if (IsLocalStandaloneUser(item.Owner))
301 {
302 return base.DeleteItem(item);
303 }
304
305 try
306 {
307 string invServ = GetUserInventoryURI(item.Owner);
308
309 return SynchronousRestSessionObjectPoster<InventoryItemBase, bool>.BeginPostObject(
310 "POST", invServ + "/DeleteItem/", item, session_id.ToString(), item.Owner.ToString());
311 }
312 catch (WebException e)
313 {
314 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Delete inventory item operation failed, {0} {1}",
315 e.Source, e.Message);
316 }
317
318 return false;
319 }
320 #endregion
321
322 #region Methods common to ISecureInventoryService and IInventoryService
323
324 /// <summary>
325 /// Does the given user have an inventory structure?
326 /// </summary>
327 /// <param name="userID"></param>
328 /// <returns></returns>
329 public override bool HasInventoryForUser(UUID userID)
330 {
331 if (IsLocalStandaloneUser(userID))
332 {
333 return base.HasInventoryForUser(userID);
334 }
335 return false;
336 }
337
338 /// <summary>
339 /// Retrieve the root inventory folder for the given user.
340 /// </summary>
341 /// <param name="userID"></param>
342 /// <returns>null if no root folder was found</returns>
343 public override InventoryFolderBase RequestRootFolder(UUID userID)
344 {
345 if (IsLocalStandaloneUser(userID))
346 {
347 return base.RequestRootFolder(userID);
348 }
349
350 return null;
351 }
352
353 #endregion
354
355
356 /// <summary>
357 /// Callback used by the inventory server GetInventory request
358 /// </summary>
359 /// <param name="userID"></param>
360 private void InventoryResponse(InventoryCollection response)
361 {
362 UUID userID = response.UserID;
363 if (m_RequestingInventory.ContainsKey(userID))
364 {
365 m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " +
366 "Received inventory response for user {0} containing {1} folders and {2} items",
367 userID, response.Folders.Count, response.Items.Count);
368
369 InventoryFolderImpl rootFolder = null;
370 InventoryReceiptCallback callback = m_RequestingInventory[userID];
371
372 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
373 ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
374
375 foreach (InventoryFolderBase folder in response.Folders)
376 {
377 if (folder.ParentID == UUID.Zero)
378 {
379 rootFolder = new InventoryFolderImpl(folder);
380 folders.Add(rootFolder);
381
382 break;
383 }
384 }
385
386 if (rootFolder != null)
387 {
388 foreach (InventoryFolderBase folder in response.Folders)
389 {
390 if (folder.ID != rootFolder.ID)
391 {
392 folders.Add(new InventoryFolderImpl(folder));
393 }
394 }
395
396 foreach (InventoryItemBase item in response.Items)
397 {
398 items.Add(item);
399 }
400 }
401 else
402 {
403 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID);
404 }
405
406 callback(folders, items);
407
408 m_RequestingInventory.Remove(userID);
409 }
410 else
411 {
412 m_log.WarnFormat(
413 "[HGrid INVENTORY SERVICE]: " +
414 "Received inventory response for {0} for which we do not have a record of requesting!",
415 userID);
416 }
417 }
418
419
420 private bool IsLocalStandaloneUser(UUID userID)
421 {
422 CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID);
423 if (uinfo == null)
424 return true;
425
426 string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI);
427
428 if ((!m_gridmode) && ((userInventoryServerURI == _inventoryServerUrl)) || (userInventoryServerURI == ""))
429 {
430 return true;
431 }
432 return false;
433 }
434
435 private string GetUserInventoryURI(UUID userID)
436 {
437 string invURI = _inventoryServerUrl;
438 CachedUserInfo uinfo = m_userProfileCache.GetUserDetails(userID);
439 if ((uinfo == null) || (uinfo.UserProfile == null))
440 return invURI;
441
442 string userInventoryServerURI = HGNetworkServersInfo.ServerURI(uinfo.UserProfile.UserInventoryURI);
443
444 if ((userInventoryServerURI != null) &&
445 (userInventoryServerURI != ""))
446 invURI = userInventoryServerURI;
447 return invURI;
448 }
449
450 }
451}
diff --git a/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs b/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs
new file mode 100644
index 0000000..d9b44a1
--- /dev/null
+++ b/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs
@@ -0,0 +1,267 @@
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 OpenSim 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;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using OpenMetaverse;
35using log4net;
36using Nwc.XmlRpc;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Region.Communications.OGS1;
40
41namespace OpenSim.Region.Communications.Hypergrid
42{
43 /// <summary>
44 /// For the time being, this class is just an identity wrapper around OGS1UserServices,
45 /// so it always fails for foreign users.
46 /// Later it needs to talk with the foreign users' user servers.
47 /// </summary>
48 public class HGUserServices : IUserService, IAvatarService, IMessagingService
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private HGCommunicationsGridMode m_parent;
53 private OGS1UserServices m_remoteUserServices;
54
55 public HGUserServices(HGCommunicationsGridMode parent)
56 {
57 m_parent = parent;
58 m_remoteUserServices = new OGS1UserServices(parent);
59 }
60
61 public UserProfileData ConvertXMLRPCDataToUserProfile(Hashtable data)
62 {
63 return m_remoteUserServices.ConvertXMLRPCDataToUserProfile(data);
64 }
65
66 /// <summary>
67 /// Get a user agent from the user server
68 /// </summary>
69 /// <param name="avatarID"></param>
70 /// <returns>null if the request fails</returns>
71 public UserAgentData GetAgentByUUID(UUID userId)
72 {
73 return m_remoteUserServices.GetAgentByUUID(userId);
74 }
75
76 public AvatarAppearance ConvertXMLRPCDataToAvatarAppearance(Hashtable data)
77 {
78 return m_remoteUserServices.ConvertXMLRPCDataToAvatarAppearance(data);
79 }
80
81 public List<AvatarPickerAvatar> ConvertXMLRPCDataToAvatarPickerList(UUID queryID, Hashtable data)
82 {
83 return m_remoteUserServices.ConvertXMLRPCDataToAvatarPickerList(queryID, data);
84 }
85
86 public List<FriendListItem> ConvertXMLRPCDataToFriendListItemList(Hashtable data)
87 {
88 return m_remoteUserServices.ConvertXMLRPCDataToFriendListItemList(data);
89 }
90
91 /// <summary>
92 /// Logs off a user on the user server
93 /// </summary>
94 /// <param name="UserID">UUID of the user</param>
95 /// <param name="regionID">UUID of the Region</param>
96 /// <param name="regionhandle">regionhandle</param>
97 /// <param name="position">final position</param>
98 /// <param name="lookat">final lookat</param>
99 public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, Vector3 position, Vector3 lookat)
100 {
101 m_remoteUserServices.LogOffUser(userid, regionid, regionhandle, position, lookat);
102 }
103
104 /// <summary>
105 /// Logs off a user on the user server (deprecated as of 2008-08-27)
106 /// </summary>
107 /// <param name="UserID">UUID of the user</param>
108 /// <param name="regionID">UUID of the Region</param>
109 /// <param name="regionhandle">regionhandle</param>
110 /// <param name="posx">final position x</param>
111 /// <param name="posy">final position y</param>
112 /// <param name="posz">final position z</param>
113 public void LogOffUser(UUID userid, UUID regionid, ulong regionhandle, float posx, float posy, float posz)
114 {
115 m_remoteUserServices.LogOffUser(userid, regionid, regionhandle, posx, posy, posz);
116 }
117
118 public UserProfileData GetUserProfile(string firstName, string lastName)
119 {
120 return GetUserProfile(firstName + " " + lastName);
121 }
122
123 public void UpdateUserCurrentRegion(UUID avatarid, UUID regionuuid, ulong regionhandle)
124 {
125 m_remoteUserServices.UpdateUserCurrentRegion(avatarid, regionuuid, regionhandle);
126 }
127
128 public List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(UUID queryID, string query)
129 {
130 return m_remoteUserServices.GenerateAgentPickerRequestResponse(queryID, query);
131 }
132
133 /// <summary>
134 /// Get a user profile from the user server
135 /// </summary>
136 /// <param name="avatarID"></param>
137 /// <returns>null if the request fails</returns>
138 public UserProfileData GetUserProfile(string name)
139 {
140 return m_remoteUserServices.GetUserProfile(name);
141 }
142
143 /// <summary>
144 /// Get a user profile from the user server
145 /// </summary>
146 /// <param name="avatarID"></param>
147 /// <returns>null if the request fails</returns>
148 public UserProfileData GetUserProfile(UUID avatarID)
149 {
150 return m_remoteUserServices.GetUserProfile(avatarID);
151 }
152
153
154 public void ClearUserAgent(UUID avatarID)
155 {
156 m_remoteUserServices.ClearUserAgent(avatarID);
157 }
158
159 /// <summary>
160 /// Retrieve the user information for the given master uuid.
161 /// </summary>
162 /// <param name="uuid"></param>
163 /// <returns></returns>
164 public UserProfileData SetupMasterUser(string firstName, string lastName)
165 {
166 return m_remoteUserServices.SetupMasterUser(firstName, lastName);
167 }
168
169 /// <summary>
170 /// Retrieve the user information for the given master uuid.
171 /// </summary>
172 /// <param name="uuid"></param>
173 /// <returns></returns>
174 public UserProfileData SetupMasterUser(string firstName, string lastName, string password)
175 {
176 return m_remoteUserServices.SetupMasterUser(firstName, lastName, password);
177 }
178
179 /// <summary>
180 /// Retrieve the user information for the given master uuid.
181 /// </summary>
182 /// <param name="uuid"></param>
183 /// <returns></returns>
184 public UserProfileData SetupMasterUser(UUID uuid)
185 {
186 return m_remoteUserServices.SetupMasterUser(uuid);
187 }
188
189 public UUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY)
190 {
191 return m_remoteUserServices.AddUserProfile(firstName, lastName, pass, regX, regY);
192 }
193
194 public bool ResetUserPassword(string firstName, string lastName, string newPassword)
195 {
196 return m_remoteUserServices.ResetUserPassword(firstName, lastName, newPassword);
197 }
198
199 public bool UpdateUserProfile(UserProfileData userProfile)
200 {
201 return m_remoteUserServices.UpdateUserProfile(userProfile);
202 }
203
204 #region IUserServices Friend Methods
205 /// <summary>
206 /// Adds a new friend to the database for XUser
207 /// </summary>
208 /// <param name="friendlistowner">The agent that who's friends list is being added to</param>
209 /// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
210 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
211 public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
212 {
213 m_remoteUserServices.AddNewUserFriend(friendlistowner, friend, perms);
214 }
215
216 /// <summary>
217 /// Delete friend on friendlistowner's friendlist.
218 /// </summary>
219 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
220 /// <param name="friend">The Ex-friend agent</param>
221 public void RemoveUserFriend(UUID friendlistowner, UUID friend)
222 {
223 m_remoteUserServices.RemoveUserFriend(friend, friend);
224 }
225
226 /// <summary>
227 /// Update permissions for friend on friendlistowner's friendlist.
228 /// </summary>
229 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
230 /// <param name="friend">The agent that is getting or loosing permissions</param>
231 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
232 public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
233 {
234 m_remoteUserServices.UpdateUserFriendPerms(friendlistowner, friend, perms);
235 }
236 /// <summary>
237 /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for UUID friendslistowner
238 /// </summary>
239 /// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
240 public List<FriendListItem> GetUserFriendList(UUID friendlistowner)
241 {
242 return m_remoteUserServices.GetUserFriendList(friendlistowner);
243 }
244
245 #endregion
246
247 /// Appearance
248 public AvatarAppearance GetUserAppearance(UUID user)
249 {
250 return m_remoteUserServices.GetUserAppearance(user);
251 }
252
253 public void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
254 {
255 m_remoteUserServices.UpdateUserAppearance(user, appearance);
256 }
257
258 #region IMessagingService
259
260 public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos(List<UUID> uuids)
261 {
262 return m_remoteUserServices.GetFriendRegionInfos(uuids);
263 }
264 #endregion
265
266 }
267}
diff --git a/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs
new file mode 100644
index 0000000..cfcda42
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs
@@ -0,0 +1,199 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using log4net;
35using Nini.Config;
36
37using OpenMetaverse;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Cache;
42using OpenSim.Framework.Servers;
43using OpenSim.Region.Environment.Interfaces;
44using OpenSim.Region.Environment.Scenes;
45using OpenSim.Grid.AssetServer;
46
47namespace OpenSim.Region.Environment.Modules.Hypergrid
48{
49 public class HGStandaloneAssetService : IRegionModule
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 private static bool initialized = false;
53 private static bool enabled = false;
54
55 Scene m_scene;
56 AssetService m_assetService;
57
58 #region IRegionModule interface
59
60 public void Initialise(Scene scene, IConfigSource config)
61 {
62 if (!initialized)
63 {
64 initialized = true;
65 m_scene = scene;
66
67 // This module is only on for standalones in hypergrid mode
68 enabled = !config.Configs["Startup"].GetBoolean("gridmode", true) && config.Configs["Startup"].GetBoolean("hypergrid", false);
69 }
70 }
71
72 public void PostInitialise()
73 {
74 if (enabled)
75 {
76 m_log.Info("[HGStandaloneAssetService]: Starting...");
77
78 m_assetService = new AssetService(m_scene);
79 }
80 }
81
82 public void Close()
83 {
84 }
85
86 public string Name
87 {
88 get { return "HGStandaloneAssetService"; }
89 }
90
91 public bool IsSharedModule
92 {
93 get { return true; }
94 }
95
96 #endregion
97
98 }
99
100 public class AssetService
101 {
102 private IUserService m_userService;
103 private bool m_doLookup = false;
104
105 public bool DoLookup
106 {
107 get { return m_doLookup; }
108 set { m_doLookup = value; }
109 }
110 private static readonly ILog m_log
111 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
112
113 public AssetService(Scene m_scene)
114 {
115 AddHttpHandlers(m_scene);
116 m_userService = m_scene.CommsManager.UserService;
117 }
118
119 protected void AddHttpHandlers(Scene m_scene)
120 {
121 IAssetProviderPlugin m_assetProvider = ((AssetServerBase)m_scene.AssetCache.AssetServer).AssetProviderPlugin;
122
123 m_scene.AddStreamHandler(new GetAssetStreamHandler(m_assetProvider));
124 m_scene.AddStreamHandler(new PostAssetStreamHandler(m_assetProvider));
125
126 }
127
128
129 ///// <summary>
130 ///// Check that the source of an inventory request is one that we trust.
131 ///// </summary>
132 ///// <param name="peer"></param>
133 ///// <returns></returns>
134 //public bool CheckTrustSource(IPEndPoint peer)
135 //{
136 // if (m_doLookup)
137 // {
138 // m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer);
139 // UriBuilder ub = new UriBuilder(m_userserver_url);
140 // IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
141 // foreach (IPAddress uaddr in uaddrs)
142 // {
143 // if (uaddr.Equals(peer.Address))
144 // {
145 // return true;
146 // }
147 // }
148
149 // m_log.WarnFormat(
150 // "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources",
151 // peer);
152
153 // return false;
154 // }
155 // else
156 // {
157 // return true;
158 // }
159 //}
160
161 /// <summary>
162 /// Check that the source of an inventory request for a particular agent is a current session belonging to
163 /// that agent.
164 /// </summary>
165 /// <param name="session_id"></param>
166 /// <param name="avatar_id"></param>
167 /// <returns></returns>
168 public bool CheckAuthSession(string session_id, string avatar_id)
169 {
170 if (m_doLookup)
171 {
172 m_log.InfoFormat("[HGStandaloneInvService]: checking authed session {0} {1}", session_id, avatar_id);
173 UUID userID = UUID.Zero;
174 UUID sessionID = UUID.Zero;
175 UUID.TryParse(avatar_id, out userID);
176 UUID.TryParse(session_id, out sessionID);
177 if (userID.Equals(UUID.Zero) || sessionID.Equals(UUID.Zero))
178 {
179 m_log.Info("[HGStandaloneInvService]: Invalid user or session id " + avatar_id + "; " + session_id);
180 return false;
181 }
182 UserProfileData userProfile = m_userService.GetUserProfile(userID);
183 if (userProfile != null && userProfile.CurrentAgent != null &&
184 userProfile.CurrentAgent.SessionID == sessionID)
185 {
186 m_log.Info("[HGStandaloneInvService]: user is logged in and session is valid. Authorizing access.");
187 return true;
188 }
189
190 m_log.Warn("[HGStandaloneInvService]: unknown user or session_id, request rejected");
191 return false;
192 }
193 else
194 {
195 return true;
196 }
197 }
198 }
199}
diff --git a/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs
new file mode 100644
index 0000000..7203b88
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs
@@ -0,0 +1,315 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using log4net;
35using Nini.Config;
36
37using OpenMetaverse;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Cache;
42using OpenSim.Framework.Servers;
43using OpenSim.Region.Environment.Interfaces;
44using OpenSim.Region.Environment.Scenes;
45
46namespace OpenSim.Region.Environment.Modules.Hypergrid
47{
48 public class HGStandaloneInventoryService : IRegionModule
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static bool initialized = false;
52 private static bool enabled = false;
53
54 Scene m_scene;
55 InventoryService m_inventoryService;
56
57 #region IRegionModule interface
58
59 public void Initialise(Scene scene, IConfigSource config)
60 {
61 if (!initialized)
62 {
63 initialized = true;
64 m_scene = scene;
65
66 // This module is only on for standalones
67 enabled = !config.Configs["Startup"].GetBoolean("gridmode", true) && config.Configs["Startup"].GetBoolean("hypergrid", false);
68 }
69 }
70
71 public void PostInitialise()
72 {
73 if (enabled)
74 {
75 m_log.Info("[HGStandaloneInvService]: Starting...");
76 m_inventoryService = new InventoryService(m_scene);
77 }
78 }
79
80 public void Close()
81 {
82 }
83
84 public string Name
85 {
86 get { return "HGStandaloneInventoryService"; }
87 }
88
89 public bool IsSharedModule
90 {
91 get { return true; }
92 }
93
94 #endregion
95
96 }
97
98 public class InventoryService
99 {
100 private InventoryServiceBase m_inventoryService;
101 private IUserService m_userService;
102 private bool m_doLookup = false;
103
104 public bool DoLookup
105 {
106 get { return m_doLookup; }
107 set { m_doLookup = value; }
108 }
109 private static readonly ILog m_log
110 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
111
112 public InventoryService(Scene m_scene)
113 {
114 m_inventoryService = (InventoryServiceBase)m_scene.CommsManager.SecureInventoryService;
115 m_userService = m_scene.CommsManager.UserService;
116 AddHttpHandlers(m_scene);
117
118 }
119
120 protected void AddHttpHandlers(Scene m_scene)
121 {
122 m_scene.AddStreamHandler(
123 new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
124 "POST", "/GetInventory/", GetUserInventory, CheckAuthSession));
125
126 m_scene.AddStreamHandler(
127 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
128 "POST", "/NewFolder/", m_inventoryService.AddFolder, CheckAuthSession));
129
130 m_scene.AddStreamHandler(
131 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
132 "POST", "/UpdateFolder/", m_inventoryService.UpdateFolder, CheckAuthSession));
133
134 m_scene.AddStreamHandler(
135 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
136 "POST", "/MoveFolder/", m_inventoryService.MoveFolder, CheckAuthSession));
137
138 m_scene.AddStreamHandler(
139 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
140 "POST", "/PurgeFolder/", m_inventoryService.PurgeFolder, CheckAuthSession));
141
142 m_scene.AddStreamHandler(
143 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
144 "POST", "/NewItem/", m_inventoryService.AddItem, CheckAuthSession));
145
146 m_scene.AddStreamHandler(
147 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
148 "POST", "/DeleteItem/", m_inventoryService.DeleteItem, CheckAuthSession));
149
150 //// WARNING: Root folders no longer just delivers the root and immediate child folders (e.g
151 //// system folders such as Objects, Textures), but it now returns the entire inventory skeleton.
152 //// It would have been better to rename this request, but complexities in the BaseHttpServer
153 //// (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier
154 //// to do this for now.
155 //m_scene.AddStreamHandler(
156 // new RestDeserialiseTrustedHandler<Guid, List<InventoryFolderBase>>
157 // ("POST", "/RootFolders/", GetInventorySkeleton, CheckTrustSource));
158
159 //// for persistent active gestures
160 //m_scene.AddStreamHandler(
161 // new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>
162 // ("POST", "/ActiveGestures/", GetActiveGestures, CheckTrustSource));
163 }
164
165
166 ///// <summary>
167 ///// Check that the source of an inventory request is one that we trust.
168 ///// </summary>
169 ///// <param name="peer"></param>
170 ///// <returns></returns>
171 //public bool CheckTrustSource(IPEndPoint peer)
172 //{
173 // if (m_doLookup)
174 // {
175 // m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer);
176 // UriBuilder ub = new UriBuilder(m_userserver_url);
177 // IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
178 // foreach (IPAddress uaddr in uaddrs)
179 // {
180 // if (uaddr.Equals(peer.Address))
181 // {
182 // return true;
183 // }
184 // }
185
186 // m_log.WarnFormat(
187 // "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources",
188 // peer);
189
190 // return false;
191 // }
192 // else
193 // {
194 // return true;
195 // }
196 //}
197
198 /// <summary>
199 /// Check that the source of an inventory request for a particular agent is a current session belonging to
200 /// that agent.
201 /// </summary>
202 /// <param name="session_id"></param>
203 /// <param name="avatar_id"></param>
204 /// <returns></returns>
205 public bool CheckAuthSession(string session_id, string avatar_id)
206 {
207 if (m_doLookup)
208 {
209 m_log.InfoFormat("[HGStandaloneInvService]: checking authed session {0} {1}", session_id, avatar_id);
210 UUID userID = UUID.Zero;
211 UUID sessionID = UUID.Zero;
212 UUID.TryParse(avatar_id, out userID);
213 UUID.TryParse(session_id, out sessionID);
214 if (userID.Equals(UUID.Zero) || sessionID.Equals(UUID.Zero))
215 {
216 m_log.Info("[HGStandaloneInvService]: Invalid user or session id " + avatar_id + "; " + session_id);
217 return false;
218 }
219 UserProfileData userProfile = m_userService.GetUserProfile(userID);
220 if (userProfile != null && userProfile.CurrentAgent != null &&
221 userProfile.CurrentAgent.SessionID == sessionID)
222 {
223 m_log.Info("[HGStandaloneInvService]: user is logged in and session is valid. Authorizing access.");
224 return true;
225 }
226
227 m_log.Warn("[HGStandaloneInvService]: unknown user or session_id, request rejected");
228 return false;
229 }
230 else
231 {
232 return true;
233 }
234 }
235
236
237 /// <summary>
238 /// Return a user's entire inventory
239 /// </summary>
240 /// <param name="rawUserID"></param>
241 /// <returns>The user's inventory. If an inventory cannot be found then an empty collection is returned.</returns>
242 public InventoryCollection GetUserInventory(Guid rawUserID)
243 {
244 UUID userID = new UUID(rawUserID);
245
246 m_log.Info("[HGStandaloneInvService]: Processing request for inventory of " + userID);
247
248 // Uncomment me to simulate a slow responding inventory server
249 //Thread.Sleep(16000);
250
251 InventoryCollection invCollection = new InventoryCollection();
252
253 List<InventoryFolderBase> allFolders = ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID);
254
255 if (null == allFolders)
256 {
257 m_log.WarnFormat("[HGStandaloneInvService]: No inventory found for user {0}", rawUserID);
258
259 return invCollection;
260 }
261
262 List<InventoryItemBase> allItems = new List<InventoryItemBase>();
263
264 foreach (InventoryFolderBase folder in allFolders)
265 {
266 List<InventoryItemBase> items = ((InventoryServiceBase)m_inventoryService).RequestFolderItems(folder.ID);
267
268 if (items != null)
269 {
270 allItems.InsertRange(0, items);
271 }
272 }
273
274 invCollection.UserID = userID;
275 invCollection.Folders = allFolders;
276 invCollection.Items = allItems;
277
278 // foreach (InventoryFolderBase folder in invCollection.Folders)
279 // {
280 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID);
281 // }
282 //
283 // foreach (InventoryItemBase item in invCollection.Items)
284 // {
285 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder);
286 // }
287
288 m_log.InfoFormat(
289 "[HGStandaloneInvService]: Sending back inventory response to user {0} containing {1} folders and {2} items",
290 invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count);
291
292 return invCollection;
293 }
294
295 /// <summary>
296 /// Guid to UUID wrapper for same name IInventoryServices method
297 /// </summary>
298 /// <param name="rawUserID"></param>
299 /// <returns></returns>
300 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
301 {
302 UUID userID = new UUID(rawUserID);
303 return ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID);
304 }
305
306 public List<InventoryItemBase> GetActiveGestures(Guid rawUserID)
307 {
308 UUID userID = new UUID(rawUserID);
309
310 m_log.InfoFormat("[HGStandaloneInvService]: fetching active gestures for user {0}", userID);
311
312 return ((InventoryServiceBase)m_inventoryService).GetActiveGestures(userID);
313 }
314 }
315}
diff --git a/OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs
new file mode 100644
index 0000000..7f8f285
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs
@@ -0,0 +1,178 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29
30using System;
31using System.Collections;
32using System.Collections.Generic;
33using System.Drawing;
34using System.Drawing.Imaging;
35using System.IO;
36using System.Net;
37using System.Reflection;
38using System.Threading;
39using OpenMetaverse;
40using OpenMetaverse.Imaging;
41using OpenMetaverse.StructuredData;
42using log4net;
43using Nini.Config;
44using Nwc.XmlRpc;
45
46using OpenSim.Framework;
47using OpenSim.Framework.Communications.Cache;
48using OpenSim.Framework.Communications.Capabilities;
49using OpenSim.Framework.Servers;
50using OpenSim.Region.Environment.Interfaces;
51using OpenSim.Region.Environment.Modules.World.WorldMap;
52using OpenSim.Region.Environment.Scenes;
53using OpenSim.Region.Environment.Types;
54using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
55
56using OSD = OpenMetaverse.StructuredData.OSD;
57using OSDMap = OpenMetaverse.StructuredData.OSDMap;
58using OSDArray = OpenMetaverse.StructuredData.OSDArray;
59
60namespace OpenSim.Region.Environment.Modules.Hypergrid
61{
62 public class HGWorldMapModule : WorldMapModule, IRegionModule
63 {
64 private static readonly ILog m_log =
65 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
66
67 #region IRegionModule Members
68
69 public override void Initialise(Scene scene, IConfigSource config)
70 {
71 IConfig startupConfig = config.Configs["Startup"];
72 if (startupConfig.GetString("WorldMapModule", "WorldMap") == "HGWorldMap")
73 m_Enabled = true;
74
75 if (!m_Enabled)
76 return;
77 m_log.Info("[HGMap] Initializing...");
78 m_scene = scene;
79 }
80
81
82 public override string Name
83 {
84 get { return "HGWorldMap"; }
85 }
86
87
88 #endregion
89
90 /// <summary>
91 /// Requests map blocks in area of minX, maxX, minY, MaxY in world cordinates
92 /// </summary>
93 /// <param name="minX"></param>
94 /// <param name="minY"></param>
95 /// <param name="maxX"></param>
96 /// <param name="maxY"></param>
97 public override void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
98 {
99 //
100 // WARNING!!! COPY & PASTE FROM SUPERCLASS
101 // The only difference is at the very end
102 //
103
104 m_log.Info("[HGMap]: Request map blocks " + minX + "-" + maxX + " " + minY + "-" + maxY);
105
106 //m_scene.ForEachScenePresence(delegate (ScenePresence sp) {
107 // if (!sp.IsChildAgent && sp.UUID == remoteClient.AgentId)
108 // {
109 // Console.WriteLine("XXX Root agent");
110 // DoRequestMapBlocks(remoteClient, minX, minY, maxX, maxY, flag);
111 // }
112 //};
113
114 List<MapBlockData> mapBlocks;
115 if ((flag & 0x10000) != 0) // user clicked on the map a tile that isn't visible
116 {
117 List<MapBlockData> response = new List<MapBlockData>();
118
119 // this should return one mapblock at most. But make sure: Look whether the one we requested is in there
120 mapBlocks = m_scene.SceneGridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
121 if (mapBlocks != null)
122 {
123 foreach (MapBlockData block in mapBlocks)
124 {
125 if (block.X == minX && block.Y == minY)
126 {
127 // found it => add it to response
128 response.Add(block);
129 break;
130 }
131 }
132 }
133 response = mapBlocks;
134 if (response.Count == 0)
135 {
136 // response still empty => couldn't find the map-tile the user clicked on => tell the client
137 MapBlockData block = new MapBlockData();
138 block.X = (ushort)minX;
139 block.Y = (ushort)minY;
140 block.Access = 254; // == not there
141 response.Add(block);
142 }
143 remoteClient.SendMapBlock(response, 0);
144 }
145 else
146 {
147 // normal mapblock request. Use the provided values
148 mapBlocks = m_scene.SceneGridService.RequestNeighbourMapBlocks(minX - 4, minY - 4, maxX + 4, maxY + 4);
149
150 // Different from super
151 FillInMap(mapBlocks, minX, minY, maxX, maxY);
152 //
153
154 remoteClient.SendMapBlock(mapBlocks, flag);
155 }
156 }
157
158
159 private void FillInMap(List<MapBlockData> mapBlocks, int minX, int minY, int maxX, int maxY)
160 {
161 for (int x = minX; x <= maxX; x++)
162 for (int y = minY; y <= maxY; y++)
163 {
164 MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return ((mb.X == x) && (mb.Y == y)); });
165 if (mblock == null)
166 {
167 mblock = new MapBlockData();
168 mblock.X = (ushort)x;
169 mblock.Y = (ushort)y;
170 mblock.Name = "";
171 mblock.Access = 254; // not here???
172 mblock.MapImageId = UUID.Zero;
173 mapBlocks.Add(mblock);
174 }
175 }
176 }
177 }
178}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs
new file mode 100644
index 0000000..3e27b7c
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs
@@ -0,0 +1,377 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections;
31using System.Collections.Generic;
32using System.Reflection;
33using System.Threading;
34
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Cache;
42using OpenSim.Framework.Servers;
43using OpenSim.Region.Environment;
44using OpenSim.Region.Environment.Scenes;
45
46//using HyperGrid.Framework;
47//using OpenSim.Region.Communications.Hypergrid;
48
49namespace OpenSim.Region.Environment.Scenes.Hypergrid
50{
51 public class HGAssetMapper
52 {
53 #region Fields
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 // This maps between asset server URLs and asset server clients
57 private Dictionary<string, GridAssetClient> m_assetServers = new Dictionary<string, GridAssetClient>();
58
59 // This maps between asset UUIDs and asset servers
60 private Dictionary<UUID, GridAssetClient> m_assetMap = new Dictionary<UUID, GridAssetClient>();
61
62 private Scene m_scene;
63 #endregion
64
65 #region Constructor
66
67 public HGAssetMapper(Scene scene)
68 {
69 m_scene = scene;
70 }
71
72 #endregion
73
74 #region Internal functions
75
76 private string UserAssetURL(UUID userID)
77 {
78 CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
79 if (uinfo != null)
80 return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI;
81 return null;
82 }
83
84 private bool IsHomeUser(UUID userID)
85 {
86 CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
87
88 if (uinfo != null)
89 {
90 //if ((uinfo.UserProfile.UserAssetURI == null) || (uinfo.UserProfile.UserAssetURI == "") ||
91 // uinfo.UserProfile.UserAssetURI.Equals(m_scene.CommsManager.NetworkServersInfo.AssetURL))
92 if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI))
93 {
94 m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
95 return true;
96 }
97 }
98
99 m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
100 return false;
101 }
102
103 private bool IsInAssetMap(UUID uuid)
104 {
105 return m_assetMap.ContainsKey(uuid);
106 }
107
108 private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture)
109 {
110 // I'm not going over 3 seconds since this will be blocking processing of all the other inbound
111 // packets from the client.
112 int pollPeriod = 200;
113 int maxPolls = 15;
114
115 AssetBase asset;
116
117 // Maybe it came late, and it's already here. Check first.
118 if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset))
119 {
120 m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID);
121 return true;
122 }
123
124
125 asscli.RequestAsset(assetID, isTexture);
126
127 do
128 {
129 Thread.Sleep(pollPeriod);
130
131 if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null))
132 {
133 m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID);
134 // I think I need to store it in the asset DB too.
135 // For now, let me just do it for textures and scripts
136 if (((AssetType)asset.Type == AssetType.Texture) ||
137 ((AssetType)asset.Type == AssetType.LSLBytecode) ||
138 ((AssetType)asset.Type == AssetType.LSLText))
139 {
140 AssetBase asset1 = new AssetBase();
141 Copy(asset, asset1);
142 m_scene.AssetCache.AssetServer.StoreAsset(asset1);
143 }
144 return true;
145 }
146 } while (--maxPolls > 0);
147
148 m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached",
149 isTexture ? "texture" : "asset", assetID.ToString());
150
151 return false;
152 }
153
154 private bool PostAsset(GridAssetClient asscli, UUID assetID)
155 {
156 AssetBase asset1;
157 m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1);
158
159 if (asset1 != null)
160 {
161 // See long comment in AssetCache.AddAsset
162 if (!asset1.Temporary || asset1.Local)
163 {
164 // The asset cache returns instances of subclasses of AssetBase:
165 // TextureImage or AssetInfo. So in passing them to the remote
166 // server we first need to convert this to instances of AssetBase,
167 // which is the serializable class for assets.
168 AssetBase asset = new AssetBase();
169 Copy(asset1, asset);
170
171 asscli.StoreAsset(asset);
172 }
173 return true;
174 }
175 else
176 m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache.");
177
178 return false;
179 }
180
181 private void Copy(AssetBase from, AssetBase to)
182 {
183 to.Data = from.Data;
184 to.Description = from.Description;
185 to.FullID = from.FullID;
186 to.ID = from.ID;
187 to.Local = from.Local;
188 to.Name = from.Name;
189 to.Temporary = from.Temporary;
190 to.Type = from.Type;
191
192 }
193
194 private void _guardedAdd(Dictionary<UUID, bool> lst, UUID obj, bool val)
195 {
196 if (!lst.ContainsKey(obj))
197 lst.Add(obj, val);
198 }
199
200 private void SniffTextureUUIDs(Dictionary<UUID, bool> uuids, SceneObjectGroup sog)
201 {
202 try
203 {
204 _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true);
205 }
206 catch (Exception) { }
207
208 foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures)
209 {
210 try
211 {
212 _guardedAdd(uuids, tface.TextureID, true);
213 }
214 catch (Exception) { }
215 }
216
217 foreach (SceneObjectPart sop in sog.Children.Values)
218 {
219 try
220 {
221 _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true);
222 }
223 catch (Exception) { }
224 foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures)
225 {
226 try
227 {
228 _guardedAdd(uuids, tface.TextureID, true);
229 }
230 catch (Exception) { }
231 }
232 }
233 }
234
235 private void SniffTaskInventoryUUIDs(Dictionary<UUID, bool> uuids, SceneObjectGroup sog)
236 {
237 TaskInventoryDictionary tinv = sog.RootPart.TaskInventory;
238
239 foreach (TaskInventoryItem titem in tinv.Values)
240 {
241 uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture);
242 }
243 }
244
245 private Dictionary<UUID, bool> SniffUUIDs(AssetBase asset)
246 {
247 Dictionary<UUID, bool> uuids = new Dictionary<UUID, bool>();
248 if ((asset != null) && ((AssetType)asset.Type == AssetType.Object))
249 {
250 string ass_str = Utils.BytesToString(asset.Data);
251 SceneObjectGroup sog = new SceneObjectGroup(ass_str, true);
252
253 SniffTextureUUIDs(uuids, sog);
254
255 // We need to sniff further...
256 SniffTaskInventoryUUIDs(uuids, sog);
257
258 }
259
260 return uuids;
261 }
262
263 private Dictionary<UUID, bool> SniffUUIDs(UUID assetID)
264 {
265 Dictionary<UUID, bool> uuids = new Dictionary<UUID, bool>();
266
267 AssetBase asset;
268 m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset);
269
270 return SniffUUIDs(asset);
271 }
272
273 private void Dump(Dictionary<UUID, bool> lst)
274 {
275 m_log.Debug("XXX -------- UUID DUMP ------- XXX");
276 foreach (KeyValuePair<UUID, bool> kvp in lst)
277 m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
278 m_log.Debug("XXX -------- UUID DUMP ------- XXX");
279 }
280
281 #endregion
282
283
284 #region Public interface
285
286 public void Get(UUID itemID, UUID ownerID)
287 {
288 if (!IsInAssetMap(itemID) && !IsHomeUser(ownerID))
289 {
290 // Get the item from the remote asset server onto the local AssetCache
291 // and place an entry in m_assetMap
292
293 GridAssetClient asscli = null;
294 string userAssetURL = UserAssetURL(ownerID);
295 if (userAssetURL != null)
296 {
297 m_assetServers.TryGetValue(userAssetURL, out asscli);
298 if (asscli == null)
299 {
300 m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
301 asscli = new GridAssetClient(userAssetURL);
302 asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
303 m_assetServers.Add(userAssetURL, asscli);
304 }
305
306 m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL);
307 bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false);
308
309 // OK, now fetch the inside.
310 Dictionary<UUID, bool> ids = SniffUUIDs(itemID);
311 Dump(ids);
312 foreach (KeyValuePair<UUID, bool> kvp in ids)
313 FetchAsset(asscli, kvp.Key, kvp.Value);
314
315
316 if (success)
317 {
318 m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL);
319 m_assetMap.Add(itemID, asscli);
320 }
321 else
322 m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL);
323 }
324 else
325 m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
326 }
327 }
328
329 public void Post(UUID itemID, UUID ownerID)
330 {
331 if (!IsHomeUser(ownerID))
332 {
333 // Post the item from the local AssetCache ontp the remote asset server
334 // and place an entry in m_assetMap
335
336 GridAssetClient asscli = null;
337 string userAssetURL = UserAssetURL(ownerID);
338 if (userAssetURL != null)
339 {
340 m_assetServers.TryGetValue(userAssetURL, out asscli);
341 if (asscli == null)
342 {
343 m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
344 asscli = new GridAssetClient(userAssetURL);
345 asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
346 m_assetServers.Add(userAssetURL, asscli);
347 }
348 m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL);
349 bool success = PostAsset(asscli, itemID);
350
351 // Now the inside
352 Dictionary<UUID, bool> ids = SniffUUIDs(itemID);
353 Dump(ids);
354 foreach (KeyValuePair<UUID, bool> kvp in ids)
355 PostAsset(asscli, kvp.Key);
356
357 if (success)
358 {
359 m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL);
360 m_assetMap.Add(itemID, asscli);
361 }
362 else
363 m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL);
364
365 //if (!m_assetMap.ContainsKey(itemID))
366 // m_assetMap.Add(itemID, asscli);
367 }
368 else
369 m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
370
371 }
372 }
373
374 #endregion
375
376 }
377}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs
new file mode 100644
index 0000000..af3c04f
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs
@@ -0,0 +1,152 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections;
31using System.Collections.Generic;
32using System.Reflection;
33using System.Threading;
34
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Cache;
42using OpenSim.Framework.Servers;
43using OpenSim.Region.Environment;
44using OpenSim.Region.Environment.Scenes;
45
46namespace OpenSim.Region.Environment.Scenes.Hypergrid
47{
48 public partial class HGScene : Scene
49 {
50 #region Fields
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private HGAssetMapper m_assMapper;
54
55 #endregion
56
57 #region Constructors
58
59 public HGScene(RegionInfo regInfo, AgentCircuitManager authen,
60 CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
61 AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer,
62 ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
63 bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
64 : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, httpServer, moduleLoader,
65 dumpAssetsToFile, physicalPrim, SeeIntoRegionFromNeighbor, config, simulatorVersion)
66 {
67 m_log.Info("[HGScene]: Starting HGScene.");
68 m_assMapper = new HGAssetMapper(this);
69
70 EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
71 }
72
73 #endregion
74
75 #region Event handlers
76
77 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
78 {
79 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(avatarID);
80 if (userInfo != null)
81 {
82 m_assMapper.Post(assetID, avatarID);
83 }
84 }
85
86 #endregion
87
88 #region Overrides of Scene.Inventory methods
89
90 ///
91 /// CapsUpdateInventoryItemAsset
92 ///
93 public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
94 {
95 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
96
97 UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0);
98
99 return newAssetID;
100 }
101
102 ///
103 /// DeleteToInventory
104 ///
105 public override UUID DeleteToInventory(int destination, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
106 {
107 UUID assetID = base.DeleteToInventory(destination, folderID, objectGroup, remoteClient);
108
109 if (!assetID.Equals(UUID.Zero))
110 {
111 UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
112 }
113 else
114 m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
115
116 return assetID;
117 }
118
119 ///
120 /// RezObject
121 ///
122 public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
123 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
124 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
125 {
126 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
127 if (userInfo != null)
128 {
129 if (userInfo.RootFolder != null)
130 {
131 InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
132
133 if (item != null)
134 {
135 m_assMapper.Get(item.AssetID, remoteClient.AgentId);
136
137 }
138 }
139 }
140
141 // OK, we're done fetching. Pass it up to the default RezObject
142 return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
143 RezSelected, RemoveItem, fromTaskID, attachment);
144
145 }
146
147
148 #endregion
149
150 }
151
152}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs
new file mode 100644
index 0000000..a1a6173
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs
@@ -0,0 +1,78 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections.Generic;
31
32using OpenMetaverse;
33
34using OpenSim.Framework;
35
36using OpenSim.Framework.Communications.Cache;
37using OpenSim.Region.Environment;
38using OpenSim.Region.Environment.Scenes;
39using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
40
41namespace OpenSim.Region.Environment.Scenes.Hypergrid
42{
43 public partial class HGScene : Scene
44 {
45 /// <summary>
46 /// Teleport an avatar to their home region
47 /// </summary>
48 /// <param name="agentId"></param>
49 /// <param name="client"></param>
50 public override void TeleportClientHome(UUID agentId, IClientAPI client)
51 {
52 m_log.Debug("[HGScene]: TeleportClientHome " + client.FirstName + " " + client.LastName);
53
54 CachedUserInfo uinfo = CommsManager.UserProfileCacheService.GetUserDetails(agentId);
55 UserProfileData UserProfile = uinfo.UserProfile;
56
57 if (UserProfile != null)
58 {
59 RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion);
60 //if (regionInfo != null)
61 //{
62 // UserProfile.HomeRegionID = regionInfo.RegionID;
63 // //CommsManager.UserService.UpdateUserProfile(UserProfile);
64 //}
65 if (regionInfo == null)
66 {
67 // can't find the Home region: Tell viewer and abort
68 client.SendTeleportFailed("Your home-region could not be found.");
69 return;
70 }
71 RequestTeleportLocation(
72 client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
73 (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
74 }
75 }
76
77 }
78}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
new file mode 100644
index 0000000..501584a
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -0,0 +1,263 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading;
33
34using OpenMetaverse;
35
36using log4net;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using OpenSim.Region.Environment.Scenes;
41using OpenSim.Region.Environment;
42using OpenSim.Region.Interfaces;
43using OSD = OpenMetaverse.StructuredData.OSD;
44
45namespace OpenSim.Region.Environment.Scenes.Hypergrid
46{
47 public class HGSceneCommunicationService : SceneCommunicationService
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IHyperlink m_hg;
52
53 public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan)
54 {
55 m_hg = hg;
56 }
57
58
59 /// <summary>
60 /// Try to teleport an agent to a new region.
61 /// </summary>
62 /// <param name="remoteClient"></param>
63 /// <param name="RegionHandle"></param>
64 /// <param name="position"></param>
65 /// <param name="lookAt"></param>
66 /// <param name="flags"></param>
67 public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position,
68 Vector3 lookAt, uint teleportFlags)
69 {
70 if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID))
71 return;
72
73 bool destRegionUp = false;
74
75 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>();
76
77 if (regionHandle == m_regionInfo.RegionHandle)
78 {
79 // Teleport within the same region
80 if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0)
81 {
82 Vector3 emergencyPos = new Vector3(128, 128, 128);
83
84 m_log.WarnFormat(
85 "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
86 position, avatar.Name, avatar.UUID, emergencyPos);
87 position = emergencyPos;
88 }
89 // TODO: Get proper AVG Height
90 float localAVHeight = 1.56f;
91 float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y);
92 float newPosZ = posZLimit + localAVHeight;
93 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
94 {
95 position.Z = newPosZ;
96 }
97
98 // Only send this if the event queue is null
99 if (eq == null)
100 avatar.ControllingClient.SendTeleportLocationStart();
101
102
103 avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
104 avatar.Teleport(position);
105 }
106 else
107 {
108 RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle);
109 if (reg != null)
110 {
111 ///
112 /// Hypergrid mod start
113 ///
114 ///
115 bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle);
116 bool isHomeUser = true;
117 ulong realHandle = regionHandle;
118 CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID);
119 if (uinfo != null)
120 {
121 isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI);
122 realHandle = m_hg.FindRegionHandle(regionHandle);
123 Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString());
124 }
125 ///
126 /// Hypergrid mod stop
127 ///
128 ///
129
130 if (eq == null)
131 avatar.ControllingClient.SendTeleportLocationStart();
132
133 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
134 agent.BaseFolder = UUID.Zero;
135 agent.InventoryFolder = UUID.Zero;
136 agent.startpos = position;
137 agent.child = true;
138
139 if (reg.RemotingAddress != "" && reg.RemotingPort != 0)
140 {
141 // region is remote. see if it is up
142 destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort);
143 }
144 else
145 {
146 // assume local regions are always up
147 destRegionUp = true;
148 }
149
150 if (destRegionUp)
151 {
152 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
153 // both regions
154 if (avatar.ParentID != (uint)0)
155 avatar.StandUp();
156 if (!avatar.ValidateAttachments())
157 {
158 avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
159 return;
160 }
161
162 // the avatar.Close below will clear the child region list. We need this below for (possibly)
163 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
164 List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
165 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
166 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
167 // once we reach here...
168 avatar.Scene.RemoveCapsHandler(avatar.UUID);
169 agent.child = false;
170 m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent);
171
172 m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
173 position, false);
174 Thread.Sleep(2000);
175 AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo();
176
177 // TODO Should construct this behind a method
178 string capsPath =
179 "http://" + reg.ExternalHostName + ":" + reg.HttpPort
180 + "/CAPS/" + circuitdata.CapsPath + "0000/";
181
182 m_log.DebugFormat(
183 "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
184
185
186 ///
187 /// Hypergrid mod: realHandle instead of reg.RegionHandle
188 ///
189 ///
190 if (eq != null)
191 {
192 OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint,
193 4, teleportFlags, capsPath, avatar.UUID);
194 eq.Enqueue(Item, avatar.UUID);
195 }
196 else
197 {
198 avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4,
199 teleportFlags, capsPath);
200 }
201 ///
202 /// Hypergrid mod stop
203 ///
204
205 avatar.MakeChildAgent();
206 Thread.Sleep(7000);
207 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
208 if (KiPrimitive != null)
209 {
210 KiPrimitive(avatar.LocalId);
211 }
212
213 avatar.Close();
214
215 uint newRegionX = (uint)(reg.RegionHandle >> 40);
216 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
217 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
218 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
219 ///
220 /// Hypergrid mod: extra check for isHyperLink
221 ///
222 if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink)
223 {
224 //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList());
225 SendCloseChildAgentConnections(avatar.UUID, childRegions);
226 CloseConnection(avatar.UUID);
227 }
228 // if (teleport success) // seems to be always success here
229 // the user may change their profile information in other region,
230 // so the userinfo in UserProfileCache is not reliable any more, delete it
231 if (avatar.Scene.NeedSceneCacheClear(avatar.UUID))
232 m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
233 m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID);
234 }
235 else
236 {
237 avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
238 }
239 }
240 else
241 {
242 // TP to a place that doesn't exist (anymore)
243 // Inform the viewer about that
244 avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
245
246 // and set the map-tile to '(Offline)'
247 uint regX, regY;
248 Utils.LongToUInts(regionHandle, out regX, out regY);
249
250 MapBlockData block = new MapBlockData();
251 block.X = (ushort)(regX / Constants.RegionSize);
252 block.Y = (ushort)(regY / Constants.RegionSize);
253 block.Access = 254; // == not there
254
255 List<MapBlockData> blocks = new List<MapBlockData>();
256 blocks.Add(block);
257 avatar.ControllingClient.SendMapBlock(blocks, 0);
258 }
259 }
260 }
261
262 }
263}