aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/GridServer.Modules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/GridServer.Modules')
-rw-r--r--OpenSim/Grid/GridServer.Modules/GridDBService.cs284
-rw-r--r--OpenSim/Grid/GridServer.Modules/GridMessagingModule.cs161
-rw-r--r--OpenSim/Grid/GridServer.Modules/GridRestModule.cs282
-rw-r--r--OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs885
4 files changed, 1612 insertions, 0 deletions
diff --git a/OpenSim/Grid/GridServer.Modules/GridDBService.cs b/OpenSim/Grid/GridServer.Modules/GridDBService.cs
new file mode 100644
index 0000000..b728f1f
--- /dev/null
+++ b/OpenSim/Grid/GridServer.Modules/GridDBService.cs
@@ -0,0 +1,284 @@
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.IO;
32using System.Reflection;
33using System.Xml;
34using log4net;
35using Nwc.XmlRpc;
36using OpenMetaverse;
37using OpenSim.Data;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Servers;
41
42
43namespace OpenSim.Grid.GridServer.Modules
44{
45 public class GridDBService
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private List<IGridDataPlugin> _plugins = new List<IGridDataPlugin>();
50 private List<ILogDataPlugin> _logplugins = new List<ILogDataPlugin>();
51
52 /// <summary>
53 /// Adds a list of grid and log data plugins, as described by
54 /// `provider' and `connect', to `_plugins' and `_logplugins',
55 /// respectively.
56 /// </summary>
57 /// <param name="provider">
58 /// The filename of the inventory server plugin DLL.
59 /// </param>
60 /// <param name="connect">
61 /// The connection string for the storage backend.
62 /// </param>
63 public void AddPlugin(string provider, string connect)
64 {
65 _plugins = DataPluginFactory.LoadDataPlugins<IGridDataPlugin>(provider, connect);
66 _logplugins = DataPluginFactory.LoadDataPlugins<ILogDataPlugin>(provider, connect);
67 }
68
69 public int GetNumberOfPlugins()
70 {
71 return _plugins.Count;
72 }
73
74 /// <summary>
75 /// Logs a piece of information to the database
76 /// </summary>
77 /// <param name="target">What you were operating on (in grid server, this will likely be the region UUIDs)</param>
78 /// <param name="method">Which method is being called?</param>
79 /// <param name="args">What arguments are being passed?</param>
80 /// <param name="priority">How high priority is this? 1 = Max, 6 = Verbose</param>
81 /// <param name="message">The message to log</param>
82 private void logToDB(string target, string method, string args, int priority, string message)
83 {
84 foreach (ILogDataPlugin plugin in _logplugins)
85 {
86 try
87 {
88 plugin.saveLog("Gridserver", target, method, args, priority, message);
89 }
90 catch (Exception)
91 {
92 m_log.Warn("[storage]: Unable to write log via " + plugin.Name);
93 }
94 }
95 }
96
97 /// <summary>
98 /// Returns a region by argument
99 /// </summary>
100 /// <param name="uuid">A UUID key of the region to return</param>
101 /// <returns>A SimProfileData for the region</returns>
102 public RegionProfileData GetRegion(UUID uuid)
103 {
104 foreach (IGridDataPlugin plugin in _plugins)
105 {
106 try
107 {
108 return plugin.GetProfileByUUID(uuid);
109 }
110 catch (Exception e)
111 {
112 m_log.Warn("[storage]: GetRegion - " + e.Message);
113 }
114 }
115 return null;
116 }
117
118 /// <summary>
119 /// Returns a region by argument
120 /// </summary>
121 /// <param name="uuid">A regionHandle of the region to return</param>
122 /// <returns>A SimProfileData for the region</returns>
123 public RegionProfileData GetRegion(ulong handle)
124 {
125 foreach (IGridDataPlugin plugin in _plugins)
126 {
127 try
128 {
129 return plugin.GetProfileByHandle(handle);
130 }
131 catch (Exception ex)
132 {
133 m_log.Debug("[storage]: " + ex.Message);
134 m_log.Warn("[storage]: Unable to find region " + handle.ToString() + " via " + plugin.Name);
135 }
136 }
137 return null;
138 }
139
140 /// <summary>
141 /// Returns a region by argument
142 /// </summary>
143 /// <param name="regionName">A partial regionName of the region to return</param>
144 /// <returns>A SimProfileData for the region</returns>
145 public RegionProfileData GetRegion(string regionName)
146 {
147 foreach (IGridDataPlugin plugin in _plugins)
148 {
149 try
150 {
151 return plugin.GetProfileByString(regionName);
152 }
153 catch
154 {
155 m_log.Warn("[storage]: Unable to find region " + regionName + " via " + plugin.Name);
156 }
157 }
158 return null;
159 }
160
161 public List<RegionProfileData> GetRegions(uint xmin, uint ymin, uint xmax, uint ymax)
162 {
163 List<RegionProfileData> regions = new List<RegionProfileData>();
164
165 foreach (IGridDataPlugin plugin in _plugins)
166 {
167 try
168 {
169 regions.AddRange(plugin.GetProfilesInRange(xmin, ymin, xmax, ymax));
170 }
171 catch
172 {
173 m_log.Warn("[storage]: Unable to query regionblock via " + plugin.Name);
174 }
175 }
176
177 return regions;
178 }
179
180 public List<RegionProfileData> GetRegions(string name, int maxNum)
181 {
182 List<RegionProfileData> regions = new List<RegionProfileData>();
183 foreach (IGridDataPlugin plugin in _plugins)
184 {
185 try
186 {
187 int num = maxNum - regions.Count;
188 List<RegionProfileData> profiles = plugin.GetRegionsByName(name, (uint)num);
189 if (profiles != null) regions.AddRange(profiles);
190 }
191 catch
192 {
193 m_log.Warn("[storage]: Unable to query regionblock via " + plugin.Name);
194 }
195 }
196
197 return regions;
198 }
199
200 public DataResponse AddUpdateRegion(RegionProfileData sim, RegionProfileData existingSim)
201 {
202 DataResponse insertResponse = DataResponse.RESPONSE_ERROR;
203 foreach (IGridDataPlugin plugin in _plugins)
204 {
205 try
206 {
207 if (existingSim == null)
208 {
209 insertResponse = plugin.AddProfile(sim);
210 }
211 else
212 {
213 insertResponse = plugin.UpdateProfile(sim);
214 }
215 }
216 catch (Exception e)
217 {
218 m_log.Warn("[LOGIN END]: " +
219 "Unable to login region " + sim.ToString() + " via " + plugin.Name);
220 m_log.Warn("[LOGIN END]: " + e.ToString());
221 }
222 }
223 return insertResponse;
224 }
225
226 public DataResponse DeleteRegion(string uuid)
227 {
228 DataResponse insertResponse = DataResponse.RESPONSE_ERROR;
229 foreach (IGridDataPlugin plugin in _plugins)
230 {
231 //OpenSim.Data.MySQL.MySQLGridData dbengine = new OpenSim.Data.MySQL.MySQLGridData();
232 try
233 {
234 //Nice are we not using multiple databases?
235 //MySQLGridData mysqldata = (MySQLGridData)(plugin);
236
237 //DataResponse insertResponse = mysqldata.DeleteProfile(TheSim);
238 insertResponse = plugin.DeleteProfile(uuid);
239 }
240 catch (Exception)
241 {
242 m_log.Error("storage Unable to delete region " + uuid + " via " + plugin.Name);
243 //MainLog.Instance.Warn("storage", e.ToString());
244 insertResponse = DataResponse.RESPONSE_ERROR;
245 }
246 }
247 return insertResponse;
248 }
249
250 public string CheckReservations(RegionProfileData theSim, XmlNode authkeynode)
251 {
252 foreach (IGridDataPlugin plugin in _plugins)
253 {
254 try
255 {
256 //Check reservations
257 ReservationData reserveData =
258 plugin.GetReservationAtPoint(theSim.regionLocX, theSim.regionLocY);
259 if ((reserveData != null && reserveData.gridRecvKey == theSim.regionRecvKey) ||
260 (reserveData == null && authkeynode.InnerText != theSim.regionRecvKey))
261 {
262 plugin.AddProfile(theSim);
263 m_log.Info("[grid]: New sim added to grid (" + theSim.regionName + ")");
264 logToDB(theSim.ToString(), "RestSetSimMethod", String.Empty, 5,
265 "Region successfully updated and connected to grid.");
266 }
267 else
268 {
269 m_log.Warn("[grid]: " +
270 "Unable to update region (RestSetSimMethod): Incorrect reservation auth key.");
271 // Wanted: " + reserveData.gridRecvKey + ", Got: " + theSim.regionRecvKey + ".");
272 return "Unable to update region (RestSetSimMethod): Incorrect auth key.";
273 }
274 }
275 catch (Exception e)
276 {
277 m_log.Warn("[GRID]: GetRegionPlugin Handle " + plugin.Name + " unable to add new sim: " +
278 e.ToString());
279 }
280 }
281 return "OK";
282 }
283 }
284}
diff --git a/OpenSim/Grid/GridServer.Modules/GridMessagingModule.cs b/OpenSim/Grid/GridServer.Modules/GridMessagingModule.cs
new file mode 100644
index 0000000..9c2b5ca
--- /dev/null
+++ b/OpenSim/Grid/GridServer.Modules/GridMessagingModule.cs
@@ -0,0 +1,161 @@
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.Reflection;
32using System.Text;
33using Nwc.XmlRpc;
34using log4net;
35using OpenSim.Framework.Servers;
36using OpenSim.Framework;
37using OpenSim.Grid.Framework;
38
39namespace OpenSim.Grid.GridServer.Modules
40{
41 public class GridMessagingModule : IGridMessagingMapper
42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 protected GridDBService m_gridDBService;
46 protected IUGAIMCore m_gridCore;
47
48 protected GridConfig m_config;
49
50 /// <value>
51 /// Used to notify old regions as to which OpenSim version to upgrade to
52 /// </value>
53 private string m_opensimVersion;
54
55 protected BaseHttpServer m_httpServer;
56
57 // This is here so that the grid server can hand out MessageServer settings to regions on registration
58 private List<MessageServerInfo> m_messageServers = new List<MessageServerInfo>();
59
60 public GridMessagingModule()
61 {
62 }
63
64 public void Initialise(string opensimVersion, GridDBService gridDBService, IUGAIMCore gridCore, GridConfig config)
65 {
66 m_opensimVersion = opensimVersion;
67 m_gridDBService = gridDBService;
68 m_gridCore = gridCore;
69 m_config = config;
70
71 m_gridCore.RegisterInterface<IGridMessagingMapper>(this);
72
73 RegisterHandlers();
74 }
75
76 public void PostInitialise()
77 {
78
79 }
80
81 public void RegisterHandlers()
82 {
83 //have these in separate method as some servers restart the http server and reregister all the handlers.
84 m_httpServer = m_gridCore.GetHttpServer();
85
86 // Message Server ---> Grid Server
87 m_httpServer.AddXmlRPCHandler("register_messageserver", XmlRPCRegisterMessageServer);
88 m_httpServer.AddXmlRPCHandler("deregister_messageserver", XmlRPCDeRegisterMessageServer);
89 }
90
91 public List<MessageServerInfo> GetMessageServersList()
92 {
93 lock (m_messageServers)
94 {
95 return new List<MessageServerInfo>(m_messageServers);
96 }
97 }
98
99 public XmlRpcResponse XmlRPCRegisterMessageServer(XmlRpcRequest request)
100 {
101 XmlRpcResponse response = new XmlRpcResponse();
102 Hashtable requestData = (Hashtable)request.Params[0];
103 Hashtable responseData = new Hashtable();
104
105 if (requestData.Contains("uri"))
106 {
107 string URI = (string)requestData["URI"];
108 string sendkey = (string)requestData["sendkey"];
109 string recvkey = (string)requestData["recvkey"];
110 MessageServerInfo m = new MessageServerInfo();
111 m.URI = URI;
112 m.sendkey = sendkey;
113 m.recvkey = recvkey;
114 RegisterMessageServer(m);
115 responseData["responsestring"] = "TRUE";
116 response.Value = responseData;
117 }
118 return response;
119 }
120
121 public XmlRpcResponse XmlRPCDeRegisterMessageServer(XmlRpcRequest request)
122 {
123 XmlRpcResponse response = new XmlRpcResponse();
124 Hashtable requestData = (Hashtable)request.Params[0];
125 Hashtable responseData = new Hashtable();
126
127 if (requestData.Contains("uri"))
128 {
129 string URI = (string)requestData["uri"];
130 string sendkey = (string)requestData["sendkey"];
131 string recvkey = (string)requestData["recvkey"];
132 MessageServerInfo m = new MessageServerInfo();
133 m.URI = URI;
134 m.sendkey = sendkey;
135 m.recvkey = recvkey;
136 DeRegisterMessageServer(m);
137 responseData["responsestring"] = "TRUE";
138 response.Value = responseData;
139 }
140 return response;
141 }
142
143 public void RegisterMessageServer(MessageServerInfo m)
144 {
145 lock (m_messageServers)
146 {
147 if (!m_messageServers.Contains(m))
148 m_messageServers.Add(m);
149 }
150 }
151
152 public void DeRegisterMessageServer(MessageServerInfo m)
153 {
154 lock (m_messageServers)
155 {
156 if (m_messageServers.Contains(m))
157 m_messageServers.Remove(m);
158 }
159 }
160 }
161}
diff --git a/OpenSim/Grid/GridServer.Modules/GridRestModule.cs b/OpenSim/Grid/GridServer.Modules/GridRestModule.cs
new file mode 100644
index 0000000..cd6d4d5
--- /dev/null
+++ b/OpenSim/Grid/GridServer.Modules/GridRestModule.cs
@@ -0,0 +1,282 @@
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.IO;
32using System.Reflection;
33using System.Xml;
34using log4net;
35using OpenMetaverse;
36using OpenSim.Data;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Servers;
40using OpenSim.Grid.Framework;
41
42namespace OpenSim.Grid.GridServer.Modules
43{
44 public class GridRestModule
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private GridDBService m_gridDBService;
49 private IUGAIMCore m_gridCore;
50
51 protected GridConfig m_config;
52
53 /// <value>
54 /// Used to notify old regions as to which OpenSim version to upgrade to
55 /// </value>
56 private string m_opensimVersion;
57
58 protected BaseHttpServer m_httpServer;
59
60 /// <summary>
61 /// Constructor
62 /// </summary>
63 /// <param name="opensimVersion">
64 /// Used to notify old regions as to which OpenSim version to upgrade to
65 /// </param>
66 public GridRestModule()
67 {
68 }
69
70 public void Initialise(string opensimVersion, GridDBService gridDBService, IUGAIMCore gridCore, GridConfig config)
71 {
72 m_opensimVersion = opensimVersion;
73 m_gridDBService = gridDBService;
74 m_gridCore = gridCore;
75 m_config = config;
76 RegisterHandlers();
77 }
78
79 public void PostInitialise()
80 {
81
82 }
83
84 public void RegisterHandlers()
85 {
86 //have these in separate method as some servers restart the http server and reregister all the handlers.
87 m_httpServer = m_gridCore.GetHttpServer();
88
89 m_httpServer.AddStreamHandler(new RestStreamHandler("GET", "/sims/", RestGetSimMethod));
90 m_httpServer.AddStreamHandler(new RestStreamHandler("POST", "/sims/", RestSetSimMethod));
91
92 m_httpServer.AddStreamHandler(new RestStreamHandler("GET", "/regions/", RestGetRegionMethod));
93 m_httpServer.AddStreamHandler(new RestStreamHandler("POST", "/regions/", RestSetRegionMethod));
94 }
95
96 /// <summary>
97 /// Performs a REST Get Operation
98 /// </summary>
99 /// <param name="request"></param>
100 /// <param name="path"></param>
101 /// <param name="param"></param>
102 /// <param name="httpRequest">HTTP request header object</param>
103 /// <param name="httpResponse">HTTP response header object</param>
104 /// <returns></returns>
105 public string RestGetRegionMethod(string request, string path, string param,
106 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
107 {
108 return RestGetSimMethod(String.Empty, "/sims/", param, httpRequest, httpResponse);
109 }
110
111 /// <summary>
112 /// Performs a REST Set Operation
113 /// </summary>
114 /// <param name="request"></param>
115 /// <param name="path"></param>
116 /// <param name="param"></param>
117 /// <param name="httpRequest">HTTP request header object</param>
118 /// <param name="httpResponse">HTTP response header object</param>
119 /// <returns></returns>
120 public string RestSetRegionMethod(string request, string path, string param,
121 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
122 {
123 return RestSetSimMethod(String.Empty, "/sims/", param, httpRequest, httpResponse);
124 }
125
126 /// <summary>
127 /// Returns information about a sim via a REST Request
128 /// </summary>
129 /// <param name="request"></param>
130 /// <param name="path"></param>
131 /// <param name="param">A string representing the sim's UUID</param>
132 /// <param name="httpRequest">HTTP request header object</param>
133 /// <param name="httpResponse">HTTP response header object</param>
134 /// <returns>Information about the sim in XML</returns>
135 public string RestGetSimMethod(string request, string path, string param,
136 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
137 {
138 string respstring = String.Empty;
139
140 RegionProfileData TheSim;
141
142 UUID UUID;
143 if (UUID.TryParse(param, out UUID))
144 {
145 TheSim = m_gridDBService.GetRegion(UUID);
146
147 if (!(TheSim == null))
148 {
149 respstring = "<Root>";
150 respstring += "<authkey>" + TheSim.regionSendKey + "</authkey>";
151 respstring += "<sim>";
152 respstring += "<uuid>" + TheSim.UUID.ToString() + "</uuid>";
153 respstring += "<regionname>" + TheSim.regionName + "</regionname>";
154 respstring += "<sim_ip>" + TheSim.serverIP + "</sim_ip>";
155 respstring += "<sim_port>" + TheSim.serverPort.ToString() + "</sim_port>";
156 respstring += "<region_locx>" + TheSim.regionLocX.ToString() + "</region_locx>";
157 respstring += "<region_locy>" + TheSim.regionLocY.ToString() + "</region_locy>";
158 respstring += "<estate_id>1</estate_id>";
159 respstring += "</sim>";
160 respstring += "</Root>";
161 }
162 }
163 else
164 {
165 respstring = "<Root>";
166 respstring += "<error>Param must be a UUID</error>";
167 respstring += "</Root>";
168 }
169
170 return respstring;
171 }
172
173 /// <summary>
174 /// Creates or updates a sim via a REST Method Request
175 /// BROKEN with SQL Update
176 /// </summary>
177 /// <param name="request"></param>
178 /// <param name="path"></param>
179 /// <param name="param"></param>
180 /// <param name="httpRequest">HTTP request header object</param>
181 /// <param name="httpResponse">HTTP response header object</param>
182 /// <returns>"OK" or an error</returns>
183 public string RestSetSimMethod(string request, string path, string param,
184 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
185 {
186 m_log.Info("Processing region update via REST method");
187 RegionProfileData theSim;
188 theSim = m_gridDBService.GetRegion(new UUID(param));
189 if (theSim == null)
190 {
191 theSim = new RegionProfileData();
192 UUID UUID = new UUID(param);
193 theSim.UUID = UUID;
194 theSim.regionRecvKey = m_config.SimRecvKey;
195 }
196
197 XmlDocument doc = new XmlDocument();
198 doc.LoadXml(request);
199 XmlNode rootnode = doc.FirstChild;
200 XmlNode authkeynode = rootnode.ChildNodes[0];
201 if (authkeynode.Name != "authkey")
202 {
203 return "ERROR! bad XML - expected authkey tag";
204 }
205
206 XmlNode simnode = rootnode.ChildNodes[1];
207 if (simnode.Name != "sim")
208 {
209 return "ERROR! bad XML - expected sim tag";
210 }
211
212 //theSim.regionSendKey = Cfg;
213 theSim.regionRecvKey = m_config.SimRecvKey;
214 theSim.regionSendKey = m_config.SimSendKey;
215 theSim.regionSecret = m_config.SimRecvKey;
216 theSim.regionDataURI = String.Empty;
217 theSim.regionAssetURI = m_config.DefaultAssetServer;
218 theSim.regionAssetRecvKey = m_config.AssetRecvKey;
219 theSim.regionAssetSendKey = m_config.AssetSendKey;
220 theSim.regionUserURI = m_config.DefaultUserServer;
221 theSim.regionUserSendKey = m_config.UserSendKey;
222 theSim.regionUserRecvKey = m_config.UserRecvKey;
223
224 for (int i = 0; i < simnode.ChildNodes.Count; i++)
225 {
226 switch (simnode.ChildNodes[i].Name)
227 {
228 case "regionname":
229 theSim.regionName = simnode.ChildNodes[i].InnerText;
230 break;
231
232 case "sim_ip":
233 theSim.serverIP = simnode.ChildNodes[i].InnerText;
234 break;
235
236 case "sim_port":
237 theSim.serverPort = Convert.ToUInt32(simnode.ChildNodes[i].InnerText);
238 break;
239
240 case "region_locx":
241 theSim.regionLocX = Convert.ToUInt32((string)simnode.ChildNodes[i].InnerText);
242 theSim.regionHandle = Utils.UIntsToLong((theSim.regionLocX * Constants.RegionSize), (theSim.regionLocY * Constants.RegionSize));
243 break;
244
245 case "region_locy":
246 theSim.regionLocY = Convert.ToUInt32((string)simnode.ChildNodes[i].InnerText);
247 theSim.regionHandle = Utils.UIntsToLong((theSim.regionLocX * Constants.RegionSize), (theSim.regionLocY * Constants.RegionSize));
248 break;
249 }
250 }
251
252 theSim.serverURI = "http://" + theSim.serverIP + ":" + theSim.serverPort + "/";
253 bool requirePublic = false;
254 bool requireValid = true;
255
256 if (requirePublic &&
257 (theSim.serverIP.StartsWith("172.16") || theSim.serverIP.StartsWith("192.168") ||
258 theSim.serverIP.StartsWith("10.") || theSim.serverIP.StartsWith("0.") ||
259 theSim.serverIP.StartsWith("255.")))
260 {
261 return "ERROR! Servers must register with public addresses.";
262 }
263
264 if (requireValid && (theSim.serverIP.StartsWith("0.") || theSim.serverIP.StartsWith("255.")))
265 {
266 return "ERROR! 0.*.*.* / 255.*.*.* Addresses are invalid, please check your server config and try again";
267 }
268
269 try
270 {
271 m_log.Info("[DATA]: " +
272 "Updating / adding via " + m_gridDBService.GetNumberOfPlugins() + " storage provider(s) registered.");
273
274 return m_gridDBService.CheckReservations(theSim, authkeynode);
275 }
276 catch (Exception e)
277 {
278 return "ERROR! Could not save to database! (" + e.ToString() + ")";
279 }
280 }
281 }
282}
diff --git a/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs b/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs
new file mode 100644
index 0000000..d5af900
--- /dev/null
+++ b/OpenSim/Grid/GridServer.Modules/GridXmlRpcModule.cs
@@ -0,0 +1,885 @@
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.IO;
32using System.Reflection;
33using System.Xml;
34using log4net;
35using Nwc.XmlRpc;
36using OpenMetaverse;
37using OpenSim.Data;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Servers;
41using OpenSim.Grid.Framework;
42
43namespace OpenSim.Grid.GridServer.Modules
44{
45 public class GridXmlRpcModule
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private GridDBService m_gridDBService;
50 private IUGAIMCore m_gridCore;
51
52 protected GridConfig m_config;
53
54 protected IGridMessagingMapper m_messagingServerMapper;
55 /// <value>
56 /// Used to notify old regions as to which OpenSim version to upgrade to
57 /// </value>
58 private string m_opensimVersion;
59
60 protected BaseHttpServer m_httpServer;
61
62 /// <summary>
63 /// Constructor
64 /// </summary>
65 /// <param name="opensimVersion">
66 /// Used to notify old regions as to which OpenSim version to upgrade to
67 /// </param>
68 public GridXmlRpcModule()
69 {
70 }
71
72 public void Initialise(string opensimVersion, GridDBService gridDBService, IUGAIMCore gridCore, GridConfig config)
73 {
74 m_opensimVersion = opensimVersion;
75 m_gridDBService = gridDBService;
76 m_gridCore = gridCore;
77 m_config = config;
78 RegisterHandlers();
79 }
80
81 public void PostInitialise()
82 {
83 IGridMessagingMapper messagingModule;
84 if (m_gridCore.TryGet<IGridMessagingMapper>(out messagingModule))
85 {
86 m_messagingServerMapper = messagingModule;
87 }
88 }
89
90 public void RegisterHandlers()
91 {
92 //have these in separate method as some servers restart the http server and reregister all the handlers.
93 m_httpServer = m_gridCore.GetHttpServer();
94
95 m_httpServer.AddXmlRPCHandler("simulator_login", XmlRpcSimulatorLoginMethod);
96 m_httpServer.AddXmlRPCHandler("simulator_data_request", XmlRpcSimulatorDataRequestMethod);
97 m_httpServer.AddXmlRPCHandler("simulator_after_region_moved", XmlRpcDeleteRegionMethod);
98 m_httpServer.AddXmlRPCHandler("map_block", XmlRpcMapBlockMethod);
99 m_httpServer.AddXmlRPCHandler("search_for_region_by_name", XmlRpcSearchForRegionMethod);
100 }
101
102 /// <summary>
103 /// Returns a XML String containing a list of the neighbouring regions
104 /// </summary>
105 /// <param name="reqhandle">The regionhandle for the center sim</param>
106 /// <returns>An XML string containing neighbour entities</returns>
107 public string GetXMLNeighbours(ulong reqhandle)
108 {
109 string response = String.Empty;
110 RegionProfileData central_region = m_gridDBService.GetRegion(reqhandle);
111 RegionProfileData neighbour;
112 for (int x = -1; x < 2; x++)
113 {
114 for (int y = -1; y < 2; y++)
115 {
116 if (
117 m_gridDBService.GetRegion(
118 Util.UIntsToLong((uint)((central_region.regionLocX + x) * Constants.RegionSize),
119 (uint)(central_region.regionLocY + y) * Constants.RegionSize)) != null)
120 {
121 neighbour =
122 m_gridDBService.GetRegion(
123 Util.UIntsToLong((uint)((central_region.regionLocX + x) * Constants.RegionSize),
124 (uint)(central_region.regionLocY + y) * Constants.RegionSize));
125
126 response += "<neighbour>";
127 response += "<sim_ip>" + neighbour.serverIP + "</sim_ip>";
128 response += "<sim_port>" + neighbour.serverPort.ToString() + "</sim_port>";
129 response += "<locx>" + neighbour.regionLocX.ToString() + "</locx>";
130 response += "<locy>" + neighbour.regionLocY.ToString() + "</locy>";
131 response += "<regionhandle>" + neighbour.regionHandle.ToString() + "</regionhandle>";
132 response += "</neighbour>";
133 }
134 }
135 }
136 return response;
137 }
138
139 /// <summary>
140 /// Checks that it's valid to replace the existing region data with new data
141 ///
142 /// Currently, this means ensure that the keys passed in by the new region
143 /// match those in the original region. (XXX Is this correct? Shouldn't we simply check
144 /// against the keys in the current configuration?)
145 /// </summary>
146 /// <param name="sim"></param>
147 /// <returns></returns>
148 protected virtual void ValidateOverwriteKeys(RegionProfileData sim, RegionProfileData existingSim)
149 {
150 if (!(existingSim.regionRecvKey == sim.regionRecvKey && existingSim.regionSendKey == sim.regionSendKey))
151 {
152 throw new LoginException(
153 String.Format(
154 "Authentication failed when trying to login existing region {0} at location {1} {2} currently occupied by {3}"
155 + " with the region's send key {4} (expected {5}) and the region's receive key {6} (expected {7})",
156 sim.regionName, sim.regionLocX, sim.regionLocY, existingSim.regionName,
157 sim.regionSendKey, existingSim.regionSendKey, sim.regionRecvKey, existingSim.regionRecvKey),
158 "The keys required to login your region did not match the grid server keys. Please check your grid send and receive keys.");
159 }
160 }
161
162 /// <summary>
163 /// Checks that the new region data is valid.
164 ///
165 /// Currently, this means checking that the keys passed in by the new region
166 /// match those in the grid server's configuration.
167 /// </summary>
168 ///
169 /// <param name="sim"></param>
170 /// <exception cref="LoginException">Thrown if region login failed</exception>
171 protected virtual void ValidateNewRegionKeys(RegionProfileData sim)
172 {
173 if (!(sim.regionRecvKey == m_config.SimSendKey && sim.regionSendKey == m_config.SimRecvKey))
174 {
175 throw new LoginException(
176 String.Format(
177 "Authentication failed when trying to login new region {0} at location {1} {2}"
178 + " with the region's send key {3} (expected {4}) and the region's receive key {5} (expected {6})",
179 sim.regionName, sim.regionLocX, sim.regionLocY,
180 sim.regionSendKey, m_config.SimRecvKey, sim.regionRecvKey, m_config.SimSendKey),
181 "The keys required to login your region did not match your existing region keys. Please check your grid send and receive keys.");
182 }
183 }
184
185 /// <summary>
186 /// Check that a region's http uri is externally contactable.
187 /// </summary>
188 /// <param name="sim"></param>
189 /// <exception cref="LoginException">Thrown if the region is not contactable</exception>
190 protected virtual void ValidateRegionContactable(RegionProfileData sim)
191 {
192 string regionStatusUrl = String.Format("{0}{1}", sim.httpServerURI, "simstatus/");
193 string regionStatusResponse;
194
195 RestClient rc = new RestClient(regionStatusUrl);
196 rc.RequestMethod = "GET";
197
198 m_log.DebugFormat("[LOGIN]: Contacting {0} for status of region {1}", regionStatusUrl, sim.regionName);
199
200 try
201 {
202 Stream rs = rc.Request();
203 StreamReader sr = new StreamReader(rs);
204 regionStatusResponse = sr.ReadToEnd();
205 sr.Close();
206 }
207 catch (Exception e)
208 {
209 throw new LoginException(
210 String.Format("Region status request to {0} failed", regionStatusUrl),
211 String.Format(
212 "The grid service could not contact the http url {0} at your region. Please make sure this url is reachable by the grid service",
213 regionStatusUrl),
214 e);
215 }
216
217 if (!regionStatusResponse.Equals("OK"))
218 {
219 throw new LoginException(
220 String.Format(
221 "Region {0} at {1} returned status response {2} rather than {3}",
222 sim.regionName, regionStatusUrl, regionStatusResponse, "OK"),
223 String.Format(
224 "When the grid service asked for the status of your region, it received the response {0} rather than {1}. Please check your status",
225 regionStatusResponse, "OK"));
226 }
227 }
228
229 /// <summary>
230 /// Construct an XMLRPC error response
231 /// </summary>
232 /// <param name="error"></param>
233 /// <returns></returns>
234 public static XmlRpcResponse ErrorResponse(string error)
235 {
236 XmlRpcResponse errorResponse = new XmlRpcResponse();
237 Hashtable errorResponseData = new Hashtable();
238 errorResponse.Value = errorResponseData;
239 errorResponseData["error"] = error;
240 return errorResponse;
241 }
242
243 /// <summary>
244 /// Performed when a region connects to the grid server initially.
245 /// </summary>
246 /// <param name="request">The XML RPC Request</param>
247 /// <returns>Startup parameters</returns>
248 public XmlRpcResponse XmlRpcSimulatorLoginMethod(XmlRpcRequest request)
249 {
250 RegionProfileData sim;
251 RegionProfileData existingSim;
252
253 Hashtable requestData = (Hashtable)request.Params[0];
254 UUID uuid;
255
256 if (!requestData.ContainsKey("UUID") || !UUID.TryParse((string)requestData["UUID"], out uuid))
257 {
258 m_log.Debug("[LOGIN PRELUDE]: Region connected without a UUID, sending back error response.");
259 return ErrorResponse("No UUID passed to grid server - unable to connect you");
260 }
261
262 try
263 {
264 sim = RegionFromRequest(requestData);
265 }
266 catch (FormatException e)
267 {
268 m_log.Debug("[LOGIN PRELUDE]: Invalid login parameters, sending back error response.");
269 return ErrorResponse("Wrong format in login parameters. Please verify parameters." + e.ToString());
270 }
271
272 m_log.InfoFormat("[LOGIN BEGIN]: Received login request from simulator: {0}", sim.regionName);
273
274 if (!m_config.AllowRegionRegistration)
275 {
276 m_log.DebugFormat(
277 "[LOGIN END]: Disabled region registration blocked login request from simulator: {0}",
278 sim.regionName);
279
280 return ErrorResponse("This grid is currently not accepting region registrations.");
281 }
282
283 int majorInterfaceVersion = 0;
284 if (requestData.ContainsKey("major_interface_version"))
285 int.TryParse((string)requestData["major_interface_version"], out majorInterfaceVersion);
286
287 if (majorInterfaceVersion != VersionInfo.MajorInterfaceVersion)
288 {
289 return ErrorResponse(
290 String.Format(
291 "Your region service implements OGS1 interface version {0}"
292 + " but this grid requires that the region implement OGS1 interface version {1} to connect."
293 + " Try changing to OpenSimulator {2}",
294 majorInterfaceVersion, VersionInfo.MajorInterfaceVersion, m_opensimVersion));
295 }
296
297 existingSim = m_gridDBService.GetRegion(sim.regionHandle);
298
299 if (existingSim == null || existingSim.UUID == sim.UUID || sim.UUID != sim.originUUID)
300 {
301 try
302 {
303 if (existingSim == null)
304 {
305 ValidateNewRegionKeys(sim);
306 }
307 else
308 {
309 ValidateOverwriteKeys(sim, existingSim);
310 }
311
312 ValidateRegionContactable(sim);
313 }
314 catch (LoginException e)
315 {
316 string logMsg = e.Message;
317 if (e.InnerException != null)
318 logMsg += ", " + e.InnerException.Message;
319
320 m_log.WarnFormat("[LOGIN END]: {0}", logMsg);
321
322 return e.XmlRpcErrorResponse;
323 }
324
325 DataResponse insertResponse = m_gridDBService.AddUpdateRegion(sim, existingSim);
326
327 switch (insertResponse)
328 {
329 case DataResponse.RESPONSE_OK:
330 m_log.Info("[LOGIN END]: " + (existingSim == null ? "New" : "Existing") + " sim login successful: " + sim.regionName);
331 break;
332 case DataResponse.RESPONSE_ERROR:
333 m_log.Warn("[LOGIN END]: Sim login failed (Error): " + sim.regionName);
334 break;
335 case DataResponse.RESPONSE_INVALIDCREDENTIALS:
336 m_log.Warn("[LOGIN END]: " +
337 "Sim login failed (Invalid Credentials): " + sim.regionName);
338 break;
339 case DataResponse.RESPONSE_AUTHREQUIRED:
340 m_log.Warn("[LOGIN END]: " +
341 "Sim login failed (Authentication Required): " +
342 sim.regionName);
343 break;
344 }
345
346 XmlRpcResponse response = CreateLoginResponse(sim);
347
348 return response;
349 }
350 else
351 {
352 m_log.Warn("[LOGIN END]: Failed to login region " + sim.regionName + " at location " + sim.regionLocX + " " + sim.regionLocY + " currently occupied by " + existingSim.regionName);
353 return ErrorResponse("Another region already exists at that location. Please try another.");
354 }
355 }
356
357 /// <summary>
358 /// Construct a successful response to a simulator's login attempt.
359 /// </summary>
360 /// <param name="sim"></param>
361 /// <returns></returns>
362 private XmlRpcResponse CreateLoginResponse(RegionProfileData sim)
363 {
364 XmlRpcResponse response = new XmlRpcResponse();
365 Hashtable responseData = new Hashtable();
366 response.Value = responseData;
367
368 ArrayList SimNeighboursData = GetSimNeighboursData(sim);
369
370 responseData["UUID"] = sim.UUID.ToString();
371 responseData["region_locx"] = sim.regionLocX.ToString();
372 responseData["region_locy"] = sim.regionLocY.ToString();
373 responseData["regionname"] = sim.regionName;
374 responseData["estate_id"] = "1";
375 responseData["neighbours"] = SimNeighboursData;
376
377 responseData["sim_ip"] = sim.serverIP;
378 responseData["sim_port"] = sim.serverPort.ToString();
379 responseData["asset_url"] = sim.regionAssetURI;
380 responseData["asset_sendkey"] = sim.regionAssetSendKey;
381 responseData["asset_recvkey"] = sim.regionAssetRecvKey;
382 responseData["user_url"] = sim.regionUserURI;
383 responseData["user_sendkey"] = sim.regionUserSendKey;
384 responseData["user_recvkey"] = sim.regionUserRecvKey;
385 responseData["authkey"] = sim.regionSecret;
386
387 // New! If set, use as URL to local sim storage (ie http://remotehost/region.Yap)
388 responseData["data_uri"] = sim.regionDataURI;
389
390 responseData["allow_forceful_banlines"] = m_config.AllowForcefulBanlines;
391
392 // Instead of sending a multitude of message servers to the registering sim
393 // we should probably be sending a single one and parhaps it's backup
394 // that has responsibility over routing it's messages.
395
396 // The Sim won't be contacting us again about any of the message server stuff during it's time up.
397
398 responseData["messageserver_count"] = 0;
399
400 // IGridMessagingModule messagingModule;
401 // if (m_gridCore.TryGet<IGridMessagingModule>(out messagingModule))
402 //{
403 if(m_messagingServerMapper != null)
404 {
405 List<MessageServerInfo> messageServers = m_messagingServerMapper.GetMessageServersList();
406 responseData["messageserver_count"] = messageServers.Count;
407
408 for (int i = 0; i < messageServers.Count; i++)
409 {
410 responseData["messageserver_uri" + i] = messageServers[i].URI;
411 responseData["messageserver_sendkey" + i] = messageServers[i].sendkey;
412 responseData["messageserver_recvkey" + i] = messageServers[i].recvkey;
413 }
414 }
415 return response;
416 }
417
418 private ArrayList GetSimNeighboursData(RegionProfileData sim)
419 {
420 ArrayList SimNeighboursData = new ArrayList();
421
422 RegionProfileData neighbour;
423 Hashtable NeighbourBlock;
424
425 //First use the fast method. (not implemented in SQLLite)
426 List<RegionProfileData> neighbours = m_gridDBService.GetRegions(sim.regionLocX - 1, sim.regionLocY - 1, sim.regionLocX + 1, sim.regionLocY + 1);
427
428 if (neighbours.Count > 0)
429 {
430 foreach (RegionProfileData aSim in neighbours)
431 {
432 NeighbourBlock = new Hashtable();
433 NeighbourBlock["sim_ip"] = aSim.serverIP;
434 NeighbourBlock["sim_port"] = aSim.serverPort.ToString();
435 NeighbourBlock["region_locx"] = aSim.regionLocX.ToString();
436 NeighbourBlock["region_locy"] = aSim.regionLocY.ToString();
437 NeighbourBlock["UUID"] = aSim.ToString();
438 NeighbourBlock["regionHandle"] = aSim.regionHandle.ToString();
439
440 if (aSim.UUID != sim.UUID)
441 {
442 SimNeighboursData.Add(NeighbourBlock);
443 }
444 }
445 }
446 else
447 {
448 for (int x = -1; x < 2; x++)
449 {
450 for (int y = -1; y < 2; y++)
451 {
452 if (
453 m_gridDBService.GetRegion(
454 Utils.UIntsToLong((uint)((sim.regionLocX + x) * Constants.RegionSize),
455 (uint)(sim.regionLocY + y) * Constants.RegionSize)) != null)
456 {
457 neighbour =
458 m_gridDBService.GetRegion(
459 Utils.UIntsToLong((uint)((sim.regionLocX + x) * Constants.RegionSize),
460 (uint)(sim.regionLocY + y) * Constants.RegionSize));
461
462 NeighbourBlock = new Hashtable();
463 NeighbourBlock["sim_ip"] = neighbour.serverIP;
464 NeighbourBlock["sim_port"] = neighbour.serverPort.ToString();
465 NeighbourBlock["region_locx"] = neighbour.regionLocX.ToString();
466 NeighbourBlock["region_locy"] = neighbour.regionLocY.ToString();
467 NeighbourBlock["UUID"] = neighbour.UUID.ToString();
468 NeighbourBlock["regionHandle"] = neighbour.regionHandle.ToString();
469
470 if (neighbour.UUID != sim.UUID) SimNeighboursData.Add(NeighbourBlock);
471 }
472 }
473 }
474 }
475 return SimNeighboursData;
476 }
477
478 /// <summary>
479 /// Loads the grid's own RegionProfileData object with data from the XMLRPC simulator_login request from a region
480 /// </summary>
481 /// <param name="requestData"></param>
482 /// <returns></returns>
483 private RegionProfileData RegionFromRequest(Hashtable requestData)
484 {
485 RegionProfileData sim;
486 sim = new RegionProfileData();
487
488 sim.UUID = new UUID((string)requestData["UUID"]);
489 sim.originUUID = new UUID((string)requestData["originUUID"]);
490
491 sim.regionRecvKey = String.Empty;
492 sim.regionSendKey = String.Empty;
493
494 if (requestData.ContainsKey("region_secret"))
495 {
496 string regionsecret = (string)requestData["region_secret"];
497 if (regionsecret.Length > 0)
498 sim.regionSecret = regionsecret;
499 else
500 sim.regionSecret = m_config.SimRecvKey;
501
502 }
503 else
504 {
505 sim.regionSecret = m_config.SimRecvKey;
506 }
507
508 sim.regionDataURI = String.Empty;
509 sim.regionAssetURI = m_config.DefaultAssetServer;
510 sim.regionAssetRecvKey = m_config.AssetRecvKey;
511 sim.regionAssetSendKey = m_config.AssetSendKey;
512 sim.regionUserURI = m_config.DefaultUserServer;
513 sim.regionUserSendKey = m_config.UserSendKey;
514 sim.regionUserRecvKey = m_config.UserRecvKey;
515
516 sim.serverIP = (string)requestData["sim_ip"];
517 sim.serverPort = Convert.ToUInt32((string)requestData["sim_port"]);
518 sim.httpPort = Convert.ToUInt32((string)requestData["http_port"]);
519 sim.remotingPort = Convert.ToUInt32((string)requestData["remoting_port"]);
520 sim.regionLocX = Convert.ToUInt32((string)requestData["region_locx"]);
521 sim.regionLocY = Convert.ToUInt32((string)requestData["region_locy"]);
522 sim.regionLocZ = 0;
523
524 UUID textureID;
525 if (UUID.TryParse((string)requestData["map-image-id"], out textureID))
526 {
527 sim.regionMapTextureID = textureID;
528 }
529
530 // part of an initial brutish effort to provide accurate information (as per the xml region spec)
531 // wrt the ownership of a given region
532 // the (very bad) assumption is that this value is being read and handled inconsistently or
533 // not at all. Current strategy is to put the code in place to support the validity of this information
534 // and to roll forward debugging any issues from that point
535 //
536 // this particular section of the mod attempts to receive a value from the region's xml file by way of
537 // OSG1GridServices for the region's owner
538 sim.owner_uuid = (UUID)(string)requestData["master_avatar_uuid"];
539
540 try
541 {
542 sim.regionRecvKey = (string)requestData["recvkey"];
543 sim.regionSendKey = (string)requestData["authkey"];
544 }
545 catch (KeyNotFoundException) { }
546
547 sim.regionHandle = Utils.UIntsToLong((sim.regionLocX * Constants.RegionSize), (sim.regionLocY * Constants.RegionSize));
548 sim.serverURI = (string)requestData["server_uri"];
549
550 sim.httpServerURI = "http://" + sim.serverIP + ":" + sim.httpPort + "/";
551
552 sim.regionName = (string)requestData["sim_name"];
553 return sim;
554 }
555
556 /// <summary>
557 /// Returns an XML RPC response to a simulator profile request
558 /// Performed after moving a region.
559 /// </summary>
560 /// <param name="request"></param>
561 /// <returns></returns>
562 /// <param name="request">The XMLRPC Request</param>
563 /// <returns>Processing parameters</returns>
564 public XmlRpcResponse XmlRpcDeleteRegionMethod(XmlRpcRequest request)
565 {
566 XmlRpcResponse response = new XmlRpcResponse();
567 Hashtable responseData = new Hashtable();
568 response.Value = responseData;
569
570 //RegionProfileData TheSim = null;
571 string uuid;
572 Hashtable requestData = (Hashtable)request.Params[0];
573
574 if (requestData.ContainsKey("UUID"))
575 {
576 //TheSim = GetRegion(new UUID((string) requestData["UUID"]));
577 uuid = requestData["UUID"].ToString();
578 m_log.InfoFormat("[LOGOUT]: Logging out region: {0}", uuid);
579 // logToDB((new LLUUID((string)requestData["UUID"])).ToString(),"XmlRpcDeleteRegionMethod","", 5,"Attempting delete with UUID.");
580 }
581 else
582 {
583 responseData["error"] = "No UUID or region_handle passed to grid server - unable to delete";
584 return response;
585 }
586
587 DataResponse insertResponse = m_gridDBService.DeleteRegion(uuid);
588
589 string insertResp = "";
590 switch (insertResponse)
591 {
592 case DataResponse.RESPONSE_OK:
593 //MainLog.Instance.Verbose("grid", "Deleting region successful: " + uuid);
594 insertResp = "Deleting region successful: " + uuid;
595 break;
596 case DataResponse.RESPONSE_ERROR:
597 //MainLog.Instance.Warn("storage", "Deleting region failed (Error): " + uuid);
598 insertResp = "Deleting region failed (Error): " + uuid;
599 break;
600 case DataResponse.RESPONSE_INVALIDCREDENTIALS:
601 //MainLog.Instance.Warn("storage", "Deleting region failed (Invalid Credentials): " + uuid);
602 insertResp = "Deleting region (Invalid Credentials): " + uuid;
603 break;
604 case DataResponse.RESPONSE_AUTHREQUIRED:
605 //MainLog.Instance.Warn("storage", "Deleting region failed (Authentication Required): " + uuid);
606 insertResp = "Deleting region (Authentication Required): " + uuid;
607 break;
608 }
609
610 responseData["status"] = insertResp;
611
612 return response;
613 }
614
615 /// <summary>
616 /// Returns an XML RPC response to a simulator profile request
617 /// </summary>
618 /// <param name="request"></param>
619 /// <returns></returns>
620 public XmlRpcResponse XmlRpcSimulatorDataRequestMethod(XmlRpcRequest request)
621 {
622 Hashtable requestData = (Hashtable)request.Params[0];
623 Hashtable responseData = new Hashtable();
624 RegionProfileData simData = null;
625 if (requestData.ContainsKey("region_UUID"))
626 {
627 UUID regionID = new UUID((string)requestData["region_UUID"]);
628 simData = m_gridDBService.GetRegion(regionID);
629 if (simData == null)
630 {
631 m_log.WarnFormat("[DATA] didn't find region for regionID {0} from {1}",
632 regionID, request.Params.Count > 1 ? request.Params[1] : "unknwon source");
633 }
634 }
635 else if (requestData.ContainsKey("region_handle"))
636 {
637 //CFK: The if/else below this makes this message redundant.
638 //CFK: m_log.Info("requesting data for region " + (string) requestData["region_handle"]);
639 ulong regionHandle = Convert.ToUInt64((string)requestData["region_handle"]);
640 simData = m_gridDBService.GetRegion(regionHandle);
641 if (simData == null)
642 {
643 m_log.WarnFormat("[DATA] didn't find region for regionHandle {0} from {1}",
644 regionHandle, request.Params.Count > 1 ? request.Params[1] : "unknwon source");
645 }
646 }
647 else if (requestData.ContainsKey("region_name_search"))
648 {
649 string regionName = (string)requestData["region_name_search"];
650 simData = m_gridDBService.GetRegion(regionName);
651 if (simData == null)
652 {
653 m_log.WarnFormat("[DATA] didn't find region for regionName {0} from {1}",
654 regionName, request.Params.Count > 1 ? request.Params[1] : "unknwon source");
655 }
656 }
657 else m_log.Warn("[DATA] regionlookup without regionID, regionHandle or regionHame");
658
659 if (simData == null)
660 {
661 //Sim does not exist
662 responseData["error"] = "Sim does not exist";
663 }
664 else
665 {
666 m_log.Info("[DATA]: found " + (string)simData.regionName + " regionHandle = " +
667 (string)requestData["region_handle"]);
668 responseData["sim_ip"] = simData.serverIP;
669 responseData["sim_port"] = simData.serverPort.ToString();
670 responseData["server_uri"] = simData.serverURI;
671 responseData["http_port"] = simData.httpPort.ToString();
672 responseData["remoting_port"] = simData.remotingPort.ToString();
673 responseData["region_locx"] = simData.regionLocX.ToString();
674 responseData["region_locy"] = simData.regionLocY.ToString();
675 responseData["region_UUID"] = simData.UUID.Guid.ToString();
676 responseData["region_name"] = simData.regionName;
677 responseData["regionHandle"] = simData.regionHandle.ToString();
678 }
679
680 XmlRpcResponse response = new XmlRpcResponse();
681 response.Value = responseData;
682 return response;
683 }
684
685 public XmlRpcResponse XmlRpcMapBlockMethod(XmlRpcRequest request)
686 {
687 int xmin = 980, ymin = 980, xmax = 1020, ymax = 1020;
688
689 Hashtable requestData = (Hashtable)request.Params[0];
690 if (requestData.ContainsKey("xmin"))
691 {
692 xmin = (Int32)requestData["xmin"];
693 }
694 if (requestData.ContainsKey("ymin"))
695 {
696 ymin = (Int32)requestData["ymin"];
697 }
698 if (requestData.ContainsKey("xmax"))
699 {
700 xmax = (Int32)requestData["xmax"];
701 }
702 if (requestData.ContainsKey("ymax"))
703 {
704 ymax = (Int32)requestData["ymax"];
705 }
706 //CFK: The second log is more meaningful and either standard or fast generally occurs.
707 //CFK: m_log.Info("[MAP]: World map request for range (" + xmin + "," + ymin + ")..(" + xmax + "," + ymax + ")");
708
709 XmlRpcResponse response = new XmlRpcResponse();
710 Hashtable responseData = new Hashtable();
711 response.Value = responseData;
712 IList simProfileList = new ArrayList();
713
714 bool fastMode = (m_config.DatabaseProvider == "OpenSim.Data.MySQL.dll" || m_config.DatabaseProvider == "OpenSim.Data.MSSQL.dll");
715
716 if (fastMode)
717 {
718 List<RegionProfileData> neighbours = m_gridDBService.GetRegions((uint)xmin, (uint)ymin, (uint)xmax, (uint)ymax);
719
720 foreach (RegionProfileData aSim in neighbours)
721 {
722 Hashtable simProfileBlock = new Hashtable();
723 simProfileBlock["x"] = aSim.regionLocX.ToString();
724 simProfileBlock["y"] = aSim.regionLocY.ToString();
725 //m_log.DebugFormat("[MAP]: Sending neighbour info for {0},{1}", aSim.regionLocX, aSim.regionLocY);
726 simProfileBlock["name"] = aSim.regionName;
727 simProfileBlock["access"] = 21;
728 simProfileBlock["region-flags"] = 512;
729 simProfileBlock["water-height"] = 0;
730 simProfileBlock["agents"] = 1;
731 simProfileBlock["map-image-id"] = aSim.regionMapTextureID.ToString();
732
733 // For Sugilite compatibility
734 simProfileBlock["regionhandle"] = aSim.regionHandle.ToString();
735 simProfileBlock["sim_ip"] = aSim.serverIP;
736 simProfileBlock["sim_port"] = aSim.serverPort.ToString();
737 simProfileBlock["sim_uri"] = aSim.serverURI.ToString();
738 simProfileBlock["uuid"] = aSim.UUID.ToString();
739 simProfileBlock["remoting_port"] = aSim.remotingPort.ToString();
740 simProfileBlock["http_port"] = aSim.httpPort.ToString();
741
742 simProfileList.Add(simProfileBlock);
743 }
744 m_log.Info("[MAP]: Fast map " + simProfileList.Count.ToString() +
745 " regions @ (" + xmin + "," + ymin + ")..(" + xmax + "," + ymax + ")");
746 }
747 else
748 {
749 RegionProfileData simProfile;
750 for (int x = xmin; x < xmax + 1; x++)
751 {
752 for (int y = ymin; y < ymax + 1; y++)
753 {
754 ulong regHandle = Utils.UIntsToLong((uint)(x * Constants.RegionSize), (uint)(y * Constants.RegionSize));
755 simProfile = m_gridDBService.GetRegion(regHandle);
756 if (simProfile != null)
757 {
758 Hashtable simProfileBlock = new Hashtable();
759 simProfileBlock["x"] = x;
760 simProfileBlock["y"] = y;
761 simProfileBlock["name"] = simProfile.regionName;
762 simProfileBlock["access"] = 0;
763 simProfileBlock["region-flags"] = 0;
764 simProfileBlock["water-height"] = 20;
765 simProfileBlock["agents"] = 1;
766 simProfileBlock["map-image-id"] = simProfile.regionMapTextureID.ToString();
767
768 // For Sugilite compatibility
769 simProfileBlock["regionhandle"] = simProfile.regionHandle.ToString();
770 simProfileBlock["sim_ip"] = simProfile.serverIP.ToString();
771 simProfileBlock["sim_port"] = simProfile.serverPort.ToString();
772 simProfileBlock["sim_uri"] = simProfile.serverURI.ToString();
773 simProfileBlock["uuid"] = simProfile.UUID.ToString();
774 simProfileBlock["remoting_port"] = simProfile.remotingPort.ToString();
775 simProfileBlock["http_port"] = simProfile.httpPort;
776
777 simProfileList.Add(simProfileBlock);
778 }
779 }
780 }
781 m_log.Info("[MAP]: Std map " + simProfileList.Count.ToString() +
782 " regions @ (" + xmin + "," + ymin + ")..(" + xmax + "," + ymax + ")");
783 }
784
785 responseData["sim-profiles"] = simProfileList;
786
787 return response;
788 }
789
790 /// <summary>
791 /// Returns up to <code>maxNumber</code> profiles of regions that have a name starting with <code>name</code>
792 /// </summary>
793 /// <param name="request"></param>
794 /// <returns></returns>
795 public XmlRpcResponse XmlRpcSearchForRegionMethod(XmlRpcRequest request)
796 {
797 Hashtable requestData = (Hashtable)request.Params[0];
798
799 if (!requestData.ContainsKey("name") || !requestData.Contains("maxNumber"))
800 {
801 m_log.Warn("[DATA] Invalid region-search request; missing name or maxNumber");
802 return new XmlRpcResponse(500, "Missing name or maxNumber in region search request");
803 }
804
805 Hashtable responseData = new Hashtable();
806
807 string name = (string)requestData["name"];
808 int maxNumber = Convert.ToInt32((string)requestData["maxNumber"]);
809 if (maxNumber == 0 || name.Length < 3)
810 {
811 // either we didn't want any, or we were too unspecific
812 responseData["numFound"] = 0;
813 }
814 else
815 {
816 List<RegionProfileData> sims = m_gridDBService.GetRegions(name, maxNumber);
817
818 responseData["numFound"] = sims.Count;
819 for (int i = 0; i < sims.Count; ++i)
820 {
821 RegionProfileData sim = sims[i];
822 string prefix = "region" + i + ".";
823 responseData[prefix + "region_name"] = sim.regionName;
824 responseData[prefix + "region_UUID"] = sim.UUID.ToString();
825 responseData[prefix + "region_locx"] = sim.regionLocX.ToString();
826 responseData[prefix + "region_locy"] = sim.regionLocY.ToString();
827 responseData[prefix + "sim_ip"] = sim.serverIP.ToString();
828 responseData[prefix + "sim_port"] = sim.serverPort.ToString();
829 responseData[prefix + "remoting_port"] = sim.remotingPort.ToString();
830 responseData[prefix + "http_port"] = sim.httpPort.ToString();
831 responseData[prefix + "map_UUID"] = sim.regionMapTextureID.ToString();
832 }
833 }
834
835 XmlRpcResponse response = new XmlRpcResponse();
836 response.Value = responseData;
837 return response;
838 }
839
840 /// <summary>
841 /// Construct an XMLRPC registration disabled response
842 /// </summary>
843 /// <param name="error"></param>
844 /// <returns></returns>
845 public static XmlRpcResponse XmlRPCRegionRegistrationDisabledResponse(string error)
846 {
847 XmlRpcResponse errorResponse = new XmlRpcResponse();
848 Hashtable errorResponseData = new Hashtable();
849 errorResponse.Value = errorResponseData;
850 errorResponseData["restricted"] = error;
851 return errorResponse;
852 }
853 }
854
855 /// <summary>
856 /// Exception generated when a simulator fails to login to the grid
857 /// </summary>
858 public class LoginException : Exception
859 {
860 /// <summary>
861 /// Return an XmlRpcResponse version of the exception message suitable for sending to a client
862 /// </summary>
863 /// <param name="message"></param>
864 /// <param name="xmlRpcMessage"></param>
865 public XmlRpcResponse XmlRpcErrorResponse
866 {
867 get { return m_xmlRpcErrorResponse; }
868 }
869 private XmlRpcResponse m_xmlRpcErrorResponse;
870
871 public LoginException(string message, string xmlRpcMessage)
872 : base(message)
873 {
874 // FIXME: Might be neater to refactor and put the method inside here
875 m_xmlRpcErrorResponse = GridXmlRpcModule.ErrorResponse(xmlRpcMessage);
876 }
877
878 public LoginException(string message, string xmlRpcMessage, Exception e)
879 : base(message, e)
880 {
881 // FIXME: Might be neater to refactor and put the method inside here
882 m_xmlRpcErrorResponse = GridXmlRpcModule.ErrorResponse(xmlRpcMessage);
883 }
884 }
885}