diff options
author | Diva Canto | 2014-12-25 08:01:50 -0800 |
---|---|---|
committer | Diva Canto | 2014-12-25 08:01:50 -0800 |
commit | 27c34b69bf5960e02b087f9f298dcbe19f03b142 (patch) | |
tree | f299009958858da9db464dcbc84bd03beae0ca15 /OpenSim | |
parent | Revert "Update libomv to grab latest bug fixes for Collada upload." (diff) | |
parent | If a moap entry has EnableWhiteList but WhiteList == null, then properly bloc... (diff) | |
download | opensim-SC-27c34b69bf5960e02b087f9f298dcbe19f03b142.zip opensim-SC-27c34b69bf5960e02b087f9f298dcbe19f03b142.tar.gz opensim-SC-27c34b69bf5960e02b087f9f298dcbe19f03b142.tar.bz2 opensim-SC-27c34b69bf5960e02b087f9f298dcbe19f03b142.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to '')
23 files changed, 757 insertions, 424 deletions
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs index 72018e4..6f517b6 100644 --- a/OpenSim/Framework/Communications/RestClient.cs +++ b/OpenSim/Framework/Communications/RestClient.cs | |||
@@ -90,7 +90,7 @@ namespace OpenSim.Framework.Communications | |||
90 | private byte[] _readbuf; | 90 | private byte[] _readbuf; |
91 | 91 | ||
92 | /// <summary> | 92 | /// <summary> |
93 | /// MemoryStream representing the resultiong resource | 93 | /// MemoryStream representing the resulting resource |
94 | /// </summary> | 94 | /// </summary> |
95 | private Stream _resource; | 95 | private Stream _resource; |
96 | 96 | ||
@@ -352,42 +352,46 @@ namespace OpenSim.Framework.Communications | |||
352 | m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri); | 352 | m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri); |
353 | 353 | ||
354 | // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); | 354 | // IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); |
355 | |||
355 | try | 356 | try |
356 | { | 357 | { |
357 | _response = (HttpWebResponse) _request.GetResponse(); | 358 | using (_response = (HttpWebResponse) _request.GetResponse()) |
359 | { | ||
360 | using (Stream src = _response.GetResponseStream()) | ||
361 | { | ||
362 | int length = src.Read(_readbuf, 0, BufferSize); | ||
363 | while (length > 0) | ||
364 | { | ||
365 | _resource.Write(_readbuf, 0, length); | ||
366 | length = src.Read(_readbuf, 0, BufferSize); | ||
367 | } | ||
368 | |||
369 | // TODO! Implement timeout, without killing the server | ||
370 | // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted | ||
371 | //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); | ||
372 | |||
373 | // _allDone.WaitOne(); | ||
374 | } | ||
375 | } | ||
358 | } | 376 | } |
359 | catch (WebException e) | 377 | catch (WebException e) |
360 | { | 378 | { |
361 | HttpWebResponse errorResponse = e.Response as HttpWebResponse; | 379 | using (HttpWebResponse errorResponse = e.Response as HttpWebResponse) |
362 | if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode) | ||
363 | { | ||
364 | // This is often benign. E.g., requesting a missing asset will return 404. | ||
365 | m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString()); | ||
366 | } | ||
367 | else | ||
368 | { | 380 | { |
369 | m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e); | 381 | if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode) |
382 | { | ||
383 | // This is often benign. E.g., requesting a missing asset will return 404. | ||
384 | m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString()); | ||
385 | } | ||
386 | else | ||
387 | { | ||
388 | m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e); | ||
389 | } | ||
370 | } | 390 | } |
371 | 391 | ||
372 | return null; | 392 | return null; |
373 | } | 393 | } |
374 | 394 | ||
375 | Stream src = _response.GetResponseStream(); | ||
376 | int length = src.Read(_readbuf, 0, BufferSize); | ||
377 | while (length > 0) | ||
378 | { | ||
379 | _resource.Write(_readbuf, 0, length); | ||
380 | length = src.Read(_readbuf, 0, BufferSize); | ||
381 | } | ||
382 | |||
383 | |||
384 | // TODO! Implement timeout, without killing the server | ||
385 | // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted | ||
386 | //ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true); | ||
387 | |||
388 | // _allDone.WaitOne(); | ||
389 | if (_response != null) | ||
390 | _response.Close(); | ||
391 | if (_asyncException != null) | 395 | if (_asyncException != null) |
392 | throw _asyncException; | 396 | throw _asyncException; |
393 | 397 | ||
@@ -515,4 +519,4 @@ namespace OpenSim.Framework.Communications | |||
515 | 519 | ||
516 | #endregion Async Invocation | 520 | #endregion Async Invocation |
517 | } | 521 | } |
518 | } | 522 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/ISceneObject.cs b/OpenSim/Framework/ISceneObject.cs index afac9b8..754b77b 100644 --- a/OpenSim/Framework/ISceneObject.cs +++ b/OpenSim/Framework/ISceneObject.cs | |||
@@ -32,6 +32,8 @@ namespace OpenSim.Framework | |||
32 | { | 32 | { |
33 | public interface ISceneObject | 33 | public interface ISceneObject |
34 | { | 34 | { |
35 | string Name { get; } | ||
36 | |||
35 | UUID UUID { get; } | 37 | UUID UUID { get; } |
36 | 38 | ||
37 | /// <summary> | 39 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index fe9a17d..6564b4d 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -256,20 +256,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
256 | // If the file is already cached, don't cache it, just touch it so access time is updated | 256 | // If the file is already cached, don't cache it, just touch it so access time is updated |
257 | if (File.Exists(filename)) | 257 | if (File.Exists(filename)) |
258 | { | 258 | { |
259 | // We don't really want to know about sharing | 259 | UpdateFileLastAccessTime(filename); |
260 | // violations here. If the file is locked, then | ||
261 | // the other thread has updated the time for us. | ||
262 | try | ||
263 | { | ||
264 | lock (m_CurrentlyWriting) | ||
265 | { | ||
266 | if (!m_CurrentlyWriting.Contains(filename)) | ||
267 | File.SetLastAccessTime(filename, DateTime.Now); | ||
268 | } | ||
269 | } | ||
270 | catch | ||
271 | { | ||
272 | } | ||
273 | } | 260 | } |
274 | else | 261 | else |
275 | { | 262 | { |
@@ -329,6 +316,24 @@ namespace OpenSim.Region.CoreModules.Asset | |||
329 | } | 316 | } |
330 | 317 | ||
331 | /// <summary> | 318 | /// <summary> |
319 | /// Updates the cached file with the current time. | ||
320 | /// </summary> | ||
321 | /// <param name="filename">Filename.</param> | ||
322 | /// <returns><c>true</c>, if the update was successful, false otherwise.</returns> | ||
323 | private bool UpdateFileLastAccessTime(string filename) | ||
324 | { | ||
325 | try | ||
326 | { | ||
327 | File.SetLastAccessTime(filename, DateTime.Now); | ||
328 | return true; | ||
329 | } | ||
330 | catch | ||
331 | { | ||
332 | return false; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | /// <summary> | ||
332 | /// Try to get an asset from the in-memory cache. | 337 | /// Try to get an asset from the in-memory cache. |
333 | /// </summary> | 338 | /// </summary> |
334 | /// <param name="id"></param> | 339 | /// <param name="id"></param> |
@@ -771,8 +776,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
771 | { | 776 | { |
772 | UuidGatherer gatherer = new UuidGatherer(m_AssetService); | 777 | UuidGatherer gatherer = new UuidGatherer(m_AssetService); |
773 | 778 | ||
774 | HashSet<UUID> uniqueUuids = new HashSet<UUID>(); | 779 | Dictionary<UUID, sbyte> assetIdsToCheck = new Dictionary<UUID, sbyte>(); |
775 | Dictionary<UUID, sbyte> assets = new Dictionary<UUID, sbyte>(); | 780 | Dictionary<UUID, bool> assetsFound = new Dictionary<UUID, bool>(); |
776 | 781 | ||
777 | foreach (Scene s in m_Scenes) | 782 | foreach (Scene s in m_Scenes) |
778 | { | 783 | { |
@@ -780,34 +785,40 @@ namespace OpenSim.Region.CoreModules.Asset | |||
780 | 785 | ||
781 | s.ForEachSOG(delegate(SceneObjectGroup e) | 786 | s.ForEachSOG(delegate(SceneObjectGroup e) |
782 | { | 787 | { |
783 | gatherer.GatherAssetUuids(e, assets); | 788 | gatherer.GatherAssetUuids(e, assetIdsToCheck); |
784 | 789 | ||
785 | foreach (UUID assetID in assets.Keys) | 790 | foreach (UUID assetID in assetIdsToCheck.Keys) |
786 | { | 791 | { |
787 | uniqueUuids.Add(assetID); | 792 | if (!assetsFound.ContainsKey(assetID)) |
788 | |||
789 | string filename = GetFileName(assetID.ToString()); | ||
790 | |||
791 | if (File.Exists(filename)) | ||
792 | { | 793 | { |
793 | File.SetLastAccessTime(filename, DateTime.Now); | 794 | string filename = GetFileName(assetID.ToString()); |
795 | |||
796 | if (File.Exists(filename)) | ||
797 | { | ||
798 | UpdateFileLastAccessTime(filename); | ||
799 | } | ||
800 | else if (storeUncached) | ||
801 | { | ||
802 | AssetBase cachedAsset = m_AssetService.Get(assetID.ToString()); | ||
803 | if (cachedAsset == null && assetIdsToCheck[assetID] != (sbyte)AssetType.Unknown) | ||
804 | assetsFound[assetID] = false; | ||
805 | else | ||
806 | assetsFound[assetID] = true; | ||
807 | } | ||
794 | } | 808 | } |
795 | else if (storeUncached) | 809 | else if (!assetsFound[assetID]) |
796 | { | 810 | { |
797 | AssetBase cachedAsset = m_AssetService.Get(assetID.ToString()); | 811 | m_log.DebugFormat( |
798 | if (cachedAsset == null && assets[assetID] != (sbyte)AssetType.Unknown) | ||
799 | m_log.DebugFormat( | ||
800 | "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", | 812 | "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", |
801 | assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name); | 813 | assetID, assetIdsToCheck[assetID], e.Name, e.AbsolutePosition, s.Name); |
802 | } | 814 | } |
803 | } | 815 | } |
804 | 816 | ||
805 | assets.Clear(); | 817 | assetIdsToCheck.Clear(); |
806 | }); | 818 | }); |
807 | } | 819 | } |
808 | 820 | ||
809 | 821 | return assetsFound.Count; | |
810 | return uniqueUuids.Count; | ||
811 | } | 822 | } |
812 | 823 | ||
813 | /// <summary> | 824 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a3368fb..4af4ddb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -255,6 +255,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
255 | 255 | ||
256 | public void CopyAttachments(AgentData ad, IScenePresence sp) | 256 | public void CopyAttachments(AgentData ad, IScenePresence sp) |
257 | { | 257 | { |
258 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Copying attachment data into {0} in {1}", sp.Name, m_scene.Name); | ||
259 | |||
258 | if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) | 260 | if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) |
259 | { | 261 | { |
260 | lock (sp.AttachmentsSyncLock) | 262 | lock (sp.AttachmentsSyncLock) |
@@ -265,6 +267,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
265 | { | 267 | { |
266 | ((SceneObjectGroup)so).LocalId = 0; | 268 | ((SceneObjectGroup)so).LocalId = 0; |
267 | ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); | 269 | ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); |
270 | |||
271 | // m_log.DebugFormat( | ||
272 | // "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}", | ||
273 | // ad.AttachmentObjectStates[i].Length, so.Name, sp.Name, m_scene.Name); | ||
274 | |||
268 | so.SetState(ad.AttachmentObjectStates[i++], m_scene); | 275 | so.SetState(ad.AttachmentObjectStates[i++], m_scene); |
269 | m_scene.IncomingCreateObject(Vector3.Zero, so); | 276 | m_scene.IncomingCreateObject(Vector3.Zero, so); |
270 | } | 277 | } |
@@ -334,11 +341,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
334 | if (!Enabled) | 341 | if (!Enabled) |
335 | return; | 342 | return; |
336 | 343 | ||
337 | if (DebugLevel > 0) | ||
338 | m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
339 | |||
340 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 344 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
341 | 345 | ||
346 | if (DebugLevel > 0) | ||
347 | m_log.DebugFormat( | ||
348 | "[ATTACHMENTS MODULE]: Saving for {0} attachments for {1} in {2}", | ||
349 | attachments.Count, sp.Name, m_scene.Name); | ||
350 | |||
342 | if (attachments.Count <= 0) | 351 | if (attachments.Count <= 0) |
343 | return; | 352 | return; |
344 | 353 | ||
@@ -352,6 +361,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
352 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | 361 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from |
353 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | 362 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. |
354 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); | 363 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); |
364 | |||
365 | // m_log.DebugFormat( | ||
366 | // "[ATTACHMENTS MODULE]: For object {0} for {1} in {2} got saved state {3}", | ||
367 | // so.Name, sp.Name, m_scene.Name, scriptStates[so]); | ||
355 | } | 368 | } |
356 | 369 | ||
357 | lock (sp.AttachmentsSyncLock) | 370 | lock (sp.AttachmentsSyncLock) |
@@ -819,8 +832,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
819 | { | 832 | { |
820 | if (DebugLevel > 0) | 833 | if (DebugLevel > 0) |
821 | m_log.DebugFormat( | 834 | m_log.DebugFormat( |
822 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 835 | "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} at pt {2} pos {3} {4} in {5}", |
823 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 836 | so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos, m_scene.Name); |
824 | 837 | ||
825 | // Remove from database and parcel prim count | 838 | // Remove from database and parcel prim count |
826 | m_scene.DeleteFromStorage(so.UUID); | 839 | m_scene.DeleteFromStorage(so.UUID); |
diff --git a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs index 5e35135..7d2cad6 100644 --- a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs | |||
@@ -103,48 +103,51 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures | |||
103 | return null; | 103 | return null; |
104 | 104 | ||
105 | int size = 0; | 105 | int size = 0; |
106 | RestClient rc = new RestClient(m_URL); | ||
107 | List<WearableCacheItem> ret = new List<WearableCacheItem>(); | ||
108 | rc.AddResourcePath("bakes"); | ||
109 | rc.AddResourcePath(id.ToString()); | ||
110 | |||
111 | rc.RequestMethod = "GET"; | ||
112 | 106 | ||
113 | try | 107 | using (RestClient rc = new RestClient(m_URL)) |
114 | { | 108 | { |
115 | Stream s = rc.Request(m_Auth); | 109 | List<WearableCacheItem> ret = new List<WearableCacheItem>(); |
116 | XmlTextReader sr = new XmlTextReader(s); | 110 | rc.AddResourcePath("bakes"); |
111 | rc.AddResourcePath(id.ToString()); | ||
117 | 112 | ||
118 | sr.ReadStartElement("BakedAppearance"); | 113 | rc.RequestMethod = "GET"; |
119 | while (sr.LocalName == "BakedTexture") | 114 | |
115 | try | ||
120 | { | 116 | { |
121 | string sTextureIndex = sr.GetAttribute("TextureIndex"); | 117 | Stream s = rc.Request(m_Auth); |
122 | int lTextureIndex = Convert.ToInt32(sTextureIndex); | 118 | |
123 | string sCacheId = sr.GetAttribute("CacheId"); | 119 | using (XmlTextReader sr = new XmlTextReader(s)) |
124 | UUID lCacheId = UUID.Zero; | ||
125 | if (!(UUID.TryParse(sCacheId, out lCacheId))) | ||
126 | { | 120 | { |
127 | // ?? Nothing here | 121 | sr.ReadStartElement("BakedAppearance"); |
122 | while (sr.LocalName == "BakedTexture") | ||
123 | { | ||
124 | string sTextureIndex = sr.GetAttribute("TextureIndex"); | ||
125 | int lTextureIndex = Convert.ToInt32(sTextureIndex); | ||
126 | string sCacheId = sr.GetAttribute("CacheId"); | ||
127 | UUID lCacheId = UUID.Zero; | ||
128 | if (!(UUID.TryParse(sCacheId, out lCacheId))) | ||
129 | { | ||
130 | // ?? Nothing here | ||
131 | } | ||
132 | |||
133 | ++size; | ||
134 | |||
135 | sr.ReadStartElement("BakedTexture"); | ||
136 | AssetBase a = (AssetBase)m_serializer.Deserialize(sr); | ||
137 | ret.Add(new WearableCacheItem() { CacheId = lCacheId, TextureIndex = (uint)lTextureIndex, TextureAsset = a, TextureID = a.FullID }); | ||
138 | |||
139 | sr.ReadEndElement(); | ||
140 | } | ||
141 | |||
142 | m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id); | ||
128 | } | 143 | } |
129 | 144 | ||
130 | ++size; | 145 | return ret.ToArray(); |
131 | 146 | } | |
132 | sr.ReadStartElement("BakedTexture"); | 147 | catch (XmlException) |
133 | AssetBase a = (AssetBase)m_serializer.Deserialize(sr); | 148 | { |
134 | ret.Add(new WearableCacheItem() { CacheId = lCacheId, TextureIndex = (uint)lTextureIndex, TextureAsset = a, TextureID = a.FullID }); | 149 | return null; |
135 | |||
136 | sr.ReadEndElement(); | ||
137 | } | 150 | } |
138 | m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id); | ||
139 | sr.Close(); | ||
140 | s.Close(); | ||
141 | |||
142 | |||
143 | return ret.ToArray(); | ||
144 | } | ||
145 | catch (XmlException) | ||
146 | { | ||
147 | return null; | ||
148 | } | 151 | } |
149 | } | 152 | } |
150 | 153 | ||
@@ -153,27 +156,32 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures | |||
153 | if (m_URL == String.Empty) | 156 | if (m_URL == String.Empty) |
154 | return; | 157 | return; |
155 | 158 | ||
156 | MemoryStream bakeStream = new MemoryStream(); | 159 | MemoryStream reqStream; |
157 | XmlTextWriter bakeWriter = new XmlTextWriter(bakeStream, null); | ||
158 | 160 | ||
159 | bakeWriter.WriteStartElement(String.Empty, "BakedAppearance", String.Empty); | 161 | using (MemoryStream bakeStream = new MemoryStream()) |
160 | 162 | using (XmlTextWriter bakeWriter = new XmlTextWriter(bakeStream, null)) | |
161 | for (int i = 0; i < data.Length; i++) | ||
162 | { | 163 | { |
163 | if (data[i] != null) | 164 | bakeWriter.WriteStartElement(String.Empty, "BakedAppearance", String.Empty); |
165 | |||
166 | for (int i = 0; i < data.Length; i++) | ||
164 | { | 167 | { |
165 | bakeWriter.WriteStartElement(String.Empty, "BakedTexture", String.Empty); | 168 | if (data[i] != null) |
166 | bakeWriter.WriteAttributeString(String.Empty, "TextureIndex", String.Empty, data[i].TextureIndex.ToString()); | 169 | { |
167 | bakeWriter.WriteAttributeString(String.Empty, "CacheId", String.Empty, data[i].CacheId.ToString()); | 170 | bakeWriter.WriteStartElement(String.Empty, "BakedTexture", String.Empty); |
168 | if (data[i].TextureAsset != null) | 171 | bakeWriter.WriteAttributeString(String.Empty, "TextureIndex", String.Empty, data[i].TextureIndex.ToString()); |
169 | m_serializer.Serialize(bakeWriter, data[i].TextureAsset); | 172 | bakeWriter.WriteAttributeString(String.Empty, "CacheId", String.Empty, data[i].CacheId.ToString()); |
173 | if (data[i].TextureAsset != null) | ||
174 | m_serializer.Serialize(bakeWriter, data[i].TextureAsset); | ||
170 | 175 | ||
171 | bakeWriter.WriteEndElement(); | 176 | bakeWriter.WriteEndElement(); |
177 | } | ||
172 | } | 178 | } |
173 | } | ||
174 | 179 | ||
175 | bakeWriter.WriteEndElement(); | 180 | bakeWriter.WriteEndElement(); |
176 | bakeWriter.Flush(); | 181 | bakeWriter.Flush(); |
182 | |||
183 | reqStream = new MemoryStream(bakeStream.ToArray()); | ||
184 | } | ||
177 | 185 | ||
178 | RestClient rc = new RestClient(m_URL); | 186 | RestClient rc = new RestClient(m_URL); |
179 | rc.AddResourcePath("bakes"); | 187 | rc.AddResourcePath("bakes"); |
@@ -181,7 +189,6 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures | |||
181 | 189 | ||
182 | rc.RequestMethod = "POST"; | 190 | rc.RequestMethod = "POST"; |
183 | 191 | ||
184 | MemoryStream reqStream = new MemoryStream(bakeStream.ToArray()); | ||
185 | Util.FireAndForget( | 192 | Util.FireAndForget( |
186 | delegate | 193 | delegate |
187 | { | 194 | { |
@@ -191,4 +198,4 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures | |||
191 | ); | 198 | ); |
192 | } | 199 | } |
193 | } | 200 | } |
194 | } | 201 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 97267c1..2ddb599 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -604,8 +604,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
604 | // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}", | 604 | // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}", |
605 | // so.Name, so.AttachedAvatar, url); | 605 | // so.Name, so.AttachedAvatar, url); |
606 | 606 | ||
607 | IteratingHGUuidGatherer uuidGatherer = new IteratingHGUuidGatherer(Scene.AssetService, url); | 607 | IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); |
608 | uuidGatherer.RecordAssetUuids(so); | 608 | IteratingHGUuidGatherer uuidGatherer |
609 | = new IteratingHGUuidGatherer(Scene.AssetService, url, ids); | ||
610 | uuidGatherer.AddForInspection(so); | ||
609 | 611 | ||
610 | while (!uuidGatherer.Complete) | 612 | while (!uuidGatherer.Complete) |
611 | { | 613 | { |
@@ -632,8 +634,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
632 | } | 634 | } |
633 | } | 635 | } |
634 | 636 | ||
635 | IDictionary<UUID, sbyte> ids = uuidGatherer.GetGatheredUuids(); | ||
636 | |||
637 | // m_log.DebugFormat( | 637 | // m_log.DebugFormat( |
638 | // "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}", | 638 | // "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}", |
639 | // ids.Count, so.Name, so.OwnerID, url); | 639 | // ids.Count, so.Name, so.OwnerID, url); |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 9bf7885..6479430 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -680,6 +680,21 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
680 | "Show the bindings between user UUIDs and user names", | 680 | "Show the bindings between user UUIDs and user names", |
681 | String.Empty, | 681 | String.Empty, |
682 | HandleShowUsers); | 682 | HandleShowUsers); |
683 | |||
684 | MainConsole.Instance.Commands.AddCommand("Users", true, | ||
685 | "reset user cache", | ||
686 | "reset user cache", | ||
687 | "reset user cache to allow changed settings to be applied", | ||
688 | String.Empty, | ||
689 | HandleResetUserCache); | ||
690 | } | ||
691 | |||
692 | private void HandleResetUserCache(string module, string[] cmd) | ||
693 | { | ||
694 | lock(m_UserCache) | ||
695 | { | ||
696 | m_UserCache.Clear(); | ||
697 | } | ||
683 | } | 698 | } |
684 | 699 | ||
685 | private void HandleShowUser(string module, string[] cmd) | 700 | private void HandleShowUser(string module, string[] cmd) |
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 601e81e..46b0470 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | |||
@@ -595,6 +595,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap | |||
595 | /// <returns>true if the url matches an entry on the whitelist, false otherwise</returns> | 595 | /// <returns>true if the url matches an entry on the whitelist, false otherwise</returns> |
596 | protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist) | 596 | protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist) |
597 | { | 597 | { |
598 | if (whitelist == null) | ||
599 | return false; | ||
600 | |||
598 | Uri url = new Uri(rawUrl); | 601 | Uri url = new Uri(rawUrl); |
599 | 602 | ||
600 | foreach (string origWlUrl in whitelist) | 603 | foreach (string origWlUrl in whitelist) |
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index d5dcddd..478833e 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs | |||
@@ -122,6 +122,17 @@ namespace OpenSim.Region.Framework.Interfaces | |||
122 | /// <summary> | 122 | /// <summary> |
123 | /// Check if the caller has permission to manipulate the given NPC. | 123 | /// Check if the caller has permission to manipulate the given NPC. |
124 | /// </summary> | 124 | /// </summary> |
125 | /// <remarks> | ||
126 | /// A caller has permission if | ||
127 | /// * An NPC exists with the given npcID. | ||
128 | /// * The caller UUID given is UUID.Zero. | ||
129 | /// * The avatar is unowned (owner is UUID.Zero). | ||
130 | /// * The avatar is owned and the owner and callerID match. | ||
131 | /// * The avatar is owned and the callerID matches its agentID. | ||
132 | /// </remarks> | ||
133 | /// <param name="av"></param> | ||
134 | /// <param name="callerID"></param> | ||
135 | /// <returns>true if they do, false if they don't.</returns> | ||
125 | /// <param name="npcID"></param> | 136 | /// <param name="npcID"></param> |
126 | /// <param name="callerID"></param> | 137 | /// <param name="callerID"></param> |
127 | /// <returns> | 138 | /// <returns> |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f7c12d6..21d47aa 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -823,7 +823,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
823 | m_sceneGridService = sceneGridService; | 823 | m_sceneGridService = sceneGridService; |
824 | m_SimulationDataService = simDataService; | 824 | m_SimulationDataService = simDataService; |
825 | m_EstateDataService = estateDataService; | 825 | m_EstateDataService = estateDataService; |
826 | m_regionHandle = RegionInfo.RegionHandle; | ||
827 | 826 | ||
828 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); | 827 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); |
829 | m_asyncSceneObjectDeleter.Enabled = true; | 828 | m_asyncSceneObjectDeleter.Enabled = true; |
@@ -2042,11 +2041,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2042 | 2041 | ||
2043 | GridRegion region = new GridRegion(RegionInfo); | 2042 | GridRegion region = new GridRegion(RegionInfo); |
2044 | string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); | 2043 | string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); |
2045 | m_log.DebugFormat("{0} RegisterRegionWithGrid. name={1},id={2},loc=<{3},{4}>,size=<{5},{6}>", | 2044 | // m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>", |
2046 | LogHeader, m_regionName, | 2045 | // m_regionName, |
2047 | RegionInfo.RegionID, | 2046 | // RegionInfo.RegionID, |
2048 | RegionInfo.RegionLocX, RegionInfo.RegionLocY, | 2047 | // RegionInfo.RegionLocX, RegionInfo.RegionLocY, |
2049 | RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); | 2048 | // RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); |
2050 | 2049 | ||
2051 | if (error != String.Empty) | 2050 | if (error != String.Empty) |
2052 | throw new Exception(error); | 2051 | throw new Exception(error); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index aaddce6..6f172e7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs | |||
@@ -145,10 +145,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
145 | get { return 1.0f; } | 145 | get { return 1.0f; } |
146 | } | 146 | } |
147 | 147 | ||
148 | protected ulong m_regionHandle; | ||
149 | protected string m_regionName; | ||
150 | protected RegionInfo m_regInfo; | ||
151 | |||
152 | public ITerrainChannel Heightmap; | 148 | public ITerrainChannel Heightmap; |
153 | 149 | ||
154 | /// <value> | 150 | /// <value> |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 93dfd00..0414f89 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1228,45 +1228,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1228 | 1228 | ||
1229 | m_scene.SwapRootAgentCount(false); | 1229 | m_scene.SwapRootAgentCount(false); |
1230 | 1230 | ||
1231 | // The initial login scene presence is already root when it gets here | 1231 | if (Scene.AttachmentsModule != null) |
1232 | // and it has already rezzed the attachments and started their scripts. | 1232 | { |
1233 | // We do the following only for non-login agents, because their scripts | 1233 | // The initial login scene presence is already root when it gets here |
1234 | // haven't started yet. | 1234 | // and it has already rezzed the attachments and started their scripts. |
1235 | if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags)) | 1235 | // We do the following only for non-login agents, because their scripts |
1236 | { | 1236 | // haven't started yet. |
1237 | // Viewers which have a current outfit folder will actually rez their own attachments. However, | 1237 | if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags)) |
1238 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | ||
1239 | if (Scene.AttachmentsModule != null) | ||
1240 | { | 1238 | { |
1239 | // Viewers which have a current outfit folder will actually rez their own attachments. However, | ||
1240 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | ||
1241 | WorkManager.RunJob( | 1241 | WorkManager.RunJob( |
1242 | "RezAttachments", | 1242 | "RezAttachments", |
1243 | o => Scene.AttachmentsModule.RezAttachments(this), | 1243 | o => Scene.AttachmentsModule.RezAttachments(this), |
1244 | null, | 1244 | null, |
1245 | string.Format("Rez attachments for {0} in {1}", Name, Scene.Name)); | 1245 | string.Format("Rez attachments for {0} in {1}", Name, Scene.Name)); |
1246 | } | 1246 | } |
1247 | } | 1247 | else |
1248 | else | ||
1249 | { | ||
1250 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1251 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1252 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1253 | // not transporting the required data. | ||
1254 | // | ||
1255 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
1256 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
1257 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
1258 | // | ||
1259 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
1260 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
1261 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
1262 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
1263 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
1264 | |||
1265 | if (attachments.Count > 0) | ||
1266 | { | 1248 | { |
1267 | WorkManager.RunJob( | 1249 | WorkManager.RunJob( |
1268 | "StartAttachmentScripts", | 1250 | "StartAttachmentScripts", |
1269 | o => RestartAttachmentScripts(attachments), | 1251 | o => RestartAttachmentScripts(), |
1270 | null, | 1252 | null, |
1271 | string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name), | 1253 | string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name), |
1272 | true); | 1254 | true); |
@@ -1292,10 +1274,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1292 | return true; | 1274 | return true; |
1293 | } | 1275 | } |
1294 | 1276 | ||
1295 | private void RestartAttachmentScripts(List<SceneObjectGroup> attachments) | 1277 | private void RestartAttachmentScripts() |
1296 | { | 1278 | { |
1279 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1280 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1281 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1282 | // not transporting the required data. | ||
1283 | // | ||
1284 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
1285 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
1286 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
1287 | // | ||
1288 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
1289 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
1290 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
1291 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
1292 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
1293 | |||
1297 | m_log.DebugFormat( | 1294 | m_log.DebugFormat( |
1298 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | 1295 | "[SCENE PRESENCE]: Restarting scripts in {0} attachments for {1} in {2}", attachments.Count, Name, Scene.Name); |
1299 | 1296 | ||
1300 | // Resume scripts | 1297 | // Resume scripts |
1301 | foreach (SceneObjectGroup sog in attachments) | 1298 | foreach (SceneObjectGroup sog in attachments) |
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 2450cdb..2c5353f 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -648,6 +648,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
648 | } | 648 | } |
649 | } | 649 | } |
650 | 650 | ||
651 | /// <summary> | ||
652 | /// Gather uuids for a given entity. | ||
653 | /// </summary> | ||
654 | /// <remarks> | ||
655 | /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts | ||
656 | /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets | ||
657 | /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be | ||
658 | /// retrieved to work out which assets it references). | ||
659 | /// </remarks> | ||
651 | public class IteratingUuidGatherer | 660 | public class IteratingUuidGatherer |
652 | { | 661 | { |
653 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 662 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -678,21 +687,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
678 | 687 | ||
679 | protected Queue<UUID> m_assetUuidsToInspect; | 688 | protected Queue<UUID> m_assetUuidsToInspect; |
680 | 689 | ||
681 | public IteratingUuidGatherer(IAssetService assetService) | 690 | /// <summary> |
691 | /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class. | ||
692 | /// </summary> | ||
693 | /// <param name="assetService"> | ||
694 | /// Asset service. | ||
695 | /// </param> | ||
696 | /// <param name="collector"> | ||
697 | /// Gathered UUIDs will be collected in this dictinaory. | ||
698 | /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected. | ||
699 | /// </param> | ||
700 | public IteratingUuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector) | ||
682 | { | 701 | { |
683 | m_assetService = assetService; | 702 | m_assetService = assetService; |
684 | m_gatheredAssetUuids = new Dictionary<UUID, sbyte>(); | 703 | m_gatheredAssetUuids = collector; |
685 | 704 | ||
686 | // FIXME: Not efficient for searching, can improve. | 705 | // FIXME: Not efficient for searching, can improve. |
687 | m_assetUuidsToInspect = new Queue<UUID>(); | 706 | m_assetUuidsToInspect = new Queue<UUID>(); |
688 | } | 707 | } |
689 | 708 | ||
690 | public IDictionary<UUID, sbyte> GetGatheredUuids() | 709 | /// <summary> |
691 | { | 710 | /// Adds the asset uuid for inspection during the gathering process. |
692 | return new Dictionary<UUID, sbyte>(m_gatheredAssetUuids); | 711 | /// </summary> |
693 | } | 712 | /// <returns><c>true</c>, if for inspection was added, <c>false</c> otherwise.</returns> |
694 | 713 | /// <param name="uuid">UUID.</param> | |
695 | public bool AddAssetUuidToInspect(UUID uuid) | 714 | public bool AddForInspection(UUID uuid) |
696 | { | 715 | { |
697 | if (m_assetUuidsToInspect.Contains(uuid)) | 716 | if (m_assetUuidsToInspect.Contains(uuid)) |
698 | return false; | 717 | return false; |
@@ -701,6 +720,107 @@ namespace OpenSim.Region.Framework.Scenes | |||
701 | 720 | ||
702 | return true; | 721 | return true; |
703 | } | 722 | } |
723 | |||
724 | /// <summary> | ||
725 | /// Gather all the asset uuids associated with a given object. | ||
726 | /// </summary> | ||
727 | /// <remarks> | ||
728 | /// This includes both those directly associated with | ||
729 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
730 | /// within this object). | ||
731 | /// </remarks> | ||
732 | /// <param name="sceneObject">The scene object for which to gather assets</param> | ||
733 | public void AddForInspection(SceneObjectGroup sceneObject) | ||
734 | { | ||
735 | // m_log.DebugFormat( | ||
736 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); | ||
737 | |||
738 | SceneObjectPart[] parts = sceneObject.Parts; | ||
739 | for (int i = 0; i < parts.Length; i++) | ||
740 | { | ||
741 | SceneObjectPart part = parts[i]; | ||
742 | |||
743 | // m_log.DebugFormat( | ||
744 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); | ||
745 | |||
746 | try | ||
747 | { | ||
748 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | ||
749 | if (textureEntry != null) | ||
750 | { | ||
751 | // Get the prim's default texture. This will be used for faces which don't have their own texture | ||
752 | if (textureEntry.DefaultTexture != null) | ||
753 | RecordTextureEntryAssetUuids(textureEntry.DefaultTexture); | ||
754 | |||
755 | if (textureEntry.FaceTextures != null) | ||
756 | { | ||
757 | // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture) | ||
758 | foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) | ||
759 | { | ||
760 | if (texture != null) | ||
761 | RecordTextureEntryAssetUuids(texture); | ||
762 | } | ||
763 | } | ||
764 | } | ||
765 | |||
766 | // If the prim is a sculpt then preserve this information too | ||
767 | if (part.Shape.SculptTexture != UUID.Zero) | ||
768 | m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; | ||
769 | |||
770 | if (part.Shape.ProjectionTextureUUID != UUID.Zero) | ||
771 | m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture; | ||
772 | |||
773 | if (part.CollisionSound != UUID.Zero) | ||
774 | m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound; | ||
775 | |||
776 | if (part.ParticleSystem.Length > 0) | ||
777 | { | ||
778 | try | ||
779 | { | ||
780 | Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0); | ||
781 | if (ps.Texture != UUID.Zero) | ||
782 | m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture; | ||
783 | } | ||
784 | catch (Exception) | ||
785 | { | ||
786 | m_log.WarnFormat( | ||
787 | "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.", | ||
788 | part.Name, part.UUID, sceneObject.Name, sceneObject.UUID); | ||
789 | } | ||
790 | } | ||
791 | |||
792 | TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); | ||
793 | |||
794 | // Now analyze this prim's inventory items to preserve all the uuids that they reference | ||
795 | foreach (TaskInventoryItem tii in taskDictionary.Values) | ||
796 | { | ||
797 | // m_log.DebugFormat( | ||
798 | // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", | ||
799 | // tii.Name, tii.Type, part.Name, part.UUID); | ||
800 | |||
801 | if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID)) | ||
802 | AddForInspection(tii.AssetID, (sbyte)tii.Type); | ||
803 | } | ||
804 | |||
805 | // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed | ||
806 | // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and | ||
807 | // inventory transfer. There needs to be a way for a module to register a method without assuming a | ||
808 | // Scene.EventManager is present. | ||
809 | // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); | ||
810 | |||
811 | |||
812 | // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs | ||
813 | RecordMaterialsUuids(part); | ||
814 | } | ||
815 | catch (Exception e) | ||
816 | { | ||
817 | m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); | ||
818 | m_log.DebugFormat( | ||
819 | "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)", | ||
820 | part.Shape.TextureEntry.Length); | ||
821 | } | ||
822 | } | ||
823 | } | ||
704 | 824 | ||
705 | /// <summary> | 825 | /// <summary> |
706 | /// Gathers the next set of assets returned by the next uuid to get from the asset service. | 826 | /// Gathers the next set of assets returned by the next uuid to get from the asset service. |
@@ -790,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
790 | } | 910 | } |
791 | } | 911 | } |
792 | 912 | ||
793 | private void RecordAssetUuids(UUID assetUuid, sbyte assetType) | 913 | private void AddForInspection(UUID assetUuid, sbyte assetType) |
794 | { | 914 | { |
795 | // Here, we want to collect uuids which require further asset fetches but mark the others as gathered | 915 | // Here, we want to collect uuids which require further asset fetches but mark the others as gathered |
796 | try | 916 | try |
@@ -799,27 +919,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
799 | 919 | ||
800 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) | 920 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) |
801 | { | 921 | { |
802 | AddAssetUuidToInspect(assetUuid); | 922 | AddForInspection(assetUuid); |
803 | } | 923 | } |
804 | else if ((sbyte)AssetType.Gesture == assetType) | 924 | else if ((sbyte)AssetType.Gesture == assetType) |
805 | { | 925 | { |
806 | AddAssetUuidToInspect(assetUuid); | 926 | AddForInspection(assetUuid); |
807 | } | 927 | } |
808 | else if ((sbyte)AssetType.Notecard == assetType) | 928 | else if ((sbyte)AssetType.Notecard == assetType) |
809 | { | 929 | { |
810 | AddAssetUuidToInspect(assetUuid); | 930 | AddForInspection(assetUuid); |
811 | } | 931 | } |
812 | else if ((sbyte)AssetType.LSLText == assetType) | 932 | else if ((sbyte)AssetType.LSLText == assetType) |
813 | { | 933 | { |
814 | AddAssetUuidToInspect(assetUuid); | 934 | AddForInspection(assetUuid); |
815 | } | 935 | } |
816 | else if ((sbyte)OpenSimAssetType.Material == assetType) | 936 | else if ((sbyte)OpenSimAssetType.Material == assetType) |
817 | { | 937 | { |
818 | AddAssetUuidToInspect(assetUuid); | 938 | AddForInspection(assetUuid); |
819 | } | 939 | } |
820 | else if ((sbyte)AssetType.Object == assetType) | 940 | else if ((sbyte)AssetType.Object == assetType) |
821 | { | 941 | { |
822 | AddAssetUuidToInspect(assetUuid); | 942 | AddForInspection(assetUuid); |
823 | } | 943 | } |
824 | } | 944 | } |
825 | catch (Exception) | 945 | catch (Exception) |
@@ -832,107 +952,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
832 | } | 952 | } |
833 | 953 | ||
834 | /// <summary> | 954 | /// <summary> |
835 | /// Gather all the asset uuids associated with a given object. | ||
836 | /// </summary> | ||
837 | /// <remarks> | ||
838 | /// This includes both those directly associated with | ||
839 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
840 | /// within this object). | ||
841 | /// </remarks> | ||
842 | /// <param name="sceneObject">The scene object for which to gather assets</param> | ||
843 | public void RecordAssetUuids(SceneObjectGroup sceneObject) | ||
844 | { | ||
845 | // m_log.DebugFormat( | ||
846 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); | ||
847 | |||
848 | SceneObjectPart[] parts = sceneObject.Parts; | ||
849 | for (int i = 0; i < parts.Length; i++) | ||
850 | { | ||
851 | SceneObjectPart part = parts[i]; | ||
852 | |||
853 | // m_log.DebugFormat( | ||
854 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); | ||
855 | |||
856 | try | ||
857 | { | ||
858 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | ||
859 | if (textureEntry != null) | ||
860 | { | ||
861 | // Get the prim's default texture. This will be used for faces which don't have their own texture | ||
862 | if (textureEntry.DefaultTexture != null) | ||
863 | RecordTextureEntryAssetUuids(textureEntry.DefaultTexture); | ||
864 | |||
865 | if (textureEntry.FaceTextures != null) | ||
866 | { | ||
867 | // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture) | ||
868 | foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) | ||
869 | { | ||
870 | if (texture != null) | ||
871 | RecordTextureEntryAssetUuids(texture); | ||
872 | } | ||
873 | } | ||
874 | } | ||
875 | |||
876 | // If the prim is a sculpt then preserve this information too | ||
877 | if (part.Shape.SculptTexture != UUID.Zero) | ||
878 | m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; | ||
879 | |||
880 | if (part.Shape.ProjectionTextureUUID != UUID.Zero) | ||
881 | m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture; | ||
882 | |||
883 | if (part.CollisionSound != UUID.Zero) | ||
884 | m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound; | ||
885 | |||
886 | if (part.ParticleSystem.Length > 0) | ||
887 | { | ||
888 | try | ||
889 | { | ||
890 | Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0); | ||
891 | if (ps.Texture != UUID.Zero) | ||
892 | m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture; | ||
893 | } | ||
894 | catch (Exception) | ||
895 | { | ||
896 | m_log.WarnFormat( | ||
897 | "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.", | ||
898 | part.Name, part.UUID, sceneObject.Name, sceneObject.UUID); | ||
899 | } | ||
900 | } | ||
901 | |||
902 | TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); | ||
903 | |||
904 | // Now analyze this prim's inventory items to preserve all the uuids that they reference | ||
905 | foreach (TaskInventoryItem tii in taskDictionary.Values) | ||
906 | { | ||
907 | // m_log.DebugFormat( | ||
908 | // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", | ||
909 | // tii.Name, tii.Type, part.Name, part.UUID); | ||
910 | |||
911 | if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID)) | ||
912 | RecordAssetUuids(tii.AssetID, (sbyte)tii.Type); | ||
913 | } | ||
914 | |||
915 | // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed | ||
916 | // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and | ||
917 | // inventory transfer. There needs to be a way for a module to register a method without assuming a | ||
918 | // Scene.EventManager is present. | ||
919 | // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); | ||
920 | |||
921 | |||
922 | // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs | ||
923 | RecordMaterialsUuids(part); | ||
924 | } | ||
925 | catch (Exception e) | ||
926 | { | ||
927 | m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); | ||
928 | m_log.DebugFormat( | ||
929 | "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)", | ||
930 | part.Shape.TextureEntry.Length); | ||
931 | } | ||
932 | } | ||
933 | } | ||
934 | |||
935 | /// <summary> | ||
936 | /// Collect all the asset uuids found in one face of a Texture Entry. | 955 | /// Collect all the asset uuids found in one face of a Texture Entry. |
937 | /// </summary> | 956 | /// </summary> |
938 | private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture) | 957 | private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture) |
@@ -940,7 +959,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
940 | m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture; | 959 | m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture; |
941 | 960 | ||
942 | if (texture.MaterialID != UUID.Zero) | 961 | if (texture.MaterialID != UUID.Zero) |
943 | AddAssetUuidToInspect(texture.MaterialID); | 962 | AddForInspection(texture.MaterialID); |
944 | } | 963 | } |
945 | 964 | ||
946 | /// <summary> | 965 | /// <summary> |
@@ -948,7 +967,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
948 | /// stored in legacy format in part.DynAttrs | 967 | /// stored in legacy format in part.DynAttrs |
949 | /// </summary> | 968 | /// </summary> |
950 | /// <param name="part"></param> | 969 | /// <param name="part"></param> |
951 | public void RecordMaterialsUuids(SceneObjectPart part) | 970 | private void RecordMaterialsUuids(SceneObjectPart part) |
952 | { | 971 | { |
953 | // scan thru the dynAttrs map of this part for any textures used as materials | 972 | // scan thru the dynAttrs map of this part for any textures used as materials |
954 | OSD osdMaterials = null; | 973 | OSD osdMaterials = null; |
@@ -1039,7 +1058,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1039 | UUID uuid = new UUID(uuidMatch.Value); | 1058 | UUID uuid = new UUID(uuidMatch.Value); |
1040 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | 1059 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); |
1041 | 1060 | ||
1042 | AddAssetUuidToInspect(uuid); | 1061 | AddForInspection(uuid); |
1043 | } | 1062 | } |
1044 | } | 1063 | } |
1045 | 1064 | ||
@@ -1074,14 +1093,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1074 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | 1093 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) |
1075 | { | 1094 | { |
1076 | foreach (SceneObjectGroup sog in coa.Objects) | 1095 | foreach (SceneObjectGroup sog in coa.Objects) |
1077 | RecordAssetUuids(sog); | 1096 | AddForInspection(sog); |
1078 | } | 1097 | } |
1079 | else | 1098 | else |
1080 | { | 1099 | { |
1081 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | 1100 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); |
1082 | 1101 | ||
1083 | if (null != sog) | 1102 | if (null != sog) |
1084 | RecordAssetUuids(sog); | 1103 | AddForInspection(sog); |
1085 | } | 1104 | } |
1086 | } | 1105 | } |
1087 | 1106 | ||
@@ -1147,8 +1166,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1147 | 1166 | ||
1148 | protected string m_assetServerURL; | 1167 | protected string m_assetServerURL; |
1149 | 1168 | ||
1150 | public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL) | 1169 | public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL, IDictionary<UUID, sbyte> collector) |
1151 | : base(assetService) | 1170 | : base(assetService, collector) |
1152 | { | 1171 | { |
1153 | m_assetServerURL = assetServerURL; | 1172 | m_assetServerURL = assetServerURL; |
1154 | if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("=")) | 1173 | if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("=")) |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 95e59ab..b834619 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -441,13 +441,20 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
441 | /// <summary> | 441 | /// <summary> |
442 | /// Check if the caller has permission to manipulate the given NPC. | 442 | /// Check if the caller has permission to manipulate the given NPC. |
443 | /// </summary> | 443 | /// </summary> |
444 | /// <remarks> | ||
445 | /// A caller has permission if | ||
446 | /// * The caller UUID given is UUID.Zero. | ||
447 | /// * The avatar is unowned (owner is UUID.Zero). | ||
448 | /// * The avatar is owned and the owner and callerID match. | ||
449 | /// * The avatar is owned and the callerID matches its agentID. | ||
450 | /// </remarks> | ||
444 | /// <param name="av"></param> | 451 | /// <param name="av"></param> |
445 | /// <param name="callerID"></param> | 452 | /// <param name="callerID"></param> |
446 | /// <returns>true if they do, false if they don't.</returns> | 453 | /// <returns>true if they do, false if they don't.</returns> |
447 | private bool CheckPermissions(NPCAvatar av, UUID callerID) | 454 | private bool CheckPermissions(NPCAvatar av, UUID callerID) |
448 | { | 455 | { |
449 | return callerID == UUID.Zero || av.OwnerID == UUID.Zero || | 456 | return callerID == UUID.Zero || av.OwnerID == UUID.Zero || |
450 | av.OwnerID == callerID; | 457 | av.OwnerID == callerID || av.AgentId == callerID; |
451 | } | 458 | } |
452 | } | 459 | } |
453 | } \ No newline at end of file | 460 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index b9a217b..1097efb 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | |||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
222 | void SetVars(Dictionary<string, object> vars); | 222 | void SetVars(Dictionary<string, object> vars); |
223 | DetectParams GetDetectParams(int idx); | 223 | DetectParams GetDetectParams(int idx); |
224 | UUID GetDetectID(int idx); | 224 | UUID GetDetectID(int idx); |
225 | void SaveState(string assembly); | 225 | void SaveState(); |
226 | void DestroyScriptInstance(); | 226 | void DestroyScriptInstance(); |
227 | 227 | ||
228 | IScriptApi GetApi(string name); | 228 | IScriptApi GetApi(string name); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 9379f8f..de5f92d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | |||
@@ -663,9 +663,8 @@ namespace SecondLife | |||
663 | 663 | ||
664 | try | 664 | try |
665 | { | 665 | { |
666 | FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read); | 666 | using (FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read)) |
667 | fs.Read(data, 0, data.Length); | 667 | fs.Read(data, 0, data.Length); |
668 | fs.Close(); | ||
669 | } | 668 | } |
670 | catch (Exception) | 669 | catch (Exception) |
671 | { | 670 | { |
@@ -680,9 +679,8 @@ namespace SecondLife | |||
680 | 679 | ||
681 | Byte[] buf = Encoding.ASCII.GetBytes(filetext); | 680 | Byte[] buf = Encoding.ASCII.GetBytes(filetext); |
682 | 681 | ||
683 | FileStream sfs = File.Create(assembly + ".text"); | 682 | using (FileStream sfs = File.Create(assembly + ".text")) |
684 | sfs.Write(buf, 0, buf.Length); | 683 | sfs.Write(buf, 0, buf.Length); |
685 | sfs.Close(); | ||
686 | 684 | ||
687 | return assembly; | 685 | return assembly; |
688 | } | 686 | } |
@@ -775,7 +773,6 @@ namespace SecondLife | |||
775 | return message; | 773 | return message; |
776 | } | 774 | } |
777 | 775 | ||
778 | |||
779 | private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) | 776 | private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) |
780 | { | 777 | { |
781 | string mapstring = String.Empty; | 778 | string mapstring = String.Empty; |
@@ -787,40 +784,42 @@ namespace SecondLife | |||
787 | } | 784 | } |
788 | 785 | ||
789 | Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); | 786 | Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); |
790 | FileStream mfs = File.Create(filename); | ||
791 | mfs.Write(mapbytes, 0, mapbytes.Length); | ||
792 | mfs.Close(); | ||
793 | } | ||
794 | 787 | ||
788 | using (FileStream mfs = File.Create(filename)) | ||
789 | mfs.Write(mapbytes, 0, mapbytes.Length); | ||
790 | } | ||
795 | 791 | ||
796 | private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ReadMapFile(string filename) | 792 | private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ReadMapFile(string filename) |
797 | { | 793 | { |
798 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; | 794 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; |
799 | try | 795 | try |
800 | { | 796 | { |
801 | StreamReader r = File.OpenText(filename); | 797 | using (StreamReader r = File.OpenText(filename)) |
802 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); | ||
803 | |||
804 | string line; | ||
805 | while ((line = r.ReadLine()) != null) | ||
806 | { | 798 | { |
807 | String[] parts = line.Split(new Char[] { ',' }); | 799 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); |
808 | int kk = System.Convert.ToInt32(parts[0]); | ||
809 | int kv = System.Convert.ToInt32(parts[1]); | ||
810 | int vk = System.Convert.ToInt32(parts[2]); | ||
811 | int vv = System.Convert.ToInt32(parts[3]); | ||
812 | 800 | ||
813 | KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv); | 801 | string line; |
814 | KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv); | 802 | while ((line = r.ReadLine()) != null) |
803 | { | ||
804 | String[] parts = line.Split(new Char[] { ',' }); | ||
805 | int kk = System.Convert.ToInt32(parts[0]); | ||
806 | int kv = System.Convert.ToInt32(parts[1]); | ||
807 | int vk = System.Convert.ToInt32(parts[2]); | ||
808 | int vv = System.Convert.ToInt32(parts[3]); | ||
809 | |||
810 | KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv); | ||
811 | KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv); | ||
815 | 812 | ||
816 | linemap[k] = v; | 813 | linemap[k] = v; |
814 | } | ||
817 | } | 815 | } |
818 | } | 816 | } |
819 | catch | 817 | catch |
820 | { | 818 | { |
821 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); | 819 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); |
822 | } | 820 | } |
821 | |||
823 | return linemap; | 822 | return linemap; |
824 | } | 823 | } |
825 | } | 824 | } |
826 | } | 825 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 9da2168..b983be9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -71,7 +71,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
71 | private bool m_TimerQueued; | 71 | private bool m_TimerQueued; |
72 | private DateTime m_EventStart; | 72 | private DateTime m_EventStart; |
73 | private bool m_InEvent; | 73 | private bool m_InEvent; |
74 | private string m_Assembly; | 74 | private string m_assemblyPath; |
75 | private string m_dataPath; | ||
75 | private string m_CurrentEvent = String.Empty; | 76 | private string m_CurrentEvent = String.Empty; |
76 | private bool m_InSelfDelete; | 77 | private bool m_InSelfDelete; |
77 | private int m_MaxScriptQueue; | 78 | private int m_MaxScriptQueue; |
@@ -244,12 +245,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
244 | /// </summary> | 245 | /// </summary> |
245 | /// <param name='dom'></param> | 246 | /// <param name='dom'></param> |
246 | /// <param name='assembly'></param> | 247 | /// <param name='assembly'></param> |
248 | /// <param name='dataPath'> | ||
249 | /// Path for all script associated data (state, etc.). In a multi-region set up | ||
250 | /// with all scripts loading into the same AppDomain this may not be the same place as the DLL itself. | ||
251 | /// </param> | ||
247 | /// <param name='stateSource'></param> | 252 | /// <param name='stateSource'></param> |
248 | /// <returns>false if load failed, true if suceeded</returns> | 253 | /// <returns>false if load failed, true if suceeded</returns> |
249 | public bool Load(AppDomain dom, Assembly scriptAssembly, StateSource stateSource) | 254 | public bool Load(AppDomain dom, Assembly scriptAssembly, string dataPath, StateSource stateSource) |
250 | { | 255 | { |
251 | //m_Assembly = scriptAssembly.CodeBase; | 256 | m_assemblyPath = scriptAssembly.Location; |
252 | m_Assembly = scriptAssembly.Location; | 257 | m_dataPath = dataPath; |
253 | m_stateSource = stateSource; | 258 | m_stateSource = stateSource; |
254 | 259 | ||
255 | try | 260 | try |
@@ -270,14 +275,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
270 | constructorParams = null; | 275 | constructorParams = null; |
271 | } | 276 | } |
272 | 277 | ||
273 | // m_log.DebugFormat( | ||
274 | // "[SCRIP | ||
275 | // scriptType.FullName, m_Assembly, Engine.World.Name); | ||
276 | |||
277 | if (dom != System.AppDomain.CurrentDomain) | 278 | if (dom != System.AppDomain.CurrentDomain) |
278 | m_Script | 279 | m_Script |
279 | = (IScript)dom.CreateInstanceAndUnwrap( | 280 | = (IScript)dom.CreateInstanceAndUnwrap( |
280 | Path.GetFileNameWithoutExtension(m_Assembly), | 281 | Path.GetFileNameWithoutExtension(m_assemblyPath), |
281 | scriptType.FullName, | 282 | scriptType.FullName, |
282 | false, | 283 | false, |
283 | BindingFlags.Default, | 284 | BindingFlags.Default, |
@@ -305,7 +306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
305 | { | 306 | { |
306 | m_log.ErrorFormat( | 307 | m_log.ErrorFormat( |
307 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}", | 308 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}", |
308 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, m_Assembly, e.Message, e.StackTrace); | 309 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, scriptAssembly.Location, e.Message, e.StackTrace); |
309 | 310 | ||
310 | return false; | 311 | return false; |
311 | } | 312 | } |
@@ -340,10 +341,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
340 | 341 | ||
341 | m_SaveState = true; | 342 | m_SaveState = true; |
342 | 343 | ||
343 | string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), ItemID.ToString() + ".state"); | 344 | string savedState = Path.Combine(m_dataPath, ItemID.ToString() + ".state"); |
344 | 345 | ||
345 | if (File.Exists(savedState)) | 346 | if (File.Exists(savedState)) |
346 | { | 347 | { |
348 | // m_log.DebugFormat( | ||
349 | // "[SCRIPT INSTANCE]: Found state for script {0} for {1} ({2}) at {3} in {4}", | ||
350 | // ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name); | ||
351 | |||
347 | string xml = String.Empty; | 352 | string xml = String.Empty; |
348 | 353 | ||
349 | try | 354 | try |
@@ -385,12 +390,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
385 | m_startedFromSavedState = true; | 390 | m_startedFromSavedState = true; |
386 | } | 391 | } |
387 | } | 392 | } |
388 | else | 393 | // else |
389 | { | 394 | // { |
390 | m_log.WarnFormat( | 395 | // m_log.WarnFormat( |
391 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", | 396 | // "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", |
392 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); | 397 | // ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); |
393 | } | 398 | // } |
394 | } | 399 | } |
395 | catch (Exception e) | 400 | catch (Exception e) |
396 | { | 401 | { |
@@ -401,11 +406,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
401 | } | 406 | } |
402 | // else | 407 | // else |
403 | // { | 408 | // { |
404 | // ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID); | 409 | // m_log.DebugFormat( |
405 | 410 | // "[SCRIPT INSTANCE]: Did not find state for script {0} for {1} ({2}) at {3} in {4}", | |
406 | // if (presence != null && (!postOnRez)) | 411 | // ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name); |
407 | // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); | ||
408 | |||
409 | // } | 412 | // } |
410 | 413 | ||
411 | return true; | 414 | return true; |
@@ -498,8 +501,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
498 | 501 | ||
499 | public void RemoveState() | 502 | public void RemoveState() |
500 | { | 503 | { |
501 | string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), | 504 | string savedState = Path.Combine(m_dataPath, ItemID.ToString() + ".state"); |
502 | ItemID.ToString() + ".state"); | 505 | |
506 | // m_log.DebugFormat( | ||
507 | // "[SCRIPT INSTANCE]: Deleting state {0} for script {1} (id {2}) in part {3} (id {4}) in object {5} in {6}.", | ||
508 | // savedState, ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name); | ||
503 | 509 | ||
504 | try | 510 | try |
505 | { | 511 | { |
@@ -822,8 +828,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
822 | if (Engine.World.PipeEventsForScript(LocalID) || | 828 | if (Engine.World.PipeEventsForScript(LocalID) || |
823 | data.EventName == "control") // Don't freeze avies! | 829 | data.EventName == "control") // Don't freeze avies! |
824 | { | 830 | { |
825 | // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", | 831 | // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", |
826 | // PrimName, ScriptName, data.EventName, State); | 832 | // PrimName, ScriptName, data.EventName, State); |
827 | 833 | ||
828 | try | 834 | try |
829 | { | 835 | { |
@@ -849,7 +855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
849 | // This will be the very first event we deliver | 855 | // This will be the very first event we deliver |
850 | // (state_entry) in default state | 856 | // (state_entry) in default state |
851 | // | 857 | // |
852 | SaveState(m_Assembly); | 858 | SaveState(); |
853 | 859 | ||
854 | m_SaveState = false; | 860 | m_SaveState = false; |
855 | } | 861 | } |
@@ -1043,7 +1049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
1043 | return m_DetectParams[idx].Key; | 1049 | return m_DetectParams[idx].Key; |
1044 | } | 1050 | } |
1045 | 1051 | ||
1046 | public void SaveState(string assembly) | 1052 | public void SaveState() |
1047 | { | 1053 | { |
1048 | // If we're currently in an event, just tell it to save upon return | 1054 | // If we're currently in an event, just tell it to save upon return |
1049 | // | 1055 | // |
@@ -1065,10 +1071,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
1065 | { | 1071 | { |
1066 | try | 1072 | try |
1067 | { | 1073 | { |
1068 | FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")); | 1074 | using (FileStream fs = File.Create(Path.Combine(m_dataPath, ItemID.ToString() + ".state"))) |
1069 | Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml); | 1075 | { |
1070 | fs.Write(buf, 0, buf.Length); | 1076 | Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml); |
1071 | fs.Close(); | 1077 | fs.Write(buf, 0, buf.Length); |
1078 | } | ||
1072 | } | 1079 | } |
1073 | catch(Exception) | 1080 | catch(Exception) |
1074 | { | 1081 | { |
@@ -1148,7 +1155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
1148 | 1155 | ||
1149 | public string GetAssemblyName() | 1156 | public string GetAssemblyName() |
1150 | { | 1157 | { |
1151 | return m_Assembly; | 1158 | return m_assemblyPath; |
1152 | } | 1159 | } |
1153 | 1160 | ||
1154 | public string GetXMLState() | 1161 | public string GetXMLState() |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs index fe15157..878e571 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs | |||
@@ -40,10 +40,10 @@ using OpenSim.Tests.Common; | |||
40 | namespace OpenSim.Region.ScriptEngine.XEngine.Tests | 40 | namespace OpenSim.Region.ScriptEngine.XEngine.Tests |
41 | { | 41 | { |
42 | /// <summary> | 42 | /// <summary> |
43 | /// XEngine tests. | 43 | /// Basic XEngine tests. |
44 | /// </summary> | 44 | /// </summary> |
45 | [TestFixture] | 45 | [TestFixture] |
46 | public class XEngineTest : OpenSimTestCase | 46 | public class XEngineBasicTests : OpenSimTestCase |
47 | { | 47 | { |
48 | private TestScene m_scene; | 48 | private TestScene m_scene; |
49 | private XEngine m_xEngine; | 49 | private XEngine m_xEngine; |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs new file mode 100644 index 0000000..587695f --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineCrossingTests.cs | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Threading; | ||
30 | using Nini.Config; | ||
31 | using NUnit.Framework; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; | ||
35 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Region.ScriptEngine.Shared; | ||
38 | using OpenSim.Tests.Common; | ||
39 | |||
40 | namespace OpenSim.Region.ScriptEngine.XEngine.Tests | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// XEngine tests connected with crossing scripts between regions. | ||
44 | /// </summary> | ||
45 | [TestFixture] | ||
46 | public class XEngineCrossingTests : OpenSimTestCase | ||
47 | { | ||
48 | [TestFixtureSetUp] | ||
49 | public void FixtureInit() | ||
50 | { | ||
51 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. | ||
52 | Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; | ||
53 | } | ||
54 | |||
55 | [TestFixtureTearDown] | ||
56 | public void TearDown() | ||
57 | { | ||
58 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
59 | // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression | ||
60 | // tests really shouldn't). | ||
61 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
62 | } | ||
63 | |||
64 | /// <summary> | ||
65 | /// Test script state preservation when a script crosses between regions on the same simulator. | ||
66 | /// </summary> | ||
67 | [Test] | ||
68 | public void TestScriptCrossOnSameSimulator() | ||
69 | { | ||
70 | TestHelpers.InMethod(); | ||
71 | // TestHelpers.EnableLogging(); | ||
72 | |||
73 | UUID userId = TestHelpers.ParseTail(0x1); | ||
74 | int sceneObjectIdTail = 0x2; | ||
75 | |||
76 | EntityTransferModule etmA = new EntityTransferModule(); | ||
77 | EntityTransferModule etmB = new EntityTransferModule(); | ||
78 | LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); | ||
79 | XEngine xEngineA = new XEngine(); | ||
80 | XEngine xEngineB = new XEngine(); | ||
81 | xEngineA.DebugLevel = 1; | ||
82 | xEngineB.DebugLevel = 1; | ||
83 | |||
84 | IConfigSource configSource = new IniConfigSource(); | ||
85 | |||
86 | IConfig startupConfig = configSource.AddConfig("Startup"); | ||
87 | startupConfig.Set("DefaultScriptEngine", "XEngine"); | ||
88 | |||
89 | IConfig xEngineConfig = configSource.AddConfig("XEngine"); | ||
90 | xEngineConfig.Set("Enabled", "true"); | ||
91 | xEngineConfig.Set("StartDelay", "0"); | ||
92 | |||
93 | // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call | ||
94 | // to AssemblyResolver.OnAssemblyResolve fails. | ||
95 | xEngineConfig.Set("AppDomainLoading", "false"); | ||
96 | |||
97 | IConfig modulesConfig = configSource.AddConfig("Modules"); | ||
98 | modulesConfig.Set("EntityTransferModule", etmA.Name); | ||
99 | modulesConfig.Set("SimulationServices", lscm.Name); | ||
100 | |||
101 | SceneHelpers sh = new SceneHelpers(); | ||
102 | TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000, configSource); | ||
103 | TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999, configSource); | ||
104 | |||
105 | SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, configSource, lscm); | ||
106 | SceneHelpers.SetupSceneModules(sceneA, configSource, etmA, xEngineA); | ||
107 | SceneHelpers.SetupSceneModules(sceneB, configSource, etmB, xEngineB); | ||
108 | sceneA.StartScripts(); | ||
109 | sceneB.StartScripts(); | ||
110 | |||
111 | SceneObjectGroup soSceneA = SceneHelpers.AddSceneObject(sceneA, 1, userId, "so1-", sceneObjectIdTail); | ||
112 | soSceneA.AbsolutePosition = new Vector3(128, 10, 20); | ||
113 | |||
114 | // CREATE SCRIPT TODO | ||
115 | InventoryItemBase scriptItemSceneA = new InventoryItemBase(); | ||
116 | // itemTemplate.ID = itemId; | ||
117 | scriptItemSceneA.Name = "script1"; | ||
118 | scriptItemSceneA.Folder = soSceneA.UUID; | ||
119 | scriptItemSceneA.InvType = (int)InventoryType.LSL; | ||
120 | |||
121 | AutoResetEvent chatEvent = new AutoResetEvent(false); | ||
122 | OSChatMessage messageReceived = null; | ||
123 | sceneA.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); }; | ||
124 | |||
125 | sceneA.RezNewScript(userId, scriptItemSceneA, | ||
126 | @"integer c = 0; | ||
127 | |||
128 | default | ||
129 | { | ||
130 | state_entry() | ||
131 | { | ||
132 | llSay(0, ""Script running""); | ||
133 | } | ||
134 | |||
135 | changed(integer change) | ||
136 | { | ||
137 | llSay(0, ""Changed""); | ||
138 | } | ||
139 | |||
140 | touch_start(integer n) | ||
141 | { | ||
142 | c = c + 1; | ||
143 | llSay(0, (string)c); | ||
144 | } | ||
145 | }"); | ||
146 | |||
147 | chatEvent.WaitOne(60000); | ||
148 | |||
149 | Assert.That(messageReceived, Is.Not.Null, "No chat message received."); | ||
150 | Assert.That(messageReceived.Message, Is.EqualTo("Script running")); | ||
151 | |||
152 | { | ||
153 | // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. | ||
154 | DetectParams[] det = new DetectParams[1]; | ||
155 | det[0] = new DetectParams(); | ||
156 | det[0].Key = userId; | ||
157 | det[0].Populate(sceneA); | ||
158 | |||
159 | EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); | ||
160 | |||
161 | xEngineA.PostObjectEvent(soSceneA.LocalId, ep); | ||
162 | chatEvent.WaitOne(60000); | ||
163 | |||
164 | Assert.That(messageReceived.Message, Is.EqualTo("1")); | ||
165 | } | ||
166 | |||
167 | sceneB.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); }; | ||
168 | |||
169 | // Cross with a negative value | ||
170 | soSceneA.AbsolutePosition = new Vector3(128, -10, 20); | ||
171 | |||
172 | chatEvent.WaitOne(60000); | ||
173 | Assert.That(messageReceived.Message, Is.EqualTo("Changed")); | ||
174 | |||
175 | // TEST sending event to moved prim and output | ||
176 | { | ||
177 | SceneObjectGroup soSceneB = sceneB.GetSceneObjectGroup(soSceneA.Name); | ||
178 | TaskInventoryItem scriptItemSceneB = soSceneB.RootPart.Inventory.GetInventoryItem(scriptItemSceneA.Name); | ||
179 | |||
180 | // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. | ||
181 | DetectParams[] det = new DetectParams[1]; | ||
182 | det[0] = new DetectParams(); | ||
183 | det[0].Key = userId; | ||
184 | det[0].Populate(sceneB); | ||
185 | |||
186 | EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); | ||
187 | |||
188 | xEngineB.PostObjectEvent(soSceneB.LocalId, ep); | ||
189 | chatEvent.WaitOne(60000); | ||
190 | |||
191 | Assert.That(messageReceived.Message, Is.EqualTo("2")); | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a4113d6..906c6ee 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -70,7 +70,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
70 | /// <remarks> | 70 | /// <remarks> |
71 | /// If DebugLevel >= 1, then we log every time that a script is started. | 71 | /// If DebugLevel >= 1, then we log every time that a script is started. |
72 | /// </remarks> | 72 | /// </remarks> |
73 | // public int DebugLevel { get; set; } | 73 | public int DebugLevel { get; set; } |
74 | 74 | ||
75 | private SmartThreadPool m_ThreadPool; | 75 | private SmartThreadPool m_ThreadPool; |
76 | private int m_MaxScriptQueue; | 76 | private int m_MaxScriptQueue; |
@@ -101,7 +101,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
101 | private bool m_InitialStartup = true; | 101 | private bool m_InitialStartup = true; |
102 | private int m_ScriptFailCount; // Number of script fails since compile queue was last empty | 102 | private int m_ScriptFailCount; // Number of script fails since compile queue was last empty |
103 | private string m_ScriptErrorMessage; | 103 | private string m_ScriptErrorMessage; |
104 | private Dictionary<string, string> m_uniqueScripts = new Dictionary<string, string>(); | ||
105 | private bool m_AppDomainLoading; | 104 | private bool m_AppDomainLoading; |
106 | private Dictionary<UUID,ArrayList> m_ScriptErrors = | 105 | private Dictionary<UUID,ArrayList> m_ScriptErrors = |
107 | new Dictionary<UUID,ArrayList>(); | 106 | new Dictionary<UUID,ArrayList>(); |
@@ -403,12 +402,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
403 | + "Level >= 2, log event invocations.\n", | 402 | + "Level >= 2, log event invocations.\n", |
404 | HandleDebugScriptLogCommand); | 403 | HandleDebugScriptLogCommand); |
405 | 404 | ||
406 | // MainConsole.Instance.Commands.AddCommand( | 405 | MainConsole.Instance.Commands.AddCommand( |
407 | // "Debug", false, "debug xengine", "debug xengine [<level>]", | 406 | "Debug", false, "debug xengine log", "debug xengine log [<level>]", |
408 | // "Turn on detailed xengine debugging.", | 407 | "Turn on detailed xengine debugging.", |
409 | // "If level <= 0, then no extra logging is done.\n" | 408 | "If level <= 0, then no extra logging is done.\n" |
410 | // + "If level >= 1, then we log every time that a script is started.", | 409 | + "If level >= 1, then we log every time that a script is started.", |
411 | // HandleDebugLevelCommand); | 410 | HandleDebugLevelCommand); |
412 | } | 411 | } |
413 | 412 | ||
414 | private void HandleDebugScriptLogCommand(string module, string[] args) | 413 | private void HandleDebugScriptLogCommand(string module, string[] args) |
@@ -451,26 +450,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
451 | /// </summary> | 450 | /// </summary> |
452 | /// <param name="module"></param> | 451 | /// <param name="module"></param> |
453 | /// <param name="args"></param> | 452 | /// <param name="args"></param> |
454 | // private void HandleDebugLevelCommand(string module, string[] args) | 453 | private void HandleDebugLevelCommand(string module, string[] args) |
455 | // { | 454 | { |
456 | // if (args.Length == 3) | 455 | if (args.Length <= 4) |
457 | // { | 456 | { |
458 | // int newDebug; | 457 | int newDebug; |
459 | // if (int.TryParse(args[2], out newDebug)) | 458 | if (ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, args[3], out newDebug)) |
460 | // { | 459 | { |
461 | // DebugLevel = newDebug; | 460 | DebugLevel = newDebug; |
462 | // MainConsole.Instance.OutputFormat("Debug level set to {0}", newDebug); | 461 | MainConsole.Instance.OutputFormat("Debug level set to {0} in XEngine for region {1}", newDebug, m_Scene.Name); |
463 | // } | 462 | } |
464 | // } | 463 | } |
465 | // else if (args.Length == 2) | 464 | else if (args.Length == 3) |
466 | // { | 465 | { |
467 | // MainConsole.Instance.OutputFormat("Current debug level is {0}", DebugLevel); | 466 | MainConsole.Instance.OutputFormat("Current debug level is {0}", DebugLevel); |
468 | // } | 467 | } |
469 | // else | 468 | else |
470 | // { | 469 | { |
471 | // MainConsole.Instance.Output("Usage: debug xengine 0..1"); | 470 | MainConsole.Instance.Output("Usage: debug xengine log <level>"); |
472 | // } | 471 | } |
473 | // } | 472 | } |
474 | 473 | ||
475 | /// <summary> | 474 | /// <summary> |
476 | /// Parse the raw item id into a script instance from the command params if it's present. | 475 | /// Parse the raw item id into a script instance from the command params if it's present. |
@@ -570,7 +569,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
570 | } | 569 | } |
571 | 570 | ||
572 | sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded); | 571 | sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded); |
573 | sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); | ||
574 | sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); | 572 | sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); |
575 | sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); | 573 | sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); |
576 | sb.AppendFormat("Min threads : {0}\n", m_ThreadPool.MinThreads); | 574 | sb.AppendFormat("Min threads : {0}\n", m_ThreadPool.MinThreads); |
@@ -716,22 +714,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
716 | { | 714 | { |
717 | // Force a final state save | 715 | // Force a final state save |
718 | // | 716 | // |
719 | if (m_Assemblies.ContainsKey(instance.AssetID)) | 717 | try |
720 | { | 718 | { |
721 | string assembly = m_Assemblies[instance.AssetID]; | 719 | instance.SaveState(); |
722 | 720 | } | |
723 | try | 721 | catch (Exception e) |
724 | { | 722 | { |
725 | instance.SaveState(assembly); | 723 | m_log.Error( |
726 | } | 724 | string.Format( |
727 | catch (Exception e) | 725 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", |
728 | { | 726 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) |
729 | m_log.Error( | 727 | , e); |
730 | string.Format( | ||
731 | "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ", | ||
732 | instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name) | ||
733 | , e); | ||
734 | } | ||
735 | } | 728 | } |
736 | 729 | ||
737 | // Clear the event queue and abort the instance thread | 730 | // Clear the event queue and abort the instance thread |
@@ -840,18 +833,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
840 | 833 | ||
841 | foreach (IScriptInstance i in instances) | 834 | foreach (IScriptInstance i in instances) |
842 | { | 835 | { |
843 | string assembly = String.Empty; | ||
844 | |||
845 | lock (m_Scripts) | ||
846 | { | ||
847 | if (!m_Assemblies.ContainsKey(i.AssetID)) | ||
848 | continue; | ||
849 | assembly = m_Assemblies[i.AssetID]; | ||
850 | } | ||
851 | |||
852 | try | 836 | try |
853 | { | 837 | { |
854 | i.SaveState(assembly); | 838 | i.SaveState(); |
855 | } | 839 | } |
856 | catch (Exception e) | 840 | catch (Exception e) |
857 | { | 841 | { |
@@ -1001,12 +985,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1001 | if (engine != ScriptEngineName) | 985 | if (engine != ScriptEngineName) |
1002 | return; | 986 | return; |
1003 | 987 | ||
1004 | // If we've seen this exact script text before, use that reference instead | ||
1005 | if (m_uniqueScripts.ContainsKey(script)) | ||
1006 | script = m_uniqueScripts[script]; | ||
1007 | else | ||
1008 | m_uniqueScripts[script] = script; | ||
1009 | |||
1010 | Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource}; | 988 | Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource}; |
1011 | 989 | ||
1012 | if (stateSource == (int)StateSource.ScriptedRez) | 990 | if (stateSource == (int)StateSource.ScriptedRez) |
@@ -1020,11 +998,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1020 | } | 998 | } |
1021 | else | 999 | else |
1022 | { | 1000 | { |
1023 | m_CompileQueue.Enqueue(parms); | ||
1024 | lock (m_CompileDict) | 1001 | lock (m_CompileDict) |
1025 | { | ||
1026 | m_CompileDict[itemID] = 0; | 1002 | m_CompileDict[itemID] = 0; |
1027 | } | 1003 | |
1004 | // This must occur after the m_CompileDict so that an existing compile thread cannot hit the check | ||
1005 | // in DoOnRezScript() before m_CompileDict has been updated. | ||
1006 | m_CompileQueue.Enqueue(parms); | ||
1028 | 1007 | ||
1029 | // m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID); | 1008 | // m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID); |
1030 | 1009 | ||
@@ -1100,7 +1079,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1100 | // due to a race condition | 1079 | // due to a race condition |
1101 | // | 1080 | // |
1102 | lock (m_CompileQueue) | 1081 | lock (m_CompileQueue) |
1082 | { | ||
1103 | m_CurrentCompile = null; | 1083 | m_CurrentCompile = null; |
1084 | |||
1085 | // This is to avoid a situation where the m_CompileQueue while loop above could complete but | ||
1086 | // OnRezScript() place a new script on the queue and check m_CurrentCompile = null before we hit | ||
1087 | // this section. | ||
1088 | if (m_CompileQueue.Count > 0) | ||
1089 | m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); | ||
1090 | } | ||
1104 | } | 1091 | } |
1105 | 1092 | ||
1106 | return null; | 1093 | return null; |
@@ -1148,10 +1135,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1148 | return false; | 1135 | return false; |
1149 | } | 1136 | } |
1150 | 1137 | ||
1151 | m_log.DebugFormat( | 1138 | if (DebugLevel > 0) |
1152 | "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1139 | m_log.DebugFormat( |
1153 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1140 | "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", |
1154 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1141 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, |
1142 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | ||
1155 | 1143 | ||
1156 | UUID assetID = item.AssetID; | 1144 | UUID assetID = item.AssetID; |
1157 | 1145 | ||
@@ -1170,7 +1158,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1170 | lock (m_AddingAssemblies) | 1158 | lock (m_AddingAssemblies) |
1171 | { | 1159 | { |
1172 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap); | 1160 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap); |
1173 | 1161 | ||
1162 | // m_log.DebugFormat( | ||
1163 | // "[XENGINE]: Found assembly path {0} onrez {1} in {2}", | ||
1164 | // assemblyPath, item.ItemID, World.Name); | ||
1165 | |||
1174 | if (!m_AddingAssemblies.ContainsKey(assemblyPath)) { | 1166 | if (!m_AddingAssemblies.ContainsKey(assemblyPath)) { |
1175 | m_AddingAssemblies[assemblyPath] = 1; | 1167 | m_AddingAssemblies[assemblyPath] = 1; |
1176 | } else { | 1168 | } else { |
@@ -1348,14 +1340,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1348 | // simulator session if the script halt strategy has been changed. Instead, we'll continue with | 1340 | // simulator session if the script halt strategy has been changed. Instead, we'll continue with |
1349 | // the existing DLL and the new one will be used in the next simulator session. | 1341 | // the existing DLL and the new one will be used in the next simulator session. |
1350 | if (recompile) | 1342 | if (recompile) |
1343 | { | ||
1344 | m_log.DebugFormat( | ||
1345 | "[XEngine]: Recompiling script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5} to switch it to {6} termination. Will be active on next restart.", | ||
1346 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | ||
1347 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.Name, | ||
1348 | m_coopTermination ? "co-op" : "abort"); | ||
1349 | |||
1351 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, true, out assemblyPath, out linemap); | 1350 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, true, out assemblyPath, out linemap); |
1351 | } | ||
1352 | 1352 | ||
1353 | instance = new ScriptInstance(this, part, | 1353 | instance = new ScriptInstance(this, part, |
1354 | item, | 1354 | item, |
1355 | startParam, postOnRez, | 1355 | startParam, postOnRez, |
1356 | m_MaxScriptQueue); | 1356 | m_MaxScriptQueue); |
1357 | 1357 | ||
1358 | if (!instance.Load(m_AppDomains[appDomain], scriptAssembly, stateSource)) | 1358 | if (!instance.Load( |
1359 | m_AppDomains[appDomain], scriptAssembly, | ||
1360 | Path.Combine(ScriptEnginePath, World.RegionInfo.RegionID.ToString()), stateSource)) | ||
1359 | return false; | 1361 | return false; |
1360 | 1362 | ||
1361 | // if (DebugLevel >= 1) | 1363 | // if (DebugLevel >= 1) |
@@ -1586,7 +1588,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1586 | 1588 | ||
1587 | IScriptInstance instance = (ScriptInstance) parms; | 1589 | IScriptInstance instance = (ScriptInstance) parms; |
1588 | 1590 | ||
1589 | //m_log.DebugFormat("[XEngine]: Processing event for {0}", instance); | 1591 | // m_log.DebugFormat("[XEngine]: Processing event for {0}", instance); |
1590 | 1592 | ||
1591 | return instance.EventProcessor(); | 1593 | return instance.EventProcessor(); |
1592 | } | 1594 | } |
@@ -2155,7 +2157,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2155 | catch (IOException ex) | 2157 | catch (IOException ex) |
2156 | { | 2158 | { |
2157 | // if there already exists a file at that location, it may be locked. | 2159 | // if there already exists a file at that location, it may be locked. |
2158 | m_log.ErrorFormat("[XEngine]: Linemap file {0} already exists! {1}", mappath, ex.Message); | 2160 | m_log.Error( |
2161 | string.Format("[XEngine]: Linemap file {0} could not be written. Exception ", mappath), ex); | ||
2159 | } | 2162 | } |
2160 | } | 2163 | } |
2161 | } | 2164 | } |
@@ -2181,6 +2184,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
2181 | m_log.ErrorFormat("[XEngine]: Error whilst writing state file {0}, {1}", statepath, ex.Message); | 2184 | m_log.ErrorFormat("[XEngine]: Error whilst writing state file {0}, {1}", statepath, ex.Message); |
2182 | } | 2185 | } |
2183 | 2186 | ||
2187 | // m_log.DebugFormat( | ||
2188 | // "[XEngine]: Wrote state for script item with ID {0} at {1} in {2}", itemID, statepath, m_Scene.Name); | ||
2189 | |||
2184 | return true; | 2190 | return true; |
2185 | } | 2191 | } |
2186 | 2192 | ||
diff --git a/OpenSim/Server/Handlers/BakedTextures/XBakes.cs b/OpenSim/Server/Handlers/BakedTextures/XBakes.cs index d1b2e12..4e55433 100644 --- a/OpenSim/Server/Handlers/BakedTextures/XBakes.cs +++ b/OpenSim/Server/Handlers/BakedTextures/XBakes.cs | |||
@@ -107,11 +107,9 @@ namespace OpenSim.Server.Handlers.BakedTextures | |||
107 | File.Delete(diskFile); | 107 | File.Delete(diskFile); |
108 | 108 | ||
109 | byte[] data = utf8encoding.GetBytes(sdata); | 109 | byte[] data = utf8encoding.GetBytes(sdata); |
110 | FileStream fs = File.Create(diskFile); | ||
111 | 110 | ||
112 | fs.Write(data, 0, data.Length); | 111 | using (FileStream fs = File.Create(diskFile)) |
113 | 112 | fs.Write(data, 0, data.Length); | |
114 | fs.Close(); | ||
115 | } | 113 | } |
116 | 114 | ||
117 | private void HandleDeleteBakes(string module, string[] args) | 115 | private void HandleDeleteBakes(string module, string[] args) |
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index e8a545c..29723d8 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs | |||
@@ -317,8 +317,10 @@ namespace OpenSim.Services.GridService | |||
317 | m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); | 317 | m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); |
318 | } | 318 | } |
319 | 319 | ||
320 | m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3} with flags {4}", | 320 | m_log.DebugFormat |
321 | regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY, | 321 | ("[GRID SERVICE]: Region {0} ({1}, {2}x{3}) registered at {4},{5} with flags {6}", |
322 | regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionSizeX, regionInfos.RegionSizeY, | ||
323 | regionInfos.RegionCoordX, regionInfos.RegionCoordY, | ||
322 | (OpenSim.Framework.RegionFlags)flags); | 324 | (OpenSim.Framework.RegionFlags)flags); |
323 | 325 | ||
324 | return String.Empty; | 326 | return String.Empty; |
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index ec6118b..4705445 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs | |||
@@ -98,7 +98,12 @@ namespace OpenSim.Services.UserAccountService | |||
98 | MainConsole.Instance.Commands.AddCommand("Users", false, | 98 | MainConsole.Instance.Commands.AddCommand("Users", false, |
99 | "reset user password", | 99 | "reset user password", |
100 | "reset user password [<first> [<last> [<password>]]]", | 100 | "reset user password [<first> [<last> [<password>]]]", |
101 | "Reset a user password", HandleResetUserPassword); | 101 | "Reset a user password", HandleResetUserPassword); |
102 | |||
103 | MainConsole.Instance.Commands.AddCommand("Users", false, | ||
104 | "reset user email", | ||
105 | "reset user email [<first> [<last> [<email>]]]", | ||
106 | "Reset a user email address", HandleResetUserEmail); | ||
102 | 107 | ||
103 | MainConsole.Instance.Commands.AddCommand("Users", false, | 108 | MainConsole.Instance.Commands.AddCommand("Users", false, |
104 | "set user level", | 109 | "set user level", |
@@ -420,6 +425,43 @@ namespace OpenSim.Services.UserAccountService | |||
420 | MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName); | 425 | MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName); |
421 | } | 426 | } |
422 | 427 | ||
428 | protected void HandleResetUserEmail(string module, string[] cmdparams) | ||
429 | { | ||
430 | string firstName; | ||
431 | string lastName; | ||
432 | string newEmail; | ||
433 | |||
434 | if (cmdparams.Length < 4) | ||
435 | firstName = MainConsole.Instance.CmdPrompt("First name"); | ||
436 | else firstName = cmdparams[3]; | ||
437 | |||
438 | if (cmdparams.Length < 5) | ||
439 | lastName = MainConsole.Instance.CmdPrompt("Last name"); | ||
440 | else lastName = cmdparams[4]; | ||
441 | |||
442 | if (cmdparams.Length < 6) | ||
443 | newEmail = MainConsole.Instance.PasswdPrompt("New Email"); | ||
444 | else newEmail = cmdparams[5]; | ||
445 | |||
446 | UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); | ||
447 | if (account == null) | ||
448 | { | ||
449 | MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); | ||
450 | return; | ||
451 | } | ||
452 | |||
453 | bool success = false; | ||
454 | |||
455 | account.Email = newEmail; | ||
456 | |||
457 | success = StoreUserAccount(account); | ||
458 | if (!success) | ||
459 | MainConsole.Instance.OutputFormat("Unable to set Email for account {0} {1}.", firstName, lastName); | ||
460 | else | ||
461 | MainConsole.Instance.OutputFormat("User Email set for user {0} {1} to {2}", firstName, lastName, account.Email); | ||
462 | } | ||
463 | |||
464 | |||
423 | protected void HandleSetUserLevel(string module, string[] cmdparams) | 465 | protected void HandleSetUserLevel(string module, string[] cmdparams) |
424 | { | 466 | { |
425 | string firstName; | 467 | string firstName; |