diff options
author | Justin Clark-Casey (justincc) | 2011-08-09 03:51:34 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2011-08-09 03:51:34 +0100 |
commit | e869eeb0bfc48c769f680970f99e4c67dd5a1a70 (patch) | |
tree | 749440ee4ba12140b708e2fe68e98419710d6ea0 | |
parent | factor out common notecard caching code from 3 methods. (diff) | |
download | opensim-SC_OLD-e869eeb0bfc48c769f680970f99e4c67dd5a1a70.zip opensim-SC_OLD-e869eeb0bfc48c769f680970f99e4c67dd5a1a70.tar.gz opensim-SC_OLD-e869eeb0bfc48c769f680970f99e4c67dd5a1a70.tar.bz2 opensim-SC_OLD-e869eeb0bfc48c769f680970f99e4c67dd5a1a70.tar.xz |
Implement first draft functions for saving and loading NPC appearance from storage.
This works by serializing and deserializing NPC AvatarAppearance to a notecard in the prim inventory and making the required baked textures permanent.
By using notecards, we avoid lots of awkward, technical and user-unfriendly issues concerning retaining asset references and creating a new asset type.
Notecards also allow different appearances to be swapped and manipulated easily.
This also allows stored NPC appearances to work transparently with OARs/IARs since the UUID scan will pick up and store the necessary references from the notecard text.
This works in my basic test but is not at all ready for user use or bug reporting yet.
12 files changed, 253 insertions, 46 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 73b068d..02af5d9 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -539,7 +539,7 @@ namespace OpenSim.Framework | |||
539 | /// </summary> | 539 | /// </summary> |
540 | public void Unpack(OSDMap data) | 540 | public void Unpack(OSDMap data) |
541 | { | 541 | { |
542 | if ((data != null) && (data["serial"] != null)) | 542 | if ((data != null) && (data["serial"] != null)) |
543 | m_serial = data["serial"].AsInteger(); | 543 | m_serial = data["serial"].AsInteger(); |
544 | if ((data != null) && (data["height"] != null)) | 544 | if ((data != null) && (data["height"] != null)) |
545 | m_avatarHeight = (float)data["height"].AsReal(); | 545 | m_avatarHeight = (float)data["height"].AsReal(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index e3e3452..75d8143 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
104 | public void NewClient(IClientAPI client) | 104 | public void NewClient(IClientAPI client) |
105 | { | 105 | { |
106 | client.OnRequestWearables += SendWearables; | 106 | client.OnRequestWearables += SendWearables; |
107 | client.OnSetAppearance += SetAppearance; | 107 | client.OnSetAppearance += SetAppearanceFromClient; |
108 | client.OnAvatarNowWearing += AvatarIsWearing; | 108 | client.OnAvatarNowWearing += AvatarIsWearing; |
109 | } | 109 | } |
110 | 110 | ||
@@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
189 | /// <param name="client"></param> | 189 | /// <param name="client"></param> |
190 | /// <param name="texture"></param> | 190 | /// <param name="texture"></param> |
191 | /// <param name="visualParam"></param> | 191 | /// <param name="visualParam"></param> |
192 | public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) | 192 | public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) |
193 | { | 193 | { |
194 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | 194 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); |
195 | if (sp == null) | 195 | if (sp == null) |
@@ -257,6 +257,47 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
257 | return true; | 257 | return true; |
258 | } | 258 | } |
259 | 259 | ||
260 | public bool SaveBakedTextures(UUID agentId) | ||
261 | { | ||
262 | ScenePresence sp = m_scene.GetScenePresence(agentId); | ||
263 | |||
264 | if (sp == null || sp.IsChildAgent) | ||
265 | return false; | ||
266 | |||
267 | AvatarAppearance appearance = sp.Appearance; | ||
268 | Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures; | ||
269 | |||
270 | m_log.DebugFormat( | ||
271 | "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", | ||
272 | sp.Name, m_scene.RegionInfo.RegionName); | ||
273 | |||
274 | for (int i = 0; i < faceTextures.Length; i++) | ||
275 | { | ||
276 | // m_log.DebugFormat( | ||
277 | // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", | ||
278 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); | ||
279 | |||
280 | if (faceTextures[i] == null) | ||
281 | continue; | ||
282 | |||
283 | AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString()); | ||
284 | |||
285 | if (asset != null) | ||
286 | { | ||
287 | asset.Temporary = false; | ||
288 | m_scene.AssetService.Store(asset); | ||
289 | } | ||
290 | else | ||
291 | { | ||
292 | m_log.WarnFormat( | ||
293 | "[AV FACTORY]: Baked texture {0} for {1} in {2} unexpectedly not found when trying to save permanently", | ||
294 | faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | return true; | ||
299 | } | ||
300 | |||
260 | #region UpdateAppearanceTimer | 301 | #region UpdateAppearanceTimer |
261 | 302 | ||
262 | /// <summary> | 303 | /// <summary> |
@@ -289,25 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
289 | } | 330 | } |
290 | } | 331 | } |
291 | 332 | ||
292 | private void HandleAppearanceSend(UUID agentid) | 333 | private void SaveAppearance(UUID agentid) |
293 | { | ||
294 | ScenePresence sp = m_scene.GetScenePresence(agentid); | ||
295 | if (sp == null) | ||
296 | { | ||
297 | m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid); | ||
302 | |||
303 | // Send the appearance to everyone in the scene | ||
304 | sp.SendAppearanceToAllOtherAgents(); | ||
305 | |||
306 | // Send animations back to the avatar as well | ||
307 | sp.Animator.SendAnimPack(); | ||
308 | } | ||
309 | |||
310 | private void HandleAppearanceSave(UUID agentid) | ||
311 | { | 334 | { |
312 | // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved | 335 | // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved |
313 | // in a culture where decimal points are commas and then reloaded in a culture which just treats them as | 336 | // in a culture where decimal points are commas and then reloaded in a culture which just treats them as |
@@ -337,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
337 | { | 360 | { |
338 | if (kvp.Value < now) | 361 | if (kvp.Value < now) |
339 | { | 362 | { |
340 | Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); | 363 | Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); }); |
341 | m_sendqueue.Remove(kvp.Key); | 364 | m_sendqueue.Remove(kvp.Key); |
342 | } | 365 | } |
343 | } | 366 | } |
@@ -350,7 +373,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
350 | { | 373 | { |
351 | if (kvp.Value < now) | 374 | if (kvp.Value < now) |
352 | { | 375 | { |
353 | Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); | 376 | Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); }); |
354 | m_savequeue.Remove(kvp.Key); | 377 | m_savequeue.Remove(kvp.Key); |
355 | } | 378 | } |
356 | } | 379 | } |
@@ -427,6 +450,24 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
427 | } | 450 | } |
428 | } | 451 | } |
429 | 452 | ||
453 | public bool SendAppearance(UUID agentId) | ||
454 | { | ||
455 | ScenePresence sp = m_scene.GetScenePresence(agentId); | ||
456 | if (sp == null) | ||
457 | { | ||
458 | m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | ||
459 | return false; | ||
460 | } | ||
461 | |||
462 | // Send the appearance to everyone in the scene | ||
463 | sp.SendAppearanceToAllOtherAgents(); | ||
464 | |||
465 | // Send animations back to the avatar as well | ||
466 | sp.Animator.SendAnimPack(); | ||
467 | |||
468 | return true; | ||
469 | } | ||
470 | |||
430 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) | 471 | private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) |
431 | { | 472 | { |
432 | IInventoryService invService = m_scene.InventoryService; | 473 | IInventoryService invService = m_scene.InventoryService; |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 1bd3b6e..b831b31 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | |||
@@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
58 | for (byte i = 0; i < visualParams.Length; i++) | 58 | for (byte i = 0; i < visualParams.Length; i++) |
59 | visualParams[i] = i; | 59 | visualParams[i] = i; |
60 | 60 | ||
61 | afm.SetAppearance(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); | 61 | afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); |
62 | 62 | ||
63 | ScenePresence sp = scene.GetScenePresence(userId); | 63 | ScenePresence sp = scene.GetScenePresence(userId); |
64 | 64 | ||
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs index d0e5609..6817725 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs | |||
@@ -32,6 +32,14 @@ namespace OpenSim.Region.Framework.Interfaces | |||
32 | { | 32 | { |
33 | public interface IAvatarFactory | 33 | public interface IAvatarFactory |
34 | { | 34 | { |
35 | /// <summary> | ||
36 | /// Send the appearance of an avatar to others in the scene. | ||
37 | /// </summary> | ||
38 | /// <param name="agentId"></param> | ||
39 | /// <returns></returns> | ||
40 | bool SendAppearance(UUID agentId); | ||
41 | |||
42 | bool SaveBakedTextures(UUID agentId); | ||
35 | bool ValidateBakedTextureCache(IClientAPI client); | 43 | bool ValidateBakedTextureCache(IClientAPI client); |
36 | void QueueAppearanceSend(UUID agentid); | 44 | void QueueAppearanceSend(UUID agentid); |
37 | void QueueAppearanceSave(UUID agentid); | 45 | void QueueAppearanceSave(UUID agentid); |
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index fa8d6b6..54575ca 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenMetaverse; | 28 | using OpenMetaverse; |
29 | using OpenSim.Framework; | ||
29 | using OpenSim.Region.Framework.Scenes; | 30 | using OpenSim.Region.Framework.Scenes; |
30 | 31 | ||
31 | namespace OpenSim.Region.Framework.Interfaces | 32 | namespace OpenSim.Region.Framework.Interfaces |
@@ -44,6 +45,23 @@ namespace OpenSim.Region.Framework.Interfaces | |||
44 | UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); | 45 | UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom); |
45 | 46 | ||
46 | /// <summary> | 47 | /// <summary> |
48 | /// Check if the agent is an NPC. | ||
49 | /// </summary> | ||
50 | /// <param name="agentID"></param> | ||
51 | /// <param name="scene"></param> | ||
52 | /// <returns>True if the agent is an NPC in the given scene. False otherwise.</returns> | ||
53 | bool IsNPC(UUID agentID, Scene scene); | ||
54 | |||
55 | /// <summary> | ||
56 | /// Set the appearance for an NPC. | ||
57 | /// </summary> | ||
58 | /// <param name="agentID"></param> | ||
59 | /// <param name="appearance"></param> | ||
60 | /// <param name="scene"></param> | ||
61 | /// <returns></returns> | ||
62 | bool SetNPCAppearance(UUID agentID, AvatarAppearance appearance, Scene scene); | ||
63 | |||
64 | /// <summary> | ||
47 | /// Move an NPC to a target over time. | 65 | /// Move an NPC to a target over time. |
48 | /// </summary> | 66 | /// </summary> |
49 | /// <param name="agentID">The UUID of the NPC</param> | 67 | /// <param name="agentID">The UUID of the NPC</param> |
@@ -59,7 +77,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
59 | /// <param name="text"></param> | 77 | /// <param name="text"></param> |
60 | void Say(UUID agentID, Scene scene, string text); | 78 | void Say(UUID agentID, Scene scene, string text); |
61 | 79 | ||
62 | |||
63 | /// <summary> | 80 | /// <summary> |
64 | /// Delete an NPC. | 81 | /// Delete an NPC. |
65 | /// </summary> | 82 | /// </summary> |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 4f21d9d..d966345 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -137,6 +137,35 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | public bool IsNPC(UUID agentId, Scene scene) | ||
141 | { | ||
142 | ScenePresence sp = scene.GetScenePresence(agentId); | ||
143 | if (sp == null || sp.IsChildAgent) | ||
144 | return false; | ||
145 | |||
146 | lock (m_avatars) | ||
147 | return m_avatars.ContainsKey(agentId); | ||
148 | } | ||
149 | |||
150 | public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene) | ||
151 | { | ||
152 | ScenePresence sp = scene.GetScenePresence(agentId); | ||
153 | if (sp == null || sp.IsChildAgent) | ||
154 | return false; | ||
155 | |||
156 | lock (m_avatars) | ||
157 | if (!m_avatars.ContainsKey(agentId)) | ||
158 | return false; | ||
159 | |||
160 | AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); | ||
161 | sp.Appearance = npcAppearance; | ||
162 | |||
163 | IAvatarFactory module = scene.RequestModuleInterface<IAvatarFactory>(); | ||
164 | module.SendAppearance(sp.UUID); | ||
165 | |||
166 | return true; | ||
167 | } | ||
168 | |||
140 | public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) | 169 | public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom) |
141 | { | 170 | { |
142 | NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); | 171 | NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index a0260a5..2ec354f 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -72,7 +72,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
72 | // ScenePresence.SendInitialData() to reset our entire appearance. | 72 | // ScenePresence.SendInitialData() to reset our entire appearance. |
73 | scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); | 73 | scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); |
74 | 74 | ||
75 | afm.SetAppearance(originalClient, originalTe, null); | 75 | afm.SetAppearanceFromClient(originalClient, originalTe, null); |
76 | 76 | ||
77 | INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); | 77 | INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); |
78 | UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); | 78 | UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7c21ba9..86ee28a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -10565,9 +10565,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10565 | } | 10565 | } |
10566 | } | 10566 | } |
10567 | 10567 | ||
10568 | public static string GetLine(UUID assetID, int line, int maxLength) | 10568 | /// <summary> |
10569 | /// Get a notecard line. | ||
10570 | /// </summary> | ||
10571 | /// <param name="assetID"></param> | ||
10572 | /// <param name="line">Lines start at index 0</param> | ||
10573 | /// <returns></returns> | ||
10574 | public static string GetLine(UUID assetID, int lineNumber) | ||
10569 | { | 10575 | { |
10570 | if (line < 0) | 10576 | if (lineNumber < 0) |
10571 | return ""; | 10577 | return ""; |
10572 | 10578 | ||
10573 | string data; | 10579 | string data; |
@@ -10579,17 +10585,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10579 | { | 10585 | { |
10580 | m_Notecards[assetID].lastRef = DateTime.Now; | 10586 | m_Notecards[assetID].lastRef = DateTime.Now; |
10581 | 10587 | ||
10582 | if (line >= m_Notecards[assetID].text.Length) | 10588 | if (lineNumber >= m_Notecards[assetID].text.Length) |
10583 | return "\n\n\n"; | 10589 | return "\n\n\n"; |
10584 | 10590 | ||
10585 | data = m_Notecards[assetID].text[line]; | 10591 | data = m_Notecards[assetID].text[lineNumber]; |
10586 | if (data.Length > maxLength) | ||
10587 | data = data.Substring(0, maxLength); | ||
10588 | 10592 | ||
10589 | return data; | 10593 | return data; |
10590 | } | 10594 | } |
10591 | } | 10595 | } |
10592 | 10596 | ||
10597 | /// <summary> | ||
10598 | /// Get a notecard line. | ||
10599 | /// </summary> | ||
10600 | /// <param name="assetID"></param> | ||
10601 | /// <param name="line">Lines start at index 0</param> | ||
10602 | /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para> | ||
10603 | /// <returns></returns> | ||
10604 | public static string GetLine(UUID assetID, int lineNumber, int maxLength) | ||
10605 | { | ||
10606 | string line = GetLine(assetID, lineNumber); | ||
10607 | |||
10608 | if (line.Length > maxLength) | ||
10609 | line = line.Substring(0, maxLength); | ||
10610 | |||
10611 | return line; | ||
10612 | } | ||
10613 | |||
10593 | public static void CacheCheck() | 10614 | public static void CacheCheck() |
10594 | { | 10615 | { |
10595 | foreach (UUID key in new List<UUID>(m_Notecards.Keys)) | 10616 | foreach (UUID key in new List<UUID>(m_Notecards.Keys)) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 154179c..07b36de 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -28,11 +28,16 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.IO; | ||
32 | using System.Reflection; | ||
31 | using System.Runtime.Remoting.Lifetime; | 33 | using System.Runtime.Remoting.Lifetime; |
32 | using System.Text; | 34 | using System.Text; |
33 | using System.Net; | 35 | using System.Net; |
34 | using System.Threading; | 36 | using System.Threading; |
37 | using System.Xml; | ||
38 | using log4net; | ||
35 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | using OpenMetaverse.StructuredData; | ||
36 | using Nini.Config; | 41 | using Nini.Config; |
37 | using OpenSim; | 42 | using OpenSim; |
38 | using OpenSim.Framework; | 43 | using OpenSim.Framework; |
@@ -119,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
119 | [Serializable] | 124 | [Serializable] |
120 | public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi | 125 | public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi |
121 | { | 126 | { |
127 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
128 | |||
122 | internal IScriptEngine m_ScriptEngine; | 129 | internal IScriptEngine m_ScriptEngine; |
123 | internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there | 130 | internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there |
124 | internal SceneObjectPart m_host; | 131 | internal SceneObjectPart m_host; |
@@ -1730,26 +1737,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1730 | for (int i = 0; i < contents.Length; i++) | 1737 | for (int i = 0; i < contents.Length; i++) |
1731 | notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n")); | 1738 | notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n")); |
1732 | 1739 | ||
1733 | SaveNotecard(notecardName, notecardData.ToString()); | 1740 | SaveNotecard(notecardName, "Script generated notecard", notecardData.ToString(), false); |
1734 | } | 1741 | } |
1735 | 1742 | ||
1736 | /// <summary> | 1743 | /// <summary> |
1737 | /// Save a notecard to prim inventory. | 1744 | /// Save a notecard to prim inventory. |
1738 | /// </summary> | 1745 | /// </summary> |
1739 | /// <param name="notecardName"></param> | 1746 | /// <param name="name"></param> |
1747 | /// <param name="description">Description of notecard</param> | ||
1740 | /// <param name="notecardData"></param> | 1748 | /// <param name="notecardData"></param> |
1749 | /// <param name="forceSameName"> | ||
1750 | /// If true, then if an item exists with the same name, it is replaced. | ||
1751 | /// If false, then a new item is created witha slightly different name (e.g. name 1) | ||
1752 | /// </param> | ||
1741 | /// <returns>Prim inventory item created.</returns> | 1753 | /// <returns>Prim inventory item created.</returns> |
1742 | protected TaskInventoryItem SaveNotecard(string notecardName, string notecardData) | 1754 | protected TaskInventoryItem SaveNotecard(string name, string description, string data, bool forceSameName) |
1743 | { | 1755 | { |
1744 | // Create new asset | 1756 | // Create new asset |
1745 | AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString()); | 1757 | AssetBase asset = new AssetBase(UUID.Random(), name, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString()); |
1746 | asset.Description = "Script Generated Notecard"; | 1758 | asset.Description = description; |
1747 | 1759 | ||
1748 | int textLength = notecardData.Length; | 1760 | int textLength = data.Length; |
1749 | notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " | 1761 | data |
1750 | + textLength.ToString() + "\n" + notecardData + "}\n"; | 1762 | = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " |
1763 | + textLength.ToString() + "\n" + data + "}\n"; | ||
1751 | 1764 | ||
1752 | asset.Data = Util.UTF8.GetBytes(notecardData); | 1765 | asset.Data = Util.UTF8.GetBytes(data); |
1753 | World.AssetService.Store(asset); | 1766 | World.AssetService.Store(asset); |
1754 | 1767 | ||
1755 | // Create Task Entry | 1768 | // Create Task Entry |
@@ -1775,7 +1788,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1775 | taskItem.PermsMask = 0; | 1788 | taskItem.PermsMask = 0; |
1776 | taskItem.AssetID = asset.FullID; | 1789 | taskItem.AssetID = asset.FullID; |
1777 | 1790 | ||
1778 | m_host.Inventory.AddInventoryItem(taskItem, false); | 1791 | if (forceSameName) |
1792 | m_host.Inventory.AddInventoryItemExclusive(taskItem, false); | ||
1793 | else | ||
1794 | m_host.Inventory.AddInventoryItem(taskItem, false); | ||
1779 | 1795 | ||
1780 | return taskItem; | 1796 | return taskItem; |
1781 | } | 1797 | } |
@@ -1791,7 +1807,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1791 | StringBuilder notecardData = new StringBuilder(); | 1807 | StringBuilder notecardData = new StringBuilder(); |
1792 | 1808 | ||
1793 | for (int count = 0; count < NotecardCache.GetLines(assetID); count++) | 1809 | for (int count = 0; count < NotecardCache.GetLines(assetID); count++) |
1794 | notecardData.Append(NotecardCache.GetLine(assetID, count, 255) + "\n"); | 1810 | { |
1811 | string line = NotecardCache.GetLine(assetID, count) + "\n"; | ||
1812 | |||
1813 | // m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line); | ||
1814 | |||
1815 | notecardData.Append(line); | ||
1816 | } | ||
1795 | 1817 | ||
1796 | return notecardData.ToString(); | 1818 | return notecardData.ToString(); |
1797 | } | 1819 | } |
@@ -1807,7 +1829,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1807 | protected UUID CacheNotecard(string notecardNameOrUuid) | 1829 | protected UUID CacheNotecard(string notecardNameOrUuid) |
1808 | { | 1830 | { |
1809 | UUID assetID = UUID.Zero; | 1831 | UUID assetID = UUID.Zero; |
1810 | StringBuilder notecardData = new StringBuilder(); | ||
1811 | 1832 | ||
1812 | if (!UUID.TryParse(notecardNameOrUuid, out assetID)) | 1833 | if (!UUID.TryParse(notecardNameOrUuid, out assetID)) |
1813 | { | 1834 | { |
@@ -1864,7 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1864 | return "ERROR!"; | 1885 | return "ERROR!"; |
1865 | } | 1886 | } |
1866 | 1887 | ||
1867 | return NotecardCache.GetLine(assetID, line, 255); | 1888 | return NotecardCache.GetLine(assetID, line); |
1868 | } | 1889 | } |
1869 | 1890 | ||
1870 | /// <summary> | 1891 | /// <summary> |
@@ -2122,9 +2143,66 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2122 | 2143 | ||
2123 | return new LSL_Key(x.ToString()); | 2144 | return new LSL_Key(x.ToString()); |
2124 | } | 2145 | } |
2146 | |||
2125 | return new LSL_Key(UUID.Zero.ToString()); | 2147 | return new LSL_Key(UUID.Zero.ToString()); |
2126 | } | 2148 | } |
2127 | 2149 | ||
2150 | public LSL_Key osNpcSaveAppearance(string avatar, string notecardName) | ||
2151 | { | ||
2152 | CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); | ||
2153 | |||
2154 | INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); | ||
2155 | IAvatarFactory appearanceModule = World.RequestModuleInterface<IAvatarFactory>(); | ||
2156 | |||
2157 | if (npcModule != null && appearanceModule != null) | ||
2158 | { | ||
2159 | UUID avatarId = UUID.Zero; | ||
2160 | if (!UUID.TryParse(avatar, out avatarId)) | ||
2161 | return new LSL_Key(UUID.Zero.ToString()); | ||
2162 | |||
2163 | if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) | ||
2164 | return new LSL_Key(UUID.Zero.ToString()); | ||
2165 | |||
2166 | appearanceModule.SaveBakedTextures(avatarId); | ||
2167 | ScenePresence sp = m_host.ParentGroup.Scene.GetScenePresence(avatarId); | ||
2168 | OSDMap appearancePacked = sp.Appearance.Pack(); | ||
2169 | |||
2170 | TaskInventoryItem item | ||
2171 | = SaveNotecard(notecardName, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); | ||
2172 | |||
2173 | return new LSL_Key(item.AssetID.ToString()); | ||
2174 | } | ||
2175 | |||
2176 | return new LSL_Key(UUID.Zero.ToString()); | ||
2177 | } | ||
2178 | |||
2179 | public void osNpcLoadAppearance(string avatar, string notecardNameOrUuid) | ||
2180 | { | ||
2181 | CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); | ||
2182 | |||
2183 | INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); | ||
2184 | |||
2185 | if (npcModule != null) | ||
2186 | { | ||
2187 | UUID avatarId = UUID.Zero; | ||
2188 | if (!UUID.TryParse(avatar, out avatarId)) | ||
2189 | return; | ||
2190 | |||
2191 | if (!npcModule.IsNPC(avatarId, m_host.ParentGroup.Scene)) | ||
2192 | return; | ||
2193 | |||
2194 | string appearanceSerialized = LoadNotecard(notecardNameOrUuid); | ||
2195 | OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); | ||
2196 | // OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized); | ||
2197 | // Console.WriteLine("appearanceSerialized {0}", appearanceSerialized); | ||
2198 | // Console.WriteLine("a.Type {0}, a.ToString() {1}", a.Type, a); | ||
2199 | AvatarAppearance appearance = new AvatarAppearance(); | ||
2200 | appearance.Unpack(appearanceOsd); | ||
2201 | |||
2202 | npcModule.SetNPCAppearance(avatarId, appearance, m_host.ParentGroup.Scene); | ||
2203 | } | ||
2204 | } | ||
2205 | |||
2128 | public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) | 2206 | public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) |
2129 | { | 2207 | { |
2130 | CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); | 2208 | CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 19352f0..868af27 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | |||
@@ -170,6 +170,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
170 | 170 | ||
171 | 171 | ||
172 | key osNpcCreate(string user, string name, vector position, key cloneFrom); | 172 | key osNpcCreate(string user, string name, vector position, key cloneFrom); |
173 | LSL_Key osNpcSaveAppearance(string avatar, string notecardName); | ||
174 | void osNpcLoadAppearance(string avatar, string notecardNameOrUuid); | ||
173 | void osNpcMoveTo(key npc, vector position); | 175 | void osNpcMoveTo(key npc, vector position); |
174 | void osNpcSay(key npc, string message); | 176 | void osNpcSay(key npc, string message); |
175 | void osNpcRemove(key npc); | 177 | void osNpcRemove(key npc); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 7c59098..959b5d5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | |||
@@ -483,6 +483,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
483 | return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); | 483 | return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); |
484 | } | 484 | } |
485 | 485 | ||
486 | public key osNpcSaveAppearance(string avatar, string notecardName) | ||
487 | { | ||
488 | return m_OSSL_Functions.osNpcSaveAppearance(avatar, notecardName); | ||
489 | } | ||
490 | |||
491 | public void osNpcLoadAppearance(string avatar, string notecardNameOrUuid) | ||
492 | { | ||
493 | m_OSSL_Functions.osNpcLoadAppearance(avatar, notecardNameOrUuid); | ||
494 | } | ||
495 | |||
486 | public void osNpcMoveTo(key npc, vector position) | 496 | public void osNpcMoveTo(key npc, vector position) |
487 | { | 497 | { |
488 | m_OSSL_Functions.osNpcMoveTo(npc, position); | 498 | m_OSSL_Functions.osNpcMoveTo(npc, position); |
diff --git a/prebuild.xml b/prebuild.xml index 92368ef..9d1be3a 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -2308,6 +2308,7 @@ | |||
2308 | <Reference name="System.Xml"/> | 2308 | <Reference name="System.Xml"/> |
2309 | <Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/> | 2309 | <Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/> |
2310 | <Reference name="OpenMetaverse" path="../../../../../../bin/"/> | 2310 | <Reference name="OpenMetaverse" path="../../../../../../bin/"/> |
2311 | <Reference name="OpenMetaverse.StructuredData" path="../../../../../../bin/"/> | ||
2311 | <Reference name="OpenSim"/> | 2312 | <Reference name="OpenSim"/> |
2312 | <Reference name="OpenSim.Framework"/> | 2313 | <Reference name="OpenSim.Framework"/> |
2313 | <Reference name="OpenSim.Framework.Communications"/> | 2314 | <Reference name="OpenSim.Framework.Communications"/> |