aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World
diff options
context:
space:
mode:
authorUbitUmarov2017-07-20 11:30:12 +0100
committerUbitUmarov2017-07-20 11:30:12 +0100
commitfe6ad384e43c11c3bf6268f5ab6fe3ea37c74540 (patch)
tree44ae3d8b00f3d2f6bf78bc0226a779f99ed6dc48 /OpenSim/Region/CoreModules/World
parentMerge branch 'master' into httptests (diff)
parentfix object updates throttle for scripts doing motion by direct change of posi... (diff)
downloadopensim-SC-fe6ad384e43c11c3bf6268f5ab6fe3ea37c74540.zip
opensim-SC-fe6ad384e43c11c3bf6268f5ab6fe3ea37c74540.tar.gz
opensim-SC-fe6ad384e43c11c3bf6268f5ab6fe3ea37c74540.tar.bz2
opensim-SC-fe6ad384e43c11c3bf6268f5ab6fe3ea37c74540.tar.xz
merge
Diffstat (limited to 'OpenSim/Region/CoreModules/World')
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs58
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs223
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs8
4 files changed, 101 insertions, 190 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index 8dabcee..11c53d7 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -181,11 +181,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
181 // Archive the regions 181 // Archive the regions
182 182
183 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); 183 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>();
184 HashSet<UUID> failedIDs = new HashSet<UUID>();
185 HashSet<UUID> uncertainAssetsUUIDs = new HashSet<UUID>();
184 186
185 scenesGroup.ForEachScene(delegate(Scene scene) 187 scenesGroup.ForEachScene(delegate(Scene scene)
186 { 188 {
187 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : ""; 189 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
188 ArchiveOneRegion(scene, regionDir, assetUuids); 190 ArchiveOneRegion(scene, regionDir, assetUuids, failedIDs, uncertainAssetsUUIDs);
189 }); 191 });
190 192
191 // Archive the assets 193 // Archive the assets
@@ -193,23 +195,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver
193 if (SaveAssets) 195 if (SaveAssets)
194 { 196 {
195 m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count); 197 m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);
196 198
197 // Asynchronously request all the assets required to perform this archive operation 199 AssetsRequest ar = new AssetsRequest(
198 AssetsRequest ar
199 = new AssetsRequest(
200 new AssetsArchiver(m_archiveWriter), assetUuids, 200 new AssetsArchiver(m_archiveWriter), assetUuids,
201 failedIDs.Count,
201 m_rootScene.AssetService, m_rootScene.UserAccountService, 202 m_rootScene.AssetService, m_rootScene.UserAccountService,
202 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); 203 m_rootScene.RegionInfo.ScopeID, options, null);
203 204 ar.Execute();
204 WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request"); 205 assetUuids = null;
205
206 // CloseArchive() will be called from ReceivedAllAssets()
207 } 206 }
208 else 207 else
209 { 208 {
210 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); 209 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
211 CloseArchive(string.Empty); 210// CloseArchive(string.Empty);
212 } 211 }
212 CloseArchive(string.Empty);
213 } 213 }
214 catch (Exception e) 214 catch (Exception e)
215 { 215 {
@@ -218,7 +218,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
218 } 218 }
219 } 219 }
220 220
221 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids) 221 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids,
222 HashSet<UUID> failedIDs, HashSet<UUID> uncertainAssetsUUIDs)
222 { 223 {
223 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name); 224 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name);
224 225
@@ -237,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
237 { 238 {
238 SceneObjectGroup sceneObject = (SceneObjectGroup)entity; 239 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
239 240
240 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) 241 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment && !sceneObject.IsTemporary && !sceneObject.inTransit)
241 { 242 {
242 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule)) 243 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule))
243 { 244 {
@@ -254,17 +255,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver
254 255
255 if (SaveAssets) 256 if (SaveAssets)
256 { 257 {
257 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids); 258 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids, failedIDs, uncertainAssetsUUIDs);
258 int prevAssets = assetUuids.Count; 259 int prevAssets = assetUuids.Count;
259 260
260 foreach (SceneObjectGroup sceneObject in sceneObjects) 261 foreach (SceneObjectGroup sceneObject in sceneObjects)
262 {
263 int curErrorCntr = assetGatherer.ErrorCount;
264 int possible = assetGatherer.possibleNotAssetCount;
261 assetGatherer.AddForInspection(sceneObject); 265 assetGatherer.AddForInspection(sceneObject);
266 assetGatherer.GatherAll();
267 curErrorCntr = assetGatherer.ErrorCount - curErrorCntr;
268 possible = assetGatherer.possibleNotAssetCount - possible;
269 if(curErrorCntr > 0)
270 {
271 m_log.ErrorFormat("[ARCHIVER]: object {0} '{1}', at {2}, contains {3} references to missing or damaged assets",
272 sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), curErrorCntr);
273 if(possible > 0)
274 m_log.WarnFormat("[ARCHIVER Warning]: object also contains {0} references that may be to missing or damaged assets or not a problem", possible);
275 }
276 else if(possible > 0)
277 {
278 m_log.WarnFormat("[ARCHIVER Warning]: object {0} '{1}', at {2}, contains {3} references that may be to missing or damaged assets or not a problem",
279 sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), possible);
280 }
281 }
262 282
263 assetGatherer.GatherAll(); 283 assetGatherer.GatherAll();
264 284
285 int errors = assetGatherer.FailedUUIDs.Count;
265 m_log.DebugFormat( 286 m_log.DebugFormat(
266 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", 287 "[ARCHIVER]: {0} region scene objects to save reference {1} possible assets",
267 sceneObjects.Count, assetUuids.Count - prevAssets); 288 sceneObjects.Count, assetUuids.Count - prevAssets + errors);
289 if(errors > 0)
290 m_log.DebugFormat("[ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors);
268 } 291 }
269 292
270 if (numObjectsSkippedPermissions > 0) 293 if (numObjectsSkippedPermissions > 0)
@@ -572,7 +595,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
572 foreach (SceneObjectGroup sceneObject in sceneObjects) 595 foreach (SceneObjectGroup sceneObject in sceneObjects)
573 { 596 {
574 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType()); 597 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
575 598 if(sceneObject.IsDeleted || sceneObject.inTransit)
599 continue;
576 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options); 600 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options);
577 string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject)); 601 string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject));
578 m_archiveWriter.WriteFile(objectPath, serializedObject); 602 m_archiveWriter.WriteFile(objectPath, serializedObject);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
index efacae3..3092fe0 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
@@ -46,7 +46,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
46 /// <value> 46 /// <value>
47 /// Post a message to the log every x assets as a progress bar 47 /// Post a message to the log every x assets as a progress bar
48 /// </value> 48 /// </value>
49 protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 50; 49 protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 100;
50 50
51 /// <value> 51 /// <value>
52 /// Keep a count of the number of assets written so that we can provide status updates 52 /// Keep a count of the number of assets written so that we can provide status updates
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index d380da8..91f4dc3 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -62,27 +62,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
62 }; 62 };
63 63
64 /// <value> 64 /// <value>
65 /// Timeout threshold if we still need assets or missing asset notifications but have stopped receiving them
66 /// from the asset service
67 /// </value>
68 protected const int TIMEOUT = 60 * 1000;
69
70 /// <value>
71 /// If a timeout does occur, limit the amount of UUID information put to the console.
72 /// </value>
73 protected const int MAX_UUID_DISPLAY_ON_TIMEOUT = 3;
74
75 protected System.Timers.Timer m_requestCallbackTimer;
76
77 /// <value>
78 /// State of this request
79 /// </value>
80 private RequestState m_requestState = RequestState.Initial;
81
82 /// <value>
83 /// uuids to request 65 /// uuids to request
84 /// </value> 66 /// </value>
85 protected IDictionary<UUID, sbyte> m_uuids; 67 protected IDictionary<UUID, sbyte> m_uuids;
68 private int m_previousErrorsCount;
86 69
87 /// <value> 70 /// <value>
88 /// Callback used when all the assets requested have been received. 71 /// Callback used when all the assets requested have been received.
@@ -104,6 +87,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
104 /// </value> 87 /// </value>
105 private int m_repliesRequired; 88 private int m_repliesRequired;
106 89
90 private System.Timers.Timer m_timeOutTimer;
91 private bool m_timeout;
92
107 /// <value> 93 /// <value>
108 /// Asset service used to request the assets 94 /// Asset service used to request the assets
109 /// </value> 95 /// </value>
@@ -117,205 +103,98 @@ namespace OpenSim.Region.CoreModules.World.Archiver
117 103
118 protected internal AssetsRequest( 104 protected internal AssetsRequest(
119 AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids, 105 AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids,
106 int previousErrorsCount,
120 IAssetService assetService, IUserAccountService userService, 107 IAssetService assetService, IUserAccountService userService,
121 UUID scope, Dictionary<string, object> options, 108 UUID scope, Dictionary<string, object> options,
122 AssetsRequestCallback assetsRequestCallback) 109 AssetsRequestCallback assetsRequestCallback)
123 { 110 {
124 m_assetsArchiver = assetsArchiver; 111 m_assetsArchiver = assetsArchiver;
125 m_uuids = uuids; 112 m_uuids = uuids;
113 m_previousErrorsCount = previousErrorsCount;
126 m_assetsRequestCallback = assetsRequestCallback; 114 m_assetsRequestCallback = assetsRequestCallback;
127 m_assetService = assetService; 115 m_assetService = assetService;
128 m_userAccountService = userService; 116 m_userAccountService = userService;
129 m_scopeID = scope; 117 m_scopeID = scope;
130 m_options = options; 118 m_options = options;
131 m_repliesRequired = uuids.Count; 119 m_repliesRequired = uuids.Count;
132
133 // FIXME: This is a really poor way of handling the timeout since it will always leave the original requesting thread
134 // hanging. Need to restructure so an original request thread waits for a ManualResetEvent on asset received
135 // so we can properly abort that thread. Or request all assets synchronously, though that would be a more
136 // radical change
137 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
138 m_requestCallbackTimer.AutoReset = false;
139 m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout);
140 } 120 }
141 121
142 protected internal void Execute() 122 protected internal void Execute()
143 { 123 {
144 m_requestState = RequestState.Running; 124 Culture.SetCurrentCulture();
145
146 m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} possible assets", m_repliesRequired);
147
148 // We can stop here if there are no assets to fetch 125 // We can stop here if there are no assets to fetch
149 if (m_repliesRequired == 0) 126 if (m_repliesRequired == 0)
150 { 127 {
151 m_requestState = RequestState.Completed;
152 PerformAssetsRequestCallback(false); 128 PerformAssetsRequestCallback(false);
153 return; 129 return;
154 } 130 }
155 131
156 m_requestCallbackTimer.Enabled = true; 132 m_timeOutTimer = new System.Timers.Timer(60000);
133 m_timeOutTimer .AutoReset = false;
134 m_timeOutTimer.Elapsed += OnTimeout;
135 m_timeout = false;
157 136
158 foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids) 137 foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids)
159 { 138 {
160// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key); 139 string thiskey = kvp.Key.ToString();
161 140 try
162// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
163 AssetBase asset = m_assetService.Get(kvp.Key.ToString());
164 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
165 }
166 }
167
168 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
169 {
170 bool timedOut = true;
171
172 try
173 {
174 lock (this)
175 { 141 {
176 // Take care of the possibilty that this thread started but was paused just outside the lock before 142 m_timeOutTimer.Enabled = true;
177 // the final request came in (assuming that such a thing is possible) 143 AssetBase asset = m_assetService.Get(thiskey);
178 if (m_requestState == RequestState.Completed) 144 if(m_timeout)
145 break;
146
147 m_timeOutTimer.Enabled = false;
148
149 if(asset == null)
179 { 150 {
180 timedOut = false; 151 m_notFoundAssetUuids.Add(new UUID(thiskey));
181 return; 152 continue;
182 } 153 }
183 154
184 m_requestState = RequestState.Aborted; 155 sbyte assetType = kvp.Value;
185 } 156 if (asset != null && assetType == (sbyte)AssetType.Unknown)
186 157 {
187 // Calculate which uuids were not found. This is an expensive way of doing it, but this is a failure 158 m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", thiskey, SLUtil.AssetTypeFromCode(assetType));
188 // case anyway. 159 asset.Type = assetType;
189 List<UUID> uuids = new List<UUID>(); 160 }
190 foreach (UUID uuid in m_uuids.Keys)
191 {
192 uuids.Add(uuid);
193 }
194
195 foreach (UUID uuid in m_foundAssetUuids)
196 {
197 uuids.Remove(uuid);
198 }
199 161
200 foreach (UUID uuid in m_notFoundAssetUuids) 162 m_foundAssetUuids.Add(asset.FullID);
201 { 163 m_assetsArchiver.WriteAsset(PostProcess(asset));
202 uuids.Remove(uuid);
203 } 164 }
204 165
205 m_log.ErrorFormat( 166 catch (Exception e)
206 "[ARCHIVER]: Asset service failed to return information about {0} requested assets", uuids.Count);
207
208 int i = 0;
209 foreach (UUID uuid in uuids)
210 { 167 {
211 m_log.ErrorFormat("[ARCHIVER]: No information about asset {0} received", uuid); 168 m_log.ErrorFormat("[ARCHIVER]: Execute failed with {0}", e);
212
213 if (++i >= MAX_UUID_DISPLAY_ON_TIMEOUT)
214 break;
215 } 169 }
216
217 if (uuids.Count > MAX_UUID_DISPLAY_ON_TIMEOUT)
218 m_log.ErrorFormat(
219 "[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
220
221 m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE.");
222 } 170 }
223 catch (Exception e)
224 {
225 m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace);
226 }
227 finally
228 {
229 if (timedOut)
230 WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback");
231 }
232 }
233 171
234 protected void PreAssetRequestCallback(string fetchedAssetID, object assetType, AssetBase fetchedAsset) 172 m_timeOutTimer.Dispose();
235 { 173 int totalerrors = m_notFoundAssetUuids.Count + m_previousErrorsCount;
236 // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer
237 if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown)
238 {
239 m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, SLUtil.AssetTypeFromCode((sbyte)assetType));
240 fetchedAsset.Type = (sbyte)assetType;
241 }
242 174
243 AssetRequestCallback(fetchedAssetID, this, fetchedAsset); 175 if(m_timeout)
244 } 176 m_log.DebugFormat("[ARCHIVER]: Aborted because AssetService request timeout. Successfully added {0} assets", m_foundAssetUuids.Count);
177 else if(totalerrors == 0)
178 m_log.DebugFormat("[ARCHIVER]: Successfully added all {0} assets", m_foundAssetUuids.Count);
179 else
180 m_log.DebugFormat("[ARCHIVER]: Successfully added {0} assets ({1} of total possible assets requested were not found, were damaged or were not assets)",
181 m_foundAssetUuids.Count, totalerrors);
245 182
246 /// <summary> 183 PerformAssetsRequestCallback(m_timeout);
247 /// Called back by the asset cache when it has the asset 184 }
248 /// </summary> 185
249 /// <param name="assetID"></param> 186 private void OnTimeout(object source, ElapsedEventArgs args)
250 /// <param name="asset"></param>
251 public void AssetRequestCallback(string id, object sender, AssetBase asset)
252 { 187 {
253 Culture.SetCurrentCulture(); 188 m_timeout = true;
254
255 try
256 {
257 lock (this)
258 {
259 //m_log.DebugFormat("[ARCHIVER]: Received callback for asset {0}", id);
260
261 m_requestCallbackTimer.Stop();
262
263 if ((m_requestState == RequestState.Aborted) || (m_requestState == RequestState.Completed))
264 {
265 m_log.WarnFormat(
266 "[ARCHIVER]: Received information about asset {0} while in state {1}. Ignoring.",
267 id, m_requestState);
268
269 return;
270 }
271
272 if (asset != null)
273 {
274// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
275 m_foundAssetUuids.Add(asset.FullID);
276
277 m_assetsArchiver.WriteAsset(PostProcess(asset));
278 }
279 else
280 {
281// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
282 m_notFoundAssetUuids.Add(new UUID(id));
283 }
284
285 if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired)
286 {
287 m_requestState = RequestState.Completed;
288 if(m_notFoundAssetUuids.Count == 0)
289 m_log.DebugFormat(
290 "[ARCHIVER]: Successfully added {0} assets",
291 m_foundAssetUuids.Count);
292 else
293 m_log.DebugFormat(
294 "[ARCHIVER]: Successfully added {0} assets ({1} assets not found but these may be expected invalid references)",
295 m_foundAssetUuids.Count, m_notFoundAssetUuids.Count);
296
297
298 // We want to stop using the asset cache thread asap
299 // as we now need to do the work of producing the rest of the archive
300 WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback");
301 }
302 else
303 {
304 m_requestCallbackTimer.Start();
305 }
306 }
307 }
308 catch (Exception e)
309 {
310 m_log.ErrorFormat("[ARCHIVER]: AssetRequestCallback failed with {0}", e);
311 }
312 } 189 }
313 190
314 /// <summary> 191 /// <summary>
315 /// Perform the callback on the original requester of the assets 192 /// Perform the callback on the original requester of the assets
316 /// </summary> 193 /// </summary>
317 protected void PerformAssetsRequestCallback(object o) 194 private void PerformAssetsRequestCallback(object o)
318 { 195 {
196 if(m_assetsRequestCallback == null)
197 return;
319 Culture.SetCurrentCulture(); 198 Culture.SetCurrentCulture();
320 199
321 Boolean timedOut = (Boolean)o; 200 Boolean timedOut = (Boolean)o;
@@ -331,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
331 } 210 }
332 } 211 }
333 212
334 protected AssetBase PostProcess(AssetBase asset) 213 private AssetBase PostProcess(AssetBase asset)
335 { 214 {
336 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home")) 215 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home"))
337 { 216 {
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index b59e2af..5ff063b 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -176,6 +176,14 @@ namespace OpenSim.Region.CoreModules.World.Land
176 } 176 }
177 } 177 }
178 178
179 public void SendParcelsOverlay(IClientAPI client)
180 {
181 if (m_landManagementModule != null)
182 {
183 m_landManagementModule.SendParcelOverlay(client);
184 }
185 }
186
179 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 187 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
180 { 188 {
181 if (m_landManagementModule != null) 189 if (m_landManagementModule != null)