aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie2009-10-02 19:53:42 +0100
committerMelanie2009-10-02 19:53:42 +0100
commit9eccea577716ee4331d30d519da389393b8606cd (patch)
tree2e3f1ad5892a7e1d1dc0155f1613adab8bcd2690
parentMerge branch 'master' into vehicles (diff)
parentMerge branch 'master' into diva-textures (diff)
downloadopensim-SC-9eccea577716ee4331d30d519da389393b8606cd.zip
opensim-SC-9eccea577716ee4331d30d519da389393b8606cd.tar.gz
opensim-SC-9eccea577716ee4331d30d519da389393b8606cd.tar.bz2
opensim-SC-9eccea577716ee4331d30d519da389393b8606cd.tar.xz
Merge branch 'master' into vehicles
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs11
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs4
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs12
-rw-r--r--OpenSim/Framework/BlockingQueue.cs5
-rw-r--r--OpenSim/Framework/IClientAPI.cs5
-rw-r--r--OpenSim/Framework/PacketPool.cs3
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs70
-rw-r--r--OpenSim/Framework/Tests/AgentCircuitDataTest.cs3
-rw-r--r--OpenSim/Region/Application/OpenSim.cs15
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs6
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs455
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs117
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs365
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs19
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs148
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs685
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs2
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs122
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs39
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs11
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs8
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs14
-rw-r--r--OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs80
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs4
-rw-r--r--Prebuild/AUTHORS10
-rw-r--r--Prebuild/COPYING65
-rw-r--r--Prebuild/ChangeLog461
-rw-r--r--Prebuild/INSTALL236
-rw-r--r--Prebuild/NEWS200
-rw-r--r--Prebuild/README274
-rw-r--r--Prebuild/THANKS18
-rw-r--r--Prebuild/TODO43
-rw-r--r--Prebuild/prebuild2
-rw-r--r--bin/CSJ2K.dllbin0 -> 544768 bytes
-rw-r--r--bin/OpenSim.ini.example13
-rw-r--r--bin/assets/TexturesAssetSet/TexturesAssetSet.xml7
-rw-r--r--bin/assets/TexturesAssetSet/default_avatar.jp2bin0 -> 36044 bytes
-rw-r--r--prebuild.xml64
41 files changed, 822 insertions, 2787 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 02eaf5d..e901ff6 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -826,12 +826,7 @@ namespace OpenSim.Client.MXP.ClientStack
826 OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene; 826 OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene;
827 AvatarAppearance appearance; 827 AvatarAppearance appearance;
828 scene.GetAvatarAppearance(this,out appearance); 828 scene.GetAvatarAppearance(this,out appearance);
829 List<byte> visualParams = new List<byte>(); 829 OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone());
830 foreach (byte visualParam in appearance.VisualParams)
831 {
832 visualParams.Add(visualParam);
833 }
834 OnSetAppearance(appearance.Texture.GetBytes(), visualParams);
835 } 830 }
836 831
837 public void Stop() 832 public void Stop()
@@ -1649,5 +1644,9 @@ namespace OpenSim.Client.MXP.ClientStack
1649 public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) 1644 public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled)
1650 { 1645 {
1651 } 1646 }
1647
1648 public void SendRebakeAvatarTextures(UUID textureID)
1649 {
1650 }
1652 } 1651 }
1653} 1652}
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index bfca954..8c9eb5f 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -1145,5 +1145,9 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
1145 } 1145 }
1146 1146
1147 #endregion 1147 #endregion
1148
1149 public void SendRebakeAvatarTextures(UUID textureID)
1150 {
1151 }
1148 } 1152 }
1149} 1153}
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 940ae3b..3f4214e 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -380,13 +380,13 @@ namespace OpenSim.Framework
380 /// <summary> 380 /// <summary>
381 /// Set up appearance textures and avatar parameters, including a height calculation 381 /// Set up appearance textures and avatar parameters, including a height calculation
382 /// </summary> 382 /// </summary>
383 /// <param name="texture"></param> 383 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
384 /// <param name="visualParam"></param>
385 public virtual void SetAppearance(byte[] texture, List<byte> visualParam)
386 { 384 {
387 Primitive.TextureEntry textureEnt = new Primitive.TextureEntry(texture, 0, texture.Length); 385 if (textureEntry != null)
388 m_texture = textureEnt; 386 m_texture = textureEntry;
389 m_visualparams = visualParam.ToArray(); 387 if (visualParams != null)
388 m_visualparams = visualParams;
389
390 m_avatarHeight = 1.23077f // Shortest possible avatar height 390 m_avatarHeight = 1.23077f // Shortest possible avatar height
391 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height 391 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
392 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size 392 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs
index e03229b..857930a 100644
--- a/OpenSim/Framework/BlockingQueue.cs
+++ b/OpenSim/Framework/BlockingQueue.cs
@@ -66,7 +66,9 @@ namespace OpenSim.Framework
66 if (m_pqueue.Count > 0) 66 if (m_pqueue.Count > 0)
67 return m_pqueue.Dequeue(); 67 return m_pqueue.Dequeue();
68 68
69 return m_queue.Dequeue(); 69 if (m_queue.Count > 0)
70 return m_queue.Dequeue();
71 return default(T);
70 } 72 }
71 } 73 }
72 74
@@ -119,6 +121,7 @@ namespace OpenSim.Framework
119 { 121 {
120 m_pqueue.Clear(); 122 m_pqueue.Clear();
121 m_queue.Clear(); 123 m_queue.Clear();
124 Monitor.Pulse(m_queueSync);
122 } 125 }
123 } 126 }
124 } 127 }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 4bc35e6..d3bd9e7 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Framework
65 65
66 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); 66 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
67 67
68 public delegate void SetAppearance(byte[] texture, List<byte> visualParamList); 68 public delegate void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams);
69 69
70 public delegate void StartAnim(IClientAPI remoteClient, UUID animID); 70 public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
71 71
@@ -1127,7 +1127,6 @@ namespace OpenSim.Framework
1127 1127
1128 void SetClientOption(string option, string value); 1128 void SetClientOption(string option, string value);
1129 string GetClientOption(string option); 1129 string GetClientOption(string option);
1130 void Terminate();
1131 1130
1132 void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters); 1131 void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters);
1133 void SendClearFollowCamProperties(UUID objectID); 1132 void SendClearFollowCamProperties(UUID objectID);
@@ -1175,5 +1174,7 @@ namespace OpenSim.Framework
1175 void KillEndDone(); 1174 void KillEndDone();
1176 1175
1177 bool AddGenericPacketHandler(string MethodName, GenericMessage handler); 1176 bool AddGenericPacketHandler(string MethodName, GenericMessage handler);
1177
1178 void SendRebakeAvatarTextures(UUID textureID);
1178 } 1179 }
1179} 1180}
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs
index 8075ce6..7e2860e 100644
--- a/OpenSim/Framework/PacketPool.cs
+++ b/OpenSim/Framework/PacketPool.cs
@@ -234,7 +234,8 @@ namespace OpenSim.Framework
234 234
235 lock (DataBlocks) 235 lock (DataBlocks)
236 { 236 {
237 DataBlocks[typeof(T)].Push(block); 237 if (DataBlocks[typeof(T)].Count < 50)
238 DataBlocks[typeof(T)].Push(block);
238 } 239 }
239 } 240 }
240 } 241 }
diff --git a/OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs b/OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs
deleted file mode 100644
index 2fa118d..0000000
--- a/OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs
+++ /dev/null
@@ -1,70 +0,0 @@
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
28using System;
29using System.Collections.Generic;
30using System.Text;
31using NUnit.Framework;
32using OpenSim.Tests.Common.Setup;
33
34namespace OpenSim.Framework.Servers.HttpServer.Tests
35{
36 [TestFixture]
37 public class BaseRequestHandlerTests
38 {
39 private const string BASE_PATH = "/testpath";
40
41 private class BaseRequestHandlerImpl : BaseRequestHandler
42 {
43 public BaseRequestHandlerImpl(string httpMethod, string path) : base(httpMethod, path)
44 {
45 }
46 }
47
48 [Test]
49 public void TestConstructor()
50 {
51 new BaseRequestHandlerImpl(null, null);
52 }
53
54 [Test]
55 public void TestGetParams()
56 {
57 BaseRequestHandlerImpl handler = new BaseRequestHandlerImpl(null, BASE_PATH);
58
59 BaseRequestHandlerTestHelper.BaseTestGetParams(handler, BASE_PATH);
60 }
61
62 [Test]
63 public void TestSplitParams()
64 {
65 BaseRequestHandlerImpl handler = new BaseRequestHandlerImpl(null, BASE_PATH);
66
67 BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, BASE_PATH);
68 }
69 }
70}
diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
index ecd35c0..2fda6f3 100644
--- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
+++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
@@ -227,8 +227,7 @@ namespace OpenSim.Framework.Tests
227 wearbyte.Add(VisualParams[i]); 227 wearbyte.Add(VisualParams[i]);
228 } 228 }
229 229
230 230 AvAppearance.SetAppearance(AvAppearance.Texture, (byte[])VisualParams.Clone());
231 AvAppearance.SetAppearance(AvAppearance.Texture.GetBytes(), wearbyte);
232 } 231 }
233 232
234 /// <summary> 233 /// <summary>
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index f070812..4d8409bb 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -306,10 +306,6 @@ namespace OpenSim
306 "delete-region <name>", 306 "delete-region <name>",
307 "Delete a region from disk", RunCommand); 307 "Delete a region from disk", RunCommand);
308 308
309 m_console.Commands.AddCommand("region", false, "predecode-j2k",
310 "predecode-j2k [<num threads>]>",
311 "Precache assets,decode j2k layerdata", RunCommand);
312
313 m_console.Commands.AddCommand("region", false, "modules list", 309 m_console.Commands.AddCommand("region", false, "modules list",
314 "modules list", 310 "modules list",
315 "List modules", HandleModules); 311 "List modules", HandleModules);
@@ -744,17 +740,6 @@ namespace OpenSim
744 } 740 }
745 break; 741 break;
746 742
747 case "predecode-j2k":
748 if (cmdparams.Length > 0)
749 {
750 m_sceneManager.CacheJ2kDecode(Convert.ToInt32(cmdparams[0]));
751 }
752 else
753 {
754 m_sceneManager.CacheJ2kDecode(1);
755 }
756 break;
757
758 } 743 }
759 } 744 }
760 745
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs
index 32a4ad4..31f9580 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs
@@ -34,16 +34,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
34{ 34{
35 public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); 35 public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes);
36 public delegate void PacketDrop(Packet pack, Object id); 36 public delegate void PacketDrop(Packet pack, Object id);
37 public delegate void QueueEmpty(ThrottleOutPacketType queue);
37 public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType); 38 public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType);
38 39
39 /// <summary> 40 /// <summary>
40 /// Interface to a class that handles all the activity involved with maintaining the client circuit (handling acks, 41 /// Interface to a class that handles all the activity involved with maintaining the client circuit (handling acks,
41 /// resends, pings, etc.) 42 /// resends, pings, etc.)
42 /// </summary> 43 /// </summary>
43 public interface ILLPacketHandler 44 public interface ILLPacketHandler : IDisposable
44 { 45 {
45 event PacketStats OnPacketStats; 46 event PacketStats OnPacketStats;
46 event PacketDrop OnPacketDrop; 47 event PacketDrop OnPacketDrop;
48 event QueueEmpty OnQueueEmpty;
47 SynchronizeClientHandler SynchronizeClient { set; } 49 SynchronizeClientHandler SynchronizeClient { set; }
48 50
49 int PacketsReceived { get; } 51 int PacketsReceived { get; }
@@ -70,12 +72,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
70 void OutPacket(Packet NewPack, 72 void OutPacket(Packet NewPack,
71 ThrottleOutPacketType throttlePacketType, Object id); 73 ThrottleOutPacketType throttlePacketType, Object id);
72 LLPacketQueue PacketQueue { get; } 74 LLPacketQueue PacketQueue { get; }
73 void Stop();
74 void Flush(); 75 void Flush();
75 void Clear(); 76 void Clear();
76 ClientInfo GetClientInfo(); 77 ClientInfo GetClientInfo();
77 void SetClientInfo(ClientInfo info); 78 void SetClientInfo(ClientInfo info);
78 void AddImportantPacket(PacketType type); 79 void AddImportantPacket(PacketType type);
79 void RemoveImportantPacket(PacketType type); 80 void RemoveImportantPacket(PacketType type);
81 int GetQueueCount(ThrottleOutPacketType queue);
80 } 82 }
81} 83}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index 638c765..5f549b5 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -38,40 +38,37 @@ using System.Reflection;
38namespace OpenSim.Region.ClientStack.LindenUDP 38namespace OpenSim.Region.ClientStack.LindenUDP
39{ 39{
40 /// <summary> 40 /// <summary>
41 /// We use this class to store image data and associated request data and attributes 41 /// Stores information about a current texture download and a reference to the texture asset
42 /// </summary> 42 /// </summary>
43 public class J2KImage 43 public class J2KImage
44 { 44 {
45 private const int IMAGE_PACKET_SIZE = 1000;
46 private const int FIRST_PACKET_SIZE = 600;
47
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 49
47 public double m_designatedPriorityKey; 50 public uint m_lastSequence;
48 public double m_requestedPriority = 0.0d; 51 public float m_requestedPriority;
49 public uint m_lastSequence = 0;
50 public uint m_requestedPacketNumber; 52 public uint m_requestedPacketNumber;
51 public sbyte m_requestedDiscardLevel; 53 public sbyte m_requestedDiscardLevel;
52 public UUID m_requestedUUID; 54 public UUID m_requestedUUID;
53 public IJ2KDecoder m_j2kDecodeModule; 55 public IJ2KDecoder m_j2kDecodeModule;
54 public IAssetService m_assetCache; 56 public IAssetService m_assetCache;
55 public OpenJPEG.J2KLayerInfo[] Layers = new OpenJPEG.J2KLayerInfo[0]; 57 public OpenJPEG.J2KLayerInfo[] m_layers;
56 public AssetBase m_MissingSubstitute = null; 58 public bool m_decoded;
57 public bool m_decoded = false; 59 public bool m_hasasset;
58 public bool m_completedSendAtCurrentDiscardLevel; 60 public C5.IPriorityQueueHandle<J2KImage> m_priorityQueueHandle;
59 61
60 private sbyte m_discardLevel=-1;
61 private uint m_packetNumber; 62 private uint m_packetNumber;
62 private bool m_decoderequested = false; 63 private bool m_decoderequested;
63 private bool m_hasasset = false; 64 private bool m_asset_requested;
64 private bool m_asset_requested = false; 65 private bool m_sentinfo;
65 private bool m_sentinfo = false; 66 private uint m_stopPacket;
66 private uint m_stopPacket = 0; 67 private AssetBase m_asset;
67 private const int cImagePacketSize = 1000; 68 private int m_assetDataLength;
68 private const int cFirstPacketSize = 600; 69 private LLImageManager m_imageManager;
69 private AssetBase m_asset = null; 70
70 private LLImageManager m_image; 71 #region Properties
71 public J2KImage(LLImageManager image)
72 {
73 m_image = image;
74 }
75 72
76 public uint m_pPacketNumber 73 public uint m_pPacketNumber
77 { 74 {
@@ -84,10 +81,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
84 81
85 public byte[] Data 82 public byte[] Data
86 { 83 {
87 get 84 get
88 { 85 {
89 if (m_asset != null) 86 if (m_asset != null)
90 return m_asset.Data; 87 return m_asset.Data;
91 else 88 else
92 return null; 89 return null;
93 } 90 }
@@ -97,9 +94,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
97 { 94 {
98 if (!m_decoded) 95 if (!m_decoded)
99 return 0; 96 return 0;
97
100 try 98 try
101 { 99 {
102 return (ushort)(((m_asset.Data.Length - cFirstPacketSize + cImagePacketSize - 1) / cImagePacketSize) + 1); 100 return (ushort)(((m_assetDataLength - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1);
103 } 101 }
104 catch (Exception) 102 catch (Exception)
105 { 103 {
@@ -110,119 +108,154 @@ namespace OpenSim.Region.ClientStack.LindenUDP
110 } 108 }
111 } 109 }
112 110
113 public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) 111 #endregion Properties
114 {
115 m_image.m_outstandingtextures++;
116 Layers = layers;
117 m_decoded = true;
118 RunUpdate();
119 }
120 112
121 public void AssetDataCallback(UUID AssetID, AssetBase asset) 113 public J2KImage(LLImageManager imageManager)
122 { 114 {
123 m_hasasset = true; 115 m_imageManager = imageManager;
124 if (asset == null || asset.Data == null)
125 {
126 m_asset = m_MissingSubstitute;
127 }
128 else
129 {
130 m_asset = asset;
131 }
132 RunUpdate();
133 } 116 }
134 117
135 protected void AssetReceived(string id, Object sender, AssetBase asset) 118 public bool SendPackets(LLClientView client, int maxpack)
136 { 119 {
137 UUID assetID = UUID.Zero; 120 if (m_packetNumber <= m_stopPacket)
138 if (asset != null) 121 {
139 assetID = asset.FullID; 122 bool SendMore = true;
140 123 if (!m_sentinfo || (m_packetNumber == 0))
141 AssetDataCallback(assetID, asset); 124 {
142 125 if (SendFirstPacket(client))
143 } 126 {
127 SendMore = false;
128 }
129 m_sentinfo = true;
130 m_packetNumber++;
131 }
132 // bool ignoreStop = false;
133 if (m_packetNumber < 2)
134 {
135 m_packetNumber = 2;
136 }
144 137
145 private int GetPacketForBytePosition(int bytePosition) 138 int count = 0;
146 { 139 while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket)
147 return ((bytePosition - cFirstPacketSize + cImagePacketSize - 1) / cImagePacketSize) + 1; 140 {
148 } 141 count++;
142 SendMore = SendPacket(client);
143 m_packetNumber++;
144 }
149 145
150 public int LastPacketSize() 146 if (m_packetNumber > m_stopPacket)
151 { 147 return true;
152 if (m_packetNumber == 1)
153 return m_asset.Data.Length;
154 int lastsize = (m_asset.Data.Length - cFirstPacketSize) % cImagePacketSize;
155 //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary
156 if (lastsize == 0)
157 {
158 lastsize = cImagePacketSize;
159 } 148 }
160 return lastsize;
161 }
162
163 public int CurrentBytePosition()
164 {
165 if (m_packetNumber == 0)
166 return 0;
167 if (m_packetNumber == 1)
168 return cFirstPacketSize;
169 149
170 int result = cFirstPacketSize + ((int)m_packetNumber - 2) * cImagePacketSize; 150 return false;
171 if (result < 0)
172 {
173 result = cFirstPacketSize;
174 }
175 return result;
176 } 151 }
177 152
178 public bool SendFirstPacket(LLClientView client) 153 public void RunUpdate()
179 { 154 {
180 // this means we don't have 155 //This is where we decide what we need to update
181 if (Data == null) 156 //and assign the real discardLevel and packetNumber
182 { 157 //assuming of course that the connected client might be bonkers
183 client.SendImageNotFound(m_requestedUUID); 158
184 m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is al", m_requestedUUID); 159 if (!m_hasasset)
185 return true;
186 }
187 // Do we have less then 1 packet's worth of data?
188 else if (m_asset.Data.Length <= cFirstPacketSize)
189 { 160 {
190 // Send only 1 packet 161 if (!m_asset_requested)
191 client.SendImageFirstPart(1, m_requestedUUID, (uint)m_asset.Data.Length, m_asset.Data, 2); 162 {
192 m_stopPacket = 0; 163 m_asset_requested = true;
193 return true; 164 m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived);
165 }
194 } 166 }
195 else 167 else
196 { 168 {
197 byte[] firstImageData = new byte[cFirstPacketSize]; 169 if (!m_decoded)
198 try 170 {
199 { 171 //We need to decode the requested image first
200 Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)cFirstPacketSize); 172 if (!m_decoderequested)
201 client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_asset.Data.Length, firstImageData, 2); 173 {
174 //Request decode
175 m_decoderequested = true;
176 // Do we have a jpeg decoder?
177 if (m_j2kDecodeModule != null)
178 {
179 if (Data == null)
180 {
181 J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]);
182 }
183 else
184 {
185 // Send it off to the jpeg decoder
186 m_j2kDecodeModule.BeginDecode(m_requestedUUID, Data, J2KDecodedCallback);
187 }
188
189 }
190 else
191 {
192 J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]);
193 }
194 }
202 } 195 }
203 catch (Exception) 196 else
204 { 197 {
205 m_log.Error("Texture block copy failed. Possibly out of memory?"); 198 // Check for missing image asset data
206 return true; 199 if (m_asset == null || m_asset.Data == null)
200 {
201 // FIXME:
202 m_packetNumber = m_stopPacket;
203 return;
204 }
205
206 if (m_requestedDiscardLevel >= 0 || m_stopPacket == 0)
207 {
208 int maxDiscardLevel = Math.Max(0, m_layers.Length - 1);
209
210 // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel
211 if (m_requestedDiscardLevel < 0 && m_stopPacket == 0)
212 m_requestedDiscardLevel = (sbyte)maxDiscardLevel;
213
214 // Clamp at the highest discard level
215 m_requestedDiscardLevel = (sbyte)Math.Min(m_requestedDiscardLevel, maxDiscardLevel);
216
217 //Calculate the m_stopPacket
218 if (m_layers.Length > 0)
219 {
220 m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - m_requestedDiscardLevel].End);
221 //I don't know why, but the viewer seems to expect the final packet if the file
222 //is just one packet bigger.
223 if (TexturePacketCount() == m_stopPacket + 1)
224 {
225 m_stopPacket = TexturePacketCount();
226 }
227 }
228 else
229 {
230 m_stopPacket = TexturePacketCount();
231 }
232
233 m_packetNumber = m_requestedPacketNumber;
234 }
235
236 if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0)
237 {
238 //m_log.Debug("No textures queued, sending one packet to kickstart it");
239 SendPacket(m_imageManager.Client);
240 }
207 } 241 }
208 } 242 }
209 return false;
210 } 243 }
211 244
212 private bool SendPacket(LLClientView client) 245 private bool SendPacket(LLClientView client)
213 { 246 {
214 bool complete = false; 247 bool complete = false;
215 int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : cImagePacketSize; 248 int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE;
216 249
217 try 250 try
218 { 251 {
219 if ((CurrentBytePosition() + cImagePacketSize) > m_asset.Data.Length) 252 if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_assetDataLength)
220 { 253 {
221 imagePacketSize = LastPacketSize(); 254 imagePacketSize = LastPacketSize();
222 complete=true; 255 complete = true;
223 if ((CurrentBytePosition() + imagePacketSize) > m_asset.Data.Length) 256 if ((CurrentBytePosition() + imagePacketSize) > m_assetDataLength)
224 { 257 {
225 imagePacketSize = m_asset.Data.Length - CurrentBytePosition(); 258 imagePacketSize = m_assetDataLength - CurrentBytePosition();
226 complete = true; 259 complete = true;
227 } 260 }
228 } 261 }
@@ -244,7 +277,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
244 } 277 }
245 278
246 //Send the packet 279 //Send the packet
247 client.SendImageNextPart((ushort)(m_packetNumber-1), m_requestedUUID, imageData); 280 client.SendImageNextPart((ushort)(m_packetNumber - 1), m_requestedUUID, imageData);
248 } 281 }
249 if (complete) 282 if (complete)
250 { 283 {
@@ -260,143 +293,115 @@ namespace OpenSim.Region.ClientStack.LindenUDP
260 return false; 293 return false;
261 } 294 }
262 } 295 }
263 public bool SendPackets(LLClientView client, int maxpack) 296
297 private int GetPacketForBytePosition(int bytePosition)
264 { 298 {
299 return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1;
300 }
265 301
266 if (!m_completedSendAtCurrentDiscardLevel) 302 private int LastPacketSize()
303 {
304 if (m_packetNumber == 1)
305 return m_assetDataLength;
306 int lastsize = (m_assetDataLength - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE;
307 //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary
308 if (lastsize == 0)
267 { 309 {
268 if (m_packetNumber <= m_stopPacket) 310 lastsize = IMAGE_PACKET_SIZE;
269 { 311 }
270 bool SendMore = true; 312 return lastsize;
271 if (!m_sentinfo || (m_packetNumber == 0)) 313 }
272 {
273 if (SendFirstPacket(client))
274 {
275 SendMore = false;
276 }
277 m_sentinfo = true;
278 m_packetNumber++;
279 }
280 // bool ignoreStop = false;
281 if (m_packetNumber < 2)
282 {
283 m_packetNumber = 2;
284 }
285 314
286 int count = 0; 315 private int CurrentBytePosition()
287 while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket) 316 {
288 { 317 if (m_packetNumber == 0)
289 count++; 318 return 0;
290 SendMore = SendPacket(client); 319 if (m_packetNumber == 1)
291 m_packetNumber++; 320 return FIRST_PACKET_SIZE;
292 }
293 321
294 if (m_packetNumber > m_stopPacket) 322 int result = FIRST_PACKET_SIZE + ((int)m_packetNumber - 2) * IMAGE_PACKET_SIZE;
295 { 323 if (result < 0)
296 return true; 324 {
297 } 325 result = FIRST_PACKET_SIZE;
326 }
327 return result;
328 }
329
330 private bool SendFirstPacket(LLClientView client)
331 {
332 // this means we don't have
333 if (Data == null)
334 {
335 client.SendImageNotFound(m_requestedUUID);
336 m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is also null", m_requestedUUID);
337 return true;
338 }
339 // Do we have less then 1 packet's worth of data?
340 else if (m_assetDataLength <= FIRST_PACKET_SIZE)
341 {
342 // Send only 1 packet
343 client.SendImageFirstPart(1, m_requestedUUID, (uint)m_assetDataLength, m_asset.Data, 2);
344 m_stopPacket = 0;
345 return true;
346 }
347 else
348 {
349 byte[] firstImageData = new byte[FIRST_PACKET_SIZE];
350 try
351 {
352 Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)FIRST_PACKET_SIZE);
353 client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_assetDataLength, firstImageData, 2);
354 }
355 catch (Exception)
356 {
357 m_log.Error("Texture block copy failed. Possibly out of memory?");
358 return true;
298 } 359 }
299 } 360 }
300 return false; 361 return false;
301 } 362 }
302 363
303 public void RunUpdate() 364 private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
304 { 365 {
305 //This is where we decide what we need to update 366 m_layers = layers;
306 //and assign the real discardLevel and packetNumber 367 m_decoded = true;
307 //assuming of course that the connected client might be bonkers 368 RunUpdate();
369 }
308 370
309 if (!m_hasasset) 371 private void AssetDataCallback(UUID AssetID, AssetBase asset)
310 { 372 {
373 m_hasasset = true;
311 374
312 if (!m_asset_requested) 375 if (asset == null || asset.Data == null)
376 {
377 if (m_imageManager.MissingImage != null)
313 { 378 {
314 m_asset_requested = true; 379 m_asset = m_imageManager.MissingImage;
315 m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived); 380 m_assetDataLength = m_asset.Data.Length;
316 381 }
382 else
383 {
384 m_asset = null;
385 m_decoded = true;
317 } 386 }
318
319 } 387 }
320 else 388 else
321 { 389 {
390 m_asset = asset;
391 m_assetDataLength = m_asset.Data.Length;
392 }
322 393
394 RunUpdate();
395 }
323 396
324 if (!m_decoded) 397 private void AssetReceived(string id, Object sender, AssetBase asset)
325 { 398 {
326 //We need to decode the requested image first 399 UUID assetID = UUID.Zero;
327 if (!m_decoderequested) 400 if (asset != null)
328 { 401 assetID = asset.FullID;
329 //Request decode
330 m_decoderequested = true;
331 // Do we have a jpeg decoder?
332 if (m_j2kDecodeModule != null)
333 {
334 if (Data == null)
335 {
336 J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]);
337 }
338 // Send it off to the jpeg decoder
339 m_j2kDecodeModule.decode(m_requestedUUID, Data, J2KDecodedCallback);
340
341 }
342 else
343 {
344 J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]);
345 }
346 }
347
348 }
349 else
350 {
351 //discardLevel of -1 means just update the priority
352 if (m_requestedDiscardLevel != -1)
353 {
354 //Evaluate the discard level
355 //First, is it positive?
356 if (m_requestedDiscardLevel >= 0)
357 {
358 if (m_requestedDiscardLevel > Layers.Length - 1)
359 {
360 m_discardLevel = (sbyte)(Layers.Length - 1);
361 }
362 else
363 {
364 m_discardLevel = m_requestedDiscardLevel;
365 }
366 402
367 //Calculate the m_stopPacket 403 AssetDataCallback(assetID, asset);
368 if (Layers.Length > 0)
369 {
370 m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - m_discardLevel].End);
371 //I don't know why, but the viewer seems to expect the final packet if the file
372 //is just one packet bigger.
373 if (TexturePacketCount() == m_stopPacket + 1)
374 {
375 m_stopPacket = TexturePacketCount();
376 }
377 }
378 else
379 {
380 m_stopPacket = TexturePacketCount();
381 }
382 //Don't reset packet number unless we're waiting or it's ahead of us
383 if (m_completedSendAtCurrentDiscardLevel || m_requestedPacketNumber>m_packetNumber)
384 {
385 m_packetNumber = m_requestedPacketNumber;
386 }
387 404
388 if (m_packetNumber <= m_stopPacket)
389 {
390 m_completedSendAtCurrentDiscardLevel = false;
391 }
392 }
393 }
394 else
395 {
396 m_packetNumber = m_stopPacket;
397 }
398 }
399 }
400 } 405 }
401 } 406 }
402} 407}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 88ace6a..3b43771 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -81,8 +81,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
81 private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = 81 private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates =
82 new List<ObjectUpdatePacket.ObjectDataBlock>(); 82 new List<ObjectUpdatePacket.ObjectDataBlock>();
83 83
84 private Timer m_textureRequestTimer;
85
86 private bool m_clientBlocked; 84 private bool m_clientBlocked;
87 85
88 private int m_probesWithNoIngressPackets; 86 private int m_probesWithNoIngressPackets;
@@ -143,9 +141,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
143 protected int m_primTerseUpdateRate = 10; 141 protected int m_primTerseUpdateRate = 10;
144 protected int m_primFullUpdateRate = 14; 142 protected int m_primFullUpdateRate = 14;
145 143
146 protected int m_textureRequestRate = 100; 144 protected int m_textureSendLimit = 20;
147 protected int m_textureSendLimit = 10; 145 protected int m_textureDataLimit = 10;
148 protected int m_textureDataLimit = 5;
149 146
150 protected int m_packetMTU = 1400; 147 protected int m_packetMTU = 1400;
151 148
@@ -534,6 +531,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
534 m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); 531 m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings);
535 m_PacketHandler.SynchronizeClient = SynchronizeClient; 532 m_PacketHandler.SynchronizeClient = SynchronizeClient;
536 m_PacketHandler.OnPacketStats += PopulateStats; 533 m_PacketHandler.OnPacketStats += PopulateStats;
534 m_PacketHandler.OnQueueEmpty += HandleQueueEmpty;
537 535
538 if (scene.Config != null) 536 if (scene.Config != null)
539 { 537 {
@@ -555,9 +553,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
555 m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", 553 m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate",
556 m_primFullUpdateRate); 554 m_primFullUpdateRate);
557 555
558 m_textureRequestRate = clientConfig.GetInt("TextureRequestRate",
559 m_textureRequestRate);
560
561 m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", 556 m_textureSendLimit = clientConfig.GetInt("TextureSendLimit",
562 m_textureSendLimit); 557 m_textureSendLimit);
563 558
@@ -607,9 +602,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
607 if (m_primFullUpdateTimer.Enabled) 602 if (m_primFullUpdateTimer.Enabled)
608 lock (m_primFullUpdateTimer) 603 lock (m_primFullUpdateTimer)
609 m_primFullUpdateTimer.Stop(); 604 m_primFullUpdateTimer.Stop();
610 if (m_textureRequestTimer.Enabled)
611 lock (m_textureRequestTimer)
612 m_textureRequestTimer.Stop();
613 605
614 // This is just to give the client a reasonable chance of 606 // This is just to give the client a reasonable chance of
615 // flushing out all it's packets. There should probably 607 // flushing out all it's packets. There should probably
@@ -633,6 +625,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
633 // of the client thread regardless of where Close() is called. 625 // of the client thread regardless of where Close() is called.
634 KillEndDone(); 626 KillEndDone();
635 } 627 }
628
629 Terminate();
636 } 630 }
637 631
638 /// <summary> 632 /// <summary>
@@ -704,10 +698,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 if (m_primFullUpdateTimer.Enabled) 698 if (m_primFullUpdateTimer.Enabled)
705 lock (m_primFullUpdateTimer) 699 lock (m_primFullUpdateTimer)
706 m_primFullUpdateTimer.Stop(); 700 m_primFullUpdateTimer.Stop();
707
708 if (m_textureRequestTimer.Enabled)
709 lock (m_textureRequestTimer)
710 m_textureRequestTimer.Stop();
711 } 701 }
712 702
713 public void Restart() 703 public void Restart()
@@ -730,23 +720,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
730 m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); 720 m_primFullUpdateTimer = new Timer(m_primFullUpdateRate);
731 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); 721 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates);
732 m_primFullUpdateTimer.AutoReset = false; 722 m_primFullUpdateTimer.AutoReset = false;
733
734 m_textureRequestTimer = new Timer(m_textureRequestRate);
735 m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests);
736 m_textureRequestTimer.AutoReset = false;
737
738 } 723 }
739 724
740 public void Terminate() 725 private void Terminate()
741 { 726 {
727 IsActive = false;
728
729 m_clientPingTimer.Close();
730 m_avatarTerseUpdateTimer.Close();
731 m_primTerseUpdateTimer.Close();
732 m_primFullUpdateTimer.Close();
733
742 m_PacketHandler.OnPacketStats -= PopulateStats; 734 m_PacketHandler.OnPacketStats -= PopulateStats;
743 m_PacketHandler.Stop(); 735 m_PacketHandler.Dispose();
744 736
745 // wait for thread stoped 737 // wait for thread stoped
746 m_clientThread.Join(); 738 // m_clientThread.Join();
747 739
748 // delete circuit code 740 // delete circuit code
749 m_networkServer.CloseClient(this); 741 //m_networkServer.CloseClient(this);
750 } 742 }
751 743
752 #endregion 744 #endregion
@@ -876,6 +868,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
876 while (IsActive) 868 while (IsActive)
877 { 869 {
878 LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); 870 LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue();
871
872 if (nextPacket == null) {
873 m_log.DebugFormat("[CLIENT]: PacketQueue return null LLQueItem");
874 continue;
875 }
879 876
880 if (nextPacket.Incoming) 877 if (nextPacket.Incoming)
881 { 878 {
@@ -967,10 +964,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
967 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); 964 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates);
968 m_primFullUpdateTimer.AutoReset = false; 965 m_primFullUpdateTimer.AutoReset = false;
969 966
970 m_textureRequestTimer = new Timer(m_textureRequestRate);
971 m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests);
972 m_textureRequestTimer.AutoReset = false;
973
974 m_scene.AddNewClient(this); 967 m_scene.AddNewClient(this);
975 968
976 RefreshGroupMembership(); 969 RefreshGroupMembership();
@@ -1042,26 +1035,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1042 } 1035 }
1043 } 1036 }
1044 1037
1045 protected virtual void TextureRequestHandler()
1046 {
1047 m_log.DebugFormat("[TRH] Thread started");
1048 while (m_imageManager != null)
1049 {
1050 try
1051 {
1052 while (m_imageManager != null)
1053 {
1054 }
1055 }
1056 catch (Exception e)
1057 {
1058 m_log.WarnFormat("[TRH] Exception in handler loop: {0}", e.Message);
1059 m_log.Debug(e);
1060 }
1061 }
1062 m_log.DebugFormat("[TRH] Thread terminated");
1063 }
1064
1065 # endregion 1038 # endregion
1066 1039
1067 // Previously ClientView.API partial class 1040 // Previously ClientView.API partial class
@@ -3161,22 +3134,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3161 } 3134 }
3162 } 3135 }
3163 3136
3164 // Unlike the other timers, this one is only started after 3137 void HandleQueueEmpty(ThrottleOutPacketType queue)
3165 // the first request is seen.
3166
3167 void ProcessTextureRequests(object sender, ElapsedEventArgs e)
3168 { 3138 {
3169 if (m_imageManager != null) 3139 switch (queue)
3170 { 3140 {
3171 if (m_imageManager.ProcessImageQueue(m_textureSendLimit, 3141 case ThrottleOutPacketType.Texture:
3172 m_textureDataLimit)) 3142 ProcessTextureRequests();
3173 { 3143 break;
3174 lock (m_textureRequestTimer)
3175 m_textureRequestTimer.Start();
3176 }
3177 } 3144 }
3178 } 3145 }
3179 3146
3147 void ProcessTextureRequests()
3148 {
3149 if (m_imageManager != null)
3150 m_imageManager.ProcessImageQueue(m_textureSendLimit, m_textureDataLimit);
3151 }
3152
3180 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) 3153 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e)
3181 { 3154 {
3182 lock (m_primFullUpdates) 3155 lock (m_primFullUpdates)
@@ -5275,13 +5248,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5275 // for the client session anyway, in order to protect ourselves against bad code in plugins 5248 // for the client session anyway, in order to protect ourselves against bad code in plugins
5276 try 5249 try
5277 { 5250 {
5278 List<byte> visualparams = new List<byte>(); 5251 byte[] visualparams = new byte[appear.VisualParam.Length];
5279 foreach (AgentSetAppearancePacket.VisualParamBlock x in appear.VisualParam) 5252 for (int i = 0; i < appear.VisualParam.Length; i++)
5280 { 5253 visualparams[i] = appear.VisualParam[i].ParamValue;
5281 visualparams.Add(x.ParamValue);
5282 }
5283 5254
5284 handlerSetAppearance(appear.ObjectData.TextureEntry, visualparams); 5255 Primitive.TextureEntry te = null;
5256 if (appear.ObjectData.TextureEntry.Length > 1)
5257 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
5258
5259 handlerSetAppearance(te, visualparams);
5285 } 5260 }
5286 catch (Exception e) 5261 catch (Exception e)
5287 { 5262 {
@@ -6624,8 +6599,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6624 if (m_imageManager != null) 6599 if (m_imageManager != null)
6625 { 6600 {
6626 m_imageManager.EnqueueReq(args); 6601 m_imageManager.EnqueueReq(args);
6627 lock (m_textureRequestTimer)
6628 m_textureRequestTimer.Start();
6629 } 6602 }
6630 } 6603 }
6631 } 6604 }
@@ -11026,5 +10999,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11026 } 10999 }
11027 11000
11028 #endregion 11001 #endregion
11002
11003 public void SendRebakeAvatarTextures(UUID textureID)
11004 {
11005 RebakeAvatarTexturesPacket pack =
11006 (RebakeAvatarTexturesPacket)PacketPool.Instance.GetPacket(PacketType.RebakeAvatarTextures);
11007
11008 pack.TextureData = new RebakeAvatarTexturesPacket.TextureDataBlock();
11009 pack.TextureData.TextureID = textureID;
11010 OutPacket(pack, ThrottleOutPacketType.Task);
11011 }
11029 } 11012 }
11030} 11013}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index 295a5e6..a484fdf 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -27,58 +27,60 @@
27 27
28using System; 28using System;
29using System.Threading; 29using System.Threading;
30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Reflection;
31using OpenMetaverse; 33using OpenMetaverse;
32using OpenMetaverse.Imaging; 34using OpenMetaverse.Imaging;
33using OpenSim.Framework; 35using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
36using log4net; 38using log4net;
37using System.Reflection;
38 39
39namespace OpenSim.Region.ClientStack.LindenUDP 40namespace OpenSim.Region.ClientStack.LindenUDP
40{ 41{
41
42 public class LLImageManager 42 public class LLImageManager
43 { 43 {
44 44 private sealed class J2KImageComparer : IComparer<J2KImage>
45 //Public interfaces: 45 {
46 //Constructor - (LLClientView, IAssetCache, IJ2KDecoder); 46 public int Compare(J2KImage x, J2KImage y)
47 //void EnqueueReq - (TextureRequestArgs) 47 {
48 //ProcessImageQueue 48 return x.m_requestedPriority.CompareTo(y.m_requestedPriority);
49 //Close 49 }
50 }
51
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private bool m_shuttingdown = false; 53 private bool m_shuttingdown = false;
52 private long m_lastloopprocessed = 0; 54 private long m_lastloopprocessed = 0;
55 private AssetBase m_missingImage = null;
53 56
54 private LLClientView m_client; //Client we're assigned to 57 private LLClientView m_client; //Client we're assigned to
55 private IAssetService m_assetCache; //Asset Cache 58 private IAssetService m_assetCache; //Asset Cache
56 private IJ2KDecoder m_j2kDecodeModule; //Our J2K module 59 private IJ2KDecoder m_j2kDecodeModule; //Our J2K module
60 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
57 61
58 private readonly AssetBase m_missingsubstitute; //Sustitute for bad decodes
59 private Dictionary<UUID,J2KImage> m_imagestore; // Our main image storage dictionary
60 private SortedList<double,UUID> m_priorities; // For fast image lookup based on priority
61 private Dictionary<int, int> m_priorityresolver; //Enabling super fast assignment of images with the same priorities
62
63 private const double doubleMinimum = .0000001;
64
65 public int m_outstandingtextures = 0;
66 //Constructor
67 public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) 62 public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
68 { 63 {
69
70 m_imagestore = new Dictionary<UUID,J2KImage>();
71 m_priorities = new SortedList<double,UUID>();
72 m_priorityresolver = new Dictionary<int, int>();
73 m_client = client; 64 m_client = client;
74 m_assetCache = pAssetCache; 65 m_assetCache = pAssetCache;
75 if (pAssetCache != null) 66 if (pAssetCache != null)
76 m_missingsubstitute = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f"); 67 m_missingImage = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f");
77 else 68 else
78 m_log.Error("[ClientView] - couldn't set missing image, all manner of things will probably break"); 69 m_log.Error("[ClientView] - couldn't set missing image asset, falling back to missing image packet. This is known to crash the client");
70
79 m_j2kDecodeModule = pJ2kDecodeModule; 71 m_j2kDecodeModule = pJ2kDecodeModule;
80 } 72 }
81 73
74 public LLClientView Client
75 {
76 get { return m_client; }
77 }
78
79 public AssetBase MissingImage
80 {
81 get { return m_missingImage; }
82 }
83
82 public void EnqueueReq(TextureRequestArgs newRequest) 84 public void EnqueueReq(TextureRequestArgs newRequest)
83 { 85 {
84 //newRequest is the properties of our new texture fetch request. 86 //newRequest is the properties of our new texture fetch request.
@@ -88,234 +90,203 @@ namespace OpenSim.Region.ClientStack.LindenUDP
88 //Make sure we're not shutting down.. 90 //Make sure we're not shutting down..
89 if (!m_shuttingdown) 91 if (!m_shuttingdown)
90 { 92 {
93 J2KImage imgrequest;
91 94
92 //Do we already know about this UUID? 95 // Do a linear search for this texture download
93 if (m_imagestore.ContainsKey(newRequest.RequestedAssetID)) 96 lock (m_priorityQueue)
94 { 97 m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest);
95 //Check the packet sequence to make sure this isn't older than
96 //one we've already received
97
98 J2KImage imgrequest = m_imagestore[newRequest.RequestedAssetID];
99
100 // This is the inbound request sequence number. We can ignore
101 // "old" ones.
102 98
103 if (newRequest.requestSequence > imgrequest.m_lastSequence) 99 if (imgrequest != null)
100 {
101 if (newRequest.DiscardLevel == -1 && newRequest.Priority == 0f)
104 { 102 {
103 //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
105 104
106 imgrequest.m_lastSequence = newRequest.requestSequence; 105 try
107
108 //Check the priority
109
110 double priority = imgrequest.m_requestedPriority;
111 if (priority != newRequest.Priority)
112 { 106 {
113 //Remove the old priority 107 lock (m_priorityQueue)
114 m_priorities.Remove(imgrequest.m_designatedPriorityKey); 108 m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle);
115 //Assign a new unique priority
116 imgrequest.m_requestedPriority = newRequest.Priority;
117 imgrequest.m_designatedPriorityKey = AssignPriority(newRequest.RequestedAssetID, newRequest.Priority);
118 } 109 }
110 catch (Exception) { }
111 }
112 else
113 {
114 //m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
115 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
119 116
120 //Update the requested discard level 117 //Check the packet sequence to make sure this isn't older than
121 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; 118 //one we've already received
119 if (newRequest.requestSequence > imgrequest.m_lastSequence)
120 {
121 //Update the sequence number of the last RequestImage packet
122 imgrequest.m_lastSequence = newRequest.requestSequence;
122 123
123 //Update the requested packet number 124 //Update the requested discard level
124 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; 125 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel;
125 126
126 //Check if this will create an outstanding texture request 127 //Update the requested packet number
127 bool activated = imgrequest.m_completedSendAtCurrentDiscardLevel; 128 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber;
128 //Run an update
129 129
130 imgrequest.RunUpdate(); 130 //Update the requested priority
131 imgrequest.m_requestedPriority = newRequest.Priority;
132 try
133 {
134 lock (m_priorityQueue)
135 m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest);
136 }
137 catch (Exception)
138 {
139 imgrequest.m_priorityQueueHandle = null;
140 lock (m_priorityQueue)
141 m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);
142 }
131 143
132 if (activated && !imgrequest.m_completedSendAtCurrentDiscardLevel && imgrequest.m_decoded) 144 //Run an update
133 { 145 imgrequest.RunUpdate();
134 Interlocked.Increment(ref m_outstandingtextures);
135 } 146 }
136 } 147 }
137 } 148 }
138 else 149 else
139 { 150 {
140 J2KImage imgrequest = new J2KImage(this); 151 if (newRequest.DiscardLevel == -1 && newRequest.Priority == 0f)
141 152 {
142 //Assign our missing substitute 153 //m_log.DebugFormat("[TEX]: (IGN) ID={0}: D={1}, S={2}, P={3}",
143 imgrequest.m_MissingSubstitute = m_missingsubstitute; 154 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
155 }
156 else
157 {
158 //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
159 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
144 160
145 //Assign our decoder module 161 imgrequest = new J2KImage(this);
146 imgrequest.m_j2kDecodeModule = m_j2kDecodeModule;
147 162
148 //Assign our asset cache module 163 //Assign our decoder module
149 imgrequest.m_assetCache = m_assetCache; 164 imgrequest.m_j2kDecodeModule = m_j2kDecodeModule;
150 165
151 //Assign a priority based on our request 166 //Assign our asset cache module
152 imgrequest.m_designatedPriorityKey = AssignPriority(newRequest.RequestedAssetID, newRequest.Priority); 167 imgrequest.m_assetCache = m_assetCache;
153 168
154 //Assign the requested discard level 169 //Assign the requested discard level
155 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; 170 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel;
156 171
157 //Assign the requested packet number 172 //Assign the requested packet number
158 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; 173 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber;
159 174
160 //Assign the requested priority 175 //Assign the requested priority
161 imgrequest.m_requestedPriority = newRequest.Priority; 176 imgrequest.m_requestedPriority = newRequest.Priority;
162 177
163 //Assign the asset uuid 178 //Assign the asset uuid
164 imgrequest.m_requestedUUID = newRequest.RequestedAssetID; 179 imgrequest.m_requestedUUID = newRequest.RequestedAssetID;
165 180
166 m_imagestore.Add(imgrequest.m_requestedUUID, imgrequest); 181 //Assign the requested priority
182 imgrequest.m_requestedPriority = newRequest.Priority;
167 183
168 //Run an update 184 //Add this download to the priority queue
169 imgrequest.RunUpdate(); 185 lock (m_priorityQueue)
186 m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);
170 187
188 //Run an update
189 imgrequest.RunUpdate();
190 }
171 } 191 }
172 } 192 }
173 } 193 }
174 194
175 private double AssignPriority(UUID pAssetID, double pPriority) 195 public bool ProcessImageQueue(int count, int maxpack)
176 { 196 {
177 197 lock (this)
178 //First, find out if we can just assign directly
179 if (m_priorityresolver.ContainsKey((int)pPriority) == false)
180 { 198 {
181 m_priorities.Add((double)((int)pPriority), pAssetID); 199 //count is the number of textures we want to process in one go.
182 m_priorityresolver.Add((int)pPriority, 0); 200 //As part of this class re-write, that number will probably rise
183 return (double)((int)pPriority); 201 //since we're processing in a more efficient manner.
184 }
185 else
186 {
187 //Use the hash lookup goodness of a secondary dictionary to find a free slot
188 double mFreePriority = ((int)pPriority) + (doubleMinimum * (m_priorityresolver[(int)pPriority] + 1));
189 m_priorities[mFreePriority] = pAssetID;
190 m_priorityresolver[(int)pPriority]++;
191 return mFreePriority;
192 }
193 202
203 // this can happen during Close()
204 if (m_client == null)
205 return false;
194 206
207 int numCollected = 0;
195 208
196 } 209 //Calculate our threshold
210 int threshold;
211 if (m_lastloopprocessed == 0)
212 {
213 if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null)
214 return false;
215 //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below
216 threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300;
217 m_lastloopprocessed = DateTime.Now.Ticks;
218 }
219 else
220 {
221 double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond;
222 throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current;
197 223
198 public bool ProcessImageQueue(int count, int maxpack) 224 //Average of 1000 bytes per packet
199 { 225 throttleseconds = throttleseconds / 1000;
226
227 //Safe-zone multiplier of 2.0
228 threshold = (int)(throttleseconds * 2.0);
229 m_lastloopprocessed = DateTime.Now.Ticks;
230
231 }
232
233 if (m_client.PacketHandler == null)
234 return false;
200 235
201 // this can happen during Close() 236 if (m_client.PacketHandler.PacketQueue == null)
202 if (m_client == null) 237 return false;
203 return false; 238
204 239 if (threshold < 10)
205 //Count is the number of textures we want to process in one go. 240 threshold = 10;
206 //As part of this class re-write, that number will probably rise 241
207 //since we're processing in a more efficient manner. 242 //Uncomment this to see what the texture stack is doing
208 243 //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.getQueueCount(ThrottleOutPacketType.Texture).ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString());
209 int numCollected = 0; 244 if (true) //m_client.PacketHandler.PacketQueue.GetQueueCount(ThrottleOutPacketType.Texture) < threshold)
210
211 //Calculate our threshold
212 int threshold;
213 if (m_lastloopprocessed == 0)
214 {
215 if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null)
216 return false;
217 //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below
218 threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300;
219 m_lastloopprocessed = DateTime.Now.Ticks;
220 }
221 else
222 {
223 double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond;
224 throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current;
225
226 //Average of 1000 bytes per packet
227 throttleseconds = throttleseconds / 1000;
228
229 //Safe-zone multiplier of 2.0
230 threshold = (int)(throttleseconds * 2.0);
231 m_lastloopprocessed = DateTime.Now.Ticks;
232
233 }
234
235 if (threshold < 10)
236 {
237 threshold = 10;
238 }
239
240 if (m_client.PacketHandler == null)
241 return false;
242
243 if (m_client.PacketHandler.PacketQueue == null)
244 return false;
245
246 //First of all make sure our packet queue isn't above our threshold
247
248 //Uncomment this to see what the texture stack is doing
249 //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount.ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString());
250 if (m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount < threshold && m_outstandingtextures > 0)
251 {
252 bool justreset = false;
253
254 for (int x = m_priorities.Count - 1; x > -1; x--)
255 { 245 {
256 246 while (m_priorityQueue.Count > 0)
257 J2KImage imagereq = m_imagestore[m_priorities.Values[x]];
258 if (imagereq.m_decoded == true && !imagereq.m_completedSendAtCurrentDiscardLevel)
259 { 247 {
260 numCollected++; 248 J2KImage imagereq = null;
261 //SendPackets will send up to ten packets per cycle 249 lock (m_priorityQueue)
262 if (imagereq.SendPackets(m_client, maxpack)) 250 imagereq = m_priorityQueue.FindMax();
251
252 if (imagereq.m_decoded == true)
263 { 253 {
264 //Send complete 254 // we need to test this here now that we are dropping assets
265 if (!imagereq.m_completedSendAtCurrentDiscardLevel) 255 if (!imagereq.m_hasasset)
266 { 256 {
267 imagereq.m_completedSendAtCurrentDiscardLevel = true; 257 m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.m_requestedUUID);
268 Interlocked.Decrement(ref m_outstandingtextures); 258 imagereq.RunUpdate();
269 //Re-assign priority to bottom 259 continue;
270 //Remove the old priority 260 }
271 m_priorities.Remove(imagereq.m_designatedPriorityKey); 261
272 int lowest; 262 ++numCollected;
273 if (m_priorities.Count > 0) 263
274 { 264 //SendPackets will send up to ten packets per cycle
275 lowest = (int)m_priorities.Keys[0]; 265 if (imagereq.SendPackets(m_client, maxpack))
276 lowest--; 266 {
277 } 267 // Send complete. Destroy any knowledge of this transfer
278 else 268 try
279 { 269 {
280 lowest = -10000; 270 lock (m_priorityQueue)
281 } 271 m_priorityQueue.Delete(imagereq.m_priorityQueueHandle);
282 m_priorities.Add((double)lowest, imagereq.m_requestedUUID);
283 imagereq.m_designatedPriorityKey = (double)lowest;
284 if (m_priorityresolver.ContainsKey((int)lowest))
285 {
286 m_priorityresolver[(int)lowest]++;
287 }
288 else
289 {
290 m_priorityresolver.Add((int)lowest, 0);
291 } 272 }
273 catch (Exception) { }
292 } 274 }
293 } 275 }
276
294 if (numCollected == count) 277 if (numCollected == count)
295 {
296 break; 278 break;
297 }
298 }
299 if (numCollected == count || m_outstandingtextures == 0)
300 break;
301 if (numCollected % m_outstandingtextures == 0 && !justreset)
302 {
303 //We've gotten as much as we can from the stack,
304 //reset to the top so that we can send MOAR DATA (nomnomnom)!
305 x = m_priorities.Count - 1;
306
307 justreset = true; //prevents us from getting stuck in a loop
308 } 279 }
309 } 280 }
310 }
311 281
312 return m_outstandingtextures != 0; 282 return m_priorityQueue.Count > 0;
283 }
313 } 284 }
314 285
315 //Faux destructor 286 //Faux destructor
316 public void Close() 287 public void Close()
317 { 288 {
318 289
319 m_shuttingdown = true; 290 m_shuttingdown = true;
320 m_j2kDecodeModule = null; 291 m_j2kDecodeModule = null;
321 m_assetCache = null; 292 m_assetCache = null;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
index eaf8f60..e98a360 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
129 // 129 //
130 public event PacketStats OnPacketStats; 130 public event PacketStats OnPacketStats;
131 public event PacketDrop OnPacketDrop; 131 public event PacketDrop OnPacketDrop;
132 public event QueueEmpty OnQueueEmpty;
132 133
133 134
134 //private SynchronizeClientHandler m_SynchronizeClient = null; 135 //private SynchronizeClientHandler m_SynchronizeClient = null;
@@ -172,13 +173,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
172 173
173 m_PacketQueue = new LLPacketQueue(client.AgentId, userSettings); 174 m_PacketQueue = new LLPacketQueue(client.AgentId, userSettings);
174 175
176 m_PacketQueue.OnQueueEmpty += TriggerOnQueueEmpty;
177
175 m_AckTimer.Elapsed += AckTimerElapsed; 178 m_AckTimer.Elapsed += AckTimerElapsed;
176 m_AckTimer.Start(); 179 m_AckTimer.Start();
177 } 180 }
178 181
179 public void Stop() 182 public void Dispose()
180 { 183 {
181 m_AckTimer.Stop(); 184 m_AckTimer.Stop();
185 m_AckTimer.Close();
182 186
183 m_PacketQueue.Enqueue(null); 187 m_PacketQueue.Enqueue(null);
184 m_PacketQueue.Close(); 188 m_PacketQueue.Close();
@@ -768,6 +772,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
768 handlerPacketDrop(packet, id); 772 handlerPacketDrop(packet, id);
769 } 773 }
770 774
775 private void TriggerOnQueueEmpty(ThrottleOutPacketType queue)
776 {
777 QueueEmpty handlerQueueEmpty = OnQueueEmpty;
778
779 if (handlerQueueEmpty != null)
780 handlerQueueEmpty(queue);
781 }
782
771 // Convert the packet to bytes and stuff it onto the send queue 783 // Convert the packet to bytes and stuff it onto the send queue
772 // 784 //
773 public void ProcessOutPacket(LLQueItem item) 785 public void ProcessOutPacket(LLQueItem item)
@@ -849,5 +861,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
849 m_PacketQueue.Close(); 861 m_PacketQueue.Close();
850 Thread.CurrentThread.Abort(); 862 Thread.CurrentThread.Abort();
851 } 863 }
864
865 public int GetQueueCount(ThrottleOutPacketType queue)
866 {
867 return m_PacketQueue.GetQueueCount(queue);
868 }
852 } 869 }
853} 870}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
index c427870..3eed2e0 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs
@@ -39,7 +39,7 @@ using Timer=System.Timers.Timer;
39 39
40namespace OpenSim.Region.ClientStack.LindenUDP 40namespace OpenSim.Region.ClientStack.LindenUDP
41{ 41{
42 public class LLPacketQueue : IPullStatsProvider 42 public class LLPacketQueue : IPullStatsProvider, IDisposable
43 { 43 {
44 private static readonly ILog m_log 44 private static readonly ILog m_log
45 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -62,6 +62,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
62 private Queue<LLQueItem> TextureOutgoingPacketQueue; 62 private Queue<LLQueItem> TextureOutgoingPacketQueue;
63 private Queue<LLQueItem> AssetOutgoingPacketQueue; 63 private Queue<LLQueItem> AssetOutgoingPacketQueue;
64 64
65 private List<ThrottleOutPacketType> Empty = new List<ThrottleOutPacketType>();
66 // m_log.Info("[THROTTLE]: Entering Throttle");
65 // private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); 67 // private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
66 // private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); 68 // private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
67 69
@@ -85,26 +87,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
85 87
86 private Dictionary<uint,int> contents = new Dictionary<uint, int>(); 88 private Dictionary<uint,int> contents = new Dictionary<uint, int>();
87 89
88 /// <summary>
89 /// The number of packets in the OutgoingPacketQueue
90 ///
91 /// </summary>
92 internal int TextureOutgoingPacketQueueCount
93 {
94 get
95 {
96 if (TextureOutgoingPacketQueue == null)
97 return 0;
98 return TextureOutgoingPacketQueue.Count;
99 }
100 }
101
102 // private long LastThrottle; 90 // private long LastThrottle;
103 // private long ThrottleInterval; 91 // private long ThrottleInterval;
104 private Timer throttleTimer; 92 private Timer throttleTimer;
105 93
106 private UUID m_agentId; 94 private UUID m_agentId;
107 95
96 public event QueueEmpty OnQueueEmpty;
97
108 public LLPacketQueue(UUID agentId, ClientStackUserSettings userSettings) 98 public LLPacketQueue(UUID agentId, ClientStackUserSettings userSettings)
109 { 99 {
110 // While working on this, the BlockingQueue had me fooled for a bit. 100 // While working on this, the BlockingQueue had me fooled for a bit.
@@ -210,28 +200,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
210 switch (item.throttleType & ThrottleOutPacketType.TypeMask) 200 switch (item.throttleType & ThrottleOutPacketType.TypeMask)
211 { 201 {
212 case ThrottleOutPacketType.Resend: 202 case ThrottleOutPacketType.Resend:
213 ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item); 203 ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item, ThrottleOutPacketType.Resend);
214 break; 204 break;
215 case ThrottleOutPacketType.Texture: 205 case ThrottleOutPacketType.Texture:
216 ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item); 206 ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item, ThrottleOutPacketType.Texture);
217 break; 207 break;
218 case ThrottleOutPacketType.Task: 208 case ThrottleOutPacketType.Task:
219 if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) 209 if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0)
220 ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item); 210 ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item, ThrottleOutPacketType.Task);
221 else 211 else
222 ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item); 212 ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item, ThrottleOutPacketType.Task);
223 break; 213 break;
224 case ThrottleOutPacketType.Land: 214 case ThrottleOutPacketType.Land:
225 ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item); 215 ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item, ThrottleOutPacketType.Land);
226 break; 216 break;
227 case ThrottleOutPacketType.Asset: 217 case ThrottleOutPacketType.Asset:
228 ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item); 218 ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item, ThrottleOutPacketType.Asset);
229 break; 219 break;
230 case ThrottleOutPacketType.Cloud: 220 case ThrottleOutPacketType.Cloud:
231 ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item); 221 ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item, ThrottleOutPacketType.Cloud);
232 break; 222 break;
233 case ThrottleOutPacketType.Wind: 223 case ThrottleOutPacketType.Wind:
234 ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item); 224 ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item, ThrottleOutPacketType.Wind);
235 break; 225 break;
236 226
237 default: 227 default:
@@ -283,43 +273,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
283 { 273 {
284 lock (this) 274 lock (this)
285 { 275 {
286 while (PacketsWaiting()) 276 // These categories do not contain transactional packets so we can safely drop any pending data in them
277 LandOutgoingPacketQueue.Clear();
278 WindOutgoingPacketQueue.Clear();
279 CloudOutgoingPacketQueue.Clear();
280 TextureOutgoingPacketQueue.Clear();
281 AssetOutgoingPacketQueue.Clear();
282
283 // Now comes the fun part.. we dump all remaining resend and task packets into the send queue
284 while (ResendOutgoingPacketQueue.Count > 0 || TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0)
287 { 285 {
288 //Now comes the fun part.. we dump all our elements into m_packetQueue that we've saved up.
289 if (ResendOutgoingPacketQueue.Count > 0) 286 if (ResendOutgoingPacketQueue.Count > 0)
290 {
291 SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); 287 SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue());
292 } 288
293 if (LandOutgoingPacketQueue.Count > 0)
294 {
295 SendQueue.Enqueue(LandOutgoingPacketQueue.Dequeue());
296 }
297 if (WindOutgoingPacketQueue.Count > 0)
298 {
299 SendQueue.Enqueue(WindOutgoingPacketQueue.Dequeue());
300 }
301 if (CloudOutgoingPacketQueue.Count > 0)
302 {
303 SendQueue.Enqueue(CloudOutgoingPacketQueue.Dequeue());
304 }
305 if (TaskOutgoingPacketQueue.Count > 0) 289 if (TaskOutgoingPacketQueue.Count > 0)
306 {
307 SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); 290 SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue());
308 } 291
309 if (TaskLowpriorityPacketQueue.Count > 0) 292 if (TaskLowpriorityPacketQueue.Count > 0)
310 {
311 SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); 293 SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue());
312 }
313 if (TextureOutgoingPacketQueue.Count > 0)
314 {
315 SendQueue.Enqueue(TextureOutgoingPacketQueue.Dequeue());
316 }
317 if (AssetOutgoingPacketQueue.Count > 0)
318 {
319 SendQueue.Enqueue(AssetOutgoingPacketQueue.Dequeue());
320 }
321 } 294 }
322 // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets");
323 } 295 }
324 } 296 }
325 297
@@ -342,11 +314,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
342 314
343 public void Close() 315 public void Close()
344 { 316 {
317 Dispose();
318 }
319
320 public void Dispose()
321 {
345 Flush(); 322 Flush();
346 WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby 323 WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby
347 324
348 m_enabled = false; 325 m_enabled = false;
349 throttleTimer.Stop(); 326 throttleTimer.Stop();
327 throttleTimer.Close();
350 328
351 if (StatsManager.SimExtraStats != null) 329 if (StatsManager.SimExtraStats != null)
352 { 330 {
@@ -388,6 +366,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
388 366
389 int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once. 367 int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once.
390 int throttleLoops = 0; 368 int throttleLoops = 0;
369 List<ThrottleOutPacketType> e;
391 370
392 // We're going to dequeue all of the saved up packets until 371 // We're going to dequeue all of the saved up packets until
393 // we've hit the throttle limit or there's no more packets to send 372 // we've hit the throttle limit or there's no more packets to send
@@ -399,7 +378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
399 bool qchanged = true; 378 bool qchanged = true;
400 379
401 ResetCounters(); 380 ResetCounters();
402 // m_log.Info("[THROTTLE]: Entering Throttle"); 381
403 while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) 382 while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops)
404 { 383 {
405 qchanged = false; // We will break out of the loop if no work was accomplished 384 qchanged = false; // We will break out of the loop if no work was accomplished
@@ -425,6 +404,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
425 TotalThrottle.AddBytes(qpack.Length); 404 TotalThrottle.AddBytes(qpack.Length);
426 LandThrottle.AddBytes(qpack.Length); 405 LandThrottle.AddBytes(qpack.Length);
427 qchanged = true; 406 qchanged = true;
407
408 if (LandOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Land))
409 Empty.Add(ThrottleOutPacketType.Land);
428 } 410 }
429 411
430 if ((WindOutgoingPacketQueue.Count > 0) && WindThrottle.UnderLimit()) 412 if ((WindOutgoingPacketQueue.Count > 0) && WindThrottle.UnderLimit())
@@ -435,6 +417,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
435 TotalThrottle.AddBytes(qpack.Length); 417 TotalThrottle.AddBytes(qpack.Length);
436 WindThrottle.AddBytes(qpack.Length); 418 WindThrottle.AddBytes(qpack.Length);
437 qchanged = true; 419 qchanged = true;
420
421 if (WindOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Wind))
422 Empty.Add(ThrottleOutPacketType.Wind);
438 } 423 }
439 424
440 if ((CloudOutgoingPacketQueue.Count > 0) && CloudThrottle.UnderLimit()) 425 if ((CloudOutgoingPacketQueue.Count > 0) && CloudThrottle.UnderLimit())
@@ -445,6 +430,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
445 TotalThrottle.AddBytes(qpack.Length); 430 TotalThrottle.AddBytes(qpack.Length);
446 CloudThrottle.AddBytes(qpack.Length); 431 CloudThrottle.AddBytes(qpack.Length);
447 qchanged = true; 432 qchanged = true;
433
434 if (CloudOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Cloud))
435 Empty.Add(ThrottleOutPacketType.Cloud);
448 } 436 }
449 437
450 if ((TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) && TaskThrottle.UnderLimit()) 438 if ((TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) && TaskThrottle.UnderLimit())
@@ -464,6 +452,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
464 TotalThrottle.AddBytes(qpack.Length); 452 TotalThrottle.AddBytes(qpack.Length);
465 TaskThrottle.AddBytes(qpack.Length); 453 TaskThrottle.AddBytes(qpack.Length);
466 qchanged = true; 454 qchanged = true;
455
456 if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Task))
457 Empty.Add(ThrottleOutPacketType.Task);
467 } 458 }
468 459
469 if ((TextureOutgoingPacketQueue.Count > 0) && TextureThrottle.UnderLimit()) 460 if ((TextureOutgoingPacketQueue.Count > 0) && TextureThrottle.UnderLimit())
@@ -474,6 +465,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
474 TotalThrottle.AddBytes(qpack.Length); 465 TotalThrottle.AddBytes(qpack.Length);
475 TextureThrottle.AddBytes(qpack.Length); 466 TextureThrottle.AddBytes(qpack.Length);
476 qchanged = true; 467 qchanged = true;
468
469 if (TextureOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Texture))
470 Empty.Add(ThrottleOutPacketType.Texture);
477 } 471 }
478 472
479 if ((AssetOutgoingPacketQueue.Count > 0) && AssetThrottle.UnderLimit()) 473 if ((AssetOutgoingPacketQueue.Count > 0) && AssetThrottle.UnderLimit())
@@ -484,10 +478,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
484 TotalThrottle.AddBytes(qpack.Length); 478 TotalThrottle.AddBytes(qpack.Length);
485 AssetThrottle.AddBytes(qpack.Length); 479 AssetThrottle.AddBytes(qpack.Length);
486 qchanged = true; 480 qchanged = true;
481
482 if (AssetOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Asset))
483 Empty.Add(ThrottleOutPacketType.Asset);
487 } 484 }
488 } 485 }
489 // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); 486 // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets");
487
488 e = new List<ThrottleOutPacketType>(Empty);
489 Empty.Clear();
490 } 490 }
491
492 foreach (ThrottleOutPacketType t in e)
493 {
494 if (GetQueueCount(t) == 0)
495 TriggerOnQueueEmpty(t);
496 }
497 }
498
499 private void TriggerOnQueueEmpty(ThrottleOutPacketType queue)
500 {
501 QueueEmpty handlerQueueEmpty = OnQueueEmpty;
502
503 if (handlerQueueEmpty != null)
504 handlerQueueEmpty(queue);
491 } 505 }
492 506
493 private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) 507 private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e)
@@ -497,7 +511,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
497 ProcessThrottle(); 511 ProcessThrottle();
498 } 512 }
499 513
500 private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue<LLQueItem> q, LLQueItem item) 514 private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue<LLQueItem> q, LLQueItem item, ThrottleOutPacketType itemType)
501 { 515 {
502 // The idea.. is if the packet throttle queues are empty 516 // The idea.. is if the packet throttle queues are empty
503 // and the client is under throttle for the type. Queue 517 // and the client is under throttle for the type. Queue
@@ -513,6 +527,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 throttle.AddBytes(item.Length); 527 throttle.AddBytes(item.Length);
514 TotalThrottle.AddBytes(item.Length); 528 TotalThrottle.AddBytes(item.Length);
515 SendQueue.Enqueue(item); 529 SendQueue.Enqueue(item);
530 lock (this)
531 {
532 if (!Empty.Contains(itemType))
533 Empty.Add(itemType);
534 }
516 } 535 }
517 catch (Exception e) 536 catch (Exception e)
518 { 537 {
@@ -698,5 +717,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
698 { 717 {
699 get { return throttleMultiplier; } 718 get { return throttleMultiplier; }
700 } 719 }
720
721 public int GetQueueCount(ThrottleOutPacketType queue)
722 {
723 switch (queue)
724 {
725 case ThrottleOutPacketType.Land:
726 return LandOutgoingPacketQueue.Count;
727 case ThrottleOutPacketType.Wind:
728 return WindOutgoingPacketQueue.Count;
729 case ThrottleOutPacketType.Cloud:
730 return CloudOutgoingPacketQueue.Count;
731 case ThrottleOutPacketType.Task:
732 return TaskOutgoingPacketQueue.Count;
733 case ThrottleOutPacketType.Texture:
734 return TextureOutgoingPacketQueue.Count;
735 case ThrottleOutPacketType.Asset:
736 return AssetOutgoingPacketQueue.Count;
737 }
738
739 return 0;
740 }
701 } 741 }
702} 742}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 1fdb003..a0f359b 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -34,8 +34,8 @@ using System.Threading;
34using log4net; 34using log4net;
35using Nini.Config; 35using Nini.Config;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.Assets;
38using OpenMetaverse.Imaging; 37using OpenMetaverse.Imaging;
38using CSJ2K;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
@@ -43,31 +43,25 @@ using OpenSim.Services.Interfaces;
43 43
44namespace OpenSim.Region.CoreModules.Agent.TextureSender 44namespace OpenSim.Region.CoreModules.Agent.TextureSender
45{ 45{
46 public delegate void J2KDecodeDelegate(UUID AssetId); 46 public delegate void J2KDecodeDelegate(UUID assetID);
47 47
48 public class J2KDecoderModule : IRegionModule, IJ2KDecoder 48 public class J2KDecoderModule : IRegionModule, IJ2KDecoder
49 { 49 {
50 #region IRegionModule Members 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private static readonly ILog m_log 52 /// <summary>Temporarily holds deserialized layer data information in memory</summary>
53 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private readonly ExpiringCache<UUID, OpenJPEG.J2KLayerInfo[]> m_decodedCache = new ExpiringCache<UUID,OpenJPEG.J2KLayerInfo[]>();
54 /// <summary>List of client methods to notify of results of decode</summary>
55 private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>();
56 /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary>
57 private IImprovedAssetCache m_cache;
58 /// <summary>Reference to a scene (doesn't matter which one as long as it can load the cache module)</summary>
59 private Scene m_scene;
54 60
55 /// <summary> 61 #region IRegionModule
56 /// Cached Decoded Layers
57 /// </summary>
58 private readonly Dictionary<UUID, OpenJPEG.J2KLayerInfo[]> m_cacheddecode = new Dictionary<UUID, OpenJPEG.J2KLayerInfo[]>();
59 private bool OpenJpegFail = false;
60 private string CacheFolder = Util.dataDir() + "/j2kDecodeCache";
61 private int CacheTimeout = 720;
62 private J2KDecodeFileCache fCache = null;
63 private Thread CleanerThread = null;
64 private IAssetService AssetService = null;
65 private Scene m_Scene = null;
66 62
67 /// <summary> 63 public string Name { get { return "J2KDecoderModule"; } }
68 /// List of client methods to notify of results of decode 64 public bool IsSharedModule { get { return true; } }
69 /// </summary>
70 private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>();
71 65
72 public J2KDecoderModule() 66 public J2KDecoderModule()
73 { 67 {
@@ -75,630 +69,267 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
75 69
76 public void Initialise(Scene scene, IConfigSource source) 70 public void Initialise(Scene scene, IConfigSource source)
77 { 71 {
78 if (m_Scene == null) 72 if (m_scene == null)
79 m_Scene = scene; 73 m_scene = scene;
80
81 IConfig j2kConfig = source.Configs["J2KDecoder"];
82 if (j2kConfig != null)
83 {
84 CacheFolder = j2kConfig.GetString("CacheDir", CacheFolder);
85 CacheTimeout = j2kConfig.GetInt("CacheTimeout", CacheTimeout);
86 }
87
88 if (fCache == null)
89 fCache = new J2KDecodeFileCache(CacheFolder, CacheTimeout);
90 74
91 scene.RegisterModuleInterface<IJ2KDecoder>(this); 75 scene.RegisterModuleInterface<IJ2KDecoder>(this);
92
93 if (CleanerThread == null && CacheTimeout != 0)
94 {
95 CleanerThread = new Thread(CleanCache);
96 CleanerThread.Name = "J2KCleanerThread";
97 CleanerThread.IsBackground = true;
98 CleanerThread.Start();
99 }
100 } 76 }
101 77
102 public void PostInitialise() 78 public void PostInitialise()
103 { 79 {
104 AssetService = m_Scene.AssetService; 80 m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
105 } 81 }
106 82
107 public void Close() 83 public void Close()
108 { 84 {
109
110 }
111
112 public string Name
113 {
114 get { return "J2KDecoderModule"; }
115 }
116
117 public bool IsSharedModule
118 {
119 get { return true; }
120 } 85 }
121 86
122 #endregion 87 #endregion IRegionModule
123
124 #region IJ2KDecoder Members
125 88
89 #region IJ2KDecoder
126 90
127 public void decode(UUID AssetId, byte[] assetData, DecodedCallback decodedReturn) 91 public void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback)
128 { 92 {
129 // Dummy for if decoding fails. 93 OpenJPEG.J2KLayerInfo[] result;
130 OpenJPEG.J2KLayerInfo[] result = new OpenJPEG.J2KLayerInfo[0];
131
132 // Check if it's cached
133 bool cached = false;
134 lock (m_cacheddecode)
135 {
136 if (m_cacheddecode.ContainsKey(AssetId))
137 {
138 cached = true;
139 result = m_cacheddecode[AssetId];
140 }
141 }
142 94
143 // If it's cached, return the cached results 95 // If it's cached, return the cached results
144 if (cached) 96 if (m_decodedCache.TryGetValue(assetID, out result))
145 { 97 {
146 decodedReturn(AssetId, result); 98 callback(assetID, result);
147 } 99 }
148 else 100 else
149 { 101 {
150 // not cached, so we need to decode it 102 // Not cached, we need to decode it.
151 // Add to notify list and start decoding. 103 // Add to notify list and start decoding.
152 // Next request for this asset while it's decoding will only be added to the notify list 104 // Next request for this asset while it's decoding will only be added to the notify list
153 // once this is decoded, requests will be served from the cache and all clients in the notifylist will be updated 105 // once this is decoded, requests will be served from the cache and all clients in the notifylist will be updated
154 bool decode = false; 106 bool decode = false;
155 lock (m_notifyList) 107 lock (m_notifyList)
156 { 108 {
157 if (m_notifyList.ContainsKey(AssetId)) 109 if (m_notifyList.ContainsKey(assetID))
158 { 110 {
159 m_notifyList[AssetId].Add(decodedReturn); 111 m_notifyList[assetID].Add(callback);
160 } 112 }
161 else 113 else
162 { 114 {
163 List<DecodedCallback> notifylist = new List<DecodedCallback>(); 115 List<DecodedCallback> notifylist = new List<DecodedCallback>();
164 notifylist.Add(decodedReturn); 116 notifylist.Add(callback);
165 m_notifyList.Add(AssetId, notifylist); 117 m_notifyList.Add(assetID, notifylist);
166 decode = true; 118 decode = true;
167 } 119 }
168 } 120 }
121
169 // Do Decode! 122 // Do Decode!
170 if (decode) 123 if (decode)
171 { 124 DoJ2KDecode(assetID, j2kData);
172 doJ2kDecode(AssetId, assetData);
173 }
174 } 125 }
175 } 126 }
176 127
177 /// <summary> 128 /// <summary>
178 /// Provides a synchronous decode so that caller can be assured that this executes before the next line 129 /// Provides a synchronous decode so that caller can be assured that this executes before the next line
179 /// </summary> 130 /// </summary>
180 /// <param name="AssetId"></param> 131 /// <param name="assetID"></param>
181 /// <param name="j2kdata"></param> 132 /// <param name="j2kData"></param>
182 public void syncdecode(UUID AssetId, byte[] j2kdata) 133 public void Decode(UUID assetID, byte[] j2kData)
183 { 134 {
184 doJ2kDecode(AssetId, j2kdata); 135 DoJ2KDecode(assetID, j2kData);
185 } 136 }
186 137
187 #endregion 138 #endregion IJ2KDecoder
188 139
189 /// <summary> 140 /// <summary>
190 /// Decode Jpeg2000 Asset Data 141 /// Decode Jpeg2000 Asset Data
191 /// </summary> 142 /// </summary>
192 /// <param name="AssetId">UUID of Asset</param> 143 /// <param name="assetID">UUID of Asset</param>
193 /// <param name="j2kdata">Byte Array Asset Data </param> 144 /// <param name="j2kData">JPEG2000 data</param>
194 private void doJ2kDecode(UUID AssetId, byte[] j2kdata) 145 private void DoJ2KDecode(UUID assetID, byte[] j2kData)
195 { 146 {
196 int DecodeTime = 0; 147 int DecodeTime = 0;
197 DecodeTime = Environment.TickCount; 148 DecodeTime = Environment.TickCount;
198 OpenJPEG.J2KLayerInfo[] layers = new OpenJPEG.J2KLayerInfo[0]; // Dummy result for if it fails. Informs that there's only full quality 149 OpenJPEG.J2KLayerInfo[] layers;
199 150
200 if (!OpenJpegFail) 151 if (!TryLoadCacheForAsset(assetID, out layers))
201 { 152 {
202 if (!fCache.TryLoadCacheForAsset(AssetId, out layers)) 153 try
203 { 154 {
204 try 155 List<int> layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(new MemoryStream(j2kData));
156
157 if (layerStarts != null && layerStarts.Count > 0)
205 { 158 {
159 layers = new OpenJPEG.J2KLayerInfo[layerStarts.Count];
206 160
207 AssetTexture texture = new AssetTexture(AssetId, j2kdata); 161 for (int i = 0; i < layerStarts.Count; i++)
208 if (texture.DecodeLayerBoundaries())
209 { 162 {
210 bool sane = true; 163 OpenJPEG.J2KLayerInfo layer = new OpenJPEG.J2KLayerInfo();
211 164
212 // Sanity check all of the layers 165 if (i == 0)
213 for (int i = 0; i < texture.LayerInfo.Length; i++) 166 layer.Start = 0;
214 {
215 if (texture.LayerInfo[i].End > texture.AssetData.Length)
216 {
217 sane = false;
218 break;
219 }
220 }
221
222 if (sane)
223 {
224 layers = texture.LayerInfo;
225 fCache.SaveFileCacheForAsset(AssetId, layers);
226
227
228 // Write out decode time
229 m_log.InfoFormat("[J2KDecoderModule]: {0} Decode Time: {1}", Environment.TickCount - DecodeTime,
230 AssetId);
231
232 }
233 else 167 else
234 { 168 layer.Start = layerStarts[i];
235 m_log.WarnFormat(
236 "[J2KDecoderModule]: JPEG2000 texture decoding succeeded, but sanity check failed for {0}",
237 AssetId);
238 }
239 }
240
241 else
242 {
243 /*
244 Random rnd = new Random();
245 // scramble ends for test
246 for (int i = 0; i < texture.LayerInfo.Length; i++)
247 {
248 texture.LayerInfo[i].End = rnd.Next(999999);
249 }
250 */
251
252 // Try to do some heuristics error correction! Yeah.
253 bool sane2Heuristics = true;
254
255
256 if (texture.Image == null)
257 sane2Heuristics = false;
258
259 if (texture.LayerInfo == null)
260 sane2Heuristics = false;
261
262 if (sane2Heuristics)
263 {
264
265 169
266 if (texture.LayerInfo.Length == 0) 170 if (i == layerStarts.Count - 1)
267 sane2Heuristics = false; 171 layer.End = j2kData.Length;
268 }
269
270 if (sane2Heuristics)
271 {
272 // Last layer start is less then the end of the file and last layer start is greater then 0
273 if (texture.LayerInfo[texture.LayerInfo.Length - 1].Start < texture.AssetData.Length && texture.LayerInfo[texture.LayerInfo.Length - 1].Start > 0)
274 {
275 }
276 else
277 {
278 sane2Heuristics = false;
279 }
280
281 }
282
283 if (sane2Heuristics)
284 {
285 int start = 0;
286
287 // try to fix it by using consistant data in the start field
288 for (int i = 0; i < texture.LayerInfo.Length; i++)
289 {
290 if (i == 0)
291 start = 0;
292
293 if (i == texture.LayerInfo.Length - 1)
294 texture.LayerInfo[i].End = texture.AssetData.Length;
295 else
296 texture.LayerInfo[i].End = texture.LayerInfo[i + 1].Start - 1;
297
298 // in this case, the end of the next packet is less then the start of the last packet
299 // after we've attempted to fix it which means the start of the last packet is borked
300 // there's no recovery from this
301 if (texture.LayerInfo[i].End < start)
302 {
303 sane2Heuristics = false;
304 break;
305 }
306
307 if (texture.LayerInfo[i].End < 0 || texture.LayerInfo[i].End > texture.AssetData.Length)
308 {
309 sane2Heuristics = false;
310 break;
311 }
312
313 if (texture.LayerInfo[i].Start < 0 || texture.LayerInfo[i].Start > texture.AssetData.Length)
314 {
315 sane2Heuristics = false;
316 break;
317 }
318
319 start = texture.LayerInfo[i].Start;
320 }
321 }
322
323 if (sane2Heuristics)
324 {
325 layers = texture.LayerInfo;
326 fCache.SaveFileCacheForAsset(AssetId, layers);
327
328
329 // Write out decode time
330 m_log.InfoFormat("[J2KDecoderModule]: HEURISTICS SUCCEEDED {0} Decode Time: {1}", Environment.TickCount - DecodeTime,
331 AssetId);
332
333 }
334 else 172 else
335 { 173 layer.End = layerStarts[i + 1] - 1;
336 m_log.WarnFormat("[J2KDecoderModule]: JPEG2000 texture decoding failed for {0}. Is this a texture? is it J2K?", AssetId); 174
337 } 175 layers[i] = layer;
338 } 176 }
339 texture = null; // dereference and dispose of ManagedImage
340 }
341 catch (DllNotFoundException)
342 {
343 m_log.Error(
344 "[J2KDecoderModule]: OpenJpeg is not installed properly. Decoding disabled! This will slow down texture performance! Often times this is because of an old version of GLIBC. You must have version 2.4 or above!");
345 OpenJpegFail = true;
346 }
347 catch (Exception ex)
348 {
349 m_log.WarnFormat(
350 "[J2KDecoderModule]: JPEG2000 texture decoding threw an exception for {0}, {1}",
351 AssetId, ex);
352 } 177 }
353 } 178 }
354 179 catch (Exception ex)
355 } 180 {
181 m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
182 }
356 183
357 // Cache Decoded layers 184 if (layers == null || layers.Length == 0)
358 lock (m_cacheddecode) 185 {
359 { 186 m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
360 if (m_cacheddecode.ContainsKey(AssetId)) 187 // Layer decoding completely failed. Guess at sane defaults for the layer boundaries
361 m_cacheddecode.Remove(AssetId); 188 layers = CreateDefaultLayers(j2kData.Length);
362 m_cacheddecode.Add(AssetId, layers); 189 }
363 190
191 // Cache Decoded layers
192 SaveFileCacheForAsset(assetID, layers);
364 } 193 }
365 194
366 // Notify Interested Parties 195 // Notify Interested Parties
367 lock (m_notifyList) 196 lock (m_notifyList)
368 { 197 {
369 if (m_notifyList.ContainsKey(AssetId)) 198 if (m_notifyList.ContainsKey(assetID))
370 { 199 {
371 foreach (DecodedCallback d in m_notifyList[AssetId]) 200 foreach (DecodedCallback d in m_notifyList[assetID])
372 { 201 {
373 if (d != null) 202 if (d != null)
374 d.DynamicInvoke(AssetId, layers); 203 d.DynamicInvoke(assetID, layers);
375 } 204 }
376 m_notifyList.Remove(AssetId); 205 m_notifyList.Remove(assetID);
377 } 206 }
378 } 207 }
379 } 208 }
380
381 private void CleanCache()
382 {
383 m_log.Info("[J2KDecoderModule]: Cleaner thread started");
384
385 while (true)
386 {
387 if (AssetService != null)
388 fCache.ScanCacheFiles(RedecodeTexture);
389 209
390 System.Threading.Thread.Sleep(600000); 210 private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)
391 }
392 }
393
394 private void RedecodeTexture(UUID assetID)
395 { 211 {
396 AssetBase texture = AssetService.Get(assetID.ToString()); 212 OpenJPEG.J2KLayerInfo[] layers = new OpenJPEG.J2KLayerInfo[5];
397 if (texture == null) 213
398 return; 214 for (int i = 0; i < layers.Length; i++)
399 215 layers[i] = new OpenJPEG.J2KLayerInfo();
400 doJ2kDecode(assetID, texture.Data); 216
217 // These default layer sizes are based on a small sampling of real-world texture data
218 // with extra padding thrown in for good measure. This is a worst case fallback plan
219 // and may not gracefully handle all real world data
220 layers[0].Start = 0;
221 layers[1].Start = (int)((float)j2kLength * 0.02f);
222 layers[2].Start = (int)((float)j2kLength * 0.05f);
223 layers[3].Start = (int)((float)j2kLength * 0.20f);
224 layers[4].Start = (int)((float)j2kLength * 0.50f);
225
226 layers[0].End = layers[1].Start - 1;
227 layers[1].End = layers[2].Start - 1;
228 layers[2].End = layers[3].Start - 1;
229 layers[3].End = layers[4].Start - 1;
230 layers[4].End = j2kLength;
231
232 return layers;
401 } 233 }
402 }
403 234
404 public class J2KDecodeFileCache 235 private void SaveFileCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers)
405 {
406 private readonly string m_cacheDecodeFolder;
407 private readonly int m_cacheTimeout;
408 private bool enabled = true;
409
410 private static readonly ILog m_log
411 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
412
413 /// <summary>
414 /// Creates a new instance of a file cache
415 /// </summary>
416 /// <param name="pFolder">base folder for the cache. Will be created if it doesn't exist</param>
417 public J2KDecodeFileCache(string pFolder, int timeout)
418 { 236 {
419 m_cacheDecodeFolder = pFolder; 237 m_decodedCache.AddOrUpdate(AssetId, Layers, TimeSpan.FromMinutes(10));
420 m_cacheTimeout = timeout;
421 if (!Directory.Exists(pFolder))
422 {
423 Createj2KCacheFolder(pFolder);
424 }
425 }
426 238
427 /// <summary> 239 if (m_cache != null)
428 /// Save Layers to Disk Cache
429 /// </summary>
430 /// <param name="AssetId">Asset to Save the layers. Used int he file name by default</param>
431 /// <param name="Layers">The Layer Data from OpenJpeg</param>
432 /// <returns></returns>
433 public bool SaveFileCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers)
434 {
435 if (Layers.Length > 0 && enabled)
436 { 240 {
437 FileStream fsCache = 241 AssetBase layerDecodeAsset = new AssetBase();
438 new FileStream(String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId)), 242 layerDecodeAsset.ID = "j2kCache_" + AssetId.ToString();
439 FileMode.Create); 243 layerDecodeAsset.Local = true;
440 StreamWriter fsSWCache = new StreamWriter(fsCache); 244 layerDecodeAsset.Name = layerDecodeAsset.ID;
245 layerDecodeAsset.Temporary = true;
246 layerDecodeAsset.Type = (sbyte)AssetType.Notecard;
247
248 #region Serialize Layer Data
249
441 StringBuilder stringResult = new StringBuilder(); 250 StringBuilder stringResult = new StringBuilder();
442 string strEnd = "\n"; 251 string strEnd = "\n";
443 for (int i = 0; i < Layers.Length; i++) 252 for (int i = 0; i < Layers.Length; i++)
444 { 253 {
445 if (i == (Layers.Length - 1)) 254 if (i == Layers.Length - 1)
446 strEnd = ""; 255 strEnd = String.Empty;
447 256
448 stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); 257 stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd);
449 } 258 }
450 fsSWCache.Write(stringResult.ToString());
451 fsSWCache.Close();
452 fsSWCache.Dispose();
453 fsCache.Dispose();
454 return true;
455 }
456
457 259
458 return false; 260 layerDecodeAsset.Data = Encoding.UTF8.GetBytes(stringResult.ToString());
459 }
460 261
461 262 #endregion Serialize Layer Data
462 /// <summary>
463 /// Loads the Layer data from the disk cache
464 /// Returns true if load succeeded
465 /// </summary>
466 /// <param name="AssetId">AssetId that we're checking the cache for</param>
467 /// <param name="Layers">out layers to save to</param>
468 /// <returns>true if load succeeded</returns>
469 public bool TryLoadCacheForAsset(UUID AssetId, out OpenJPEG.J2KLayerInfo[] Layers)
470 {
471 string filename = String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId));
472 Layers = new OpenJPEG.J2KLayerInfo[0];
473 263
474 if (!File.Exists(filename)) 264 m_cache.Cache(layerDecodeAsset);
475 return false;
476
477 if (!enabled)
478 {
479 return false;
480 } 265 }
266 }
481 267
482 string readResult = string.Empty; 268 bool TryLoadCacheForAsset(UUID AssetId, out OpenJPEG.J2KLayerInfo[] Layers)
483 269 {
484 try 270 if (m_decodedCache.TryGetValue(AssetId, out Layers))
485 { 271 {
486 FileStream fsCachefile = 272 return true;
487 new FileStream(filename,
488 FileMode.Open);
489
490 StreamReader sr = new StreamReader(fsCachefile);
491 readResult = sr.ReadToEnd();
492
493 sr.Close();
494 sr.Dispose();
495 fsCachefile.Dispose();
496
497 } 273 }
498 catch (IOException ioe) 274 else if (m_cache != null)
499 { 275 {
500 if (ioe is PathTooLongException) 276 string assetName = "j2kCache_" + AssetId.ToString();
501 { 277 AssetBase layerDecodeAsset = m_cache.Get(assetName);
502 m_log.Error(
503 "[J2KDecodeCache]: Cache Read failed. Path is too long.");
504 }
505 else if (ioe is DirectoryNotFoundException)
506 {
507 m_log.Error(
508 "[J2KDecodeCache]: Cache Read failed. Cache Directory does not exist!");
509 enabled = false;
510 }
511 else
512 {
513 m_log.Error(
514 "[J2KDecodeCache]: Cache Read failed. IO Exception.");
515 }
516 return false;
517 278
518 } 279 if (layerDecodeAsset != null)
519 catch (UnauthorizedAccessException)
520 {
521 m_log.Error(
522 "[J2KDecodeCache]: Cache Read failed. UnauthorizedAccessException Exception. Do you have the proper permissions on this file?");
523 return false;
524 }
525 catch (ArgumentException ae)
526 {
527 if (ae is ArgumentNullException)
528 {
529 m_log.Error(
530 "[J2KDecodeCache]: Cache Read failed. No Filename provided");
531 }
532 else
533 { 280 {
534 m_log.Error( 281 #region Deserialize Layer Data
535 "[J2KDecodeCache]: Cache Read failed. Filname was invalid");
536 }
537 return false;
538 }
539 catch (NotSupportedException)
540 {
541 m_log.Error(
542 "[J2KDecodeCache]: Cache Read failed, not supported. Cache disabled!");
543 enabled = false;
544 282
545 return false; 283 string readResult = Encoding.UTF8.GetString(layerDecodeAsset.Data);
546 } 284 string[] lines = readResult.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
547 catch (Exception e)
548 {
549 m_log.ErrorFormat(
550 "[J2KDecodeCache]: Cache Read failed, unknown exception. Error: {0}",
551 e.ToString());
552 return false;
553 }
554
555 string[] lines = readResult.Split('\n');
556 285
557 if (lines.Length <= 0) 286 if (lines.Length == 0)
558 return false;
559
560 Layers = new OpenJPEG.J2KLayerInfo[lines.Length];
561
562 for (int i = 0; i < lines.Length; i++)
563 {
564 string[] elements = lines[i].Split('|');
565 if (elements.Length == 3)
566 {
567 int element1, element2;
568
569 try
570 {
571 element1 = Convert.ToInt32(elements[0]);
572 element2 = Convert.ToInt32(elements[1]);
573 }
574 catch (FormatException)
575 { 287 {
576 m_log.WarnFormat("[J2KDecodeCache]: Cache Read failed with ErrorConvert for {0}", AssetId); 288 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (empty) " + assetName);
577 Layers = new OpenJPEG.J2KLayerInfo[0]; 289 m_cache.Expire(assetName);
578 return false; 290 return false;
579 } 291 }
580 292
581 Layers[i] = new OpenJPEG.J2KLayerInfo(); 293 Layers = new OpenJPEG.J2KLayerInfo[lines.Length];
582 Layers[i].Start = element1;
583 Layers[i].End = element2;
584
585 }
586 else
587 {
588 // reading failed
589 m_log.WarnFormat("[J2KDecodeCache]: Cache Read failed for {0}", AssetId);
590 Layers = new OpenJPEG.J2KLayerInfo[0];
591 return false;
592 }
593 }
594
595
596
597
598 return true;
599 }
600 294
601 /// <summary> 295 for (int i = 0; i < lines.Length; i++)
602 /// Routine which converts assetid to file name 296 {
603 /// </summary> 297 string[] elements = lines[i].Split('|');
604 /// <param name="AssetId">asset id of the image</param> 298 if (elements.Length == 3)
605 /// <returns>string filename</returns> 299 {
606 public string FileNameFromAssetId(UUID AssetId) 300 int element1, element2;
607 {
608 return String.Format("j2kCache_{0}.cache", AssetId);
609 }
610 301
611 public UUID AssetIdFromFileName(string fileName) 302 try
612 { 303 {
613 string rawId = fileName.Replace("j2kCache_", "").Replace(".cache", ""); 304 element1 = Convert.ToInt32(elements[0]);
614 UUID asset; 305 element2 = Convert.ToInt32(elements[1]);
615 if (!UUID.TryParse(rawId, out asset)) 306 }
616 return UUID.Zero; 307 catch (FormatException)
308 {
309 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (format) " + assetName);
310 m_cache.Expire(assetName);
311 return false;
312 }
617 313
618 return asset; 314 Layers[i] = new OpenJPEG.J2KLayerInfo();
619 } 315 Layers[i].Start = element1;
316 Layers[i].End = element2;
317 }
318 else
319 {
320 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (layout) " + assetName);
321 m_cache.Expire(assetName);
322 return false;
323 }
324 }
620 325
621 /// <summary> 326 #endregion Deserialize Layer Data
622 /// Creates the Cache Folder
623 /// </summary>
624 /// <param name="pFolder">Folder to Create</param>
625 public void Createj2KCacheFolder(string pFolder)
626 {
627 try
628 {
629 Directory.CreateDirectory(pFolder);
630 }
631 catch (IOException ioe)
632 {
633 if (ioe is PathTooLongException)
634 {
635 m_log.Error(
636 "[J2KDecodeCache]: Cache Directory does not exist and create failed because the path to the cache folder is too long. Cache disabled!");
637 }
638 else if (ioe is DirectoryNotFoundException)
639 {
640 m_log.Error(
641 "[J2KDecodeCache]: Cache Directory does not exist and create failed because the supplied base of the directory folder does not exist. Cache disabled!");
642 }
643 else
644 {
645 m_log.Error(
646 "[J2KDecodeCache]: Cache Directory does not exist and create failed because of an IO Exception. Cache disabled!");
647 }
648 enabled = false;
649 327
650 } 328 return true;
651 catch (UnauthorizedAccessException)
652 {
653 m_log.Error(
654 "[J2KDecodeCache]: Cache Directory does not exist and create failed because of an UnauthorizedAccessException Exception. Cache disabled!");
655 enabled = false;
656 }
657 catch (ArgumentException ae)
658 {
659 if (ae is ArgumentNullException)
660 {
661 m_log.Error(
662 "[J2KDecodeCache]: Cache Directory does not exist and create failed because the folder provided is invalid! Cache disabled!");
663 } 329 }
664 else
665 {
666 m_log.Error(
667 "[J2KDecodeCache]: Cache Directory does not exist and create failed because no cache folder was provided! Cache disabled!");
668 }
669 enabled = false;
670 } 330 }
671 catch (NotSupportedException)
672 {
673 m_log.Error(
674 "[J2KDecodeCache]: Cache Directory does not exist and create failed because it's not supported. Cache disabled!");
675 enabled = false;
676 }
677 catch (Exception e)
678 {
679 m_log.ErrorFormat(
680 "[J2KDecodeCache]: Cache Directory does not exist and create failed because of an unknown exception. Cache disabled! Error: {0}",
681 e.ToString());
682 enabled = false;
683 }
684 }
685
686 public void ScanCacheFiles(J2KDecodeDelegate decode)
687 {
688 DirectoryInfo dir = new DirectoryInfo(m_cacheDecodeFolder);
689 FileInfo[] files = dir.GetFiles("j2kCache_*.cache");
690 331
691 foreach (FileInfo f in files) 332 return false;
692 {
693 TimeSpan fileAge = DateTime.Now - f.CreationTime;
694
695 if (m_cacheTimeout != 0 && fileAge >= TimeSpan.FromMinutes(m_cacheTimeout))
696 {
697 File.Delete(f.Name);
698 decode(AssetIdFromFileName(f.Name));
699 System.Threading.Thread.Sleep(5000);
700 }
701 }
702 } 333 }
703 } 334 }
704} 335}
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 14eb9a2..9a6c49a 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
325 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); 325 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
326 if (cacheLayerDecode != null) 326 if (cacheLayerDecode != null)
327 { 327 {
328 cacheLayerDecode.syncdecode(asset.FullID, asset.Data); 328 cacheLayerDecode.Decode(asset.FullID, asset.Data);
329 cacheLayerDecode = null; 329 cacheLayerDecode = null;
330 LastAssetID = asset.FullID; 330 LastAssetID = asset.FullID;
331 } 331 }
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index f4526ae..8ad4844 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -1102,5 +1102,9 @@ namespace OpenSim.Region.Examples.SimpleModule
1102 { 1102 {
1103 } 1103 }
1104 #endregion 1104 #endregion
1105
1106 public void SendRebakeAvatarTextures(UUID textureID)
1107 {
1108 }
1105 } 1109 }
1106} 1110}
diff --git a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
index b153997..856eb11 100644
--- a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
@@ -30,12 +30,11 @@ using OpenMetaverse.Imaging;
30 30
31namespace OpenSim.Region.Framework.Interfaces 31namespace OpenSim.Region.Framework.Interfaces
32{ 32{
33
34 public delegate void DecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers); 33 public delegate void DecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers);
35 34
36 public interface IJ2KDecoder 35 public interface IJ2KDecoder
37 { 36 {
38 void decode(UUID AssetId, byte[] assetData, DecodedCallback decodedReturn); 37 void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback);
39 void syncdecode(UUID AssetId, byte[] j2kdata); 38 void Decode(UUID assetID, byte[] j2kData);
40 } 39 }
41} 40}
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 1d4efd0..3097929 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -540,127 +540,5 @@ namespace OpenSim.Region.Framework.Scenes
540 { 540 {
541 m_localScenes.ForEach(action); 541 m_localScenes.ForEach(action);
542 } 542 }
543
544 public void CacheJ2kDecode(int threads)
545 {
546 if (threads < 1) threads = 1;
547
548 IJ2KDecoder m_decoder = m_localScenes[0].RequestModuleInterface<IJ2KDecoder>();
549
550 List<UUID> assetRequestList = new List<UUID>();
551
552 #region AssetGathering!
553 foreach (Scene scene in m_localScenes)
554 {
555 List<EntityBase> entitles = scene.GetEntities();
556 foreach (EntityBase entity in entitles)
557 {
558 if (entity is SceneObjectGroup)
559 {
560 SceneObjectGroup sog = (SceneObjectGroup) entity;
561 foreach (SceneObjectPart part in sog.Children.Values)
562 {
563 if (part.Shape != null)
564 {
565 if (part.Shape.TextureEntry.Length > 0)
566 {
567 OpenMetaverse.Primitive.TextureEntry te =
568 new Primitive.TextureEntry(part.Shape.TextureEntry, 0,
569 part.Shape.TextureEntry.Length);
570 if (te.DefaultTexture != null) // this has been null for some reason...
571 {
572 if (te.DefaultTexture.TextureID != UUID.Zero)
573 assetRequestList.Add(te.DefaultTexture.TextureID);
574 }
575 for (int i=0; i<te.FaceTextures.Length; i++)
576 {
577 if (te.FaceTextures[i] != null)
578 {
579 if (te.FaceTextures[i].TextureID != UUID.Zero)
580 {
581 assetRequestList.Add(te.FaceTextures[i].TextureID);
582 }
583 }
584 }
585 }
586 if (part.Shape.SculptTexture != UUID.Zero)
587 {
588 assetRequestList.Add(part.Shape.SculptTexture);
589 }
590
591 }
592 }
593 }
594 }
595 }
596 #endregion
597
598 int entries_per_thread = (assetRequestList.Count / threads) + 1;
599
600 UUID[] arrAssetRequestList = assetRequestList.ToArray();
601
602 List<UUID[]> arrvalus = new List<UUID[]>();
603
604 //split into separate arrays
605 for (int j = 0; j < threads; j++)
606 {
607 List<UUID> val = new List<UUID>();
608
609 for (int k = j * entries_per_thread; k < ((j + 1) * entries_per_thread); k++)
610 {
611 if (k < arrAssetRequestList.Length)
612 {
613 val.Add(arrAssetRequestList[k]);
614 }
615
616 }
617 arrvalus.Add(val.ToArray());
618 }
619
620 for (int l = 0; l < arrvalus.Count; l++)
621 {
622 DecodeThreadContents threadworkItem = new DecodeThreadContents();
623 threadworkItem.sn = m_localScenes[0];
624 threadworkItem.j2kdecode = m_decoder;
625 threadworkItem.arrassets = arrvalus[l];
626
627 System.Threading.Thread decodethread =
628 new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(threadworkItem.run));
629
630 threadworkItem.SetThread(decodethread);
631
632 decodethread.Priority = System.Threading.ThreadPriority.Lowest;
633 decodethread.Name = "J2kCacheDecodeThread_" + l + 1;
634 ThreadTracker.Add(decodethread);
635 decodethread.Start();
636
637 }
638 }
639 }
640
641 public class DecodeThreadContents
642 {
643 public Scene sn;
644 public UUID[] arrassets;
645 public IJ2KDecoder j2kdecode;
646 private System.Threading.Thread thisthread;
647
648 public void run(object o)
649 {
650 for (int i=0;i<arrassets.Length;i++)
651 {
652 AssetBase ab = sn.AssetService.Get(arrassets[i].ToString());
653 if (ab != null && ab.Data != null)
654 {
655 j2kdecode.syncdecode(arrassets[i], ab.Data);
656 }
657 }
658 ThreadTracker.Remove(thisthread);
659 }
660
661 public void SetThread(System.Threading.Thread thr)
662 {
663 thisthread = thr;
664 }
665 } 543 }
666} 544}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 66fefa3..3996cdc 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -74,6 +74,8 @@ namespace OpenSim.Region.Framework.Scenes
74 74
75 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 75 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
76 76
77 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
78
77 public static byte[] DefaultTexture; 79 public static byte[] DefaultTexture;
78 80
79 public UUID currentParcelUUID = UUID.Zero; 81 public UUID currentParcelUUID = UUID.Zero;
@@ -2686,7 +2688,7 @@ namespace OpenSim.Region.Framework.Scenes
2686 /// </summary> 2688 /// </summary>
2687 /// <param name="texture"></param> 2689 /// <param name="texture"></param>
2688 /// <param name="visualParam"></param> 2690 /// <param name="visualParam"></param>
2689 public void SetAppearance(byte[] texture, List<byte> visualParam) 2691 public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
2690 { 2692 {
2691 if (m_physicsActor != null) 2693 if (m_physicsActor != null)
2692 { 2694 {
@@ -2704,7 +2706,30 @@ namespace OpenSim.Region.Framework.Scenes
2704 AddToPhysicalScene(flyingTemp); 2706 AddToPhysicalScene(flyingTemp);
2705 } 2707 }
2706 } 2708 }
2707 m_appearance.SetAppearance(texture, visualParam); 2709
2710 #region Bake Cache Check
2711
2712 if (textureEntry != null)
2713 {
2714 for (int i = 0; i < BAKE_INDICES.Length; i++)
2715 {
2716 int j = BAKE_INDICES[i];
2717 Primitive.TextureEntryFace face = textureEntry.FaceTextures[j];
2718
2719 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
2720 {
2721 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
2722 {
2723 m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + (AppearanceManager.TextureIndex)j + ") for avatar " + this.Name);
2724 this.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
2725 }
2726 }
2727 }
2728 }
2729
2730 #endregion Bake Cache Check
2731
2732 m_appearance.SetAppearance(textureEntry, visualParams);
2708 if (m_appearance.AvatarHeight > 0) 2733 if (m_appearance.AvatarHeight > 0)
2709 SetHeight(m_appearance.AvatarHeight); 2734 SetHeight(m_appearance.AvatarHeight);
2710 m_scene.CommsManager.AvatarService.UpdateUserAppearance(m_controllingClient.AgentId, m_appearance); 2735 m_scene.CommsManager.AvatarService.UpdateUserAppearance(m_controllingClient.AgentId, m_appearance);
@@ -3255,14 +3280,14 @@ namespace OpenSim.Region.Framework.Scenes
3255 wears[i++] = new AvatarWearable(itemId, assetId); 3280 wears[i++] = new AvatarWearable(itemId, assetId);
3256 } 3281 }
3257 m_appearance.Wearables = wears; 3282 m_appearance.Wearables = wears;
3258 byte[] te = null; 3283 Primitive.TextureEntry te;
3259 if (cAgent.AgentTextures != null) 3284 if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
3260 te = cAgent.AgentTextures; 3285 te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
3261 else 3286 else
3262 te = AvatarAppearance.GetDefaultTexture().GetBytes(); 3287 te = AvatarAppearance.GetDefaultTexture();
3263 if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) 3288 if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
3264 cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); 3289 cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams();
3265 m_appearance.SetAppearance(te, new List<byte>(cAgent.VisualParams)); 3290 m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone());
3266 } 3291 }
3267 catch (Exception e) 3292 catch (Exception e)
3268 { 3293 {
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 605645b..ee2d2db 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -861,12 +861,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
861 Scene scene = (Scene)Scene; 861 Scene scene = (Scene)Scene;
862 AvatarAppearance appearance; 862 AvatarAppearance appearance;
863 scene.GetAvatarAppearance(this, out appearance); 863 scene.GetAvatarAppearance(this, out appearance);
864 List<byte> visualParams = new List<byte>(); 864 OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone());
865 foreach (byte visualParam in appearance.VisualParams)
866 {
867 visualParams.Add(visualParam);
868 }
869 OnSetAppearance(appearance.Texture.GetBytes(), visualParams);
870 } 865 }
871 866
872 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) 867 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
@@ -1609,5 +1604,9 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1609 } 1604 }
1610 1605
1611 #endregion 1606 #endregion
1607
1608 public void SendRebakeAvatarTextures(UUID textureID)
1609 {
1610 }
1612 } 1611 }
1613} 1612}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index f0bdf3b..ac8b98c 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -1101,5 +1101,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
1101 { 1101 {
1102 } 1102 }
1103 #endregion 1103 #endregion
1104
1105 public void SendRebakeAvatarTextures(UUID textureID)
1106 {
1107 }
1104 } 1108 }
1105} 1109}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index b3bfe07..30a2675 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -163,13 +163,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
163 { 163 {
164 AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); 164 AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene);
165 165
166 List<byte> wearbyte = new List<byte>(); 166 sp.SetAppearance(x.Texture, (byte[])x.VisualParams.Clone());
167 for (int i = 0; i < x.VisualParams.Length; i++)
168 {
169 wearbyte.Add(x.VisualParams[i]);
170 }
171
172 sp.SetAppearance(x.Texture.GetBytes(), wearbyte);
173 } 167 }
174 168
175 m_avatars.Add(npcAvatar.AgentId, npcAvatar); 169 m_avatars.Add(npcAvatar.AgentId, npcAvatar);
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 56eb359..d56ddc8 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -78,6 +78,20 @@ namespace OpenSim.Region.Physics.Meshing
78 78
79 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 79 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
80 80
81 public Meshmerizer()
82 {
83 try
84 {
85 if (!Directory.Exists(decodedScultMapPath))
86 Directory.CreateDirectory(decodedScultMapPath);
87 }
88 catch (Exception e)
89 {
90 m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedScultMapPath, e.Message);
91 }
92
93 }
94
81 /// <summary> 95 /// <summary>
82 /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may 96 /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
83 /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail 97 /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail
diff --git a/OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs b/OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs
deleted file mode 100644
index 04a73e4..0000000
--- a/OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs
+++ /dev/null
@@ -1,80 +0,0 @@
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
28using NUnit.Framework;
29using OpenSim.Framework;
30using OpenSim.Framework.Servers.HttpServer;
31using OpenSim.Server.Handlers.Asset;
32using OpenSim.Services.Interfaces;
33using OpenSim.Tests.Common;
34using OpenSim.Tests.Common.Mock;
35using OpenSim.Tests.Common.Setup;
36
37namespace OpenSim.Server.Handlers.Tests.Asset
38{
39 [TestFixture]
40 public class AssetServerGetHandlerTests
41 {
42 private const string ASSETS_PATH = "/assets";
43
44 [Test]
45 public void TestConstructor()
46 {
47 TestHelper.InMethod();
48
49 new AssetServerGetHandler(null);
50 }
51
52 [Test]
53 public void TestGetParams()
54 {
55 TestHelper.InMethod();
56
57 AssetServerGetHandler handler = new AssetServerGetHandler(null);
58 BaseRequestHandlerTestHelper.BaseTestGetParams(handler, ASSETS_PATH);
59 }
60
61 [Test]
62 public void TestSplitParams()
63 {
64 TestHelper.InMethod();
65
66 AssetServerGetHandler handler = new AssetServerGetHandler(null);
67 BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, ASSETS_PATH);
68 }
69
70 // TODO: unused
71 // private static AssetBase CreateTestEnvironment(out AssetServerGetHandler handler, out OSHttpResponse response)
72 // {
73 // AssetBase asset = GetAssetStreamHandlerTestHelpers.CreateCommonTestResources(out response);
74 // IAssetService assetDataPlugin = new TestAssetService();
75 // handler = new AssetServerGetHandler(assetDataPlugin);
76 // assetDataPlugin.Store(asset);
77 // return asset;
78 // }
79 }
80}
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index fe31729..2b54890 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -1163,5 +1163,9 @@ namespace OpenSim.Tests.Common.Mock
1163 { 1163 {
1164 } 1164 }
1165 1165
1166 public void SendRebakeAvatarTextures(UUID textureID)
1167 {
1168 }
1169
1166 } 1170 }
1167} 1171}
diff --git a/Prebuild/AUTHORS b/Prebuild/AUTHORS
deleted file mode 100644
index 9e86ac0..0000000
--- a/Prebuild/AUTHORS
+++ /dev/null
@@ -1,10 +0,0 @@
1Dave Hudson (jendave@yahoo.com),
2Matthew Holmes (matthew@wildfiregames.com)
3Dan Moorehead (dan05a@gmail.com)
4Rob Loach (http://www.robloach.net)
5C.J. Adams-Collier (cjac@colliertech.org)
6
7Patch Contributers
8lbsa71
9chi11ken
10sdague
diff --git a/Prebuild/COPYING b/Prebuild/COPYING
deleted file mode 100644
index c57c080..0000000
--- a/Prebuild/COPYING
+++ /dev/null
@@ -1,65 +0,0 @@
1BSD License
2Copyright (c)2004-2008
3
4See AUTHORS file for list of copyright holders
5
6Dave Hudson (jendave@yahoo.com),
7Matthew Holmes (matthew@wildfiregames.com)
8Dan Moorehead (dan05a@gmail.com)
9Rob Loach (http://www.robloach.net)
10C.J. Adams-Collier (cjac@colliertech.org)
11
12http://dnpb.sourceforge.net
13All rights reserved.
14
15Redistribution and use in source and binary forms, with or without
16modification, are permitted provided that the following conditions
17are met:
18
191. Redistributions of source code must retain the above copyright notice,
20 this list of conditions and the following disclaimer.
21
222. Redistributions in binary form must reproduce the above copyright notice,
23 this list of conditions and the following disclaimer in the documentation
24 and/or other materials provided with the distribution.
25
263. The names of the authors may not be used to endorse or promote
27 products derived from this software without specific prior written
28 permission.
29
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 POSSIBILITY OF SUCH DAMAGE.
42
43---
44
45Portions of src/Core/Targets/AutotoolsTarget.cs
46// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
47//
48// Permission is hereby granted, free of charge, to any person obtaining
49// a copy of this software and associated documentation files (the
50// "Software"), to deal in the Software without restriction, including
51// without limitation the rights to use, copy, modify, merge, publish,
52// distribute, sublicense, and/or sell copies of the Software, and to
53// permit persons to whom the Software is furnished to do so, subject to
54// the following conditions:
55//
56// The above copyright notice and this permission notice shall be
57// included in all copies or substantial portions of the Software.
58//
59// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
60// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
62// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
63// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
64// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
65// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Prebuild/ChangeLog b/Prebuild/ChangeLog
deleted file mode 100644
index bb8e7b0..0000000
--- a/Prebuild/ChangeLog
+++ /dev/null
@@ -1,461 +0,0 @@
12008-12-09T02:15 D. Moonfire <d.moonfire@mfgames.com>
2 * src/Core/Kernel.cs
3 - Added a /ppi target to get the results of processing but before
4 processing the actual results.
5 * src/Core/Preprocessor.cs
6 - Applied the patch from kanato with formatting changes.
7 - Uses the <?include file="" ?> format.
8 * tests/
9 - Added some lightweight tests to test the functionality of the
10 include patch.
11
122008-06-19T09:37 John Anderson <sontek@gmail.com>
13 * src/Core/Kernel.cs
14 - Only Loop through targets that are not abstract.
15 * src/Core/Targets/VSGenericTarget.cs
16 - Marked abstract and removed the Target attribute.
17
182008-06-16T17:37 John Anderson <sontek@gmail.com>
19 * src/Core/Nodes/ProjectNode.cs,data/prebuild-1.7.xsd
20 - Added the ability to hardcode guid's in the projects
21
222008-05-21T0737 C.J. Adams-Collier <cjac@colliertech.org>
23 * src/Core/Targets/AutotoolsTarget.cs
24 - catch exception when unable to compile AssemblyInfo.cs
25
262008-05-07T17:29 John Anderson <sontek@gmail.com>
27 * src/Core/Targets/VSGenericTarget.cs
28 - Generate asp.net output in bin\ folder (asp.net requires it there)
29
302008-04-30T17:29 John Anderson <sontek@gmail.com>
31 * src/Core/Nodes/DatabaseReferenceNode.cs,
32 src/Core/Nodes/Datanode.cs,
33 src/Core/Nodes/FileNode.cs,
34 src/Core/Nodes/FileNodes.cs,
35 src/Core/Nodes/MatchNode.cs,
36 src/Core/Targets/VS2008Target.cs,
37 src/data/prebuild-1.7.xsd
38 - Refactored the project generation code to handle web projects and more
39 logically handle embedded resources and designer files.
40
412008-04-30T17:29 Joseph Lombrozo <digitaljeebus@gmail.com>
42 * src/Core/Nodes/SolutionNode.cs
43 - Had solutions inherit Configurations in the same way that Projects do.
44
452008-04-29T06:35 Joseph Lombrozo <digitaljeebus@gmail.com>
46 * src/Core/Targets/VS2008Target.cs,
47 src/Core/Nodes/DatabaseProjectNode.cs,
48 src/Core/Nodes/DatabaseReferenceNode.cs,
49 src/data/prebuild-1.7.xsd
50 - Added database references to database projects.
51 - Prevented nested solutions from being written to disk.
52
532008-04-29T05:43 Joseph Lombrozo <digitaljeebus@gmail.com>
54 * src/Core/Targets/VS2008Target.cs
55 - Enabled embedded solutions to contain Files.
56
572008-04-29T04:13 Joseph Lombrozo <digitaljeebus@gmail.com>
58 * src/Core/VSVersion.cs
59 - Fixed spelling mistake in enum comment.
60 * src/Core/Attributes/DataNodeAttribute.cs
61 - Allowed the DataNodeAttribute to be attached to a single class
62 more than once, allowing one class to be used to parse more than
63 one node at a time.
64 * src/Core/Kernel.cs
65 - Changed CacheNodeTypes() to allow for multiple DataNodeAttribute
66 instances in one class. Refactored ProcessFile(...) to return Solutions,
67 rather than adding them to the Kernel.
68 * src/Core/Nodes/SolutionNode.cs
69 - Added Guid (for embedded folders)
70 - Added DatabaseProjects, Solutions and Processes to the SolutionNode
71 when parsing.
72 * src/Core/Nodes/ProjectNode.cs
73 - Added FrameworkVersion property to allow for 2.0/3.0/3.5 differentiation.
74 * src/Core/Targets/VS2008Target.cs, src/data/prebuild-1.7.xsd
75 - Added ability to have embedded solutions, and externally referenced
76 prebuild scripts.
77
782008-04-24T04:33 John M. Anderson <sontek@gmail.com>
79 * src/Core/Targets/VS2003Target.cs, src/Core/Targets/VSVersion.cs
80 - Moved the VSVersion enum into its own file.
81 * src/Core/Targets/VS2008Target.cs
82 - added support for VS2008
83 * src/Core/Nodes/ProjectNode.cs
84 - Added initial support for ASP.NET projects
85 * src/Core/Nodes/DatabaseProjectNode.cs
86 - Added support for Visual Studio database projects
87
882008-02-19T07:08 C.J. Adams-Collier <cjac@colliertech.org>
89 * TODO
90 - added some tasks from Sam Hocevar
91 * src/Core/Targets/AutotoolsTarget.cs
92 - added a missing end paren
93 * COPYING
94 - Removed Randy Ridge's name from the copyright. Looks to me like
95 his name was present only because the file was nabbed from Tao
96
972008-02-09T20:29 C.J. Adams-Collier <cjac@colliertech.org>
98 * COPYING
99 - added MIT/X11 license due to inclusion of code from Monodevelop
100 * THANKS
101 - added Lluis Sanchez Gual and Todd Berman - I yoinked code from
102 their pkg-config .pc file parser to build AutotoolsTarget.cs.
103 Sorry it took me so long to remember to add mention of you guys!
104 * src/Core/Targets/AutotoolsTarget.cs
105 - added MIT/X11 license. see above.
106
1072008-02-07T08:27 C.J. Adams-Collier <cjac@colliertech.org>
108 * AUTHORS
109 - consolidated names and contact info found laying around the
110 source
111 * src/Core/Kernel.cs
112 - updated copyright date
113 - re-formatted license for 80-column editor
114 - updated log banner to indicate new date, new authors
115 * src/Core/Targets/AutotoolsTarget.cs
116 - clarified reasoning behind use of constants in
117 AutotoolsTarget.ParsePCFile
118 - reduced length of some long lines using newline/indent
119 - added log messages for parsing .pc files, emitting solutions,
120 projects
121 - robustified the inter-package dependency resolution target
122 - log warning when we can't find assembly for <Reference />
123 - clarified code for case of inability to find embedded
124 autotools.xml
125 * src/data/autotools.xml
126 - adding system lookup of resgen2 to configure.ac
127 - fixed .resource -> .resources typo
128 - added a rule to create <foo>.response file containing all sources
129 - using @<foo>.response on $(CSC) command line instead of listing
130 all source files
131 * src/Properties/AssemblyInfo.cs
132 - re-formatted license for an 80-column editor
133 - added more authors to the AssemblyCopyright attribute
134 - bumped version to 2.0.3
135 * prebuild.xml
136 - bumped version to 2.0.3
137 * scripts/autotools.sh
138 - if 'mono' is in the path, run Prebuild.exe with it
139 - using dirname to capture correct path to prebuild.xml &c
140
1412008-02-06T17:18 C.J. Adams-Collier <cjac@colliertech.org>
142 * src/Core/Targets/NAntTarget.cs
143 - re-formatted the license for an 80-column editor
144 - added myself to the copyright
145 - added a fix submitted by Gryc Ueusp <gryc.ueusp@gmail.com>
146 * src/Core/Targets/AutotoolsTarget.cs
147 - updated copyright to include 2008
148 * THANKS
149 - created file, added Gryc Ueusp <gryc.ueusp@gmail.com>
150
1512008-01-01T14:50 C.J. Adams-Collier <cjac@colliertech.org>
152 * src/data/autotools.xml
153 - fixed .resx -> .resource compilation
154 - fixed failing edge case where Project is an unsigned Library
155 - added $(RESOURCE_SRC) to list of extra dist files
156 * src/Core/Targets/AutotoolsTarget.cs
157 - removed embeddedResources from extraDistFiles list
158
1592007-04-18T07:49 C.J. Adams-Collier <cjac@colliertech.org>
160 * src/data/prebuild-1.7.xsd
161 - removed default version from references
162
1632007-04-06T12:42 C.J. Adams-Collier <cjac@colliertech.org>
164 * src/data/autotools.xml
165 - added support for /doc: output when XmlDocFile is not empty
166 - not printing \t \\n on lines that have no content
167 - gacutil now installs the root assembly instead of the one under
168 bin/Debug or whatever
169
1702007-04-04T22:12 C.J. Adams-Collier <cjac@colliertech.org>
171 * src/Core/Targets/AutotoolsTarget.cs
172 - removed debugging Console.WriteLine()
173 * src/data/autotools.xml
174 - ensuring that install-sh and missing get distributed
175 - explicitly stating that the sources, snk, resources and binary
176 references live under $(srcdir)
177 - corrected uninstall target
178 - verified distcheck completes successfully
179
1802007-04-03T21:56 C.J. Adams-Collier <cjac@colliertech.org>
181 * src/Core/Targets/AutotoolsTarget.cs
182 - added a using for System.Diagnostics
183 - added enum ClrVersion for use with the pkg-config parser
184 - added class SystemPackage for use with the pkg-config parser
185 - removed explicit "private" property of members since it is implied
186 - flushing the stream-writer before it's closed
187 - removed excess braces around an if statement
188 ! NormalizeAsmName(), AddAssembly(), GetAssembliesWithLibInfo(),
189 GetAssembliesWithoutLibInfo(), ProcessPiece(),
190 GetVariableFromPkgConfig(), ParsePCFile(),
191 RegisterSystemAssemblies(), RunInitialization()
192 - pulled the above from MonoDevelop to parse the system pkgconfig
193 files and determine /pkg: arguments. Original sources are here:
194 http://svn.myrealbox.com/source/trunk/monodevelop/Core/src/MonoDevelop.Core/MonoDevelop.Core/SystemAssemblyService.cs
195 http://svn.myrealbox.com/source/trunk/monodevelop/Core/src/MonoDevelop.Core/MonoDevelop.Core/ClrVersion.cs
196 ! WriteProject()
197 - now gathering project version from AssemblyInfo.cs if it is part
198 of the project
199 - changed the declaration of the ArrayList's in the method
200 - now copying assembly .config files to the project, distributing,
201 installing
202 - making sure all needed files live under the Project directory
203 - copying strongname keys to project directory
204 - parsing AssemblyInfo.cs to determine assembly version
205 - removing all references to ".."
206 - removed superfluous if(project.References.Count > 0) around
207 for(int refNum = 0; refNum < project.References.Count; refNum++)
208 - removed use of runtimeLibs
209 - adding hook to copy sibling project's generated assemblies to
210 this project during Make time
211 - added extra dist target to ensure all files required to build
212 get distributed during "make dist"
213 - added new xslt processing args:
214 -- assemblyName
215 -- extraDistFiles
216 -- pkgLibs (/pkg:foo)
217 -- localCopyTargets (to copy sibling assemblies at Make time)
218 -- projectVersion (if determined from AssemblyInfo.cs)
219 -- hasAssemblyConfig (if there's a assembly.exe.config present)
220 ! Write()
221 - calling RunInitialization() to gather pkg-config data
222 * src/data/autotools.xml
223 - accepting new args passed from AutotoolsTarget.cs
224 - modernized configure.ac a bit
225 - using a version of tar that allows >99-char filenames
226 - added ASSEMBLY_NAME variable
227 - using assembly name rather than project name for gac installation
228 - generated assembly is now assembly name and not project name
229 - accepting /pkg: flags gathered from AutotoolsTarget.cs
230 - adding Makefile targets to copy sibling project assemblies to .
231 - fixed Debug, Release targets
232 - adding support for strongname key signing
233 - adding /unsafe support
234 - adding a clean make target
235 - only running gacutil /u if the assembly being uninstalled is in gac
236 - added some templates to determine each Configuration's .snk
237 - added explanation as to why .exe assemblies live in $prefix/lib
238 * src/Properties/AssemblyInfo.cs
239 - bumped assembly version
240 * prebuild.xml
241 - bumped assembly version
242
2432007-03-29T18:03 C.J. Adams-Collier <cjac@colliertech.org>
244 * src/Core/Targets/AutotoolsTarget.cs
245 ! WriteProject()
246 - re-named incorrectly-named variable gacLibs to systemLibs
247 - added another reference list, runtimeLibs which contains the
248 libs we will need at runtime. we use this to build a MONO_PATH
249 - added monoPath to the xslt args list
250 * src/data/autotools.xml
251 ! <ProjectMakefileAm />
252 - renamed gacLibs to systemLibs
253 - added the sources to the dist list
254 - added logic to install libs that aren't strongnamed
255 ! <ProjectWrapperScriptIn />
256 - accepting a param to update the MONO_PATH
257
2582007-03-28T19:46 C.J. Adams-Collier <cjac@colliertech.org>
259 * src/Core/Targets/MonoDevelopTarget.cs
260 ! CleanProject()
261 - using Assembly.LoadWithPartialName to locate the assembly
262 * src/Core/Targets/AutotoolsTarget.cs
263 ! WriteCombine()
264 - no longer using $PWD to determine a project's source dir; this
265 doesn't work with <Process /> elements
266 - passing the solution name to all templates - fixes
267 multi-solution prebuild systems
268 ! WriteProject()
269 - no longer using $PWD to determine a project's source dir; this
270 doesn't work with <Process /> elements
271 - passing the solution name to all templates - fixes
272 multi-solution prebuild systems
273 - copying strongname key to the autotools directory
274 - using Assembly.LoadWithPartialName to locate assemblies
275 * src/data/autotools.xml
276 ! <ProjectConfigureAc />
277 - fixed the .pc AC_CONFIG_FILES macro
278 ! <ProjectMakefileAm />
279 - added solution name param
280 - wrapping if type=exe check around script install macro
281 - added type=lib check and .pc file install macro
282 - added support for Configuration-specific builds (Debug, Release, etc)
283 - added strongname keyfile code
284 - TODO: support non-strongnamed library installation
285 ! <ProjectWrapperScriptIn />
286 - added space preservation attribute to stylesheet element
287 - added a lower-case project name variable
288 - added solution name param
289 - made for-each template more specific
290 ! <SolutionAutogenSh />
291 - added solution name param
292 ! <SolutionConfigureAc />
293 - added solution name param
294 ! <SolutionMakefileAm />
295 - added solution name param
296 ! <ProjectPcIn />
297 - added solution name param
298
2992007-03-27T09:33 C.J. Adams-Collier <cjac@colliertech.org>
300 * src/Core/Targets/AutotoolsTarget.cs
301 - now processing the wrapper script if type is "Exe" or "WinExe"
302 * src/data/autotools.xml
303 ! <ProjectConfigureAc />
304 - being more exact about where text escaping is used
305 - using the correct variable name for the GACUTIL_FLAGS template
306 - using correct test="" for the AC_CONFIG_FILES macros
307 ! <ProjectMakefileAm />
308 - uncommented the bin_SCRIPTS section now that the script is being
309 generated correctly
310 ! <ProjectWrapperScriptIn />
311 - fixed whitespace at beginning of file, before #!
312 - using lower-case packageName to indicate installation location
313
3142007-03-27T09:33 C.J. Adams-Collier <cjac@colliertech.org>
315 * src/data/autotools.xml
316 ! <ProjectConfigureAc />
317 * added a lcProjectName which is $projectName lower-cased
318 * moved autoconf template specifier near AC_OUTPUT
319 * AC_OUTPUT with args is deprecated. now using AC_CONFIG_FILES
320 * placed AC_CONFIG_FILES() calls for wrapper script or pkg-config
321 file in xslt project type checks
322 ! <ProjectMakefileAm />
323 * commented out bin_SCRIPTS
324 * added a lcProjectName which is $projectName lower-cased
325 * using $lcProjectName instead of the longer version
326
3272007-03-27T08:39 C.J. Adams-Collier <cjac@colliertech.org>
328 * src/data/autotools.xml
329 ! <ProjectMakefileAm />
330 - added whitespace-preservation
331 - added the missing projectName param
332 - replaced bin_SCRIPTS with something that worked
333
3342007-03-27T07:56 C.J. Adams-Collier <cjac@colliertech.org>
335 * src/data/autotools.xml
336 ! <ProjectConfigureAc />
337 - cleaned up duplicate checks
338 - placed initialization macros above system check macros
339 - added some more messages about what's going on
340 - added GACUTIL_FLAGS variable including /package option
341 ! <ProjectMakefileAm />
342 - added an incomplete bin_SCRIPTS
343 - RCS check says "building" instead of "compiling"
344 ! <SolutionConfigureAc />
345 - removed macros that are useful only for projects
346 ! <ProjectWrapperScriptIn />
347 - created this element on this revision
348 - this is a wrapper shell script that lives in the $PATH and runs
349 the CIL assembly
350
3512007-03-26T20:18 C.J. Adams-Collier <cjac@colliertech.org>
352 * src/Core/Targets/AutotoolsTarget.cs
353 - creating new template arguments to contain the list of libs to
354 reference: source, binary & GAC
355 - source libs are included as part of this solution (untested)
356 - binary libs are distributed with the source (untested)
357 - GAC libs are assumed to be in the GAC or other lib path (tested)
358 * src/data/autotools.xml
359 - created new params through which to accept reference info
360 - created a working $(CSC) line
361 - added a TODO item for ordering project dependency for
362 AC_CONFIG_SUBDIRS code
363
3642007-03-26T08:41 C.J. Adams-Collier <cjac@colliertech.org>
365 * src/Core/Targets/AutotoolsTarget.cs
366 - now creating list of source files in managed code and passing
367 them to the template via <xsl:param>s
368 * src/data/prebuild-1.7.xsd
369 - updated the header comment to 2007
370 * src/data/autotools.xml
371 ! <ProjectConfigureAc>
372 - copied checks from Solution-level configure.ac
373 - copied solution-level config status
374 ! <ProjectMakefileAm>
375 - added <xsl:param> elements for file list to be passed through
376 - made a temporary target for the assembly we're building
377 - added this target to the deps of "all:"
378 ! <SolutionConfigureAc>
379 - changed status header/footer from "- - -" to "==="
380
3812007-03-23T08:33 C.J. Adams-Collier <cjac@colliertech.org>
382 Added version attribute handling code for Property element
383 Added description element handling code
384 * prebuild.xml
385 - added /Prebuild/Solution/Property/@version attribute
386 - added /Prebuild/Solution/Property/Description element
387 * src/Core/Nodes/ProjectNode.cs
388 - added some docs where they were missing and obvious
389 - added code to handle @version
390 * src/Core/Nodes/DescriptionNode.cs
391 - new file. Used to handle /Prebuild/Solution/Property/Description
392 * src/Core/Targets/AutotoolsTarget.cs
393 - added mkdirDashP(), a recursive directory creation method
394 - WriteProject() now copies the files to autotools/
395 * src/data/prebuild-1.7.xsd
396 - added /Prebuild/Solution/Property/Description element
397 - added /Prebuild/Solution/Property/@version attribute
398 * src/data/autotools.xml
399 - removed excess <xsl:value-of select="$projectName"/>
400 - explicitly using dnpb: prefix
401
4022007-03-23T04:31 C.J. Adams-Collier <cjac@colliertech.org>
403 Merged code from my stripped-down test
404 Adding support for the /Prebuild/Solution/Project/Author element
405 * prebuild.xml
406 - added Author elements
407 - cleaned up the really long Project element
408 * src/Core/Nodes/ProjectNode.cs
409 - added Author tag processing code
410 * src/Core/Nodes/AuthorNode.cs
411 - Created to process Author elements
412 - based off of ReferencePathNode.cs
413 * src/Core/Targets/AutotoolsTarget.cs
414 - merged code from https://svn.colliertech.org/mono/dnpbAutotools/dnpbAutotools/test.cs
415 - renamed old WriteCombine to WriteCombineOld
416 - renamed old WriteProject to WriteProjectOld
417 * src/data/prebuild-1.7.xsd
418 - added Author element to Project
419 * src/data/autotools.xml
420 - lower-cased utf
421
422
4232007-03-22T13:58 C.J. Adams-Collier <cjac@colliertech.org>
424 Exposing an XmlDocument that represents the prebuild.xml file
425 passed to the program
426
427 * src/Core/Kernel.cs
428 - created an object member called XmlDocument m_CurrentDoc
429 - created a property to access its value
430 - using m_CurrentDoc to load up the prebuild.xml file rather than
431 a local variable called "doc"
432
4332007-03-22 C.J. Adams-Collier <cjac@colliertech.org>
434 * prebuild.xml
435 - added autotools.xml created at https://svn.colliertech.org/mono/dnpbAutotools/dnpbAutotools/autotools.xml
436 * src/data/autotools.xml
437 - the same
438 * src/Core/Targets/MonoDevelopTarget.cs
439 - fixed bug introduced in r206
440
4412007-03-07 C.J. Adams-Collier <cjcollier@colliertech.org>
442 * src/data/prebuild-1.7.xsd
443 - added version attribute to Solution and Project elements
444
4452006-11-04T00:38 C.J. Adams-Collier <cjcollier@colliertech.org>
446 * placing AssemblyInfo.cs into Properties/
447 * Fixed double-mention of the package name
448
4492006-11-03T15:23 C.J. Adams-Collier <cjcollier@colliertech.org>
450 * corrected a problem in the Include.am generation code
451 * created the new .exe
452 * copied it to the root of the build
453
4542006-11-03T14:57 C.J. Adams-Collier <cjcollier@colliertech.org>
455 * Updated the .exe file
456
4572006-11-03 C.J. Adams-Collier <cjcollier@colliertech.org>
458 * Added a TODO file
459 * Added a ChangeLog file
460 * applied some fixes for autotools gac and pkg-config installation
461 problems
diff --git a/Prebuild/INSTALL b/Prebuild/INSTALL
deleted file mode 100644
index 23e5f25..0000000
--- a/Prebuild/INSTALL
+++ /dev/null
@@ -1,236 +0,0 @@
1Installation Instructions
2*************************
3
4Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
5Software Foundation, Inc.
6
7This file is free documentation; the Free Software Foundation gives
8unlimited permission to copy, distribute and modify it.
9
10Basic Installation
11==================
12
13These are generic installation instructions.
14
15 The `configure' shell script attempts to guess correct values for
16various system-dependent variables used during compilation. It uses
17those values to create a `Makefile' in each directory of the package.
18It may also create one or more `.h' files containing system-dependent
19definitions. Finally, it creates a shell script `config.status' that
20you can run in the future to recreate the current configuration, and a
21file `config.log' containing compiler output (useful mainly for
22debugging `configure').
23
24 It can also use an optional file (typically called `config.cache'
25and enabled with `--cache-file=config.cache' or simply `-C') that saves
26the results of its tests to speed up reconfiguring. (Caching is
27disabled by default to prevent problems with accidental use of stale
28cache files.)
29
30 If you need to do unusual things to compile the package, please try
31to figure out how `configure' could check whether to do them, and mail
32diffs or instructions to the address given in the `README' so they can
33be considered for the next release. If you are using the cache, and at
34some point `config.cache' contains results you don't want to keep, you
35may remove or edit it.
36
37 The file `configure.ac' (or `configure.in') is used to create
38`configure' by a program called `autoconf'. You only need
39`configure.ac' if you want to change it or regenerate `configure' using
40a newer version of `autoconf'.
41
42The simplest way to compile this package is:
43
44 1. `cd' to the directory containing the package's source code and type
45 `./configure' to configure the package for your system. If you're
46 using `csh' on an old version of System V, you might need to type
47 `sh ./configure' instead to prevent `csh' from trying to execute
48 `configure' itself.
49
50 Running `configure' takes awhile. While running, it prints some
51 messages telling which features it is checking for.
52
53 2. Type `make' to compile the package.
54
55 3. Optionally, type `make check' to run any self-tests that come with
56 the package.
57
58 4. Type `make install' to install the programs and any data files and
59 documentation.
60
61 5. You can remove the program binaries and object files from the
62 source code directory by typing `make clean'. To also remove the
63 files that `configure' created (so you can compile the package for
64 a different kind of computer), type `make distclean'. There is
65 also a `make maintainer-clean' target, but that is intended mainly
66 for the package's developers. If you use it, you may have to get
67 all sorts of other programs in order to regenerate files that came
68 with the distribution.
69
70Compilers and Options
71=====================
72
73Some systems require unusual options for compilation or linking that the
74`configure' script does not know about. Run `./configure --help' for
75details on some of the pertinent environment variables.
76
77 You can give `configure' initial values for configuration parameters
78by setting variables in the command line or in the environment. Here
79is an example:
80
81 ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
82
83 *Note Defining Variables::, for more details.
84
85Compiling For Multiple Architectures
86====================================
87
88You can compile the package for more than one kind of computer at the
89same time, by placing the object files for each architecture in their
90own directory. To do this, you must use a version of `make' that
91supports the `VPATH' variable, such as GNU `make'. `cd' to the
92directory where you want the object files and executables to go and run
93the `configure' script. `configure' automatically checks for the
94source code in the directory that `configure' is in and in `..'.
95
96 If you have to use a `make' that does not support the `VPATH'
97variable, you have to compile the package for one architecture at a
98time in the source code directory. After you have installed the
99package for one architecture, use `make distclean' before reconfiguring
100for another architecture.
101
102Installation Names
103==================
104
105By default, `make install' installs the package's commands under
106`/usr/local/bin', include files under `/usr/local/include', etc. You
107can specify an installation prefix other than `/usr/local' by giving
108`configure' the option `--prefix=PREFIX'.
109
110 You can specify separate installation prefixes for
111architecture-specific files and architecture-independent files. If you
112pass the option `--exec-prefix=PREFIX' to `configure', the package uses
113PREFIX as the prefix for installing programs and libraries.
114Documentation and other data files still use the regular prefix.
115
116 In addition, if you use an unusual directory layout you can give
117options like `--bindir=DIR' to specify different values for particular
118kinds of files. Run `configure --help' for a list of the directories
119you can set and what kinds of files go in them.
120
121 If the package supports it, you can cause programs to be installed
122with an extra prefix or suffix on their names by giving `configure' the
123option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
124
125Optional Features
126=================
127
128Some packages pay attention to `--enable-FEATURE' options to
129`configure', where FEATURE indicates an optional part of the package.
130They may also pay attention to `--with-PACKAGE' options, where PACKAGE
131is something like `gnu-as' or `x' (for the X Window System). The
132`README' should mention any `--enable-' and `--with-' options that the
133package recognizes.
134
135 For packages that use the X Window System, `configure' can usually
136find the X include and library files automatically, but if it doesn't,
137you can use the `configure' options `--x-includes=DIR' and
138`--x-libraries=DIR' to specify their locations.
139
140Specifying the System Type
141==========================
142
143There may be some features `configure' cannot figure out automatically,
144but needs to determine by the type of machine the package will run on.
145Usually, assuming the package is built to be run on the _same_
146architectures, `configure' can figure that out, but if it prints a
147message saying it cannot guess the machine type, give it the
148`--build=TYPE' option. TYPE can either be a short name for the system
149type, such as `sun4', or a canonical name which has the form:
150
151 CPU-COMPANY-SYSTEM
152
153where SYSTEM can have one of these forms:
154
155 OS KERNEL-OS
156
157 See the file `config.sub' for the possible values of each field. If
158`config.sub' isn't included in this package, then this package doesn't
159need to know the machine type.
160
161 If you are _building_ compiler tools for cross-compiling, you should
162use the option `--target=TYPE' to select the type of system they will
163produce code for.
164
165 If you want to _use_ a cross compiler, that generates code for a
166platform different from the build platform, you should specify the
167"host" platform (i.e., that on which the generated programs will
168eventually be run) with `--host=TYPE'.
169
170Sharing Defaults
171================
172
173If you want to set default values for `configure' scripts to share, you
174can create a site shell script called `config.site' that gives default
175values for variables like `CC', `cache_file', and `prefix'.
176`configure' looks for `PREFIX/share/config.site' if it exists, then
177`PREFIX/etc/config.site' if it exists. Or, you can set the
178`CONFIG_SITE' environment variable to the location of the site script.
179A warning: not all `configure' scripts look for a site script.
180
181Defining Variables
182==================
183
184Variables not defined in a site shell script can be set in the
185environment passed to `configure'. However, some packages may run
186configure again during the build, and the customized values of these
187variables may be lost. In order to avoid this problem, you should set
188them in the `configure' command line, using `VAR=value'. For example:
189
190 ./configure CC=/usr/local2/bin/gcc
191
192causes the specified `gcc' to be used as the C compiler (unless it is
193overridden in the site shell script). Here is a another example:
194
195 /bin/bash ./configure CONFIG_SHELL=/bin/bash
196
197Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
198configuration-related scripts to be executed by `/bin/bash'.
199
200`configure' Invocation
201======================
202
203`configure' recognizes the following options to control how it operates.
204
205`--help'
206`-h'
207 Print a summary of the options to `configure', and exit.
208
209`--version'
210`-V'
211 Print the version of Autoconf used to generate the `configure'
212 script, and exit.
213
214`--cache-file=FILE'
215 Enable the cache: use and save the results of the tests in FILE,
216 traditionally `config.cache'. FILE defaults to `/dev/null' to
217 disable caching.
218
219`--config-cache'
220`-C'
221 Alias for `--cache-file=config.cache'.
222
223`--quiet'
224`--silent'
225`-q'
226 Do not print messages saying which checks are being made. To
227 suppress all normal output, redirect it to `/dev/null' (any error
228 messages will still be shown).
229
230`--srcdir=DIR'
231 Look for the package's source code in directory DIR. Usually
232 `configure' can determine that directory automatically.
233
234`configure' also accepts some other, not widely useful, options. Run
235`configure --help' for more details.
236
diff --git a/Prebuild/NEWS b/Prebuild/NEWS
deleted file mode 100644
index 3ab3108..0000000
--- a/Prebuild/NEWS
+++ /dev/null
@@ -1,200 +0,0 @@
1Prebuild is an XML-driven pre-build tool allowing developers to easily generate project or make files for major IDE's and .NET development tools including: Visual Studio 2005, Visual Studio 2003, Visual Studio 2002, SharpDevelop, MonoDevelop, and NAnt.
2
3Documentation and downloads are available at http://dnpb.sourceforge.net.
4
5Prebuild is licensed under the BSD license.
6
7[ XXXXXXX XX, XXX - 1.3.2 ]
8 + Added Keyfile signing to NAnt target and VS2005 target
9 + Updated XSD file to 1.7
10 + Boo and VisualBasic Language support in VS2005 target
11 + Added basic Autotools target. It creates a non-recursive Autotools system.
12 ! Multiple files can be excluded from the Match node
13 ! VS2005 now handles .resx files correctly.
14 ! NAnt and Autotools now handle defines
15 ! NAnt and Autotools now handle resources
16 + Conditional XML variables can be passed through the command line.
17 + Added /install and /remove command line flags to install and remove assemblies from the GAC
18 + Many fixes to VS2005 target
19
20[ July 21, 2006 - 1.3.1 ]
21 ! VS2005 fixes from Rob Loach
22 ! NAnt fixes from Rob Loach and David Hudson
23 ! XML doc fixes from Rob Loach
24 + Added SharpDevelop2 target (really just uses VS2005 target)
25 ! Fixed bug with BuildEvents in Monodevelop target
26 + Passing /yes will default to answering yes to any warnings
27
28[ February 28, 2006 - 1.3 ]
29 + Added MonoDevelop target.
30 + Added NAnt target.
31 + Lots of fixes to all targets.
32 * Cleaned up the code using FXCop.
33 * Updated schema to 1.6 to fix a typo and add a new parameter.
34 * jendave is now the maintainer of the project. RobLoach has been added as a developer.
35 * Removed references to 'dnpb'.
36 + Added rudimentary support for pre- and post- build scripts
37 * Updated examples.
38
39[ August 5, 2004 - 1.2 ]
40 + Added Visual Studio Express (vs2005express) target contributed by Borrillis and modified for use with different languages
41 + Added the allowedgroups command line option followed by a pipe-delimited list of project group filter flags (eg. Group1|Group2) allow optional filtering of all projects that dont have at least one of these flags
42 + Added the filterGroups XML attribute to the project node and updated the scheme to v1.5 for this addition, it is used to specified the delimited list of filter groups to which a project belongs
43 * Modified the removedir command line option to allow for a pipe-delimited list of directory names
44 ! Modified the resource loading code to search for resourced without the prepended namespace (as Visual Studio .NET does it) to allow for it to be compiled with SharpDevelop as well
45 + Added the GenerateXmlDocFile boolean option to the Options XML element
46 * Changed the behavior of the XmlDocFile option so that if not specified it uses the assemblyName (without file extension) + .xml for the file name instead of just not generating the file since the new GenerateXmlDocFile takes care of this
47
48[ January 3, 2004 - 1.1 ]
49 ! Replaced regex use for more efficient manual parsing to allow use on non-windows platforms with Mono which has Regex problems
50 + Added the checkOsVars attribute to the root element for enabling interpolation for Enviroment variables in the form ${var}, otherwise no checking is performed for efficiency-sake
51 * Make the version attribute on the root element optional as it isn't used and not needed since the schema url contains the version
52
53[ December 30, 2004 - 1.1 ]
54 ! Applied Leed's fix for SharpDevelop references
55 + Rewrote much of the processing for better validation and without the use of a temp file
56 + Added support for configurations at the project level which are named All. They now apply changes to all Solution level defined configs
57 * Changed all spaces into tabs
58 + Added support for the None build action
59 * Replaced all sequence's in the XML schema for all's because the order doesn't matter since the xml file is loaded into an XmlDocument
60
61[ December 25, 2004 - 1.0 ]
62 + Added the /removedir option for cleaning directories like obj before file releases
63 + Changed WriteTempXml() and the new DeleteTempXml() methods to be compiled only in DEBUG builds
64 * Made path optional for Match elements (defaults to current directory) and updates schema for it
65 ! Fixed XML example in the readme.txt
66 + Added example xml files to docs directory
67 * Updated license.txt to add Dan Moorehead and update copyright years
68 + Updated prebuild.xml to take advantage of the default path attribute for match elements
69 + Updated Clean to delete the obj directories
70
71[ December 25, 2004 - 0.13 ]
72 + Added dnpb.exe so that it can be used to generate the project files
73 + Added dnpb.ico
74 * Added parameterless Write statement to Log for writing a single line
75 * Changed scehema to version 1.3 for support of icon attribute
76 * Added support for All configuration name under a Project node signifying common settings for all configurations
77 ! Fixed the SupressWarnings by adding the corresponding field to OptionsNode
78 * Wrote documentation in docs/readme.txt
79 * Added Dan Moorehead to copyrights and extended date from 2004 to 2004-2005
80 * Updated prebuild.xml
81 * Optimized Log class
82 * Updated OutputUsage()
83 * /clean targets all by default
84 * No log file is used by default, /log without value specified uses default file name
85 + Added support for the /pause which pauses the utility after execution to observe output
86
87
88[ September 27, 2004 - 0.12.2a ]
89 ! Fixed a nasty bug when trying to delete our temp file for pre-processing.
90
91[ September 15, 2004 - 0.12.2 ]
92 + Expanded platform identification, thanks to the NAnt guys for shedding some
93 light on how to properly check for UNIX platforms! Thanks guys!
94 * POSIX OS identifier changed to UNIX. Valid OS names are now "Win32", "UNIX",
95 and "Unknown".
96 ! Fixed SharpDevelop target to properly use the 'rootNamespace' attribute of
97 the Project tag.
98 + New command-line switch, /ppo, forces DNPB to pre-process the file and write
99 the pre-processed file. This allows you to test/debug your pre-processor
100 macros. No other processing will be done. You can specify a target file as
101 a paramter for the /ppo switch, or DNPB will write the file 'preprocessed.xml'
102 if you do not specify a file.
103 + The Match tag now has a 'buildAction' attribute which functions exactly like
104 the attribute of the same name for the File tag.
105
106[ August 5, 2004 - 0.12.1 ]
107 + Added environment variable expansion for all values. Environment variables
108 should be listed in the form ${VAR}.
109
110[ July 30, 2004 - 0.12.0 ]
111 + Added preprocessing via XML processing information tags. Available tags
112 are: <?if <exp> ?>, <?elseif <exp> ?>, <?else ?> and <?endif ?>. The
113 current expression parser is very basic, but will be replaced with a more
114 capable parser over time. Current operators available are: =, !=, <, >,
115 <=, >=. Current test variables available: OS, RuntimeVersion, RuntimeMajor,
116 RuntimeMinor, RuntimeRevision.
117
118[ July 27, 2004 - 0.11.4 ]
119 + Added 'useRegex' attribute to the Match tag. Matches can now use regular
120 expressions to match filenames.
121 + Added the 'assemblyName' attribute to the Project tag. Projects can now
122 set their output assembly name.
123 ! Fixed several bugs in the way that Project tags inheirt their parent
124 Solutions configuration options. This operation should now work fully as
125 intended.
126 ! Due to some wierdness, Project Guid's are now stored as part of the Project
127 node and created at parse time.
128
129[ May 11, 2004 - 0.11.3 ]
130 ! Fixed a bug where I was writing the wrong property name for a projects root
131 namespace.
132 ! Removed a DEBUG statement I had left in the code in 0.11.2.
133 ! Fixed a bug in the VS2002 writer which caused the version variables to not
134 be overriden correctly.
135 + Added the rootNamespace property to the <Project> element, allowing you to
136 specify the root namespace.
137 * /target and /clean are now mutually exclusive command line switches, and
138 they both now take the all option. In the case of /target all, all build
139 file for all targets will be created. In the case of /clean all, the user
140 will be prompted to make sure they want to do it, and if so, will clean
141 all build files for all targets.
142
143[ April 22, 2004 - 0.11.2 ]
144 ! Fixed a bug with the /file command-line operator. Was using the unresolved
145 file path rather then the resolved one, was making the attempt to open the
146 dnpb file fail.
147 ! Fixed a bug in the schema that required at least 1 solution and 1 reference
148 path. We can do just fine with 0 of either of these. Some files may be all
149 <Process> statements and not have any <Solution> tags.
150 ! Fixed a bug that caused the project references not to be written with the
151 SharpDevelop target.
152 * Changed the schema to version 1.2, allowing for Configuration nodes to exist
153 under project nodes. The inheritance of values is hierarchical. Meaning, if
154 you define a configuration named Debug at the Soltion level, and one by the
155 same name at the Project level, the one at the Project level will first
156 inherit the options of the Solution level configuration, then set it's own
157 options. If you define a configuration at the Project level and it does not
158 exist at the Solution level, it will be created at the Solution level.
159 * Project references should now work correctly across the board. Note that due
160 to a restriction in Visual Studio, you can only reference projects in the same
161 solution.
162
163[ April 21, 2004 - 0.11.1 ]
164 ! Fixed a problem with resolving paths in various targets. Was not properly
165 setting the CWD.
166 * Schema updated to 1.1, moving the ReferencePath element from the Options
167 element to the Project element. This makes more logical sense, given that
168 reference paths are resolved relative to the project path. Any prebuild.xml
169 file referecning verison 1.0 will fail! Please update to the 1.1 schema.
170
171[ April 19, 2004 - 0.11.0 ]
172 * Added several attributes across the code to make FxCop happy
173 ! Fixed bugs in reference paths being written in the VS targets.
174 ! Fixed a bug in ProjectNode which was doing two CWDStack.Push() calls instead of
175 a Push/Pop pair. Was wreaking havoc with <Process> tags.
176 ! Fixed some bugs in the path tracking, both the Project and Solution nodes now
177 have a FullPath property, which is the full path to the file resolved at load
178 time. This should fix all path relativity problems.
179 + Added new /clean switch, allowing the target to clean up any files it generated.
180 in accordance, the ITarget interface has been updated to support a new Clean()
181 method.
182 + Completed addition of the <Process> tag, to allow the referencing of external
183 prebuild.xml files.
184 + Added the runtime attribute to the Project element. This allows the developer
185 to specify which runtime a project should target (Mono or Microsoft). This is
186 of course ignored in certain targets like the Visual Studio targets.
187 + Added the SharpDevelop target.
188
189[ April 13, 2004 - 0.10.1a ]
190 + Added the buildAction attribute to the File node. This is needed for dnpb
191 to even be able to bootstrap itself (dnpb-1.0.xsd must be an embedded resource)
192
193[ April 13, 2004 - 0.10.1 ]
194 * First Release
195
196[ Key ]
197* = Change or information
198+ = Addition
199! = Bug Fix
200
diff --git a/Prebuild/README b/Prebuild/README
deleted file mode 100644
index e8a2d69..0000000
--- a/Prebuild/README
+++ /dev/null
@@ -1,274 +0,0 @@
1Prebuild Instructions
2
3Prebuild is an XML-driven pre-build tool allowing developers to easily generate project or make files for major IDE's and .NET development tools including: Visual Studio 2005, Visual Studio 2003, Visual Studio 2002, SharpDevelop, SharpDevelop2, MonoDevelop, and NAnt.
4
5_______________________________________________________________________________
6Overview
7
8Prebuild can be either be run from the command line to generate the
9project and make files or you can execute the included batch (*.bat)
10and Unix Shell script (*.sh) files.
11
12_______________________________________________________________________________
13The currently supported developement tools and their associated batch
14and shell script files.
15
16Visual Studio .NET 2005 (VS2005.bat)
17Visual Studio .NET 2003 (VS2003.bat)
18Visual Studio .NET 2002 (VS2002.bat)
19SharpDevelop (SharpDevelop.bat) - http://www.icsharpcode.net/OpenSource/SD/
20SharpDevelop2 (SharpDevelop.bat) - http://www.icsharpcode.net/OpenSource/SD/
21MonoDevelop (MonoDevelop.sh) - http://www.monodevelop.com/
22NAnt (nant.sh and nant.bat) - http://nant.sourceforge.net/
23Autotools (autotools.bat and autotools.sh) - http://en.wikipedia.org/wiki/GNU_build_system
24
25Notes:
26
27A Unix Shell script is provided for MonoDevelop, as it does not run on
28Windows at this time.
29
30Visual Studio .NET 2005 and the Visual Express IDE's can import
31solutions from older versions of Visual Studio .NET.
32
33Makefiles are not currently supported.
34
35_______________________________________________________________________________
36Command Line Syntax:
37
38Example:
39> Prebuild /target vs2003
40
41This will generate the project files for Visual Studio.NET 2003 and
42place the redirect the log to a file named PrebuildLog.txt in the
43parent directory
44
45
46The syntax structure is as below, where commandParameter is optional
47depending on the command and you can provide several option-value
48pairs.
49
50Note: The '> ' signifies the command prompt, do not enter this literally
51
52> Prebuild /<option> <commandParameter>
53
54> Prebuild /target vs2003 /pause
55
56> Prebuild /target vs2003 /log ../Log.txt /pause /ppo /file ProjectConfig.xml
57
58> Prebuild /target sharpdev /log
59
60> Prebuild /removedir obj|bin
61
62> Prebuild /target vs2003 /allowedgroups Group1|Group2
63
64> Prebuild /clean
65
66> Prebuild /clean /yes
67
68> Prebuild /clean vs2003
69
70_______________________________________________________________________________
71Command Line Options:
72
73/usage - Shows the help information on how to use Prebuild and what
74the different options are and what they do
75
76/clean - The project files generated for the target type specified as
77a parameter for this option will be deleted. If no value is specified
78or if 'all' is specified, then project files for all the target types
79will be deleted.
80
81/target - Specified the name of the development tool for which project
82or make files will be generated. Possible parameter values include:
83vs2003, vs2002, sharpdev
84
85/file - Specifies the name of the XML which defines what files are to
86be referenced by the generated project files as well as configures the
87options for them. If not specified, prebuild.xml in the current
88directory will be used as the default.
89
90/log - Specified the log file that should be written to for build
91errors. If this option is not specified, no log file is generated,
92but if just no value is specified, then the defaul filename will be
93used for the log (Prebuild.log).
94
95/ppo - Preprocesses the xml file to test for syntax errors or problems
96but doesn't generate the files
97
98/pause - Shows the console until you press a key so that you can view
99the messages written while performing the specified actions.
100
101This allows you to check if an errors occurred and - if so - what it
102was.
103
104/showtargets - Shows a list of all the targets that can be specified
105as values for the /clean and /target commands.
106
107/allowedgroups - This is followed by a pipe-delimited list of project
108group filter flags (eg. Group1|Group2) allow optional filtering of all
109projects that dont have at least one of these flags
110
111/removedir - This is followed by a pipe-delimited list of directory
112names that will be deleted while recursivly searching the directory of
113the prebuild application and its child directories (eg. use obj|bin to
114delete all output and temporary directories before file releases)
115
116/yes - Answer yes to any warnings (e.g. when cleaning all projects).
117
118_______________________________________________________________________________
119Example Batch Files and Shell Scripts
120
121NOTE: Common batch and shell script files are included with Prebuild source and file releases.
122______________________________
123MonoDevelop
124
125#!/bin/sh
126# Generates a solution (.mds) and a set of project files (.mdp)
127
128# for MonoDevelop, a Mono port of SharpDevelop
129# (http://icsharpcode.net/OpenSource/SD/Default.aspx)
130
131./Prebuild /target monodev /pause
132
133______________________________
134Visual Studio .NET 2003
135
136@rem Generates a solution (.sln) and a set of project files (.csproj)
137@rem for Microsoft Visual Studio .NET 2002
138Prebuild /target vs2003 /pause
139
140Notes:
141Text after lines that start with @rem are comments and are not evaluated
142You can also place pause on the last line instead of specifing the /pause command.
143
144_______________________________________________________________________________
145Example XML Configuration File
146
147Note:
148
149XML Comments (<!-- Comment -->) are used to markup the prebuild.xml
150file with notes
151
152The below file may be out-of-date, however the RealmForge Prebuild
153file serves as an up-to-date and extensive example.
154
155It can be viewed using Tigris.org's WebSVN
156(http://realmforge.tigris.org/source/browse/realmforge/trunk/src/prebuild.xml)
157by just clicking on the "view file" link for the latest revision.
158
159_________________________________
160
161<?xml version="1.0" encoding="utf-8"?>
162 <!--The version of the XML schema specified in the version and xmlns attributes should match the one for which the version of Prebuild.exe used was compiled for. In this example it is the version 1.3 schema, you can find the XSD schema file at the url specified in the xmlns attribute. -->
163<Prebuild version="1.6" xmlns="http://dnpb.sourceforge.net/schemas/prebuild-1.6.xsd">
164 <Solution name="RealmForge"> <!--The title and file name for the solution, combine, workspace, or project group (depending on what development tool you are using)-->
165 <!--Configurations found as children of Solution are used as templates for the configurations found in the project, this allows you to avoid writing the same options in each project (and maintaining each of these). You can provide defaults and then override them in the configurations defined for each project. All options are optional.-->
166 <Configuration name="Debug">
167 <Options>
168 <!-- simple logically expressions can be evaluated, if, else, elseif, and endif are valid statements. Note that it is not neccisary to define POSIX or WIN32 -->
169 <?if OS = "Win32" ?>
170 <CompilerDefines>DEBUG;TRACE;WIN32</CompilerDefines>
171 <?else ?>
172 <CompilerDefines>DEBUG;TRACE;POSIX</CompilerDefines>
173 <?endif ?>
174 <OptimizeCode>false</OptimizeCode>
175 <CheckUnderflowOverflow>false</CheckUnderflowOverflow>
176 <AllowUnsafe>false</AllowUnsafe>
177 <WarningLevel>4</WarningLevel>
178 <!-The filter for the number of warnings or errors shown and the tolerance level as to what is an error. This is value from 0 to 4 where 4 is the most strict (least tolerent).-->
179
180 <WarningsAsErrors>false</WarningsAsErrors>
181 <SuppressWarnings>1591;219;1573;1572;168</SuppressWarnings>
182 <!-- A semicolon ';' delimited list of the warnings that are filtered and not shown in the output window during compiling a project. Only include the number portion of the warning codes that are shown in output during compilation (eg CS1591, should be entered as 1591)-->
183
184 <OutputPath>..\bin</OutputPath>
185 <DebugInformation>true</DebugInformation>
186 <RegisterComInterop>false</RegisterComInterop>
187 <IncrementalBuild>true</IncrementalBuild>
188 <BaseAddress>285212672</BaseAddress>
189 <FileAlignment>4096</FileAlignment>
190 <NoStdLib>false</NoStdLib>
191 <XmlDocFile>Docs.xml</XmlDocFile>
192 </Options>
193 </Configuration>
194 <Configuration name="Release"> <!-- You can define multple configurations that projects can have, but there is no way to define which one is selected by default as this is a part of the user preferences for a project, not the solution or project files -->
195 <Options>
196 <CompilerDefines>TRACE</CompilerDefines>
197 <OptimizeCode>true</OptimizeCode>
198 <CheckUnderflowOverflow>false</CheckUnderflowOverflow>
199 <AllowUnsafe>false</AllowUnsafe>
200 <WarningLevel>4</WarningLevel>
201 <WarningsAsErrors>false</WarningsAsErrors>
202 <SuppressWarnings>1591;219;1573;1572;168</SuppressWarnings>
203 <OutputPath>..\bin</OutputPath>
204 <DebugInformation>false</DebugInformation>
205 <RegisterComInterop>false</RegisterComInterop>
206 <IncrementalBuild>true</IncrementalBuild>
207 <BaseAddress>285212672</BaseAddress>
208 <FileAlignment>4096</FileAlignment>
209 <NoStdLib>false</NoStdLib>
210 <GenerateXmlDocFile>true</GenerateXmlDocFile>
211 <XmlDocFile>Docs.xml</XmlDocFile>
212 </Options>
213 </Configuration>
214
215 <!-- One of the projects that is included in the Solution -->
216 <Project name="RealmForge.Utility" Language="VisualBasic" path="Utility" type="Library" assemblyName="RealmForge.Utility" rootNamespace="RealmForge">
217 <Configuration name="Debug">
218 <Options>
219 <OutputPath>..\bin\lib\Utility</OutputPath>
220 <XmlDocFile>RealmForge.Utility.xml</XmlDocFile>
221 </Options>
222 </Configuration>
223 <Configuration name="Release">
224 <Options>
225 <OutputPath>..\bin\lib\Utility</OutputPath>
226 <XmlDocFile>RealmForge.Utility.xml</XmlDocFile>
227 </Options>
228 </Configuration>
229 <ReferencePath>../bin</ReferencePath>
230 <Reference name="System"/>
231 <Reference name="System.Data"/>
232 <Reference name="System.Drawing"/>
233 <Reference name="System.Xml"/>
234 <Reference name="System.Runtime.Serialization.Formatters.Soap"/>
235 <Reference name="ICSharpCode.SharpZipLib"/>
236 <Files>
237 <Match path="." pattern="*.vb" recurse="true"/>
238 </Files>
239 </Project>
240
241 <!-- Another projects that is included in the Solution -->
242 <Project name="DemoGame" Language="C#" path="DemoGame" type="WinExe" icon="..\bin\RealmForge.ico" assemblyName="DemoGame" rootNamespace="RealmForge">
243 <!-- icon is used to define the location of the .ico file that is embeeded in the assembly when the project is compiled. This is relative to the project path -->
244 <!--type defines the type of project, valid types are Library (.dll), WinExe (.exe), and Exe (.exe). WinExe is not windows specific, it just defines that it is a GUI application and that no Console or Command window will show when it is started-->
245
246 <Configuration name="Debug">
247 <Options>
248 <OutputPath>..\bin</OutputPath>
249 <XmlDocFile>DemoGame.xml</XmlDocFile>
250 </Options>
251 </Configuration>
252 <Configuration name="Release">
253 <Options>
254 <OutputPath>..\bin</OutputPath>
255 <XmlDocFile>DemoGame.xml</XmlDocFile>
256 </Options>
257 </Configuration>
258 <ReferencePath>../bin</ReferencePath>
259 <Reference name="System"/> <!-- Assemblies that are located in the GAC (installed, global) can be referenced-->
260 <Reference name="ode"/> <!-- Assemblies that are located in the output directory to which the file is built can be referenced -->
261 <Reference name="RealmForge.Utility"/> <!-- When you reference the name of another project, then that project (and it's output) will be referenced instead of looking for a pre-built assembly-->
262 <Files>
263 <Match path="." pattern="*.cs" recurse="true"/>
264 <Match path="." pattern="*.bmp" recurse="true" buildAction="EmbeddedResource"/>
265 <Match path="." pattern="[^a]*\.(png|jpg)" useRegex="true" buildAction="EmbeddedResource"/>
266
267 <!-- Uses a regex or regular expression to find all files that end with .png or .jpg but dont have the letter 'a' in their name and add them to the project as EmbeddedResource's. Because recurse enabled (default is false), only the values in the files in that are directly in the project directory (not child directories) are checked.-->
268 <!--EmbeddedResource, Content, and Compile are valid buildAction's-->
269 </Files>
270 </Project>
271
272 </Solution>
273</Prebuild>
274
diff --git a/Prebuild/THANKS b/Prebuild/THANKS
deleted file mode 100644
index 576467c..0000000
--- a/Prebuild/THANKS
+++ /dev/null
@@ -1,18 +0,0 @@
1Gryc Ueusp <gryc.ueusp@gmail.com>
2
3 caught a problem with the NAnt target's .build output which caused
4 the Ubuntu build servers to choke on prebuild-generated packages
5
6Todd Berman <tberman@sevenl.net>
7Lluis Sanchez Gual <lluis@novell.com>
8
9 pkg-config .pc file parser used in AutotoolsTarget.cs was ripped off
10 from work contributed to MonoDevelop by Lluis and Todd. It came
11 from
12
13src/core/MonoDevelop.Core/MonoDevelop.Core/SystemPackage.cs (Lluis)
14
15 and
16
17src/core/MonoDevelop.Core/MonoDevelop.Core/SystemAssemblyService.cs
18 (Lluis && Todd)
diff --git a/Prebuild/TODO b/Prebuild/TODO
deleted file mode 100644
index 33b19a1..0000000
--- a/Prebuild/TODO
+++ /dev/null
@@ -1,43 +0,0 @@
1* monodev target should be able to detect whether the project is 1.x
2 or 2.x runtime
3
4* remove target which links ../project/foo.dll to each project's build
5 root
6
7* generate .config files
8
9* Fix the autotools target so that
10sub generate_project_files { ... }
11sub generate_solution_files { ... }
12sub generate_multi_solution_files { ... }
13sub generate_project {
14 ...
15 generate_project_files();
16}
17sub generate_solution {
18 foreach $project ( @projects ){
19 mkdir "$project/";
20 pushd "$project/";
21 generate_project();
22 popd;
23 }
24 generate_solution_files();
25}
26sub generate_multi_solution {
27 foreach $solution ( @solutions ){
28 mkdir "$solution/";
29 pushd "$solution/";
30 generate_solution();
31 popd;
32 }
33 generate_multi_solution_files();
34}
35
36if(numProjects == 1){
37 generate_project();
38}elsif(numSolutions == 1){
39 generate_solution();
40}else{
41 generate_multi_solution();
42}
43
diff --git a/Prebuild/prebuild b/Prebuild/prebuild
deleted file mode 100644
index 0dc648d..0000000
--- a/Prebuild/prebuild
+++ /dev/null
@@ -1,2 +0,0 @@
1#!/bin/sh
2exec mono [PREFIX]/prebuild.exe "$@"
diff --git a/bin/CSJ2K.dll b/bin/CSJ2K.dll
new file mode 100644
index 0000000..ff7e809
--- /dev/null
+++ b/bin/CSJ2K.dll
Binary files differ
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 1aae98a..fa8dc9d 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1356,11 +1356,6 @@
1356 1356
1357 ;PacketMTU = 1400 1357 ;PacketMTU = 1400
1358 1358
1359 ; TextureUpdateRate (mS) determines how many times per second
1360 ; texture send processing will occur. The default is 100mS.
1361 ;
1362 ;TextureRequestRate = 100
1363
1364 ; TextureSendLimit determines how many different textures 1359 ; TextureSendLimit determines how many different textures
1365 ; will be considered on each cycle. Textures are selected 1360 ; will be considered on each cycle. Textures are selected
1366 ; by priority. The old mechanism specified a value of 10 for 1361 ; by priority. The old mechanism specified a value of 10 for
@@ -1373,14 +1368,6 @@
1373 ; 1368 ;
1374 ;TextureDataLimit = 5 1369 ;TextureDataLimit = 5
1375 1370
1376;; The JPEG2000 decode cache
1377;; Timeout is in minutes
1378
1379[J2KDecoder]
1380;CacheDir = "./j2kDecodeCache"
1381; Time in minutes before cached decodes expire. Set to 0 for no expiration. Default is 720 minutes.
1382;CacheTimeout = 720
1383
1384;; 1371;;
1385;; These are defaults that are overwritten below in [Architecture]. 1372;; These are defaults that are overwritten below in [Architecture].
1386;; These defaults allow OpenSim to work out of the box with 1373;; These defaults allow OpenSim to work out of the box with
diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml
index 0352c99..773de44 100644
--- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml
+++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml
@@ -401,4 +401,11 @@
401 <Key Name="assetType" Value="0" /> 401 <Key Name="assetType" Value="0" />
402 <Key Name="fileName" Value="default_clear.jp2" /> 402 <Key Name="fileName" Value="default_clear.jp2" />
403 </Section> 403 </Section>
404
405 <Section Name="Default Avatar">
406 <Key Name="assetID" Value="c228d1cf-4b5d-4ba8-84f4-899a0796aa97"/>
407 <Key Name="name" Value="Default Avatar"/>
408 <Key Name="assetType" Value="0" />
409 <Key Name="fileName" Value="default_avatar.jp2" />
410 </Section>
404</Nini> 411</Nini>
diff --git a/bin/assets/TexturesAssetSet/default_avatar.jp2 b/bin/assets/TexturesAssetSet/default_avatar.jp2
new file mode 100644
index 0000000..116b860
--- /dev/null
+++ b/bin/assets/TexturesAssetSet/default_avatar.jp2
Binary files differ
diff --git a/prebuild.xml b/prebuild.xml
index ce04f12..22ff3d7 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1541,6 +1541,7 @@
1541 <Reference name="OpenMetaverseTypes.dll"/> 1541 <Reference name="OpenMetaverseTypes.dll"/>
1542 <Reference name="OpenMetaverse.StructuredData.dll"/> 1542 <Reference name="OpenMetaverse.StructuredData.dll"/>
1543 <Reference name="OpenMetaverse.dll"/> 1543 <Reference name="OpenMetaverse.dll"/>
1544 <Reference name="CSJ2K.dll"/>
1544 <Reference name="OpenSim.Framework"/> 1545 <Reference name="OpenSim.Framework"/>
1545 <Reference name="OpenSim.Framework.Capabilities"/> 1546 <Reference name="OpenSim.Framework.Capabilities"/>
1546 <Reference name="OpenSim.Framework.Communications"/> 1547 <Reference name="OpenSim.Framework.Communications"/>
@@ -3534,35 +3535,6 @@
3534 </Files> 3535 </Files>
3535 </Project> 3536 </Project>
3536 3537
3537 <Project frameworkVersion="v3_5" name="OpenSim.Framework.Servers.HttpServer.Tests" path="OpenSim/Framework/Servers/HttpServer/Tests" type="Library">
3538 <Configuration name="Debug">
3539 <Options>
3540 <OutputPath>../../../../../bin/</OutputPath>
3541 </Options>
3542 </Configuration>
3543 <Configuration name="Release">
3544 <Options>
3545 <OutputPath>../../../../../bin/</OutputPath>
3546 </Options>
3547 </Configuration>
3548
3549 <ReferencePath>../../../../../bin/</ReferencePath>
3550 <Reference name="System"/>
3551 <Reference name="OpenSim.Data"/>
3552 <Reference name="OpenSim.Tests.Common"/>
3553 <Reference name="OpenSim.Framework"/>
3554 <Reference name="OpenSim.Framework.Servers"/>
3555 <Reference name="OpenSim.Framework.Servers.HttpServer"/>
3556 <Reference name="log4net.dll"/>
3557 <Reference name="HttpServer_OpenSim.dll"/>
3558 <Reference name="nunit.framework.dll" />
3559
3560 <Files>
3561 <Match pattern="*.cs" recurse="true">
3562 </Match>
3563 </Files>
3564 </Project>
3565
3566 <Project frameworkVersion="v3_5" name="OpenSim.Framework.Communications.Tests" path="OpenSim/Framework/Communications/Tests" type="Library"> 3538 <Project frameworkVersion="v3_5" name="OpenSim.Framework.Communications.Tests" path="OpenSim/Framework/Communications/Tests" type="Library">
3567 <Configuration name="Debug"> 3539 <Configuration name="Debug">
3568 <Options> 3540 <Options>
@@ -3829,40 +3801,6 @@
3829 </Files> 3801 </Files>
3830 </Project> 3802 </Project>
3831 3803
3832 <Project frameworkVersion="v3_5" name="OpenSim.Server.Handlers.Tests" path="OpenSim/Server/Handlers/Tests" type="Library">
3833 <Configuration name="Debug">
3834 <Options>
3835 <OutputPath>../../../../bin/</OutputPath>
3836 </Options>
3837 </Configuration>
3838 <Configuration name="Release">
3839 <Options>
3840 <OutputPath>../../../../bin/</OutputPath>
3841 </Options>
3842 </Configuration>
3843
3844 <ReferencePath>../../../../bin/</ReferencePath>
3845 <Reference name="System"/>
3846 <Reference name="System.Xml"/>
3847 <Reference name="OpenMetaverseTypes.dll"/>
3848 <Reference name="OpenMetaverse.dll"/>
3849 <Reference name="nunit.framework.dll" />
3850 <Reference name="OpenSim.Framework"/>
3851 <Reference name="OpenSim.Framework.Console"/>
3852 <Reference name="OpenSim.Framework.Servers.HttpServer"/>
3853 <Reference name="OpenSim.Server.Handlers"/>
3854 <Reference name="OpenSim.Server.Base"/>
3855 <Reference name="OpenSim.Services.Base" />
3856 <Reference name="OpenSim.Services.Interfaces"/>
3857 <Reference name="OpenSim.Tests.Common"/>
3858 <Reference name="Nini.dll" />
3859 <Reference name="log4net.dll"/>
3860
3861 <Files>
3862 <Match pattern="*.cs" recurse="true"/>
3863 </Files>
3864 </Project>
3865
3866 <?include file="addon-modules/*/prebuild.xml" ?> 3804 <?include file="addon-modules/*/prebuild.xml" ?>
3867 3805
3868 </Solution> 3806 </Solution>