diff options
author | Charles Krinke | 2008-08-16 19:20:14 +0000 |
---|---|---|
committer | Charles Krinke | 2008-08-16 19:20:14 +0000 |
commit | d9cc908471922a1239bb8a757e07084072852982 (patch) | |
tree | 3390870e039a51194efa9c2e1e20142c9266dddd /OpenSim/Region/Environment/Modules/World/Land | |
parent | * Fix a rare maptile shading error, terrain difference mod 1 = 0 + abs = oops. (diff) | |
download | opensim-SC-d9cc908471922a1239bb8a757e07084072852982.zip opensim-SC-d9cc908471922a1239bb8a757e07084072852982.tar.gz opensim-SC-d9cc908471922a1239bb8a757e07084072852982.tar.bz2 opensim-SC-d9cc908471922a1239bb8a757e07084072852982.tar.xz |
Mantis#1965. Thank you kindly, HomerHorwitz for a patch that:
Places touched:
- Added two events for in-packets to LLCLientView: RegionHandleRequest and
ParcelInfoRequest
- Added sending of two out-packets to LLCLientView: RegionIDAndHandleReply and
ParcelInfoReply.
- Scene handles the RegionHandleRequest, LandManagementModule the
ParcelInfoRequest
- Added inter-region request for LandData by RegionHandle and local position.
This was implemented as XML-RPC request. The returned LandData isn't
complete, it only contains the data necessary for answering the
ParcelInfoRequest
- Added new CAPS (0009) for RemoteParcelRequest and some methods for LandData
handling to LandManagementModule
- Added methods for fake parcelID creation and parsing to Util
- Fixed missing implementation of interface methods.
- Added new file:
OpenSim/Framework/Communications/Capabilities/LLSDRemoteParcelResponse.cs
NOTE: This is part of the patch, too.
Due to the many places touched, I would consider this patch as experimental.
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Land')
-rw-r--r-- | OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs | 120 |
1 files changed, 119 insertions, 1 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs index 92eda80..46f108e 100644 --- a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs | |||
@@ -26,19 +26,30 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | ||
30 | using libsecondlife; | 32 | using libsecondlife; |
33 | using log4net; | ||
31 | using Nini.Config; | 34 | using Nini.Config; |
32 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
33 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
34 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Servers; | ||
39 | using OpenSim.Framework.Communications.Capabilities; | ||
35 | using OpenSim.Region.Physics.Manager; | 40 | using OpenSim.Region.Physics.Manager; |
36 | using Axiom.Math; | 41 | using Axiom.Math; |
42 | using Caps = OpenSim.Framework.Communications.Capabilities.Caps; | ||
37 | 43 | ||
38 | namespace OpenSim.Region.Environment.Modules.World.Land | 44 | namespace OpenSim.Region.Environment.Modules.World.Land |
39 | { | 45 | { |
40 | public class LandManagementModule : IRegionModule | 46 | public class LandManagementModule : IRegionModule |
41 | { | 47 | { |
48 | private static readonly ILog m_log = | ||
49 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | private static readonly string remoteParcelRequestPath = "0009/"; | ||
52 | |||
42 | private LandChannel landChannel; | 53 | private LandChannel landChannel; |
43 | private Scene m_scene; | 54 | private Scene m_scene; |
44 | 55 | ||
@@ -75,6 +86,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
75 | m_scene.EventManager.OnSetAllowForcefulBan += this.SetAllowedForcefulBans; | 86 | m_scene.EventManager.OnSetAllowForcefulBan += this.SetAllowedForcefulBans; |
76 | m_scene.EventManager.OnRequestParcelPrimCountUpdate += this.PerformParcelPrimCountUpdate; | 87 | m_scene.EventManager.OnRequestParcelPrimCountUpdate += this.PerformParcelPrimCountUpdate; |
77 | m_scene.EventManager.OnParcelPrimCountTainted += this.SetPrimsTainted; | 88 | m_scene.EventManager.OnParcelPrimCountTainted += this.SetPrimsTainted; |
89 | m_scene.EventManager.OnRegisterCaps += this.OnRegisterCaps; | ||
78 | 90 | ||
79 | lock (m_scene) | 91 | lock (m_scene) |
80 | { | 92 | { |
@@ -95,7 +107,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
95 | client.OnParcelAccessListUpdateRequest += new ParcelAccessListUpdateRequest(handleParcelAccessUpdateRequest); | 107 | client.OnParcelAccessListUpdateRequest += new ParcelAccessListUpdateRequest(handleParcelAccessUpdateRequest); |
96 | client.OnParcelAbandonRequest += new ParcelAbandonRequest(handleParcelAbandonRequest); | 108 | client.OnParcelAbandonRequest += new ParcelAbandonRequest(handleParcelAbandonRequest); |
97 | client.OnParcelReclaim += new ParcelReclaim(handleParcelReclaim); | 109 | client.OnParcelReclaim += new ParcelReclaim(handleParcelReclaim); |
98 | 110 | client.OnParcelInfoRequest += new ParcelInfoRequest(handleParcelInfo); | |
99 | if (m_scene.Entities.ContainsKey(client.AgentId)) | 111 | if (m_scene.Entities.ContainsKey(client.AgentId)) |
100 | { | 112 | { |
101 | SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true); | 113 | SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true); |
@@ -1084,6 +1096,112 @@ namespace OpenSim.Region.Environment.Modules.World.Land | |||
1084 | public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) | 1096 | public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) |
1085 | { | 1097 | { |
1086 | } | 1098 | } |
1099 | |||
1100 | #region CAPS handler | ||
1101 | private void OnRegisterCaps(LLUUID agentID, Caps caps) | ||
1102 | { | ||
1103 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | ||
1104 | caps.RegisterHandler("RemoteParcelRequest", | ||
1105 | new RestStreamHandler("POST", capsBase + remoteParcelRequestPath, | ||
1106 | delegate(string request, string path, string param, | ||
1107 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||
1108 | { | ||
1109 | return RemoteParcelRequest(request, path, param, agentID, caps); | ||
1110 | })); | ||
1111 | } | ||
1112 | |||
1113 | // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the | ||
1114 | // "real" parcelID, because we wouldn't be able to map that to the region the parcel belongs to. | ||
1115 | // So, we create a "fake" parcelID by using the regionHandle (64 bit), and the local (integer) x | ||
1116 | // and y coordinate (each 8 bit), encoded in a LLUUID (128 bit). | ||
1117 | // | ||
1118 | // Request format: | ||
1119 | // <llsd> | ||
1120 | // <map> | ||
1121 | // <key>location</key> | ||
1122 | // <array> | ||
1123 | // <real>1.23</real> | ||
1124 | // <real>45..6</real> | ||
1125 | // <real>78.9</real> | ||
1126 | // </array> | ||
1127 | // <key>region_id</key> | ||
1128 | // <uuid>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</uuid> | ||
1129 | // </map> | ||
1130 | // </llsd> | ||
1131 | private string RemoteParcelRequest(string request, string path, string param, LLUUID agentID, Caps caps) | ||
1132 | { | ||
1133 | LLUUID parcelID = LLUUID.Zero; | ||
1134 | try | ||
1135 | { | ||
1136 | Hashtable hash = new Hashtable(); | ||
1137 | hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request)); | ||
1138 | if(hash.ContainsKey("region_id") && hash.ContainsKey("location")) | ||
1139 | { | ||
1140 | LLUUID regionID = (LLUUID)hash["region_id"]; | ||
1141 | ArrayList list = (ArrayList)hash["location"]; | ||
1142 | uint x = (uint)(double)list[0]; | ||
1143 | uint y = (uint)(double)list[1]; | ||
1144 | if(hash.ContainsKey("region_handle")) | ||
1145 | { | ||
1146 | // if you do a "About Landmark" on a landmark a second time, the viewer sends the | ||
1147 | // region_handle it got earlier via RegionHandleRequest | ||
1148 | ulong regionHandle = Helpers.BytesToUInt64((byte[])hash["region_handle"]); | ||
1149 | parcelID = Util.BuildFakeParcelID(regionHandle, x, y); | ||
1150 | } | ||
1151 | else if(regionID == m_scene.RegionInfo.RegionID) | ||
1152 | { | ||
1153 | // a parcel request for a local parcel => no need to query the grid | ||
1154 | parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y); | ||
1155 | } | ||
1156 | else | ||
1157 | { | ||
1158 | // a parcel request for a parcel in another region. Ask the grid about the region | ||
1159 | RegionInfo info = m_scene.CommsManager.GridService.RequestNeighbourInfo(regionID); | ||
1160 | if(info != null) parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y); | ||
1161 | } | ||
1162 | } | ||
1163 | } | ||
1164 | catch (LLSD.LLSDParseException e) | ||
1165 | { | ||
1166 | m_log.ErrorFormat("[LAND] Fetch error: {0}", e.Message); | ||
1167 | m_log.ErrorFormat("[LAND] ... in request {0}", request); | ||
1168 | } | ||
1169 | catch(InvalidCastException) | ||
1170 | { | ||
1171 | m_log.ErrorFormat("[LAND] Wrong type in request {0}", request); | ||
1172 | } | ||
1173 | |||
1174 | LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse(); | ||
1175 | response.parcel_id = parcelID; | ||
1176 | m_log.DebugFormat("[LAND] got parcelID {0}", parcelID); | ||
1177 | |||
1178 | return LLSDHelpers.SerialiseLLSDReply(response); | ||
1179 | } | ||
1180 | |||
1181 | #endregion | ||
1182 | |||
1183 | private void handleParcelInfo(IClientAPI remoteClient, LLUUID parcelID) | ||
1184 | { | ||
1185 | if(parcelID == LLUUID.Zero) return; | ||
1186 | |||
1187 | // assume we've got the parcelID we just computed in RemoteParcelRequest | ||
1188 | ulong regionHandle; | ||
1189 | uint x, y; | ||
1190 | Util.ParseFakeParcelID(parcelID, out regionHandle, out x, out y); | ||
1191 | m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}", regionHandle, x, y); | ||
1192 | |||
1193 | LandData landData; | ||
1194 | if(regionHandle == m_scene.RegionInfo.RegionHandle) landData = this.GetLandObject(x, y).landData; | ||
1195 | else landData = m_scene.CommsManager.GridService.RequestLandData(regionHandle, x, y); | ||
1196 | |||
1197 | if(landData != null) | ||
1198 | { | ||
1199 | // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. | ||
1200 | m_log.Debug("[LAND] got parcelinfo; sending"); | ||
1201 | remoteClient.SendParcelInfo(m_scene.RegionInfo, landData, parcelID, x, y); | ||
1202 | } | ||
1203 | else m_log.Debug("[LAND] got no parcelinfo; not sending"); | ||
1204 | } | ||
1087 | } | 1205 | } |
1088 | 1206 | ||
1089 | } | 1207 | } |