diff options
Diffstat (limited to '')
76 files changed, 16470 insertions, 16470 deletions
diff --git a/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs index c0b7380..48db51b 100644 --- a/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs | |||
@@ -1,228 +1,228 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using libsecondlife; | 29 | using libsecondlife; |
30 | using libsecondlife.Packets; | 30 | using libsecondlife.Packets; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload | 36 | namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload |
37 | { | 37 | { |
38 | public class AssetDownloadModule : IRegionModule | 38 | public class AssetDownloadModule : IRegionModule |
39 | { | 39 | { |
40 | /// <summary> | 40 | /// <summary> |
41 | /// Asset requests with data which are ready to be sent back to requesters. This includes textures. | 41 | /// Asset requests with data which are ready to be sent back to requesters. This includes textures. |
42 | /// </summary> | 42 | /// </summary> |
43 | private List<AssetRequest> AssetRequests; | 43 | private List<AssetRequest> AssetRequests; |
44 | 44 | ||
45 | private Scene m_scene; | 45 | private Scene m_scene; |
46 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); | 46 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); |
47 | 47 | ||
48 | /// | 48 | /// |
49 | /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests | 49 | /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests |
50 | /// </summary> | 50 | /// </summary> |
51 | private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> RequestedAssets; | 51 | private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> RequestedAssets; |
52 | 52 | ||
53 | public AssetDownloadModule() | 53 | public AssetDownloadModule() |
54 | { | 54 | { |
55 | RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>(); | 55 | RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>(); |
56 | AssetRequests = new List<AssetRequest>(); | 56 | AssetRequests = new List<AssetRequest>(); |
57 | } | 57 | } |
58 | 58 | ||
59 | #region IRegionModule Members | 59 | #region IRegionModule Members |
60 | 60 | ||
61 | public void Initialise(Scene scene, IConfigSource config) | 61 | public void Initialise(Scene scene, IConfigSource config) |
62 | { | 62 | { |
63 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | 63 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) |
64 | { | 64 | { |
65 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); | 65 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); |
66 | // scene.EventManager.OnNewClient += NewClient; | 66 | // scene.EventManager.OnNewClient += NewClient; |
67 | } | 67 | } |
68 | 68 | ||
69 | if (m_scene == null) | 69 | if (m_scene == null) |
70 | { | 70 | { |
71 | m_scene = scene; | 71 | m_scene = scene; |
72 | // m_thread = new Thread(new ThreadStart(RunAssetQueue)); | 72 | // m_thread = new Thread(new ThreadStart(RunAssetQueue)); |
73 | // m_thread.Name = "AssetDownloadQueueThread"; | 73 | // m_thread.Name = "AssetDownloadQueueThread"; |
74 | // m_thread.IsBackground = true; | 74 | // m_thread.IsBackground = true; |
75 | // m_thread.Start(); | 75 | // m_thread.Start(); |
76 | // OpenSim.Framework.ThreadTracker.Add(m_thread); | 76 | // OpenSim.Framework.ThreadTracker.Add(m_thread); |
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | public void PostInitialise() | 80 | public void PostInitialise() |
81 | { | 81 | { |
82 | } | 82 | } |
83 | 83 | ||
84 | public void Close() | 84 | public void Close() |
85 | { | 85 | { |
86 | } | 86 | } |
87 | 87 | ||
88 | public string Name | 88 | public string Name |
89 | { | 89 | { |
90 | get { return "AssetDownloadModule"; } | 90 | get { return "AssetDownloadModule"; } |
91 | } | 91 | } |
92 | 92 | ||
93 | public bool IsSharedModule | 93 | public bool IsSharedModule |
94 | { | 94 | { |
95 | get { return true; } | 95 | get { return true; } |
96 | } | 96 | } |
97 | 97 | ||
98 | #endregion | 98 | #endregion |
99 | 99 | ||
100 | public void NewClient(IClientAPI client) | 100 | public void NewClient(IClientAPI client) |
101 | { | 101 | { |
102 | // client.OnRequestAsset += AddAssetRequest; | 102 | // client.OnRequestAsset += AddAssetRequest; |
103 | } | 103 | } |
104 | 104 | ||
105 | /// <summary> | 105 | /// <summary> |
106 | /// Make an asset request the result of which will be packeted up and sent directly back to the client. | 106 | /// Make an asset request the result of which will be packeted up and sent directly back to the client. |
107 | /// </summary> | 107 | /// </summary> |
108 | /// <param name="userInfo"></param> | 108 | /// <param name="userInfo"></param> |
109 | /// <param name="transferRequest"></param> | 109 | /// <param name="transferRequest"></param> |
110 | public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) | 110 | public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) |
111 | { | 111 | { |
112 | LLUUID requestID = null; | 112 | LLUUID requestID = null; |
113 | byte source = 2; | 113 | byte source = 2; |
114 | if (transferRequest.TransferInfo.SourceType == 2) | 114 | if (transferRequest.TransferInfo.SourceType == 2) |
115 | { | 115 | { |
116 | //direct asset request | 116 | //direct asset request |
117 | requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); | 117 | requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); |
118 | } | 118 | } |
119 | else if (transferRequest.TransferInfo.SourceType == 3) | 119 | else if (transferRequest.TransferInfo.SourceType == 3) |
120 | { | 120 | { |
121 | //inventory asset request | 121 | //inventory asset request |
122 | requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); | 122 | requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); |
123 | source = 3; | 123 | source = 3; |
124 | //Console.WriteLine("asset request " + requestID); | 124 | //Console.WriteLine("asset request " + requestID); |
125 | } | 125 | } |
126 | 126 | ||
127 | //not found asset | 127 | //not found asset |
128 | // so request from asset server | 128 | // so request from asset server |
129 | Dictionary<LLUUID, AssetRequest> userRequests = null; | 129 | Dictionary<LLUUID, AssetRequest> userRequests = null; |
130 | if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests)) | 130 | if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests)) |
131 | { | 131 | { |
132 | if (!userRequests.ContainsKey(requestID)) | 132 | if (!userRequests.ContainsKey(requestID)) |
133 | { | 133 | { |
134 | AssetRequest request = new AssetRequest(); | 134 | AssetRequest request = new AssetRequest(); |
135 | request.RequestUser = userInfo; | 135 | request.RequestUser = userInfo; |
136 | request.RequestAssetID = requestID; | 136 | request.RequestAssetID = requestID; |
137 | request.TransferRequestID = transferRequest.TransferInfo.TransferID; | 137 | request.TransferRequestID = transferRequest.TransferInfo.TransferID; |
138 | request.AssetRequestSource = source; | 138 | request.AssetRequestSource = source; |
139 | request.Params = transferRequest.TransferInfo.Params; | 139 | request.Params = transferRequest.TransferInfo.Params; |
140 | userRequests[requestID] = request; | 140 | userRequests[requestID] = request; |
141 | m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); | 141 | m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); |
142 | } | 142 | } |
143 | } | 143 | } |
144 | else | 144 | else |
145 | { | 145 | { |
146 | userRequests = new Dictionary<LLUUID, AssetRequest>(); | 146 | userRequests = new Dictionary<LLUUID, AssetRequest>(); |
147 | AssetRequest request = new AssetRequest(); | 147 | AssetRequest request = new AssetRequest(); |
148 | request.RequestUser = userInfo; | 148 | request.RequestUser = userInfo; |
149 | request.RequestAssetID = requestID; | 149 | request.RequestAssetID = requestID; |
150 | request.TransferRequestID = transferRequest.TransferInfo.TransferID; | 150 | request.TransferRequestID = transferRequest.TransferInfo.TransferID; |
151 | request.AssetRequestSource = source; | 151 | request.AssetRequestSource = source; |
152 | request.Params = transferRequest.TransferInfo.Params; | 152 | request.Params = transferRequest.TransferInfo.Params; |
153 | userRequests.Add(requestID, request); | 153 | userRequests.Add(requestID, request); |
154 | RequestedAssets[userInfo.AgentId] = userRequests; | 154 | RequestedAssets[userInfo.AgentId] = userRequests; |
155 | m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); | 155 | m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); |
156 | } | 156 | } |
157 | } | 157 | } |
158 | 158 | ||
159 | public void AssetCallback(LLUUID assetID, AssetBase asset) | 159 | public void AssetCallback(LLUUID assetID, AssetBase asset) |
160 | { | 160 | { |
161 | if (asset != null) | 161 | if (asset != null) |
162 | { | 162 | { |
163 | foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values) | 163 | foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values) |
164 | { | 164 | { |
165 | if (userRequests.ContainsKey(assetID)) | 165 | if (userRequests.ContainsKey(assetID)) |
166 | { | 166 | { |
167 | AssetRequest req = userRequests[assetID]; | 167 | AssetRequest req = userRequests[assetID]; |
168 | if (req != null) | 168 | if (req != null) |
169 | { | 169 | { |
170 | req.AssetInf = asset; | 170 | req.AssetInf = asset; |
171 | req.NumPackets = CalculateNumPackets(asset.Data); | 171 | req.NumPackets = CalculateNumPackets(asset.Data); |
172 | 172 | ||
173 | userRequests.Remove(assetID); | 173 | userRequests.Remove(assetID); |
174 | AssetRequests.Add(req); | 174 | AssetRequests.Add(req); |
175 | } | 175 | } |
176 | } | 176 | } |
177 | } | 177 | } |
178 | } | 178 | } |
179 | } | 179 | } |
180 | 180 | ||
181 | /// <summary> | 181 | /// <summary> |
182 | /// Calculate the number of packets required to send the asset to the client. | 182 | /// Calculate the number of packets required to send the asset to the client. |
183 | /// </summary> | 183 | /// </summary> |
184 | /// <param name="data"></param> | 184 | /// <param name="data"></param> |
185 | /// <returns></returns> | 185 | /// <returns></returns> |
186 | private int CalculateNumPackets(byte[] data) | 186 | private int CalculateNumPackets(byte[] data) |
187 | { | 187 | { |
188 | const uint m_maxPacketSize = 600; | 188 | const uint m_maxPacketSize = 600; |
189 | int numPackets = 1; | 189 | int numPackets = 1; |
190 | 190 | ||
191 | if (data.LongLength > m_maxPacketSize) | 191 | if (data.LongLength > m_maxPacketSize) |
192 | { | 192 | { |
193 | // over max number of bytes so split up file | 193 | // over max number of bytes so split up file |
194 | long restData = data.LongLength - m_maxPacketSize; | 194 | long restData = data.LongLength - m_maxPacketSize; |
195 | int restPackets = (int) ((restData + m_maxPacketSize - 1) / m_maxPacketSize); | 195 | int restPackets = (int) ((restData + m_maxPacketSize - 1) / m_maxPacketSize); |
196 | numPackets += restPackets; | 196 | numPackets += restPackets; |
197 | } | 197 | } |
198 | 198 | ||
199 | return numPackets; | 199 | return numPackets; |
200 | } | 200 | } |
201 | 201 | ||
202 | #region Nested type: AssetRequest | 202 | #region Nested type: AssetRequest |
203 | 203 | ||
204 | public class AssetRequest | 204 | public class AssetRequest |
205 | { | 205 | { |
206 | public AssetBase AssetInf; | 206 | public AssetBase AssetInf; |
207 | public byte AssetRequestSource = 2; | 207 | public byte AssetRequestSource = 2; |
208 | public long DataPointer = 0; | 208 | public long DataPointer = 0; |
209 | public int DiscardLevel = -1; | 209 | public int DiscardLevel = -1; |
210 | public AssetBase ImageInfo; | 210 | public AssetBase ImageInfo; |
211 | public bool IsTextureRequest; | 211 | public bool IsTextureRequest; |
212 | public int NumPackets = 0; | 212 | public int NumPackets = 0; |
213 | public int PacketCounter = 0; | 213 | public int PacketCounter = 0; |
214 | public byte[] Params = null; | 214 | public byte[] Params = null; |
215 | public LLUUID RequestAssetID; | 215 | public LLUUID RequestAssetID; |
216 | public IClientAPI RequestUser; | 216 | public IClientAPI RequestUser; |
217 | public LLUUID TransferRequestID; | 217 | public LLUUID TransferRequestID; |
218 | //public bool AssetInCache; | 218 | //public bool AssetInCache; |
219 | //public int TimeRequested; | 219 | //public int TimeRequested; |
220 | 220 | ||
221 | public AssetRequest() | 221 | public AssetRequest() |
222 | { | 222 | { |
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | #endregion | 226 | #endregion |
227 | } | 227 | } |
228 | } \ No newline at end of file | 228 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 8192be4..555d5f4 100644 --- a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs | |||
@@ -1,412 +1,412 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using libsecondlife.Packets; | 32 | using libsecondlife.Packets; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Communications.Cache; | 34 | using OpenSim.Framework.Communications.Cache; |
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction | 36 | namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction |
37 | { | 37 | { |
38 | /// <summary> | 38 | /// <summary> |
39 | /// Manage asset transactions for a single agent. | 39 | /// Manage asset transactions for a single agent. |
40 | /// </summary> | 40 | /// </summary> |
41 | public class AgentAssetTransactions | 41 | public class AgentAssetTransactions |
42 | { | 42 | { |
43 | //private static readonly log4net.ILog m_log | 43 | //private static readonly log4net.ILog m_log |
44 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 44 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
46 | // Fields | 46 | // Fields |
47 | private bool m_dumpAssetsToFile; | 47 | private bool m_dumpAssetsToFile; |
48 | public AgentAssetTransactionsManager Manager; | 48 | public AgentAssetTransactionsManager Manager; |
49 | public LLUUID UserID; | 49 | public LLUUID UserID; |
50 | public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>(); | 50 | public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>(); |
51 | 51 | ||
52 | // Methods | 52 | // Methods |
53 | public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile) | 53 | public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile) |
54 | { | 54 | { |
55 | UserID = agentID; | 55 | UserID = agentID; |
56 | Manager = manager; | 56 | Manager = manager; |
57 | m_dumpAssetsToFile = dumpAssetsToFile; | 57 | m_dumpAssetsToFile = dumpAssetsToFile; |
58 | } | 58 | } |
59 | 59 | ||
60 | public AssetXferUploader RequestXferUploader(LLUUID transactionID) | 60 | public AssetXferUploader RequestXferUploader(LLUUID transactionID) |
61 | { | 61 | { |
62 | if (!XferUploaders.ContainsKey(transactionID)) | 62 | if (!XferUploaders.ContainsKey(transactionID)) |
63 | { | 63 | { |
64 | AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); | 64 | AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); |
65 | 65 | ||
66 | lock (XferUploaders) | 66 | lock (XferUploaders) |
67 | { | 67 | { |
68 | XferUploaders.Add(transactionID, uploader); | 68 | XferUploaders.Add(transactionID, uploader); |
69 | } | 69 | } |
70 | 70 | ||
71 | return uploader; | 71 | return uploader; |
72 | } | 72 | } |
73 | return null; | 73 | return null; |
74 | } | 74 | } |
75 | 75 | ||
76 | public void HandleXfer(ulong xferID, uint packetID, byte[] data) | 76 | public void HandleXfer(ulong xferID, uint packetID, byte[] data) |
77 | { | 77 | { |
78 | // AssetXferUploader uploaderFound = null; | 78 | // AssetXferUploader uploaderFound = null; |
79 | 79 | ||
80 | lock (XferUploaders) | 80 | lock (XferUploaders) |
81 | { | 81 | { |
82 | foreach (AssetXferUploader uploader in XferUploaders.Values) | 82 | foreach (AssetXferUploader uploader in XferUploaders.Values) |
83 | { | 83 | { |
84 | if (uploader.XferID == xferID) | 84 | if (uploader.XferID == xferID) |
85 | { | 85 | { |
86 | uploader.HandleXferPacket(xferID, packetID, data); | 86 | uploader.HandleXferPacket(xferID, packetID, data); |
87 | break; | 87 | break; |
88 | } | 88 | } |
89 | } | 89 | } |
90 | } | 90 | } |
91 | } | 91 | } |
92 | 92 | ||
93 | public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, | 93 | public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, |
94 | uint callbackID, string description, string name, sbyte invType, | 94 | uint callbackID, string description, string name, sbyte invType, |
95 | sbyte type, byte wearableType, uint nextOwnerMask) | 95 | sbyte type, byte wearableType, uint nextOwnerMask) |
96 | { | 96 | { |
97 | if (XferUploaders.ContainsKey(transactionID)) | 97 | if (XferUploaders.ContainsKey(transactionID)) |
98 | { | 98 | { |
99 | XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, | 99 | XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, |
100 | callbackID, description, name, invType, type, | 100 | callbackID, description, name, invType, type, |
101 | wearableType, nextOwnerMask); | 101 | wearableType, nextOwnerMask); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, | 105 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, |
106 | InventoryItemBase item) | 106 | InventoryItemBase item) |
107 | { | 107 | { |
108 | if (XferUploaders.ContainsKey(transactionID)) | 108 | if (XferUploaders.ContainsKey(transactionID)) |
109 | { | 109 | { |
110 | XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item); | 110 | XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item); |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | /// <summary> | 114 | /// <summary> |
115 | /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. | 115 | /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. |
116 | /// </summary> | 116 | /// </summary> |
117 | /// <param name="transactionID"></param> | 117 | /// <param name="transactionID"></param> |
118 | /// <returns>The asset if the upload has completed, null if it has not.</returns> | 118 | /// <returns>The asset if the upload has completed, null if it has not.</returns> |
119 | public AssetBase GetTransactionAsset(LLUUID transactionID) | 119 | public AssetBase GetTransactionAsset(LLUUID transactionID) |
120 | { | 120 | { |
121 | if (XferUploaders.ContainsKey(transactionID)) | 121 | if (XferUploaders.ContainsKey(transactionID)) |
122 | { | 122 | { |
123 | AssetXferUploader uploader = XferUploaders[transactionID]; | 123 | AssetXferUploader uploader = XferUploaders[transactionID]; |
124 | AssetBase asset = uploader.GetAssetData(); | 124 | AssetBase asset = uploader.GetAssetData(); |
125 | 125 | ||
126 | lock (XferUploaders) | 126 | lock (XferUploaders) |
127 | { | 127 | { |
128 | XferUploaders.Remove(transactionID); | 128 | XferUploaders.Remove(transactionID); |
129 | } | 129 | } |
130 | 130 | ||
131 | return asset; | 131 | return asset; |
132 | } | 132 | } |
133 | 133 | ||
134 | return null; | 134 | return null; |
135 | } | 135 | } |
136 | 136 | ||
137 | // Nested Types | 137 | // Nested Types |
138 | 138 | ||
139 | #region Nested type: AssetXferUploader | 139 | #region Nested type: AssetXferUploader |
140 | 140 | ||
141 | public class AssetXferUploader | 141 | public class AssetXferUploader |
142 | { | 142 | { |
143 | // Fields | 143 | // Fields |
144 | public bool AddToInventory; | 144 | public bool AddToInventory; |
145 | public AssetBase Asset; | 145 | public AssetBase Asset; |
146 | public LLUUID InventFolder = LLUUID.Zero; | 146 | public LLUUID InventFolder = LLUUID.Zero; |
147 | private sbyte invType = 0; | 147 | private sbyte invType = 0; |
148 | private bool m_createItem = false; | 148 | private bool m_createItem = false; |
149 | private string m_description = String.Empty; | 149 | private string m_description = String.Empty; |
150 | private bool m_dumpAssetToFile; | 150 | private bool m_dumpAssetToFile; |
151 | private bool m_finished = false; | 151 | private bool m_finished = false; |
152 | private string m_name = String.Empty; | 152 | private string m_name = String.Empty; |
153 | private bool m_storeLocal; | 153 | private bool m_storeLocal; |
154 | private AgentAssetTransactions m_userTransactions; | 154 | private AgentAssetTransactions m_userTransactions; |
155 | private uint nextPerm = 0; | 155 | private uint nextPerm = 0; |
156 | private IClientAPI ourClient; | 156 | private IClientAPI ourClient; |
157 | public LLUUID TransactionID = LLUUID.Zero; | 157 | public LLUUID TransactionID = LLUUID.Zero; |
158 | private sbyte type = 0; | 158 | private sbyte type = 0; |
159 | public bool UploadComplete; | 159 | public bool UploadComplete; |
160 | private byte wearableType = 0; | 160 | private byte wearableType = 0; |
161 | public ulong XferID; | 161 | public ulong XferID; |
162 | 162 | ||
163 | public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) | 163 | public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) |
164 | { | 164 | { |
165 | m_userTransactions = transactions; | 165 | m_userTransactions = transactions; |
166 | m_dumpAssetToFile = dumpAssetToFile; | 166 | m_dumpAssetToFile = dumpAssetToFile; |
167 | } | 167 | } |
168 | 168 | ||
169 | /// <summary> | 169 | /// <summary> |
170 | /// Process transfer data received from the client. | 170 | /// Process transfer data received from the client. |
171 | /// </summary> | 171 | /// </summary> |
172 | /// <param name="xferID"></param> | 172 | /// <param name="xferID"></param> |
173 | /// <param name="packetID"></param> | 173 | /// <param name="packetID"></param> |
174 | /// <param name="data"></param> | 174 | /// <param name="data"></param> |
175 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> | 175 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> |
176 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) | 176 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) |
177 | { | 177 | { |
178 | if (XferID == xferID) | 178 | if (XferID == xferID) |
179 | { | 179 | { |
180 | if (Asset.Data.Length > 1) | 180 | if (Asset.Data.Length > 1) |
181 | { | 181 | { |
182 | byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; | 182 | byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; |
183 | Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); | 183 | Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); |
184 | Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); | 184 | Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); |
185 | Asset.Data = destinationArray; | 185 | Asset.Data = destinationArray; |
186 | } | 186 | } |
187 | else | 187 | else |
188 | { | 188 | { |
189 | byte[] buffer2 = new byte[data.Length - 4]; | 189 | byte[] buffer2 = new byte[data.Length - 4]; |
190 | Array.Copy(data, 4, buffer2, 0, data.Length - 4); | 190 | Array.Copy(data, 4, buffer2, 0, data.Length - 4); |
191 | Asset.Data = buffer2; | 191 | Asset.Data = buffer2; |
192 | } | 192 | } |
193 | ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); | 193 | ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); |
194 | newPack.XferID.ID = xferID; | 194 | newPack.XferID.ID = xferID; |
195 | newPack.XferID.Packet = packetID; | 195 | newPack.XferID.Packet = packetID; |
196 | ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); | 196 | ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); |
197 | if ((packetID & 0x80000000) != 0) | 197 | if ((packetID & 0x80000000) != 0) |
198 | { | 198 | { |
199 | SendCompleteMessage(); | 199 | SendCompleteMessage(); |
200 | return true; | 200 | return true; |
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | return false; | 204 | return false; |
205 | } | 205 | } |
206 | 206 | ||
207 | /// <summary> | 207 | /// <summary> |
208 | /// Initialise asset transfer from the client | 208 | /// Initialise asset transfer from the client |
209 | /// </summary> | 209 | /// </summary> |
210 | /// <param name="xferID"></param> | 210 | /// <param name="xferID"></param> |
211 | /// <param name="packetID"></param> | 211 | /// <param name="packetID"></param> |
212 | /// <param name="data"></param> | 212 | /// <param name="data"></param> |
213 | /// <returns>True if the transfer is complete, false otherwise</returns> | 213 | /// <returns>True if the transfer is complete, false otherwise</returns> |
214 | public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, | 214 | public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, |
215 | bool storeLocal, bool tempFile) | 215 | bool storeLocal, bool tempFile) |
216 | { | 216 | { |
217 | ourClient = remoteClient; | 217 | ourClient = remoteClient; |
218 | Asset = new AssetBase(); | 218 | Asset = new AssetBase(); |
219 | Asset.FullID = assetID; | 219 | Asset.FullID = assetID; |
220 | Asset.InvType = type; | 220 | Asset.InvType = type; |
221 | Asset.Type = type; | 221 | Asset.Type = type; |
222 | Asset.Data = data; | 222 | Asset.Data = data; |
223 | Asset.Name = "blank"; | 223 | Asset.Name = "blank"; |
224 | Asset.Description = "empty"; | 224 | Asset.Description = "empty"; |
225 | Asset.Local = storeLocal; | 225 | Asset.Local = storeLocal; |
226 | Asset.Temporary = tempFile; | 226 | Asset.Temporary = tempFile; |
227 | 227 | ||
228 | TransactionID = transaction; | 228 | TransactionID = transaction; |
229 | m_storeLocal = storeLocal; | 229 | m_storeLocal = storeLocal; |
230 | if (Asset.Data.Length > 2) | 230 | if (Asset.Data.Length > 2) |
231 | { | 231 | { |
232 | SendCompleteMessage(); | 232 | SendCompleteMessage(); |
233 | return true; | 233 | return true; |
234 | } | 234 | } |
235 | else | 235 | else |
236 | { | 236 | { |
237 | RequestStartXfer(); | 237 | RequestStartXfer(); |
238 | } | 238 | } |
239 | 239 | ||
240 | return false; | 240 | return false; |
241 | } | 241 | } |
242 | 242 | ||
243 | protected void RequestStartXfer() | 243 | protected void RequestStartXfer() |
244 | { | 244 | { |
245 | UploadComplete = false; | 245 | UploadComplete = false; |
246 | XferID = Util.GetNextXferID(); | 246 | XferID = Util.GetNextXferID(); |
247 | RequestXferPacket newPack = new RequestXferPacket(); | 247 | RequestXferPacket newPack = new RequestXferPacket(); |
248 | newPack.XferID.ID = XferID; | 248 | newPack.XferID.ID = XferID; |
249 | newPack.XferID.VFileType = Asset.Type; | 249 | newPack.XferID.VFileType = Asset.Type; |
250 | newPack.XferID.VFileID = Asset.FullID; | 250 | newPack.XferID.VFileID = Asset.FullID; |
251 | newPack.XferID.FilePath = 0; | 251 | newPack.XferID.FilePath = 0; |
252 | newPack.XferID.Filename = new byte[0]; | 252 | newPack.XferID.Filename = new byte[0]; |
253 | ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); | 253 | ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); |
254 | } | 254 | } |
255 | 255 | ||
256 | protected void SendCompleteMessage() | 256 | protected void SendCompleteMessage() |
257 | { | 257 | { |
258 | UploadComplete = true; | 258 | UploadComplete = true; |
259 | AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); | 259 | AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); |
260 | newPack.AssetBlock.Type = Asset.Type; | 260 | newPack.AssetBlock.Type = Asset.Type; |
261 | newPack.AssetBlock.Success = true; | 261 | newPack.AssetBlock.Success = true; |
262 | newPack.AssetBlock.UUID = Asset.FullID; | 262 | newPack.AssetBlock.UUID = Asset.FullID; |
263 | ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); | 263 | ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); |
264 | m_finished = true; | 264 | m_finished = true; |
265 | if (m_createItem) | 265 | if (m_createItem) |
266 | { | 266 | { |
267 | DoCreateItem(); | 267 | DoCreateItem(); |
268 | } | 268 | } |
269 | else if (m_storeLocal) | 269 | else if (m_storeLocal) |
270 | { | 270 | { |
271 | m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); | 271 | m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); |
272 | } | 272 | } |
273 | 273 | ||
274 | // Console.WriteLine("upload complete "+ this.TransactionID); | 274 | // Console.WriteLine("upload complete "+ this.TransactionID); |
275 | 275 | ||
276 | if (m_dumpAssetToFile) | 276 | if (m_dumpAssetToFile) |
277 | { | 277 | { |
278 | DateTime now = DateTime.Now; | 278 | DateTime now = DateTime.Now; |
279 | string filename = | 279 | string filename = |
280 | String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, | 280 | String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, |
281 | now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); | 281 | now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); |
282 | SaveAssetToFile(filename, Asset.Data); | 282 | SaveAssetToFile(filename, Asset.Data); |
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | ///Left this in and commented in case there are unforseen issues | 286 | ///Left this in and commented in case there are unforseen issues |
287 | //private void SaveAssetToFile(string filename, byte[] data) | 287 | //private void SaveAssetToFile(string filename, byte[] data) |
288 | //{ | 288 | //{ |
289 | // FileStream fs = File.Create(filename); | 289 | // FileStream fs = File.Create(filename); |
290 | // BinaryWriter bw = new BinaryWriter(fs); | 290 | // BinaryWriter bw = new BinaryWriter(fs); |
291 | // bw.Write(data); | 291 | // bw.Write(data); |
292 | // bw.Close(); | 292 | // bw.Close(); |
293 | // fs.Close(); | 293 | // fs.Close(); |
294 | //} | 294 | //} |
295 | private void SaveAssetToFile(string filename, byte[] data) | 295 | private void SaveAssetToFile(string filename, byte[] data) |
296 | { | 296 | { |
297 | string assetPath = "UserAssets"; | 297 | string assetPath = "UserAssets"; |
298 | if (!Directory.Exists(assetPath)) | 298 | if (!Directory.Exists(assetPath)) |
299 | { | 299 | { |
300 | Directory.CreateDirectory(assetPath); | 300 | Directory.CreateDirectory(assetPath); |
301 | } | 301 | } |
302 | FileStream fs = File.Create(Path.Combine(assetPath, filename)); | 302 | FileStream fs = File.Create(Path.Combine(assetPath, filename)); |
303 | BinaryWriter bw = new BinaryWriter(fs); | 303 | BinaryWriter bw = new BinaryWriter(fs); |
304 | bw.Write(data); | 304 | bw.Write(data); |
305 | bw.Close(); | 305 | bw.Close(); |
306 | fs.Close(); | 306 | fs.Close(); |
307 | } | 307 | } |
308 | 308 | ||
309 | public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, | 309 | public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, |
310 | uint callbackID, string description, string name, sbyte invType, | 310 | uint callbackID, string description, string name, sbyte invType, |
311 | sbyte type, byte wearableType, uint nextOwnerMask) | 311 | sbyte type, byte wearableType, uint nextOwnerMask) |
312 | { | 312 | { |
313 | if (TransactionID == transactionID) | 313 | if (TransactionID == transactionID) |
314 | { | 314 | { |
315 | InventFolder = folderID; | 315 | InventFolder = folderID; |
316 | m_name = name; | 316 | m_name = name; |
317 | m_description = description; | 317 | m_description = description; |
318 | this.type = type; | 318 | this.type = type; |
319 | this.invType = invType; | 319 | this.invType = invType; |
320 | this.wearableType = wearableType; | 320 | this.wearableType = wearableType; |
321 | nextPerm = nextOwnerMask; | 321 | nextPerm = nextOwnerMask; |
322 | Asset.Name = name; | 322 | Asset.Name = name; |
323 | Asset.Description = description; | 323 | Asset.Description = description; |
324 | Asset.Type = type; | 324 | Asset.Type = type; |
325 | Asset.InvType = invType; | 325 | Asset.InvType = invType; |
326 | m_createItem = true; | 326 | m_createItem = true; |
327 | if (m_finished) | 327 | if (m_finished) |
328 | { | 328 | { |
329 | DoCreateItem(); | 329 | DoCreateItem(); |
330 | } | 330 | } |
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, | 334 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, |
335 | InventoryItemBase item) | 335 | InventoryItemBase item) |
336 | { | 336 | { |
337 | if (TransactionID == transactionID) | 337 | if (TransactionID == transactionID) |
338 | { | 338 | { |
339 | CachedUserInfo userInfo = | 339 | CachedUserInfo userInfo = |
340 | m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails( | 340 | m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails( |
341 | remoteClient.AgentId); | 341 | remoteClient.AgentId); |
342 | 342 | ||
343 | if (userInfo != null) | 343 | if (userInfo != null) |
344 | { | 344 | { |
345 | LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId); | 345 | LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId); |
346 | 346 | ||
347 | AssetBase asset | 347 | AssetBase asset |
348 | = m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset( | 348 | = m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset( |
349 | assetID, (item.AssetType == (int) AssetType.Texture ? true : false)); | 349 | assetID, (item.AssetType == (int) AssetType.Texture ? true : false)); |
350 | 350 | ||
351 | if (asset == null) | 351 | if (asset == null) |
352 | { | 352 | { |
353 | asset = m_userTransactions.GetTransactionAsset(transactionID); | 353 | asset = m_userTransactions.GetTransactionAsset(transactionID); |
354 | } | 354 | } |
355 | 355 | ||
356 | if (asset != null && asset.FullID == assetID) | 356 | if (asset != null && asset.FullID == assetID) |
357 | { | 357 | { |
358 | asset.Name = item.Name; | 358 | asset.Name = item.Name; |
359 | asset.Description = item.Description; | 359 | asset.Description = item.Description; |
360 | asset.InvType = (sbyte) item.InvType; | 360 | asset.InvType = (sbyte) item.InvType; |
361 | asset.Type = (sbyte) item.AssetType; | 361 | asset.Type = (sbyte) item.AssetType; |
362 | item.AssetID = asset.FullID; | 362 | item.AssetID = asset.FullID; |
363 | 363 | ||
364 | m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); | 364 | m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); |
365 | } | 365 | } |
366 | 366 | ||
367 | userInfo.UpdateItem(remoteClient.AgentId, item); | 367 | userInfo.UpdateItem(remoteClient.AgentId, item); |
368 | } | 368 | } |
369 | } | 369 | } |
370 | } | 370 | } |
371 | 371 | ||
372 | private void DoCreateItem() | 372 | private void DoCreateItem() |
373 | { | 373 | { |
374 | //really need to fix this call, if lbsa71 saw this he would die. | 374 | //really need to fix this call, if lbsa71 saw this he would die. |
375 | m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); | 375 | m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); |
376 | CachedUserInfo userInfo = | 376 | CachedUserInfo userInfo = |
377 | m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); | 377 | m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); |
378 | if (userInfo != null) | 378 | if (userInfo != null) |
379 | { | 379 | { |
380 | InventoryItemBase item = new InventoryItemBase(); | 380 | InventoryItemBase item = new InventoryItemBase(); |
381 | item.Owner = ourClient.AgentId; | 381 | item.Owner = ourClient.AgentId; |
382 | item.Creator = ourClient.AgentId; | 382 | item.Creator = ourClient.AgentId; |
383 | item.ID = LLUUID.Random(); | 383 | item.ID = LLUUID.Random(); |
384 | item.AssetID = Asset.FullID; | 384 | item.AssetID = Asset.FullID; |
385 | item.Description = m_description; | 385 | item.Description = m_description; |
386 | item.Name = m_name; | 386 | item.Name = m_name; |
387 | item.AssetType = type; | 387 | item.AssetType = type; |
388 | item.InvType = invType; | 388 | item.InvType = invType; |
389 | item.Folder = InventFolder; | 389 | item.Folder = InventFolder; |
390 | item.BasePermissions = 2147483647; | 390 | item.BasePermissions = 2147483647; |
391 | item.CurrentPermissions = 2147483647; | 391 | item.CurrentPermissions = 2147483647; |
392 | item.NextPermissions = nextPerm; | 392 | item.NextPermissions = nextPerm; |
393 | item.Flags = (uint) wearableType; | 393 | item.Flags = (uint) wearableType; |
394 | 394 | ||
395 | userInfo.AddItem(ourClient.AgentId, item); | 395 | userInfo.AddItem(ourClient.AgentId, item); |
396 | ourClient.SendInventoryItemCreateUpdate(item); | 396 | ourClient.SendInventoryItemCreateUpdate(item); |
397 | } | 397 | } |
398 | } | 398 | } |
399 | 399 | ||
400 | public AssetBase GetAssetData() | 400 | public AssetBase GetAssetData() |
401 | { | 401 | { |
402 | if (m_finished) | 402 | if (m_finished) |
403 | { | 403 | { |
404 | return Asset; | 404 | return Asset; |
405 | } | 405 | } |
406 | return null; | 406 | return null; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | #endregion | 410 | #endregion |
411 | } | 411 | } |
412 | } \ No newline at end of file | 412 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs index b264c8a..fcd0e0c 100644 --- a/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs | |||
@@ -1,291 +1,291 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
36 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction | 38 | namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction |
39 | { | 39 | { |
40 | public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions | 40 | public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions |
41 | { | 41 | { |
42 | private readonly Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); | 42 | private readonly Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); |
43 | private bool m_dumpAssetsToFile = false; | 43 | private bool m_dumpAssetsToFile = false; |
44 | private Scene m_scene = null; | 44 | private Scene m_scene = null; |
45 | 45 | ||
46 | private AgentAssetTransactionsManager m_transactionManager; | 46 | private AgentAssetTransactionsManager m_transactionManager; |
47 | 47 | ||
48 | public AssetTransactionModule() | 48 | public AssetTransactionModule() |
49 | { | 49 | { |
50 | // System.Console.WriteLine("creating AgentAssetTransactionModule"); | 50 | // System.Console.WriteLine("creating AgentAssetTransactionModule"); |
51 | } | 51 | } |
52 | 52 | ||
53 | #region IAgentAssetTransactions Members | 53 | #region IAgentAssetTransactions Members |
54 | 54 | ||
55 | public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, | 55 | public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, |
56 | uint callbackID, string description, string name, sbyte invType, | 56 | uint callbackID, string description, string name, sbyte invType, |
57 | sbyte type, byte wearableType, uint nextOwnerMask) | 57 | sbyte type, byte wearableType, uint nextOwnerMask) |
58 | { | 58 | { |
59 | m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, | 59 | m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, |
60 | wearableType, nextOwnerMask); | 60 | wearableType, nextOwnerMask); |
61 | } | 61 | } |
62 | 62 | ||
63 | public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, | 63 | public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, |
64 | InventoryItemBase item) | 64 | InventoryItemBase item) |
65 | { | 65 | { |
66 | m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); | 66 | m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); |
67 | } | 67 | } |
68 | 68 | ||
69 | public void RemoveAgentAssetTransactions(LLUUID userID) | 69 | public void RemoveAgentAssetTransactions(LLUUID userID) |
70 | { | 70 | { |
71 | m_transactionManager.RemoveAgentAssetTransactions(userID); | 71 | m_transactionManager.RemoveAgentAssetTransactions(userID); |
72 | } | 72 | } |
73 | 73 | ||
74 | #endregion | 74 | #endregion |
75 | 75 | ||
76 | #region IRegionModule Members | 76 | #region IRegionModule Members |
77 | 77 | ||
78 | public void Initialise(Scene scene, IConfigSource config) | 78 | public void Initialise(Scene scene, IConfigSource config) |
79 | { | 79 | { |
80 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | 80 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) |
81 | { | 81 | { |
82 | // System.Console.WriteLine("initialising AgentAssetTransactionModule"); | 82 | // System.Console.WriteLine("initialising AgentAssetTransactionModule"); |
83 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); | 83 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); |
84 | scene.RegisterModuleInterface<IAgentAssetTransactions>(this); | 84 | scene.RegisterModuleInterface<IAgentAssetTransactions>(this); |
85 | 85 | ||
86 | scene.EventManager.OnNewClient += NewClient; | 86 | scene.EventManager.OnNewClient += NewClient; |
87 | } | 87 | } |
88 | 88 | ||
89 | if (m_scene == null) | 89 | if (m_scene == null) |
90 | { | 90 | { |
91 | m_scene = scene; | 91 | m_scene = scene; |
92 | if (config.Configs["StandAlone"] != null) | 92 | if (config.Configs["StandAlone"] != null) |
93 | { | 93 | { |
94 | try | 94 | try |
95 | { | 95 | { |
96 | m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false); | 96 | m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false); |
97 | m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile); | 97 | m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile); |
98 | } | 98 | } |
99 | catch (Exception) | 99 | catch (Exception) |
100 | { | 100 | { |
101 | m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); | 101 | m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | else | 104 | else |
105 | { | 105 | { |
106 | m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); | 106 | m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); |
107 | } | 107 | } |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | public void PostInitialise() | 111 | public void PostInitialise() |
112 | { | 112 | { |
113 | } | 113 | } |
114 | 114 | ||
115 | public void Close() | 115 | public void Close() |
116 | { | 116 | { |
117 | } | 117 | } |
118 | 118 | ||
119 | public string Name | 119 | public string Name |
120 | { | 120 | { |
121 | get { return "AgentTransactionModule"; } | 121 | get { return "AgentTransactionModule"; } |
122 | } | 122 | } |
123 | 123 | ||
124 | public bool IsSharedModule | 124 | public bool IsSharedModule |
125 | { | 125 | { |
126 | get { return true; } | 126 | get { return true; } |
127 | } | 127 | } |
128 | 128 | ||
129 | #endregion | 129 | #endregion |
130 | 130 | ||
131 | public void NewClient(IClientAPI client) | 131 | public void NewClient(IClientAPI client) |
132 | { | 132 | { |
133 | client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest; | 133 | client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest; |
134 | client.OnXferReceive += m_transactionManager.HandleXfer; | 134 | client.OnXferReceive += m_transactionManager.HandleXfer; |
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
138 | public class AgentAssetTransactionsManager | 138 | public class AgentAssetTransactionsManager |
139 | { | 139 | { |
140 | private static readonly ILog m_log | 140 | private static readonly ILog m_log |
141 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 141 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
142 | 142 | ||
143 | // Fields | 143 | // Fields |
144 | 144 | ||
145 | /// <summary> | 145 | /// <summary> |
146 | /// Each agent has its own singleton collection of transactions | 146 | /// Each agent has its own singleton collection of transactions |
147 | /// </summary> | 147 | /// </summary> |
148 | private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions = | 148 | private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions = |
149 | new Dictionary<LLUUID, AgentAssetTransactions>(); | 149 | new Dictionary<LLUUID, AgentAssetTransactions>(); |
150 | 150 | ||
151 | /// <summary> | 151 | /// <summary> |
152 | /// Should we dump uploaded assets to the filesystem? | 152 | /// Should we dump uploaded assets to the filesystem? |
153 | /// </summary> | 153 | /// </summary> |
154 | private bool m_dumpAssetsToFile; | 154 | private bool m_dumpAssetsToFile; |
155 | 155 | ||
156 | public Scene MyScene; | 156 | public Scene MyScene; |
157 | 157 | ||
158 | public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile) | 158 | public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile) |
159 | { | 159 | { |
160 | MyScene = scene; | 160 | MyScene = scene; |
161 | m_dumpAssetsToFile = dumpAssetsToFile; | 161 | m_dumpAssetsToFile = dumpAssetsToFile; |
162 | } | 162 | } |
163 | 163 | ||
164 | /// <summary> | 164 | /// <summary> |
165 | /// Get the collection of asset transactions for the given user. If one does not already exist, it | 165 | /// Get the collection of asset transactions for the given user. If one does not already exist, it |
166 | /// is created. | 166 | /// is created. |
167 | /// </summary> | 167 | /// </summary> |
168 | /// <param name="userID"></param> | 168 | /// <param name="userID"></param> |
169 | /// <returns></returns> | 169 | /// <returns></returns> |
170 | private AgentAssetTransactions GetUserTransactions(LLUUID userID) | 170 | private AgentAssetTransactions GetUserTransactions(LLUUID userID) |
171 | { | 171 | { |
172 | lock (AgentTransactions) | 172 | lock (AgentTransactions) |
173 | { | 173 | { |
174 | if (!AgentTransactions.ContainsKey(userID)) | 174 | if (!AgentTransactions.ContainsKey(userID)) |
175 | { | 175 | { |
176 | AgentAssetTransactions transactions | 176 | AgentAssetTransactions transactions |
177 | = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); | 177 | = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); |
178 | AgentTransactions.Add(userID, transactions); | 178 | AgentTransactions.Add(userID, transactions); |
179 | } | 179 | } |
180 | 180 | ||
181 | return AgentTransactions[userID]; | 181 | return AgentTransactions[userID]; |
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | /// <summary> | 185 | /// <summary> |
186 | /// Remove the given agent asset transactions. This should be called when a client is departing | 186 | /// Remove the given agent asset transactions. This should be called when a client is departing |
187 | /// from a scene (and hence won't be making any more transactions here). | 187 | /// from a scene (and hence won't be making any more transactions here). |
188 | /// </summary> | 188 | /// </summary> |
189 | /// <param name="userID"></param> | 189 | /// <param name="userID"></param> |
190 | public void RemoveAgentAssetTransactions(LLUUID userID) | 190 | public void RemoveAgentAssetTransactions(LLUUID userID) |
191 | { | 191 | { |
192 | // m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID); | 192 | // m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID); |
193 | 193 | ||
194 | lock (AgentTransactions) | 194 | lock (AgentTransactions) |
195 | { | 195 | { |
196 | AgentTransactions.Remove(userID); | 196 | AgentTransactions.Remove(userID); |
197 | } | 197 | } |
198 | } | 198 | } |
199 | 199 | ||
200 | /// <summary> | 200 | /// <summary> |
201 | /// Create an inventory item from data that has been received through a transaction. | 201 | /// Create an inventory item from data that has been received through a transaction. |
202 | /// | 202 | /// |
203 | /// This is called when new clothing or body parts are created. It may also be called in other | 203 | /// This is called when new clothing or body parts are created. It may also be called in other |
204 | /// situations. | 204 | /// situations. |
205 | /// </summary> | 205 | /// </summary> |
206 | /// <param name="remoteClient"></param> | 206 | /// <param name="remoteClient"></param> |
207 | /// <param name="transactionID"></param> | 207 | /// <param name="transactionID"></param> |
208 | /// <param name="folderID"></param> | 208 | /// <param name="folderID"></param> |
209 | /// <param name="callbackID"></param> | 209 | /// <param name="callbackID"></param> |
210 | /// <param name="description"></param> | 210 | /// <param name="description"></param> |
211 | /// <param name="name"></param> | 211 | /// <param name="name"></param> |
212 | /// <param name="invType"></param> | 212 | /// <param name="invType"></param> |
213 | /// <param name="type"></param> | 213 | /// <param name="type"></param> |
214 | /// <param name="wearableType"></param> | 214 | /// <param name="wearableType"></param> |
215 | /// <param name="nextOwnerMask"></param> | 215 | /// <param name="nextOwnerMask"></param> |
216 | public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, | 216 | public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, |
217 | uint callbackID, string description, string name, sbyte invType, | 217 | uint callbackID, string description, string name, sbyte invType, |
218 | sbyte type, byte wearableType, uint nextOwnerMask) | 218 | sbyte type, byte wearableType, uint nextOwnerMask) |
219 | { | 219 | { |
220 | m_log.DebugFormat( | 220 | m_log.DebugFormat( |
221 | "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); | 221 | "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); |
222 | 222 | ||
223 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); | 223 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); |
224 | 224 | ||
225 | transactions.RequestCreateInventoryItem( | 225 | transactions.RequestCreateInventoryItem( |
226 | remoteClient, transactionID, folderID, callbackID, description, | 226 | remoteClient, transactionID, folderID, callbackID, description, |
227 | name, invType, type, wearableType, nextOwnerMask); | 227 | name, invType, type, wearableType, nextOwnerMask); |
228 | } | 228 | } |
229 | 229 | ||
230 | /// <summary> | 230 | /// <summary> |
231 | /// Update an inventory item with data that has been received through a transaction. | 231 | /// Update an inventory item with data that has been received through a transaction. |
232 | /// | 232 | /// |
233 | /// This is called when clothing or body parts are updated (for instance, with new textures or | 233 | /// This is called when clothing or body parts are updated (for instance, with new textures or |
234 | /// colours). It may also be called in other situations. | 234 | /// colours). It may also be called in other situations. |
235 | /// </summary> | 235 | /// </summary> |
236 | /// <param name="remoteClient"></param> | 236 | /// <param name="remoteClient"></param> |
237 | /// <param name="transactionID"></param> | 237 | /// <param name="transactionID"></param> |
238 | /// <param name="item"></param> | 238 | /// <param name="item"></param> |
239 | public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, | 239 | public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, |
240 | InventoryItemBase item) | 240 | InventoryItemBase item) |
241 | { | 241 | { |
242 | m_log.DebugFormat( | 242 | m_log.DebugFormat( |
243 | "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", | 243 | "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", |
244 | item.Name); | 244 | item.Name); |
245 | 245 | ||
246 | AgentAssetTransactions transactions | 246 | AgentAssetTransactions transactions |
247 | = GetUserTransactions(remoteClient.AgentId); | 247 | = GetUserTransactions(remoteClient.AgentId); |
248 | 248 | ||
249 | transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); | 249 | transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); |
250 | } | 250 | } |
251 | 251 | ||
252 | /// <summary> | 252 | /// <summary> |
253 | /// Request that a client (agent) begin an asset transfer. | 253 | /// Request that a client (agent) begin an asset transfer. |
254 | /// </summary> | 254 | /// </summary> |
255 | /// <param name="remoteClient"></param> | 255 | /// <param name="remoteClient"></param> |
256 | /// <param name="assetID"></param> | 256 | /// <param name="assetID"></param> |
257 | /// <param name="transaction"></param> | 257 | /// <param name="transaction"></param> |
258 | /// <param name="type"></param> | 258 | /// <param name="type"></param> |
259 | /// <param name="data"></param></param> | 259 | /// <param name="data"></param></param> |
260 | /// <param name="tempFile"></param> | 260 | /// <param name="tempFile"></param> |
261 | public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, | 261 | public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, |
262 | byte[] data, bool storeLocal, bool tempFile) | 262 | byte[] data, bool storeLocal, bool tempFile) |
263 | { | 263 | { |
264 | // Console.WriteLine("asset upload of " + assetID); | 264 | // Console.WriteLine("asset upload of " + assetID); |
265 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); | 265 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); |
266 | 266 | ||
267 | AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); | 267 | AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); |
268 | if (uploader != null) | 268 | if (uploader != null) |
269 | { | 269 | { |
270 | if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) | 270 | if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) |
271 | { | 271 | { |
272 | } | 272 | } |
273 | } | 273 | } |
274 | } | 274 | } |
275 | 275 | ||
276 | /// <summary> | 276 | /// <summary> |
277 | /// Handle asset transfer data packets received in response to the asset upload request in | 277 | /// Handle asset transfer data packets received in response to the asset upload request in |
278 | /// HandleUDPUploadRequest() | 278 | /// HandleUDPUploadRequest() |
279 | /// </summary> | 279 | /// </summary> |
280 | /// <param name="remoteClient"></param> | 280 | /// <param name="remoteClient"></param> |
281 | /// <param name="xferID"></param> | 281 | /// <param name="xferID"></param> |
282 | /// <param name="packetID"></param> | 282 | /// <param name="packetID"></param> |
283 | /// <param name="data"></param> | 283 | /// <param name="data"></param> |
284 | public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) | 284 | public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) |
285 | { | 285 | { |
286 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); | 286 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); |
287 | 287 | ||
288 | transactions.HandleXfer(xferID, packetID, data); | 288 | transactions.HandleXfer(xferID, packetID, data); |
289 | } | 289 | } |
290 | } | 290 | } |
291 | } \ No newline at end of file | 291 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs index ae2df69..474ac75 100644 --- a/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs | |||
@@ -1,219 +1,219 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Threading; | 30 | using System.Threading; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload | 37 | namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload |
38 | { | 38 | { |
39 | public class TextureDownloadModule : IRegionModule | 39 | public class TextureDownloadModule : IRegionModule |
40 | { | 40 | { |
41 | //private static readonly log4net.ILog m_log | 41 | //private static readonly log4net.ILog m_log |
42 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 42 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
43 | 43 | ||
44 | /// <summary> | 44 | /// <summary> |
45 | /// There is one queue for all textures waiting to be sent, regardless of the requesting user. | 45 | /// There is one queue for all textures waiting to be sent, regardless of the requesting user. |
46 | /// </summary> | 46 | /// </summary> |
47 | private readonly BlockingQueue<ITextureSender> m_queueSenders | 47 | private readonly BlockingQueue<ITextureSender> m_queueSenders |
48 | = new BlockingQueue<ITextureSender>(); | 48 | = new BlockingQueue<ITextureSender>(); |
49 | 49 | ||
50 | /// <summary> | 50 | /// <summary> |
51 | /// Each user has their own texture download service. | 51 | /// Each user has their own texture download service. |
52 | /// </summary> | 52 | /// </summary> |
53 | private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = | 53 | private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = |
54 | new Dictionary<LLUUID, UserTextureDownloadService>(); | 54 | new Dictionary<LLUUID, UserTextureDownloadService>(); |
55 | 55 | ||
56 | private Scene m_scene; | 56 | private Scene m_scene; |
57 | private List<Scene> m_scenes = new List<Scene>(); | 57 | private List<Scene> m_scenes = new List<Scene>(); |
58 | 58 | ||
59 | private Thread m_thread; | 59 | private Thread m_thread; |
60 | 60 | ||
61 | public TextureDownloadModule() | 61 | public TextureDownloadModule() |
62 | { | 62 | { |
63 | } | 63 | } |
64 | 64 | ||
65 | #region IRegionModule Members | 65 | #region IRegionModule Members |
66 | 66 | ||
67 | public void Initialise(Scene scene, IConfigSource config) | 67 | public void Initialise(Scene scene, IConfigSource config) |
68 | { | 68 | { |
69 | if (m_scene == null) | 69 | if (m_scene == null) |
70 | { | 70 | { |
71 | //Console.WriteLine("Creating Texture download module"); | 71 | //Console.WriteLine("Creating Texture download module"); |
72 | m_thread = new Thread(new ThreadStart(ProcessTextureSenders)); | 72 | m_thread = new Thread(new ThreadStart(ProcessTextureSenders)); |
73 | m_thread.Name = "ProcessTextureSenderThread"; | 73 | m_thread.Name = "ProcessTextureSenderThread"; |
74 | m_thread.IsBackground = true; | 74 | m_thread.IsBackground = true; |
75 | m_thread.Start(); | 75 | m_thread.Start(); |
76 | ThreadTracker.Add(m_thread); | 76 | ThreadTracker.Add(m_thread); |
77 | } | 77 | } |
78 | 78 | ||
79 | if (!m_scenes.Contains(scene)) | 79 | if (!m_scenes.Contains(scene)) |
80 | { | 80 | { |
81 | m_scenes.Add(scene); | 81 | m_scenes.Add(scene); |
82 | m_scene = scene; | 82 | m_scene = scene; |
83 | m_scene.EventManager.OnNewClient += NewClient; | 83 | m_scene.EventManager.OnNewClient += NewClient; |
84 | m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence; | 84 | m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence; |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | public void PostInitialise() | 88 | public void PostInitialise() |
89 | { | 89 | { |
90 | } | 90 | } |
91 | 91 | ||
92 | public void Close() | 92 | public void Close() |
93 | { | 93 | { |
94 | } | 94 | } |
95 | 95 | ||
96 | public string Name | 96 | public string Name |
97 | { | 97 | { |
98 | get { return "TextureDownloadModule"; } | 98 | get { return "TextureDownloadModule"; } |
99 | } | 99 | } |
100 | 100 | ||
101 | public bool IsSharedModule | 101 | public bool IsSharedModule |
102 | { | 102 | { |
103 | get { return false; } | 103 | get { return false; } |
104 | } | 104 | } |
105 | 105 | ||
106 | #endregion | 106 | #endregion |
107 | 107 | ||
108 | /// <summary> | 108 | /// <summary> |
109 | /// Cleanup the texture service related objects for the removed presence. | 109 | /// Cleanup the texture service related objects for the removed presence. |
110 | /// </summary> | 110 | /// </summary> |
111 | /// <param name="agentId"> </param> | 111 | /// <param name="agentId"> </param> |
112 | private void EventManager_OnRemovePresence(LLUUID agentId) | 112 | private void EventManager_OnRemovePresence(LLUUID agentId) |
113 | { | 113 | { |
114 | UserTextureDownloadService textureService; | 114 | UserTextureDownloadService textureService; |
115 | 115 | ||
116 | lock (m_userTextureServices) | 116 | lock (m_userTextureServices) |
117 | { | 117 | { |
118 | if (m_userTextureServices.TryGetValue(agentId, out textureService)) | 118 | if (m_userTextureServices.TryGetValue(agentId, out textureService)) |
119 | { | 119 | { |
120 | textureService.Close(); | 120 | textureService.Close(); |
121 | 121 | ||
122 | m_userTextureServices.Remove(agentId); | 122 | m_userTextureServices.Remove(agentId); |
123 | } | 123 | } |
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | public void NewClient(IClientAPI client) | 127 | public void NewClient(IClientAPI client) |
128 | { | 128 | { |
129 | client.OnRequestTexture += TextureRequest; | 129 | client.OnRequestTexture += TextureRequest; |
130 | } | 130 | } |
131 | 131 | ||
132 | /// <summary> | 132 | /// <summary> |
133 | /// Does this user have a registered texture download service? | 133 | /// Does this user have a registered texture download service? |
134 | /// </summary> | 134 | /// </summary> |
135 | /// <param name="userID"></param> | 135 | /// <param name="userID"></param> |
136 | /// <param name="textureService"></param> | 136 | /// <param name="textureService"></param> |
137 | /// <returns>Always returns true, since a service is created if one does not already exist</returns> | 137 | /// <returns>Always returns true, since a service is created if one does not already exist</returns> |
138 | private bool TryGetUserTextureService( | 138 | private bool TryGetUserTextureService( |
139 | IClientAPI client, out UserTextureDownloadService textureService) | 139 | IClientAPI client, out UserTextureDownloadService textureService) |
140 | { | 140 | { |
141 | lock (m_userTextureServices) | 141 | lock (m_userTextureServices) |
142 | { | 142 | { |
143 | if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) | 143 | if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) |
144 | { | 144 | { |
145 | return true; | 145 | return true; |
146 | } | 146 | } |
147 | 147 | ||
148 | textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders); | 148 | textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders); |
149 | m_userTextureServices.Add(client.AgentId, textureService); | 149 | m_userTextureServices.Add(client.AgentId, textureService); |
150 | 150 | ||
151 | return true; | 151 | return true; |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | /// <summary> | 155 | /// <summary> |
156 | /// Start the process of requesting a given texture. | 156 | /// Start the process of requesting a given texture. |
157 | /// </summary> | 157 | /// </summary> |
158 | /// <param name="sender"> </param> | 158 | /// <param name="sender"> </param> |
159 | /// <param name="e"></param> | 159 | /// <param name="e"></param> |
160 | public void TextureRequest(Object sender, TextureRequestArgs e) | 160 | public void TextureRequest(Object sender, TextureRequestArgs e) |
161 | { | 161 | { |
162 | IClientAPI client = (IClientAPI) sender; | 162 | IClientAPI client = (IClientAPI) sender; |
163 | UserTextureDownloadService textureService; | 163 | UserTextureDownloadService textureService; |
164 | 164 | ||
165 | if (TryGetUserTextureService(client, out textureService)) | 165 | if (TryGetUserTextureService(client, out textureService)) |
166 | { | 166 | { |
167 | textureService.HandleTextureRequest(e); | 167 | textureService.HandleTextureRequest(e); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | /// <summary> | 171 | /// <summary> |
172 | /// Entry point for the thread dedicated to processing the texture queue. | 172 | /// Entry point for the thread dedicated to processing the texture queue. |
173 | /// </summary> | 173 | /// </summary> |
174 | public void ProcessTextureSenders() | 174 | public void ProcessTextureSenders() |
175 | { | 175 | { |
176 | ITextureSender sender = null; | 176 | ITextureSender sender = null; |
177 | 177 | ||
178 | while (true) | 178 | while (true) |
179 | { | 179 | { |
180 | sender = m_queueSenders.Dequeue(); | 180 | sender = m_queueSenders.Dequeue(); |
181 | 181 | ||
182 | if (sender.Cancel) | 182 | if (sender.Cancel) |
183 | { | 183 | { |
184 | TextureSent(sender); | 184 | TextureSent(sender); |
185 | 185 | ||
186 | sender.Cancel = false; | 186 | sender.Cancel = false; |
187 | } | 187 | } |
188 | else | 188 | else |
189 | { | 189 | { |
190 | bool finished = sender.SendTexturePacket(); | 190 | bool finished = sender.SendTexturePacket(); |
191 | if (finished) | 191 | if (finished) |
192 | { | 192 | { |
193 | TextureSent(sender); | 193 | TextureSent(sender); |
194 | } | 194 | } |
195 | else | 195 | else |
196 | { | 196 | { |
197 | m_queueSenders.Enqueue(sender); | 197 | m_queueSenders.Enqueue(sender); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | 200 | ||
201 | // Make sure that any sender we currently have can get garbage collected | 201 | // Make sure that any sender we currently have can get garbage collected |
202 | sender = null; | 202 | sender = null; |
203 | 203 | ||
204 | //m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count()); | 204 | //m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count()); |
205 | } | 205 | } |
206 | } | 206 | } |
207 | 207 | ||
208 | /// <summary> | 208 | /// <summary> |
209 | /// Called when the texture has finished sending. | 209 | /// Called when the texture has finished sending. |
210 | /// </summary> | 210 | /// </summary> |
211 | /// <param name="sender"></param> | 211 | /// <param name="sender"></param> |
212 | private void TextureSent(ITextureSender sender) | 212 | private void TextureSent(ITextureSender sender) |
213 | { | 213 | { |
214 | sender.Sending = false; | 214 | sender.Sending = false; |
215 | //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID); | 215 | //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID); |
216 | m_scene.AddPendingDownloads(-1); | 216 | m_scene.AddPendingDownloads(-1); |
217 | } | 217 | } |
218 | } | 218 | } |
219 | } \ No newline at end of file | 219 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs index b181d20..70e44d4 100644 --- a/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs +++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs | |||
@@ -1,98 +1,98 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using libsecondlife; | 28 | using libsecondlife; |
29 | using libsecondlife.Packets; | 29 | using libsecondlife.Packets; |
30 | using OpenSim.Framework; | 30 | using OpenSim.Framework; |
31 | using OpenSim.Region.Environment.Interfaces; | 31 | using OpenSim.Region.Environment.Interfaces; |
32 | 32 | ||
33 | namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload | 33 | namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload |
34 | { | 34 | { |
35 | /// <summary> | 35 | /// <summary> |
36 | /// Sends a 'texture not found' packet back to the client | 36 | /// Sends a 'texture not found' packet back to the client |
37 | /// </summary> | 37 | /// </summary> |
38 | public class TextureNotFoundSender : ITextureSender | 38 | public class TextureNotFoundSender : ITextureSender |
39 | { | 39 | { |
40 | //private static readonly log4net.ILog m_log | 40 | //private static readonly log4net.ILog m_log |
41 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 41 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
42 | 42 | ||
43 | private bool m_cancel = false; | 43 | private bool m_cancel = false; |
44 | private IClientAPI m_client; | 44 | private IClientAPI m_client; |
45 | 45 | ||
46 | // See ITextureSender | 46 | // See ITextureSender |
47 | 47 | ||
48 | private bool m_sending = false; | 48 | private bool m_sending = false; |
49 | private LLUUID m_textureId; | 49 | private LLUUID m_textureId; |
50 | 50 | ||
51 | // See ITextureSender | 51 | // See ITextureSender |
52 | 52 | ||
53 | public TextureNotFoundSender(IClientAPI client, LLUUID textureID) | 53 | public TextureNotFoundSender(IClientAPI client, LLUUID textureID) |
54 | { | 54 | { |
55 | m_client = client; | 55 | m_client = client; |
56 | m_textureId = textureID; | 56 | m_textureId = textureID; |
57 | } | 57 | } |
58 | 58 | ||
59 | #region ITextureSender Members | 59 | #region ITextureSender Members |
60 | 60 | ||
61 | public bool Sending | 61 | public bool Sending |
62 | { | 62 | { |
63 | get { return false; } | 63 | get { return false; } |
64 | set { m_sending = value; } | 64 | set { m_sending = value; } |
65 | } | 65 | } |
66 | 66 | ||
67 | public bool Cancel | 67 | public bool Cancel |
68 | { | 68 | { |
69 | get { return false; } | 69 | get { return false; } |
70 | set { m_cancel = value; } | 70 | set { m_cancel = value; } |
71 | } | 71 | } |
72 | 72 | ||
73 | // See ITextureSender | 73 | // See ITextureSender |
74 | public void UpdateRequest(int discardLevel, uint packetNumber) | 74 | public void UpdateRequest(int discardLevel, uint packetNumber) |
75 | { | 75 | { |
76 | // Not need to implement since priority changes don't affect this operation | 76 | // Not need to implement since priority changes don't affect this operation |
77 | } | 77 | } |
78 | 78 | ||
79 | // See ITextureSender | 79 | // See ITextureSender |
80 | public bool SendTexturePacket() | 80 | public bool SendTexturePacket() |
81 | { | 81 | { |
82 | //m_log.InfoFormat( | 82 | //m_log.InfoFormat( |
83 | // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found", | 83 | // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found", |
84 | // m_textureId); | 84 | // m_textureId); |
85 | 85 | ||
86 | ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket(); | 86 | ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket(); |
87 | notFound.ImageID.ID = m_textureId; | 87 | notFound.ImageID.ID = m_textureId; |
88 | 88 | ||
89 | // XXX Temporarily disabling as this appears to be causing client crashes on at least | 89 | // XXX Temporarily disabling as this appears to be causing client crashes on at least |
90 | // 1.19.0(5) of the Linden Second Life client. | 90 | // 1.19.0(5) of the Linden Second Life client. |
91 | // m_client.OutPacket(notFound, ThrottleOutPacketType.Texture); | 91 | // m_client.OutPacket(notFound, ThrottleOutPacketType.Texture); |
92 | 92 | ||
93 | return true; | 93 | return true; |
94 | } | 94 | } |
95 | 95 | ||
96 | #endregion | 96 | #endregion |
97 | } | 97 | } |
98 | } \ No newline at end of file | 98 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs index 4f63fd0..a450cdc 100644 --- a/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs +++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs | |||
@@ -1,249 +1,249 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using log4net; | 31 | using log4net; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Communications.Limit; | 33 | using OpenSim.Framework.Communications.Limit; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload | 37 | namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload |
38 | { | 38 | { |
39 | /// <summary> | 39 | /// <summary> |
40 | /// This module sets up texture senders in response to client texture requests, and places them on a | 40 | /// This module sets up texture senders in response to client texture requests, and places them on a |
41 | /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the | 41 | /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the |
42 | /// asset cache). | 42 | /// asset cache). |
43 | /// </summary> | 43 | /// </summary> |
44 | public class UserTextureDownloadService | 44 | public class UserTextureDownloadService |
45 | { | 45 | { |
46 | private static readonly ILog m_log | 46 | private static readonly ILog m_log |
47 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | /// <summary> | 49 | /// <summary> |
50 | /// We will allow the client to request the same texture n times before dropping further requests | 50 | /// We will allow the client to request the same texture n times before dropping further requests |
51 | /// | 51 | /// |
52 | /// This number includes repeated requests for the same texture at different resolutions (which we don't | 52 | /// This number includes repeated requests for the same texture at different resolutions (which we don't |
53 | /// currently handle properly as far as I know). However, this situation should be handled in a more | 53 | /// currently handle properly as far as I know). However, this situation should be handled in a more |
54 | /// sophisticated way. | 54 | /// sophisticated way. |
55 | /// </summary> | 55 | /// </summary> |
56 | private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5; | 56 | private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5; |
57 | 57 | ||
58 | /// <summary> | 58 | /// <summary> |
59 | /// XXX Also going to limit requests for found textures. | 59 | /// XXX Also going to limit requests for found textures. |
60 | /// </summary> | 60 | /// </summary> |
61 | private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy | 61 | private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy |
62 | = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); | 62 | = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); |
63 | 63 | ||
64 | private readonly IClientAPI m_client; | 64 | private readonly IClientAPI m_client; |
65 | private readonly Scene m_scene; | 65 | private readonly Scene m_scene; |
66 | 66 | ||
67 | /// <summary> | 67 | /// <summary> |
68 | /// Texture Senders are placed in this queue once they have received their texture from the asset | 68 | /// Texture Senders are placed in this queue once they have received their texture from the asset |
69 | /// cache. Another module actually invokes the send. | 69 | /// cache. Another module actually invokes the send. |
70 | /// </summary> | 70 | /// </summary> |
71 | private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue; | 71 | private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue; |
72 | 72 | ||
73 | /// <summary> | 73 | /// <summary> |
74 | /// Holds texture senders before they have received the appropriate texture from the asset cache. | 74 | /// Holds texture senders before they have received the appropriate texture from the asset cache. |
75 | /// </summary> | 75 | /// </summary> |
76 | private readonly Dictionary<LLUUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender.TextureSender>(); | 76 | private readonly Dictionary<LLUUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender.TextureSender>(); |
77 | 77 | ||
78 | /// <summary> | 78 | /// <summary> |
79 | /// We're going to limit requests for the same missing texture. | 79 | /// We're going to limit requests for the same missing texture. |
80 | /// XXX This is really a temporary solution to deal with the situation where a client continually requests | 80 | /// XXX This is really a temporary solution to deal with the situation where a client continually requests |
81 | /// the same missing textures | 81 | /// the same missing textures |
82 | /// </summary> | 82 | /// </summary> |
83 | private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy | 83 | private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy |
84 | = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); | 84 | = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); |
85 | 85 | ||
86 | public UserTextureDownloadService( | 86 | public UserTextureDownloadService( |
87 | IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue) | 87 | IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue) |
88 | { | 88 | { |
89 | m_client = client; | 89 | m_client = client; |
90 | m_scene = scene; | 90 | m_scene = scene; |
91 | m_sharedSendersQueue = sharedQueue; | 91 | m_sharedSendersQueue = sharedQueue; |
92 | } | 92 | } |
93 | 93 | ||
94 | /// <summary> | 94 | /// <summary> |
95 | /// Handle a texture request. This involves creating a texture sender and placing it on the | 95 | /// Handle a texture request. This involves creating a texture sender and placing it on the |
96 | /// previously passed in shared queue. | 96 | /// previously passed in shared queue. |
97 | /// </summary> | 97 | /// </summary> |
98 | /// <param name="e"></param> | 98 | /// <param name="e"></param> |
99 | public void HandleTextureRequest(TextureRequestArgs e) | 99 | public void HandleTextureRequest(TextureRequestArgs e) |
100 | { | 100 | { |
101 | TextureSender.TextureSender textureSender; | 101 | TextureSender.TextureSender textureSender; |
102 | 102 | ||
103 | //TODO: should be working out the data size/ number of packets to be sent for each discard level | 103 | //TODO: should be working out the data size/ number of packets to be sent for each discard level |
104 | if ((e.DiscardLevel >= 0) || (e.Priority != 0)) | 104 | if ((e.DiscardLevel >= 0) || (e.Priority != 0)) |
105 | { | 105 | { |
106 | lock (m_textureSenders) | 106 | lock (m_textureSenders) |
107 | { | 107 | { |
108 | if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) | 108 | if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) |
109 | { | 109 | { |
110 | // If we've received new non UUID information for this request and it hasn't dispatched | 110 | // If we've received new non UUID information for this request and it hasn't dispatched |
111 | // yet, then update the request accordingly. | 111 | // yet, then update the request accordingly. |
112 | textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); | 112 | textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); |
113 | } | 113 | } |
114 | else | 114 | else |
115 | { | 115 | { |
116 | if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) | 116 | if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) |
117 | { | 117 | { |
118 | // m_log.DebugFormat( | 118 | // m_log.DebugFormat( |
119 | // "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}", | 119 | // "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}", |
120 | // e.RequestedAssetID, m_client.AgentId); | 120 | // e.RequestedAssetID, m_client.AgentId); |
121 | 121 | ||
122 | return; | 122 | return; |
123 | } | 123 | } |
124 | else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) | 124 | else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) |
125 | { | 125 | { |
126 | if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID)) | 126 | if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID)) |
127 | { | 127 | { |
128 | // Commenting out this message for now as it causes too much noise with other | 128 | // Commenting out this message for now as it causes too much noise with other |
129 | // debug messages. | 129 | // debug messages. |
130 | // TODO: possibly record this as a statistic in the future | 130 | // TODO: possibly record this as a statistic in the future |
131 | // | 131 | // |
132 | // m_log.DebugFormat( | 132 | // m_log.DebugFormat( |
133 | // "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests", | 133 | // "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests", |
134 | // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS); | 134 | // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS); |
135 | } | 135 | } |
136 | 136 | ||
137 | return; | 137 | return; |
138 | } | 138 | } |
139 | 139 | ||
140 | m_scene.AddPendingDownloads(1); | 140 | m_scene.AddPendingDownloads(1); |
141 | 141 | ||
142 | TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber); | 142 | TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber); |
143 | m_textureSenders.Add(e.RequestedAssetID, requestHandler); | 143 | m_textureSenders.Add(e.RequestedAssetID, requestHandler); |
144 | 144 | ||
145 | m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true); | 145 | m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
149 | else | 149 | else |
150 | { | 150 | { |
151 | lock (m_textureSenders) | 151 | lock (m_textureSenders) |
152 | { | 152 | { |
153 | if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) | 153 | if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) |
154 | { | 154 | { |
155 | textureSender.Cancel = true; | 155 | textureSender.Cancel = true; |
156 | } | 156 | } |
157 | } | 157 | } |
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
161 | /// <summary> | 161 | /// <summary> |
162 | /// The callback for the asset cache when a texture has been retrieved. This method queues the | 162 | /// The callback for the asset cache when a texture has been retrieved. This method queues the |
163 | /// texture sender for processing. | 163 | /// texture sender for processing. |
164 | /// </summary> | 164 | /// </summary> |
165 | /// <param name="textureID"></param> | 165 | /// <param name="textureID"></param> |
166 | /// <param name="texture"></param> | 166 | /// <param name="texture"></param> |
167 | public void TextureCallback(LLUUID textureID, AssetBase texture) | 167 | public void TextureCallback(LLUUID textureID, AssetBase texture) |
168 | { | 168 | { |
169 | //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false)); | 169 | //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false)); |
170 | 170 | ||
171 | lock (m_textureSenders) | 171 | lock (m_textureSenders) |
172 | { | 172 | { |
173 | TextureSender.TextureSender textureSender; | 173 | TextureSender.TextureSender textureSender; |
174 | 174 | ||
175 | if (m_textureSenders.TryGetValue(textureID, out textureSender)) | 175 | if (m_textureSenders.TryGetValue(textureID, out textureSender)) |
176 | { | 176 | { |
177 | // XXX It may be perfectly valid for a texture to have no data... but if we pass | 177 | // XXX It may be perfectly valid for a texture to have no data... but if we pass |
178 | // this on to the TextureSender it will blow up, so just discard for now. | 178 | // this on to the TextureSender it will blow up, so just discard for now. |
179 | // Needs investigation. | 179 | // Needs investigation. |
180 | if (texture == null || texture.Data == null) | 180 | if (texture == null || texture.Data == null) |
181 | { | 181 | { |
182 | if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID)) | 182 | if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID)) |
183 | { | 183 | { |
184 | missingTextureLimitStrategy.MonitorRequests(textureID); | 184 | missingTextureLimitStrategy.MonitorRequests(textureID); |
185 | 185 | ||
186 | m_log.DebugFormat( | 186 | m_log.DebugFormat( |
187 | "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}", | 187 | "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}", |
188 | textureID, m_client.AgentId); | 188 | textureID, m_client.AgentId); |
189 | } | 189 | } |
190 | 190 | ||
191 | ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID); | 191 | ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID); |
192 | EnqueueTextureSender(textureNotFoundSender); | 192 | EnqueueTextureSender(textureNotFoundSender); |
193 | } | 193 | } |
194 | else | 194 | else |
195 | { | 195 | { |
196 | if (!textureSender.ImageLoaded) | 196 | if (!textureSender.ImageLoaded) |
197 | { | 197 | { |
198 | textureSender.TextureReceived(texture); | 198 | textureSender.TextureReceived(texture); |
199 | EnqueueTextureSender(textureSender); | 199 | EnqueueTextureSender(textureSender); |
200 | 200 | ||
201 | foundTextureLimitStrategy.MonitorRequests(textureID); | 201 | foundTextureLimitStrategy.MonitorRequests(textureID); |
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | //m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID); | 205 | //m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID); |
206 | m_textureSenders.Remove(textureID); | 206 | m_textureSenders.Remove(textureID); |
207 | //m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count); | 207 | //m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count); |
208 | } | 208 | } |
209 | else | 209 | else |
210 | { | 210 | { |
211 | m_log.WarnFormat( | 211 | m_log.WarnFormat( |
212 | "Got a texture uuid {0} with no sender object to handle it, this shouldn't happen", | 212 | "Got a texture uuid {0} with no sender object to handle it, this shouldn't happen", |
213 | textureID); | 213 | textureID); |
214 | } | 214 | } |
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | /// <summary> | 218 | /// <summary> |
219 | /// Place a ready texture sender on the processing queue. | 219 | /// Place a ready texture sender on the processing queue. |
220 | /// </summary> | 220 | /// </summary> |
221 | /// <param name="textureSender"></param> | 221 | /// <param name="textureSender"></param> |
222 | private void EnqueueTextureSender(ITextureSender textureSender) | 222 | private void EnqueueTextureSender(ITextureSender textureSender) |
223 | { | 223 | { |
224 | textureSender.Cancel = false; | 224 | textureSender.Cancel = false; |
225 | textureSender.Sending = true; | 225 | textureSender.Sending = true; |
226 | 226 | ||
227 | if (!m_sharedSendersQueue.Contains(textureSender)) | 227 | if (!m_sharedSendersQueue.Contains(textureSender)) |
228 | { | 228 | { |
229 | m_sharedSendersQueue.Enqueue(textureSender); | 229 | m_sharedSendersQueue.Enqueue(textureSender); |
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | /// <summary> | 233 | /// <summary> |
234 | /// Close this module. | 234 | /// Close this module. |
235 | /// </summary> | 235 | /// </summary> |
236 | internal void Close() | 236 | internal void Close() |
237 | { | 237 | { |
238 | lock (m_textureSenders) | 238 | lock (m_textureSenders) |
239 | { | 239 | { |
240 | foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values) | 240 | foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values) |
241 | { | 241 | { |
242 | textureSender.Cancel = true; | 242 | textureSender.Cancel = true; |
243 | } | 243 | } |
244 | 244 | ||
245 | m_textureSenders.Clear(); | 245 | m_textureSenders.Clear(); |
246 | } | 246 | } |
247 | } | 247 | } |
248 | } | 248 | } |
249 | } \ No newline at end of file | 249 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs b/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs index b6f7095..02c541b 100644 --- a/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs +++ b/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs | |||
@@ -1,223 +1,223 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife.Packets; | 30 | using libsecondlife.Packets; |
31 | using log4net; | 31 | using log4net; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | 34 | ||
35 | namespace OpenSim.Region.Environment.Modules.Agent.TextureSender | 35 | namespace OpenSim.Region.Environment.Modules.Agent.TextureSender |
36 | { | 36 | { |
37 | /// <summary> | 37 | /// <summary> |
38 | /// A TextureSender handles the process of receiving a texture requested by the client from the | 38 | /// A TextureSender handles the process of receiving a texture requested by the client from the |
39 | /// AssetCache, and then sending that texture back to the client. | 39 | /// AssetCache, and then sending that texture back to the client. |
40 | /// </summary> | 40 | /// </summary> |
41 | public class TextureSender : ITextureSender | 41 | public class TextureSender : ITextureSender |
42 | { | 42 | { |
43 | private static readonly ILog m_log | 43 | private static readonly ILog m_log |
44 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
46 | /// <summary> | 46 | /// <summary> |
47 | /// Records the number of times texture send has been called. | 47 | /// Records the number of times texture send has been called. |
48 | /// </summary> | 48 | /// </summary> |
49 | public int counter = 0; | 49 | public int counter = 0; |
50 | 50 | ||
51 | public bool ImageLoaded = false; | 51 | public bool ImageLoaded = false; |
52 | 52 | ||
53 | /// <summary> | 53 | /// <summary> |
54 | /// Holds the texture asset to send. | 54 | /// Holds the texture asset to send. |
55 | /// </summary> | 55 | /// </summary> |
56 | private AssetBase m_asset; | 56 | private AssetBase m_asset; |
57 | 57 | ||
58 | //public LLUUID assetID { get { return m_asset.FullID; } } | 58 | //public LLUUID assetID { get { return m_asset.FullID; } } |
59 | 59 | ||
60 | private bool m_cancel = false; | 60 | private bool m_cancel = false; |
61 | 61 | ||
62 | // See ITextureSender | 62 | // See ITextureSender |
63 | 63 | ||
64 | private bool m_sending = false; | 64 | private bool m_sending = false; |
65 | 65 | ||
66 | /// <summary> | 66 | /// <summary> |
67 | /// This is actually the number of extra packets required to send the texture data! We always assume | 67 | /// This is actually the number of extra packets required to send the texture data! We always assume |
68 | /// at least one is required. | 68 | /// at least one is required. |
69 | /// </summary> | 69 | /// </summary> |
70 | private int NumPackets = 0; | 70 | private int NumPackets = 0; |
71 | 71 | ||
72 | /// <summary> | 72 | /// <summary> |
73 | /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts | 73 | /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts |
74 | /// at the 600th byte (0th indexed). | 74 | /// at the 600th byte (0th indexed). |
75 | /// </summary> | 75 | /// </summary> |
76 | private int PacketCounter = 0; | 76 | private int PacketCounter = 0; |
77 | 77 | ||
78 | private int RequestedDiscardLevel = -1; | 78 | private int RequestedDiscardLevel = -1; |
79 | private IClientAPI RequestUser; | 79 | private IClientAPI RequestUser; |
80 | private uint StartPacketNumber = 0; | 80 | private uint StartPacketNumber = 0; |
81 | 81 | ||
82 | public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) | 82 | public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) |
83 | { | 83 | { |
84 | RequestUser = client; | 84 | RequestUser = client; |
85 | RequestedDiscardLevel = discardLevel; | 85 | RequestedDiscardLevel = discardLevel; |
86 | StartPacketNumber = packetNumber; | 86 | StartPacketNumber = packetNumber; |
87 | } | 87 | } |
88 | 88 | ||
89 | #region ITextureSender Members | 89 | #region ITextureSender Members |
90 | 90 | ||
91 | public bool Cancel | 91 | public bool Cancel |
92 | { | 92 | { |
93 | get { return false; } | 93 | get { return false; } |
94 | set { m_cancel = value; } | 94 | set { m_cancel = value; } |
95 | } | 95 | } |
96 | 96 | ||
97 | public bool Sending | 97 | public bool Sending |
98 | { | 98 | { |
99 | get { return false; } | 99 | get { return false; } |
100 | set { m_sending = value; } | 100 | set { m_sending = value; } |
101 | } | 101 | } |
102 | 102 | ||
103 | // See ITextureSender | 103 | // See ITextureSender |
104 | public void UpdateRequest(int discardLevel, uint packetNumber) | 104 | public void UpdateRequest(int discardLevel, uint packetNumber) |
105 | { | 105 | { |
106 | RequestedDiscardLevel = discardLevel; | 106 | RequestedDiscardLevel = discardLevel; |
107 | StartPacketNumber = packetNumber; | 107 | StartPacketNumber = packetNumber; |
108 | PacketCounter = (int) StartPacketNumber; | 108 | PacketCounter = (int) StartPacketNumber; |
109 | } | 109 | } |
110 | 110 | ||
111 | // See ITextureSender | 111 | // See ITextureSender |
112 | public bool SendTexturePacket() | 112 | public bool SendTexturePacket() |
113 | { | 113 | { |
114 | //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID); | 114 | //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID); |
115 | 115 | ||
116 | SendPacket(); | 116 | SendPacket(); |
117 | counter++; | 117 | counter++; |
118 | if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || | 118 | if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || |
119 | ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1))))) | 119 | ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1))))) |
120 | { | 120 | { |
121 | return true; | 121 | return true; |
122 | } | 122 | } |
123 | return false; | 123 | return false; |
124 | } | 124 | } |
125 | 125 | ||
126 | #endregion | 126 | #endregion |
127 | 127 | ||
128 | /// <summary> | 128 | /// <summary> |
129 | /// Load up the texture data to send. | 129 | /// Load up the texture data to send. |
130 | /// </summary> | 130 | /// </summary> |
131 | /// <param name="asset"> | 131 | /// <param name="asset"> |
132 | /// A <see cref="AssetBase"/> | 132 | /// A <see cref="AssetBase"/> |
133 | /// </param> | 133 | /// </param> |
134 | public void TextureReceived(AssetBase asset) | 134 | public void TextureReceived(AssetBase asset) |
135 | { | 135 | { |
136 | m_asset = asset; | 136 | m_asset = asset; |
137 | NumPackets = CalculateNumPackets(asset.Data.Length); | 137 | NumPackets = CalculateNumPackets(asset.Data.Length); |
138 | PacketCounter = (int) StartPacketNumber; | 138 | PacketCounter = (int) StartPacketNumber; |
139 | ImageLoaded = true; | 139 | ImageLoaded = true; |
140 | } | 140 | } |
141 | 141 | ||
142 | /// <summary> | 142 | /// <summary> |
143 | /// Sends a texture packet to the client. | 143 | /// Sends a texture packet to the client. |
144 | /// </summary> | 144 | /// </summary> |
145 | private void SendPacket() | 145 | private void SendPacket() |
146 | { | 146 | { |
147 | if (PacketCounter <= NumPackets) | 147 | if (PacketCounter <= NumPackets) |
148 | { | 148 | { |
149 | if (PacketCounter == 0) | 149 | if (PacketCounter == 0) |
150 | { | 150 | { |
151 | if (NumPackets == 0) | 151 | if (NumPackets == 0) |
152 | { | 152 | { |
153 | ImageDataPacket im = new ImageDataPacket(); | 153 | ImageDataPacket im = new ImageDataPacket(); |
154 | im.Header.Reliable = false; | 154 | im.Header.Reliable = false; |
155 | im.ImageID.Packets = 1; | 155 | im.ImageID.Packets = 1; |
156 | im.ImageID.ID = m_asset.FullID; | 156 | im.ImageID.ID = m_asset.FullID; |
157 | im.ImageID.Size = (uint) m_asset.Data.Length; | 157 | im.ImageID.Size = (uint) m_asset.Data.Length; |
158 | im.ImageData.Data = m_asset.Data; | 158 | im.ImageData.Data = m_asset.Data; |
159 | im.ImageID.Codec = 2; | 159 | im.ImageID.Codec = 2; |
160 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | 160 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); |
161 | PacketCounter++; | 161 | PacketCounter++; |
162 | } | 162 | } |
163 | else | 163 | else |
164 | { | 164 | { |
165 | ImageDataPacket im = new ImageDataPacket(); | 165 | ImageDataPacket im = new ImageDataPacket(); |
166 | im.Header.Reliable = false; | 166 | im.Header.Reliable = false; |
167 | im.ImageID.Packets = (ushort) (NumPackets); | 167 | im.ImageID.Packets = (ushort) (NumPackets); |
168 | im.ImageID.ID = m_asset.FullID; | 168 | im.ImageID.ID = m_asset.FullID; |
169 | im.ImageID.Size = (uint) m_asset.Data.Length; | 169 | im.ImageID.Size = (uint) m_asset.Data.Length; |
170 | im.ImageData.Data = new byte[600]; | 170 | im.ImageData.Data = new byte[600]; |
171 | Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); | 171 | Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); |
172 | im.ImageID.Codec = 2; | 172 | im.ImageID.Codec = 2; |
173 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | 173 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); |
174 | PacketCounter++; | 174 | PacketCounter++; |
175 | } | 175 | } |
176 | } | 176 | } |
177 | else | 177 | else |
178 | { | 178 | { |
179 | ImagePacketPacket im = new ImagePacketPacket(); | 179 | ImagePacketPacket im = new ImagePacketPacket(); |
180 | im.Header.Reliable = false; | 180 | im.Header.Reliable = false; |
181 | im.ImageID.Packet = (ushort) (PacketCounter); | 181 | im.ImageID.Packet = (ushort) (PacketCounter); |
182 | im.ImageID.ID = m_asset.FullID; | 182 | im.ImageID.ID = m_asset.FullID; |
183 | int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1)); | 183 | int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1)); |
184 | if (size > 1000) size = 1000; | 184 | if (size > 1000) size = 1000; |
185 | im.ImageData.Data = new byte[size]; | 185 | im.ImageData.Data = new byte[size]; |
186 | try | 186 | try |
187 | { | 187 | { |
188 | Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size); | 188 | Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size); |
189 | } | 189 | } |
190 | catch (ArgumentOutOfRangeException) | 190 | catch (ArgumentOutOfRangeException) |
191 | { | 191 | { |
192 | m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" + | 192 | m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" + |
193 | m_asset.FullID.ToString()); | 193 | m_asset.FullID.ToString()); |
194 | return; | 194 | return; |
195 | } | 195 | } |
196 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | 196 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); |
197 | PacketCounter++; | 197 | PacketCounter++; |
198 | } | 198 | } |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | /// <summary> | 202 | /// <summary> |
203 | /// Calculate the number of packets that will be required to send the texture loaded into this sender | 203 | /// Calculate the number of packets that will be required to send the texture loaded into this sender |
204 | /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... | 204 | /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... |
205 | /// </summary> | 205 | /// </summary> |
206 | /// <param name="length"></param> | 206 | /// <param name="length"></param> |
207 | /// <returns></returns> | 207 | /// <returns></returns> |
208 | private int CalculateNumPackets(int length) | 208 | private int CalculateNumPackets(int length) |
209 | { | 209 | { |
210 | int numPackets = 0; | 210 | int numPackets = 0; |
211 | 211 | ||
212 | if (length > 600) | 212 | if (length > 600) |
213 | { | 213 | { |
214 | //over 600 bytes so split up file | 214 | //over 600 bytes so split up file |
215 | int restData = (length - 600); | 215 | int restData = (length - 600); |
216 | int restPackets = ((restData + 999) / 1000); | 216 | int restPackets = ((restData + 999) / 1000); |
217 | numPackets = restPackets; | 217 | numPackets = restPackets; |
218 | } | 218 | } |
219 | 219 | ||
220 | return numPackets; | 220 | return numPackets; |
221 | } | 221 | } |
222 | } | 222 | } |
223 | } \ No newline at end of file | 223 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs index e35b6f5..8e90d17 100644 --- a/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs | |||
@@ -1,235 +1,235 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.Modules.Agent.Xfer | 36 | namespace OpenSim.Region.Environment.Modules.Agent.Xfer |
37 | { | 37 | { |
38 | public class XferModule : IRegionModule, IXfer | 38 | public class XferModule : IRegionModule, IXfer |
39 | { | 39 | { |
40 | private Scene m_scene; | 40 | private Scene m_scene; |
41 | public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>(); | 41 | public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>(); |
42 | public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); | 42 | public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); |
43 | 43 | ||
44 | public XferModule() | 44 | public XferModule() |
45 | { | 45 | { |
46 | } | 46 | } |
47 | 47 | ||
48 | #region IRegionModule Members | 48 | #region IRegionModule Members |
49 | 49 | ||
50 | public void Initialise(Scene scene, IConfigSource config) | 50 | public void Initialise(Scene scene, IConfigSource config) |
51 | { | 51 | { |
52 | m_scene = scene; | 52 | m_scene = scene; |
53 | m_scene.EventManager.OnNewClient += NewClient; | 53 | m_scene.EventManager.OnNewClient += NewClient; |
54 | 54 | ||
55 | m_scene.RegisterModuleInterface<IXfer>(this); | 55 | m_scene.RegisterModuleInterface<IXfer>(this); |
56 | } | 56 | } |
57 | 57 | ||
58 | public void PostInitialise() | 58 | public void PostInitialise() |
59 | { | 59 | { |
60 | } | 60 | } |
61 | 61 | ||
62 | public void Close() | 62 | public void Close() |
63 | { | 63 | { |
64 | } | 64 | } |
65 | 65 | ||
66 | public string Name | 66 | public string Name |
67 | { | 67 | { |
68 | get { return "XferModule"; } | 68 | get { return "XferModule"; } |
69 | } | 69 | } |
70 | 70 | ||
71 | public bool IsSharedModule | 71 | public bool IsSharedModule |
72 | { | 72 | { |
73 | get { return false; } | 73 | get { return false; } |
74 | } | 74 | } |
75 | 75 | ||
76 | #endregion | 76 | #endregion |
77 | 77 | ||
78 | #region IXfer Members | 78 | #region IXfer Members |
79 | 79 | ||
80 | public bool AddNewFile(string fileName, byte[] data) | 80 | public bool AddNewFile(string fileName, byte[] data) |
81 | { | 81 | { |
82 | lock (NewFiles) | 82 | lock (NewFiles) |
83 | { | 83 | { |
84 | if (NewFiles.ContainsKey(fileName)) | 84 | if (NewFiles.ContainsKey(fileName)) |
85 | { | 85 | { |
86 | NewFiles[fileName] = data; | 86 | NewFiles[fileName] = data; |
87 | } | 87 | } |
88 | else | 88 | else |
89 | { | 89 | { |
90 | NewFiles.Add(fileName, data); | 90 | NewFiles.Add(fileName, data); |
91 | } | 91 | } |
92 | } | 92 | } |
93 | return true; | 93 | return true; |
94 | } | 94 | } |
95 | 95 | ||
96 | #endregion | 96 | #endregion |
97 | 97 | ||
98 | public void NewClient(IClientAPI client) | 98 | public void NewClient(IClientAPI client) |
99 | { | 99 | { |
100 | client.OnRequestXfer += RequestXfer; | 100 | client.OnRequestXfer += RequestXfer; |
101 | client.OnConfirmXfer += AckPacket; | 101 | client.OnConfirmXfer += AckPacket; |
102 | } | 102 | } |
103 | 103 | ||
104 | /// <summary> | 104 | /// <summary> |
105 | /// | 105 | /// |
106 | /// </summary> | 106 | /// </summary> |
107 | /// <param name="remoteClient"></param> | 107 | /// <param name="remoteClient"></param> |
108 | /// <param name="xferID"></param> | 108 | /// <param name="xferID"></param> |
109 | /// <param name="fileName"></param> | 109 | /// <param name="fileName"></param> |
110 | public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName) | 110 | public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName) |
111 | { | 111 | { |
112 | lock (NewFiles) | 112 | lock (NewFiles) |
113 | { | 113 | { |
114 | if (NewFiles.ContainsKey(fileName)) | 114 | if (NewFiles.ContainsKey(fileName)) |
115 | { | 115 | { |
116 | if (!Transfers.ContainsKey(xferID)) | 116 | if (!Transfers.ContainsKey(xferID)) |
117 | { | 117 | { |
118 | byte[] fileData = NewFiles[fileName]; | 118 | byte[] fileData = NewFiles[fileName]; |
119 | XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); | 119 | XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); |
120 | Transfers.Add(xferID, transaction); | 120 | Transfers.Add(xferID, transaction); |
121 | NewFiles.Remove(fileName); | 121 | NewFiles.Remove(fileName); |
122 | 122 | ||
123 | if (transaction.StartSend()) | 123 | if (transaction.StartSend()) |
124 | { | 124 | { |
125 | Transfers.Remove(xferID); | 125 | Transfers.Remove(xferID); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) | 132 | public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) |
133 | { | 133 | { |
134 | if (Transfers.ContainsKey(xferID)) | 134 | if (Transfers.ContainsKey(xferID)) |
135 | { | 135 | { |
136 | if (Transfers[xferID].AckPacket(packet)) | 136 | if (Transfers[xferID].AckPacket(packet)) |
137 | { | 137 | { |
138 | { | 138 | { |
139 | Transfers.Remove(xferID); | 139 | Transfers.Remove(xferID); |
140 | } | 140 | } |
141 | } | 141 | } |
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | #region Nested type: XferDownLoad | 145 | #region Nested type: XferDownLoad |
146 | 146 | ||
147 | public class XferDownLoad | 147 | public class XferDownLoad |
148 | { | 148 | { |
149 | public IClientAPI Client; | 149 | public IClientAPI Client; |
150 | private bool complete; | 150 | private bool complete; |
151 | public byte[] Data = new byte[0]; | 151 | public byte[] Data = new byte[0]; |
152 | public int DataPointer = 0; | 152 | public int DataPointer = 0; |
153 | public string FileName = String.Empty; | 153 | public string FileName = String.Empty; |
154 | public uint Packet = 0; | 154 | public uint Packet = 0; |
155 | public uint Serial = 1; | 155 | public uint Serial = 1; |
156 | public ulong XferID = 0; | 156 | public ulong XferID = 0; |
157 | 157 | ||
158 | public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) | 158 | public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) |
159 | { | 159 | { |
160 | FileName = fileName; | 160 | FileName = fileName; |
161 | Data = data; | 161 | Data = data; |
162 | XferID = xferID; | 162 | XferID = xferID; |
163 | Client = client; | 163 | Client = client; |
164 | } | 164 | } |
165 | 165 | ||
166 | public XferDownLoad() | 166 | public XferDownLoad() |
167 | { | 167 | { |
168 | } | 168 | } |
169 | 169 | ||
170 | /// <summary> | 170 | /// <summary> |
171 | /// Start a transfer | 171 | /// Start a transfer |
172 | /// </summary> | 172 | /// </summary> |
173 | /// <returns>True if the transfer is complete, false if not</returns> | 173 | /// <returns>True if the transfer is complete, false if not</returns> |
174 | public bool StartSend() | 174 | public bool StartSend() |
175 | { | 175 | { |
176 | if (Data.Length < 1000) | 176 | if (Data.Length < 1000) |
177 | { | 177 | { |
178 | // for now (testing ) we only support files under 1000 bytes | 178 | // for now (testing ) we only support files under 1000 bytes |
179 | byte[] transferData = new byte[Data.Length + 4]; | 179 | byte[] transferData = new byte[Data.Length + 4]; |
180 | Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); | 180 | Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); |
181 | Array.Copy(Data, 0, transferData, 4, Data.Length); | 181 | Array.Copy(Data, 0, transferData, 4, Data.Length); |
182 | Client.SendXferPacket(XferID, 0 + 0x80000000, transferData); | 182 | Client.SendXferPacket(XferID, 0 + 0x80000000, transferData); |
183 | 183 | ||
184 | complete = true; | 184 | complete = true; |
185 | } | 185 | } |
186 | else | 186 | else |
187 | { | 187 | { |
188 | byte[] transferData = new byte[1000 + 4]; | 188 | byte[] transferData = new byte[1000 + 4]; |
189 | Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); | 189 | Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); |
190 | Array.Copy(Data, 0, transferData, 4, 1000); | 190 | Array.Copy(Data, 0, transferData, 4, 1000); |
191 | Client.SendXferPacket(XferID, 0, transferData); | 191 | Client.SendXferPacket(XferID, 0, transferData); |
192 | Packet++; | 192 | Packet++; |
193 | DataPointer = 1000; | 193 | DataPointer = 1000; |
194 | } | 194 | } |
195 | 195 | ||
196 | return complete; | 196 | return complete; |
197 | } | 197 | } |
198 | 198 | ||
199 | /// <summary> | 199 | /// <summary> |
200 | /// Respond to an ack packet from the client | 200 | /// Respond to an ack packet from the client |
201 | /// </summary> | 201 | /// </summary> |
202 | /// <param name="packet"></param> | 202 | /// <param name="packet"></param> |
203 | /// <returns>True if the transfer is complete, false otherwise</returns> | 203 | /// <returns>True if the transfer is complete, false otherwise</returns> |
204 | public bool AckPacket(uint packet) | 204 | public bool AckPacket(uint packet) |
205 | { | 205 | { |
206 | if (!complete) | 206 | if (!complete) |
207 | { | 207 | { |
208 | if ((Data.Length - DataPointer) > 1000) | 208 | if ((Data.Length - DataPointer) > 1000) |
209 | { | 209 | { |
210 | byte[] transferData = new byte[1000]; | 210 | byte[] transferData = new byte[1000]; |
211 | Array.Copy(Data, DataPointer, transferData, 0, 1000); | 211 | Array.Copy(Data, DataPointer, transferData, 0, 1000); |
212 | Client.SendXferPacket(XferID, Packet, transferData); | 212 | Client.SendXferPacket(XferID, Packet, transferData); |
213 | Packet++; | 213 | Packet++; |
214 | DataPointer += 1000; | 214 | DataPointer += 1000; |
215 | } | 215 | } |
216 | else | 216 | else |
217 | { | 217 | { |
218 | byte[] transferData = new byte[Data.Length - DataPointer]; | 218 | byte[] transferData = new byte[Data.Length - DataPointer]; |
219 | Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); | 219 | Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); |
220 | uint endPacket = Packet |= (uint) 0x80000000; | 220 | uint endPacket = Packet |= (uint) 0x80000000; |
221 | Client.SendXferPacket(XferID, endPacket, transferData); | 221 | Client.SendXferPacket(XferID, endPacket, transferData); |
222 | Packet++; | 222 | Packet++; |
223 | DataPointer += (Data.Length - DataPointer); | 223 | DataPointer += (Data.Length - DataPointer); |
224 | 224 | ||
225 | complete = true; | 225 | complete = true; |
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | return complete; | 229 | return complete; |
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | #endregion | 233 | #endregion |
234 | } | 234 | } |
235 | } \ No newline at end of file | 235 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 3614686..cb94021 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -1,338 +1,338 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* | 28 | /* |
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Threading; | 31 | using System.Threading; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications.Cache; | 35 | using OpenSim.Framework.Communications.Cache; |
36 | using OpenSim.Data.MySQLMapper; | 36 | using OpenSim.Data.MySQLMapper; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | using OpenSim.Data.Base; | 39 | using OpenSim.Data.Base; |
40 | 40 | ||
41 | namespace OpenSim.Region.Environment.Modules | 41 | namespace OpenSim.Region.Environment.Modules |
42 | { | 42 | { |
43 | public class AvatarFactoryModule : IAvatarFactory | 43 | public class AvatarFactoryModule : IAvatarFactory |
44 | { | 44 | { |
45 | private Scene m_scene = null; | 45 | private Scene m_scene = null; |
46 | private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>(); | 46 | private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>(); |
47 | 47 | ||
48 | private bool m_enablePersist = false; | 48 | private bool m_enablePersist = false; |
49 | private string m_connectionString; | 49 | private string m_connectionString; |
50 | private bool m_configured = false; | 50 | private bool m_configured = false; |
51 | private BaseDatabaseConnector m_databaseMapper; | 51 | private BaseDatabaseConnector m_databaseMapper; |
52 | private AppearanceTableMapper m_appearanceMapper; | 52 | private AppearanceTableMapper m_appearanceMapper; |
53 | 53 | ||
54 | private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>(); | 54 | private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>(); |
55 | private object m_syncLock = new object(); | 55 | private object m_syncLock = new object(); |
56 | 56 | ||
57 | public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) | 57 | public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) |
58 | { | 58 | { |
59 | 59 | ||
60 | //should only let one thread at a time do this part | 60 | //should only let one thread at a time do this part |
61 | EventWaitHandle waitHandle = null; | 61 | EventWaitHandle waitHandle = null; |
62 | bool fetchInProgress = false; | 62 | bool fetchInProgress = false; |
63 | lock (m_syncLock) | 63 | lock (m_syncLock) |
64 | { | 64 | { |
65 | appearance = CheckCache(avatarId); | 65 | appearance = CheckCache(avatarId); |
66 | if (appearance != null) | 66 | if (appearance != null) |
67 | { | 67 | { |
68 | return true; | 68 | return true; |
69 | } | 69 | } |
70 | 70 | ||
71 | //not in cache so check to see if another thread is already fetching it | 71 | //not in cache so check to see if another thread is already fetching it |
72 | if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) | 72 | if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) |
73 | { | 73 | { |
74 | fetchInProgress = true; | 74 | fetchInProgress = true; |
75 | } | 75 | } |
76 | else | 76 | else |
77 | { | 77 | { |
78 | fetchInProgress = false; | 78 | fetchInProgress = false; |
79 | 79 | ||
80 | //no thread already fetching this appearance, so add a wait handle to list | 80 | //no thread already fetching this appearance, so add a wait handle to list |
81 | //for any following threads that want the same appearance | 81 | //for any following threads that want the same appearance |
82 | waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); | 82 | waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); |
83 | m_fetchesInProgress.Add(avatarId, waitHandle); | 83 | m_fetchesInProgress.Add(avatarId, waitHandle); |
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
87 | if (fetchInProgress) | 87 | if (fetchInProgress) |
88 | { | 88 | { |
89 | waitHandle.WaitOne(); | 89 | waitHandle.WaitOne(); |
90 | appearance = CheckCache(avatarId); | 90 | appearance = CheckCache(avatarId); |
91 | if (appearance != null) | 91 | if (appearance != null) |
92 | { | 92 | { |
93 | waitHandle = null; | 93 | waitHandle = null; |
94 | return true; | 94 | return true; |
95 | } | 95 | } |
96 | else | 96 | else |
97 | { | 97 | { |
98 | waitHandle = null; | 98 | waitHandle = null; |
99 | return false; | 99 | return false; |
100 | } | 100 | } |
101 | } | 101 | } |
102 | else | 102 | else |
103 | { | 103 | { |
104 | Thread.Sleep(5000); | 104 | Thread.Sleep(5000); |
105 | 105 | ||
106 | //this is the first thread to request this appearance | 106 | //this is the first thread to request this appearance |
107 | //so let it check the db and if not found then create a default appearance | 107 | //so let it check the db and if not found then create a default appearance |
108 | //and add that to the cache | 108 | //and add that to the cache |
109 | appearance = CheckDatabase(avatarId); | 109 | appearance = CheckDatabase(avatarId); |
110 | if (appearance != null) | 110 | if (appearance != null) |
111 | { | 111 | { |
112 | //appearance has now been added to cache so lets pulse any waiting threads | 112 | //appearance has now been added to cache so lets pulse any waiting threads |
113 | lock (m_syncLock) | 113 | lock (m_syncLock) |
114 | { | 114 | { |
115 | m_fetchesInProgress.Remove(avatarId); | 115 | m_fetchesInProgress.Remove(avatarId); |
116 | waitHandle.Set(); | 116 | waitHandle.Set(); |
117 | } | 117 | } |
118 | // waitHandle.Close(); | 118 | // waitHandle.Close(); |
119 | waitHandle = null; | 119 | waitHandle = null; |
120 | return true; | 120 | return true; |
121 | } | 121 | } |
122 | 122 | ||
123 | //not found a appearance for the user, so create a new default one | 123 | //not found a appearance for the user, so create a new default one |
124 | appearance = CreateDefault(avatarId); | 124 | appearance = CreateDefault(avatarId); |
125 | if (appearance != null) | 125 | if (appearance != null) |
126 | { | 126 | { |
127 | //update database | 127 | //update database |
128 | if (m_enablePersist) | 128 | if (m_enablePersist) |
129 | { | 129 | { |
130 | m_appearanceMapper.Add(avatarId.UUID, appearance); | 130 | m_appearanceMapper.Add(avatarId.UUID, appearance); |
131 | } | 131 | } |
132 | 132 | ||
133 | //add appearance to dictionary cache | 133 | //add appearance to dictionary cache |
134 | lock (m_avatarsAppearance) | 134 | lock (m_avatarsAppearance) |
135 | { | 135 | { |
136 | m_avatarsAppearance[avatarId] = appearance; | 136 | m_avatarsAppearance[avatarId] = appearance; |
137 | } | 137 | } |
138 | 138 | ||
139 | //appearance has now been added to cache so lets pulse any waiting threads | 139 | //appearance has now been added to cache so lets pulse any waiting threads |
140 | lock (m_syncLock) | 140 | lock (m_syncLock) |
141 | { | 141 | { |
142 | m_fetchesInProgress.Remove(avatarId); | 142 | m_fetchesInProgress.Remove(avatarId); |
143 | waitHandle.Set(); | 143 | waitHandle.Set(); |
144 | } | 144 | } |
145 | // waitHandle.Close(); | 145 | // waitHandle.Close(); |
146 | waitHandle = null; | 146 | waitHandle = null; |
147 | return true; | 147 | return true; |
148 | } | 148 | } |
149 | else | 149 | else |
150 | { | 150 | { |
151 | //something went wrong, so release the wait handle and remove it | 151 | //something went wrong, so release the wait handle and remove it |
152 | //all waiting threads will fail to find cached appearance | 152 | //all waiting threads will fail to find cached appearance |
153 | //but its better for them to fail than wait for ever | 153 | //but its better for them to fail than wait for ever |
154 | lock (m_syncLock) | 154 | lock (m_syncLock) |
155 | { | 155 | { |
156 | m_fetchesInProgress.Remove(avatarId); | 156 | m_fetchesInProgress.Remove(avatarId); |
157 | waitHandle.Set(); | 157 | waitHandle.Set(); |
158 | } | 158 | } |
159 | //waitHandle.Close(); | 159 | //waitHandle.Close(); |
160 | waitHandle = null; | 160 | waitHandle = null; |
161 | return false; | 161 | return false; |
162 | } | 162 | } |
163 | } | 163 | } |
164 | } | 164 | } |
165 | 165 | ||
166 | private AvatarAppearance CreateDefault(LLUUID avatarId) | 166 | private AvatarAppearance CreateDefault(LLUUID avatarId) |
167 | { | 167 | { |
168 | AvatarAppearance appearance = null; | 168 | AvatarAppearance appearance = null; |
169 | AvatarWearable[] wearables; | 169 | AvatarWearable[] wearables; |
170 | byte[] visualParams; | 170 | byte[] visualParams; |
171 | GetDefaultAvatarAppearance(out wearables, out visualParams); | 171 | GetDefaultAvatarAppearance(out wearables, out visualParams); |
172 | appearance = new AvatarAppearance(avatarId, wearables, visualParams); | 172 | appearance = new AvatarAppearance(avatarId, wearables, visualParams); |
173 | 173 | ||
174 | return appearance; | 174 | return appearance; |
175 | } | 175 | } |
176 | 176 | ||
177 | private AvatarAppearance CheckDatabase(LLUUID avatarId) | 177 | private AvatarAppearance CheckDatabase(LLUUID avatarId) |
178 | { | 178 | { |
179 | AvatarAppearance appearance = null; | 179 | AvatarAppearance appearance = null; |
180 | if (m_enablePersist) | 180 | if (m_enablePersist) |
181 | { | 181 | { |
182 | if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance)) | 182 | if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance)) |
183 | { | 183 | { |
184 | appearance.VisualParams = GetDefaultVisualParams(); | 184 | appearance.VisualParams = GetDefaultVisualParams(); |
185 | appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry(); | 185 | appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry(); |
186 | lock (m_avatarsAppearance) | 186 | lock (m_avatarsAppearance) |
187 | { | 187 | { |
188 | m_avatarsAppearance[avatarId] = appearance; | 188 | m_avatarsAppearance[avatarId] = appearance; |
189 | } | 189 | } |
190 | } | 190 | } |
191 | } | 191 | } |
192 | return appearance; | 192 | return appearance; |
193 | } | 193 | } |
194 | 194 | ||
195 | private AvatarAppearance CheckCache(LLUUID avatarId) | 195 | private AvatarAppearance CheckCache(LLUUID avatarId) |
196 | { | 196 | { |
197 | AvatarAppearance appearance = null; | 197 | AvatarAppearance appearance = null; |
198 | lock (m_avatarsAppearance) | 198 | lock (m_avatarsAppearance) |
199 | { | 199 | { |
200 | if (m_avatarsAppearance.ContainsKey(avatarId)) | 200 | if (m_avatarsAppearance.ContainsKey(avatarId)) |
201 | { | 201 | { |
202 | appearance = m_avatarsAppearance[avatarId]; | 202 | appearance = m_avatarsAppearance[avatarId]; |
203 | } | 203 | } |
204 | } | 204 | } |
205 | return appearance; | 205 | return appearance; |
206 | } | 206 | } |
207 | 207 | ||
208 | public void Initialise(Scene scene, IConfigSource source) | 208 | public void Initialise(Scene scene, IConfigSource source) |
209 | { | 209 | { |
210 | scene.RegisterModuleInterface<IAvatarFactory>(this); | 210 | scene.RegisterModuleInterface<IAvatarFactory>(this); |
211 | scene.EventManager.OnNewClient += NewClient; | 211 | scene.EventManager.OnNewClient += NewClient; |
212 | 212 | ||
213 | if (m_scene == null) | 213 | if (m_scene == null) |
214 | { | 214 | { |
215 | m_scene = scene; | 215 | m_scene = scene; |
216 | } | 216 | } |
217 | 217 | ||
218 | if (!m_configured) | 218 | if (!m_configured) |
219 | { | 219 | { |
220 | m_configured = true; | 220 | m_configured = true; |
221 | try | 221 | try |
222 | { | 222 | { |
223 | m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false); | 223 | m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false); |
224 | m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", ""); | 224 | m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", ""); |
225 | } | 225 | } |
226 | catch (Exception) | 226 | catch (Exception) |
227 | { | 227 | { |
228 | } | 228 | } |
229 | if (m_enablePersist) | 229 | if (m_enablePersist) |
230 | { | 230 | { |
231 | m_databaseMapper = new MySQLDatabaseMapper(m_connectionString); | 231 | m_databaseMapper = new MySQLDatabaseMapper(m_connectionString); |
232 | m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance"); | 232 | m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance"); |
233 | } | 233 | } |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | public void PostInitialise() | 237 | public void PostInitialise() |
238 | { | 238 | { |
239 | } | 239 | } |
240 | 240 | ||
241 | public void Close() | 241 | public void Close() |
242 | { | 242 | { |
243 | } | 243 | } |
244 | 244 | ||
245 | public string Name | 245 | public string Name |
246 | { | 246 | { |
247 | get { return "Default Avatar Factory"; } | 247 | get { return "Default Avatar Factory"; } |
248 | } | 248 | } |
249 | 249 | ||
250 | public bool IsSharedModule | 250 | public bool IsSharedModule |
251 | { | 251 | { |
252 | get { return true; } | 252 | get { return true; } |
253 | } | 253 | } |
254 | 254 | ||
255 | public void NewClient(IClientAPI client) | 255 | public void NewClient(IClientAPI client) |
256 | { | 256 | { |
257 | client.OnAvatarNowWearing += AvatarIsWearing; | 257 | client.OnAvatarNowWearing += AvatarIsWearing; |
258 | } | 258 | } |
259 | 259 | ||
260 | public void RemoveClient(IClientAPI client) | 260 | public void RemoveClient(IClientAPI client) |
261 | { | 261 | { |
262 | // client.OnAvatarNowWearing -= AvatarIsWearing; | 262 | // client.OnAvatarNowWearing -= AvatarIsWearing; |
263 | } | 263 | } |
264 | 264 | ||
265 | public void AvatarIsWearing(Object sender, AvatarWearingArgs e) | 265 | public void AvatarIsWearing(Object sender, AvatarWearingArgs e) |
266 | { | 266 | { |
267 | IClientAPI clientView = (IClientAPI)sender; | 267 | IClientAPI clientView = (IClientAPI)sender; |
268 | CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId); | 268 | CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId); |
269 | if (profile != null) | 269 | if (profile != null) |
270 | { | 270 | { |
271 | if (profile.RootFolder != null) | 271 | if (profile.RootFolder != null) |
272 | { | 272 | { |
273 | if (m_avatarsAppearance.ContainsKey(clientView.AgentId)) | 273 | if (m_avatarsAppearance.ContainsKey(clientView.AgentId)) |
274 | { | 274 | { |
275 | AvatarAppearance avatAppearance = null; | 275 | AvatarAppearance avatAppearance = null; |
276 | lock (m_avatarsAppearance) | 276 | lock (m_avatarsAppearance) |
277 | { | 277 | { |
278 | avatAppearance = m_avatarsAppearance[clientView.AgentId]; | 278 | avatAppearance = m_avatarsAppearance[clientView.AgentId]; |
279 | } | 279 | } |
280 | 280 | ||
281 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 281 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
282 | { | 282 | { |
283 | if (wear.Type < 13) | 283 | if (wear.Type < 13) |
284 | { | 284 | { |
285 | if (wear.ItemID == LLUUID.Zero) | 285 | if (wear.ItemID == LLUUID.Zero) |
286 | { | 286 | { |
287 | avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero; | 287 | avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero; |
288 | avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero; | 288 | avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero; |
289 | 289 | ||
290 | UpdateDatabase(clientView.AgentId, avatAppearance); | 290 | UpdateDatabase(clientView.AgentId, avatAppearance); |
291 | } | 291 | } |
292 | else | 292 | else |
293 | { | 293 | { |
294 | LLUUID assetId; | 294 | LLUUID assetId; |
295 | 295 | ||
296 | InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID); | 296 | InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID); |
297 | if (baseItem != null) | 297 | if (baseItem != null) |
298 | { | 298 | { |
299 | assetId = baseItem.assetID; | 299 | assetId = baseItem.assetID; |
300 | avatAppearance.Wearables[wear.Type].AssetID = assetId; | 300 | avatAppearance.Wearables[wear.Type].AssetID = assetId; |
301 | avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; | 301 | avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; |
302 | 302 | ||
303 | UpdateDatabase(clientView.AgentId, avatAppearance); | 303 | UpdateDatabase(clientView.AgentId, avatAppearance); |
304 | } | 304 | } |
305 | } | 305 | } |
306 | } | 306 | } |
307 | } | 307 | } |
308 | } | 308 | } |
309 | } | 309 | } |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance) | 313 | public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance) |
314 | { | 314 | { |
315 | if (m_enablePersist) | 315 | if (m_enablePersist) |
316 | { | 316 | { |
317 | m_appearanceMapper.Update(userID.UUID, avatAppearance); | 317 | m_appearanceMapper.Update(userID.UUID, avatAppearance); |
318 | } | 318 | } |
319 | } | 319 | } |
320 | 320 | ||
321 | public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) | 321 | public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) |
322 | { | 322 | { |
323 | visualParams = GetDefaultVisualParams(); | 323 | visualParams = GetDefaultVisualParams(); |
324 | wearables = AvatarWearable.DefaultWearables; | 324 | wearables = AvatarWearable.DefaultWearables; |
325 | } | 325 | } |
326 | 326 | ||
327 | private static byte[] GetDefaultVisualParams() | 327 | private static byte[] GetDefaultVisualParams() |
328 | { | 328 | { |
329 | byte[] visualParams; | 329 | byte[] visualParams; |
330 | visualParams = new byte[218]; | 330 | visualParams = new byte[218]; |
331 | for (int i = 0; i < 218; i++) | 331 | for (int i = 0; i < 218; i++) |
332 | { | 332 | { |
333 | visualParams[i] = 100; | 333 | visualParams[i] = 100; |
334 | } | 334 | } |
335 | return visualParams; | 335 | return visualParams; |
336 | } | 336 | } |
337 | } | 337 | } |
338 | }*/ | 338 | }*/ |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs index 966f5f3..15720fc 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs | |||
@@ -1,868 +1,868 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net.Sockets; | 31 | using System.Net.Sockets; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Text.RegularExpressions; | 33 | using System.Text.RegularExpressions; |
34 | using System.Threading; | 34 | using System.Threading; |
35 | using libsecondlife; | 35 | using libsecondlife; |
36 | using log4net; | 36 | using log4net; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Region.Environment.Interfaces; | 39 | using OpenSim.Region.Environment.Interfaces; |
40 | using OpenSim.Region.Environment.Scenes; | 40 | using OpenSim.Region.Environment.Scenes; |
41 | 41 | ||
42 | namespace OpenSim.Region.Environment.Modules.Avatar.Chat | 42 | namespace OpenSim.Region.Environment.Modules.Avatar.Chat |
43 | { | 43 | { |
44 | public class ChatModule : IRegionModule, ISimChat | 44 | public class ChatModule : IRegionModule, ISimChat |
45 | { | 45 | { |
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | private string m_defaultzone = null; | 47 | private string m_defaultzone = null; |
48 | 48 | ||
49 | private IRCChatModule m_irc = null; | 49 | private IRCChatModule m_irc = null; |
50 | private Thread m_irc_connector = null; | 50 | private Thread m_irc_connector = null; |
51 | 51 | ||
52 | private string m_last_leaving_user = null; | 52 | private string m_last_leaving_user = null; |
53 | private string m_last_new_user = null; | 53 | private string m_last_new_user = null; |
54 | private int m_saydistance = 30; | 54 | private int m_saydistance = 30; |
55 | private List<Scene> m_scenes = new List<Scene>(); | 55 | private List<Scene> m_scenes = new List<Scene>(); |
56 | private int m_shoutdistance = 100; | 56 | private int m_shoutdistance = 100; |
57 | internal object m_syncInit = new object(); | 57 | internal object m_syncInit = new object(); |
58 | internal object m_syncLogout = new object(); | 58 | internal object m_syncLogout = new object(); |
59 | private int m_whisperdistance = 10; | 59 | private int m_whisperdistance = 10; |
60 | 60 | ||
61 | #region IRegionModule Members | 61 | #region IRegionModule Members |
62 | 62 | ||
63 | public void Initialise(Scene scene, IConfigSource config) | 63 | public void Initialise(Scene scene, IConfigSource config) |
64 | { | 64 | { |
65 | lock (m_syncInit) | 65 | lock (m_syncInit) |
66 | { | 66 | { |
67 | if (!m_scenes.Contains(scene)) | 67 | if (!m_scenes.Contains(scene)) |
68 | { | 68 | { |
69 | m_scenes.Add(scene); | 69 | m_scenes.Add(scene); |
70 | scene.EventManager.OnNewClient += NewClient; | 70 | scene.EventManager.OnNewClient += NewClient; |
71 | scene.RegisterModuleInterface<ISimChat>(this); | 71 | scene.RegisterModuleInterface<ISimChat>(this); |
72 | } | 72 | } |
73 | 73 | ||
74 | // wrap this in a try block so that defaults will work if | 74 | // wrap this in a try block so that defaults will work if |
75 | // the config file doesn't specify otherwise. | 75 | // the config file doesn't specify otherwise. |
76 | try | 76 | try |
77 | { | 77 | { |
78 | m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); | 78 | m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); |
79 | m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); | 79 | m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); |
80 | m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); | 80 | m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); |
81 | } | 81 | } |
82 | catch (Exception) | 82 | catch (Exception) |
83 | { | 83 | { |
84 | } | 84 | } |
85 | 85 | ||
86 | try | 86 | try |
87 | { | 87 | { |
88 | m_defaultzone = config.Configs["IRC"].GetString("nick", "Sim"); | 88 | m_defaultzone = config.Configs["IRC"].GetString("nick", "Sim"); |
89 | } | 89 | } |
90 | catch (Exception) | 90 | catch (Exception) |
91 | { | 91 | { |
92 | } | 92 | } |
93 | 93 | ||
94 | // setup IRC Relay | 94 | // setup IRC Relay |
95 | if (m_irc == null) | 95 | if (m_irc == null) |
96 | { | 96 | { |
97 | m_irc = new IRCChatModule(config); | 97 | m_irc = new IRCChatModule(config); |
98 | } | 98 | } |
99 | if (m_irc_connector == null) | 99 | if (m_irc_connector == null) |
100 | { | 100 | { |
101 | m_irc_connector = new Thread(IRCConnectRun); | 101 | m_irc_connector = new Thread(IRCConnectRun); |
102 | m_irc_connector.Name = "IRCConnectorThread"; | 102 | m_irc_connector.Name = "IRCConnectorThread"; |
103 | m_irc_connector.IsBackground = true; | 103 | m_irc_connector.IsBackground = true; |
104 | } | 104 | } |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | public void PostInitialise() | 108 | public void PostInitialise() |
109 | { | 109 | { |
110 | if (m_irc.Enabled) | 110 | if (m_irc.Enabled) |
111 | { | 111 | { |
112 | try | 112 | try |
113 | { | 113 | { |
114 | //m_irc.Connect(m_scenes); | 114 | //m_irc.Connect(m_scenes); |
115 | if (m_irc_connector == null) | 115 | if (m_irc_connector == null) |
116 | { | 116 | { |
117 | m_irc_connector = new Thread(IRCConnectRun); | 117 | m_irc_connector = new Thread(IRCConnectRun); |
118 | m_irc_connector.Name = "IRCConnectorThread"; | 118 | m_irc_connector.Name = "IRCConnectorThread"; |
119 | m_irc_connector.IsBackground = true; | 119 | m_irc_connector.IsBackground = true; |
120 | } | 120 | } |
121 | if (!m_irc_connector.IsAlive) | 121 | if (!m_irc_connector.IsAlive) |
122 | { | 122 | { |
123 | m_irc_connector.Start(); | 123 | m_irc_connector.Start(); |
124 | ThreadTracker.Add(m_irc_connector); | 124 | ThreadTracker.Add(m_irc_connector); |
125 | } | 125 | } |
126 | } | 126 | } |
127 | catch (Exception) | 127 | catch (Exception) |
128 | { | 128 | { |
129 | } | 129 | } |
130 | } | 130 | } |
131 | } | 131 | } |
132 | 132 | ||
133 | public void Close() | 133 | public void Close() |
134 | { | 134 | { |
135 | m_irc.Close(); | 135 | m_irc.Close(); |
136 | } | 136 | } |
137 | 137 | ||
138 | public string Name | 138 | public string Name |
139 | { | 139 | { |
140 | get { return "ChatModule"; } | 140 | get { return "ChatModule"; } |
141 | } | 141 | } |
142 | 142 | ||
143 | public bool IsSharedModule | 143 | public bool IsSharedModule |
144 | { | 144 | { |
145 | get { return true; } | 145 | get { return true; } |
146 | } | 146 | } |
147 | 147 | ||
148 | #endregion | 148 | #endregion |
149 | 149 | ||
150 | #region ISimChat Members | 150 | #region ISimChat Members |
151 | 151 | ||
152 | public void SimChat(Object sender, ChatFromViewerArgs e) | 152 | public void SimChat(Object sender, ChatFromViewerArgs e) |
153 | { | 153 | { |
154 | // FROM: Sim TO: IRC | 154 | // FROM: Sim TO: IRC |
155 | 155 | ||
156 | ScenePresence avatar = null; | 156 | ScenePresence avatar = null; |
157 | 157 | ||
158 | //TODO: Move ForEachScenePresence and others into IScene. | 158 | //TODO: Move ForEachScenePresence and others into IScene. |
159 | Scene scene = (Scene) e.Scene; | 159 | Scene scene = (Scene) e.Scene; |
160 | 160 | ||
161 | //TODO: Remove the need for this check | 161 | //TODO: Remove the need for this check |
162 | if (scene == null) | 162 | if (scene == null) |
163 | scene = m_scenes[0]; | 163 | scene = m_scenes[0]; |
164 | 164 | ||
165 | // Filled in since it's easier than rewriting right now. | 165 | // Filled in since it's easier than rewriting right now. |
166 | LLVector3 fromPos = e.Position; | 166 | LLVector3 fromPos = e.Position; |
167 | LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 167 | LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
168 | 168 | ||
169 | string fromName = e.From; | 169 | string fromName = e.From; |
170 | string message = e.Message; | 170 | string message = e.Message; |
171 | LLUUID fromAgentID = LLUUID.Zero; | 171 | LLUUID fromAgentID = LLUUID.Zero; |
172 | 172 | ||
173 | if (e.Sender != null) | 173 | if (e.Sender != null) |
174 | { | 174 | { |
175 | avatar = scene.GetScenePresence(e.Sender.AgentId); | 175 | avatar = scene.GetScenePresence(e.Sender.AgentId); |
176 | } | 176 | } |
177 | 177 | ||
178 | if (avatar != null) | 178 | if (avatar != null) |
179 | { | 179 | { |
180 | fromPos = avatar.AbsolutePosition; | 180 | fromPos = avatar.AbsolutePosition; |
181 | regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 181 | regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
182 | fromName = avatar.Firstname + " " + avatar.Lastname; | 182 | fromName = avatar.Firstname + " " + avatar.Lastname; |
183 | fromAgentID = e.Sender.AgentId; | 183 | fromAgentID = e.Sender.AgentId; |
184 | } | 184 | } |
185 | 185 | ||
186 | // Try to reconnect to server if not connected | 186 | // Try to reconnect to server if not connected |
187 | if (m_irc.Enabled && !m_irc.Connected) | 187 | if (m_irc.Enabled && !m_irc.Connected) |
188 | { | 188 | { |
189 | // In a non-blocking way. Eventually the connector will get it started | 189 | // In a non-blocking way. Eventually the connector will get it started |
190 | try | 190 | try |
191 | { | 191 | { |
192 | if (m_irc_connector == null) | 192 | if (m_irc_connector == null) |
193 | { | 193 | { |
194 | m_irc_connector = new Thread(IRCConnectRun); | 194 | m_irc_connector = new Thread(IRCConnectRun); |
195 | m_irc_connector.Name = "IRCConnectorThread"; | 195 | m_irc_connector.Name = "IRCConnectorThread"; |
196 | m_irc_connector.IsBackground = true; | 196 | m_irc_connector.IsBackground = true; |
197 | } | 197 | } |
198 | if (!m_irc_connector.IsAlive) | 198 | if (!m_irc_connector.IsAlive) |
199 | { | 199 | { |
200 | m_irc_connector.Start(); | 200 | m_irc_connector.Start(); |
201 | ThreadTracker.Add(m_irc_connector); | 201 | ThreadTracker.Add(m_irc_connector); |
202 | } | 202 | } |
203 | } | 203 | } |
204 | catch (Exception) | 204 | catch (Exception) |
205 | { | 205 | { |
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | 209 | ||
210 | // We only want to relay stuff on channel 0 | 210 | // We only want to relay stuff on channel 0 |
211 | if (e.Channel == 0) | 211 | if (e.Channel == 0) |
212 | { | 212 | { |
213 | // IRC stuff | 213 | // IRC stuff |
214 | if (e.Message.Length > 0) | 214 | if (e.Message.Length > 0) |
215 | { | 215 | { |
216 | if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC | 216 | if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC |
217 | { | 217 | { |
218 | m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); | 218 | m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); |
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | foreach (Scene s in m_scenes) | 222 | foreach (Scene s in m_scenes) |
223 | { | 223 | { |
224 | s.ForEachScenePresence(delegate(ScenePresence presence) | 224 | s.ForEachScenePresence(delegate(ScenePresence presence) |
225 | { | 225 | { |
226 | TrySendChatMessage(presence, fromPos, regionPos, | 226 | TrySendChatMessage(presence, fromPos, regionPos, |
227 | fromAgentID, fromName, e.Type, message); | 227 | fromAgentID, fromName, e.Type, message); |
228 | }); | 228 | }); |
229 | } | 229 | } |
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | #endregion | 233 | #endregion |
234 | 234 | ||
235 | public void NewClient(IClientAPI client) | 235 | public void NewClient(IClientAPI client) |
236 | { | 236 | { |
237 | try | 237 | try |
238 | { | 238 | { |
239 | client.OnChatFromViewer += SimChat; | 239 | client.OnChatFromViewer += SimChat; |
240 | 240 | ||
241 | if ((m_irc.Enabled) && (m_irc.Connected)) | 241 | if ((m_irc.Enabled) && (m_irc.Connected)) |
242 | { | 242 | { |
243 | string clientName = client.FirstName + " " + client.LastName; | 243 | string clientName = client.FirstName + " " + client.LastName; |
244 | // handles simple case. May not work for hundred connecting in per second. | 244 | // handles simple case. May not work for hundred connecting in per second. |
245 | // and the NewClients calles getting interleved | 245 | // and the NewClients calles getting interleved |
246 | // but filters out multiple reports | 246 | // but filters out multiple reports |
247 | if (clientName != m_last_new_user) | 247 | if (clientName != m_last_new_user) |
248 | { | 248 | { |
249 | m_last_new_user = clientName; | 249 | m_last_new_user = clientName; |
250 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); | 250 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); |
251 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in " + clientRegion); | 251 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in " + clientRegion); |
252 | } | 252 | } |
253 | } | 253 | } |
254 | client.OnLogout += ClientLoggedOut; | 254 | client.OnLogout += ClientLoggedOut; |
255 | client.OnConnectionClosed += ClientLoggedOut; | 255 | client.OnConnectionClosed += ClientLoggedOut; |
256 | client.OnLogout += ClientLoggedOut; | 256 | client.OnLogout += ClientLoggedOut; |
257 | } | 257 | } |
258 | catch (Exception ex) | 258 | catch (Exception ex) |
259 | { | 259 | { |
260 | m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); | 260 | m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); |
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | public void ClientLoggedOut(IClientAPI client) | 264 | public void ClientLoggedOut(IClientAPI client) |
265 | { | 265 | { |
266 | lock (m_syncLogout) | 266 | lock (m_syncLogout) |
267 | { | 267 | { |
268 | try | 268 | try |
269 | { | 269 | { |
270 | if ((m_irc.Enabled) && (m_irc.Connected)) | 270 | if ((m_irc.Enabled) && (m_irc.Connected)) |
271 | { | 271 | { |
272 | string clientName = client.FirstName + " " + client.LastName; | 272 | string clientName = client.FirstName + " " + client.LastName; |
273 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); | 273 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); |
274 | // handles simple case. May not work for hundred connecting in per second. | 274 | // handles simple case. May not work for hundred connecting in per second. |
275 | // and the NewClients calles getting interleved | 275 | // and the NewClients calles getting interleved |
276 | // but filters out multiple reports | 276 | // but filters out multiple reports |
277 | if (clientName != m_last_leaving_user) | 277 | if (clientName != m_last_leaving_user) |
278 | { | 278 | { |
279 | m_last_leaving_user = clientName; | 279 | m_last_leaving_user = clientName; |
280 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); | 280 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); |
281 | m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); | 281 | m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); |
282 | } | 282 | } |
283 | } | 283 | } |
284 | } | 284 | } |
285 | catch (Exception ex) | 285 | catch (Exception ex) |
286 | { | 286 | { |
287 | m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); | 287 | m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); |
288 | } | 288 | } |
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, | 292 | private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, |
293 | LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) | 293 | LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) |
294 | { | 294 | { |
295 | if (!presence.IsChildAgent) | 295 | if (!presence.IsChildAgent) |
296 | { | 296 | { |
297 | LLVector3 fromRegionPos = fromPos + regionPos; | 297 | LLVector3 fromRegionPos = fromPos + regionPos; |
298 | LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; | 298 | LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; |
299 | int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); | 299 | int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); |
300 | 300 | ||
301 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | 301 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || |
302 | type == ChatTypeEnum.Say && dis > m_saydistance || | 302 | type == ChatTypeEnum.Say && dis > m_saydistance || |
303 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | 303 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) |
304 | { | 304 | { |
305 | return; | 305 | return; |
306 | } | 306 | } |
307 | 307 | ||
308 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 308 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
309 | presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); | 309 | presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | // if IRC is enabled then just keep trying using a monitor thread | 313 | // if IRC is enabled then just keep trying using a monitor thread |
314 | public void IRCConnectRun() | 314 | public void IRCConnectRun() |
315 | { | 315 | { |
316 | while (true) | 316 | while (true) |
317 | { | 317 | { |
318 | if ((m_irc.Enabled) && (!m_irc.Connected)) | 318 | if ((m_irc.Enabled) && (!m_irc.Connected)) |
319 | { | 319 | { |
320 | m_irc.Connect(m_scenes); | 320 | m_irc.Connect(m_scenes); |
321 | } | 321 | } |
322 | Thread.Sleep(15000); | 322 | Thread.Sleep(15000); |
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | public string FindClientRegion(string client_FirstName, string client_LastName) | 326 | public string FindClientRegion(string client_FirstName, string client_LastName) |
327 | { | 327 | { |
328 | string sourceRegion = null; | 328 | string sourceRegion = null; |
329 | foreach (Scene s in m_scenes) | 329 | foreach (Scene s in m_scenes) |
330 | { | 330 | { |
331 | s.ForEachScenePresence(delegate(ScenePresence presence) | 331 | s.ForEachScenePresence(delegate(ScenePresence presence) |
332 | { | 332 | { |
333 | if ((presence.IsChildAgent == false) | 333 | if ((presence.IsChildAgent == false) |
334 | && (presence.Firstname == client_FirstName) | 334 | && (presence.Firstname == client_FirstName) |
335 | && (presence.Lastname == client_LastName)) | 335 | && (presence.Lastname == client_LastName)) |
336 | { | 336 | { |
337 | sourceRegion = presence.Scene.RegionInfo.RegionName; | 337 | sourceRegion = presence.Scene.RegionInfo.RegionName; |
338 | //sourceRegion= s.RegionInfo.RegionName; | 338 | //sourceRegion= s.RegionInfo.RegionName; |
339 | } | 339 | } |
340 | }); | 340 | }); |
341 | if (sourceRegion != null) return sourceRegion; | 341 | if (sourceRegion != null) return sourceRegion; |
342 | } | 342 | } |
343 | if (m_defaultzone == null) | 343 | if (m_defaultzone == null) |
344 | { | 344 | { |
345 | m_defaultzone = "Sim"; | 345 | m_defaultzone = "Sim"; |
346 | } | 346 | } |
347 | return m_defaultzone; | 347 | return m_defaultzone; |
348 | } | 348 | } |
349 | } | 349 | } |
350 | 350 | ||
351 | internal class IRCChatModule | 351 | internal class IRCChatModule |
352 | { | 352 | { |
353 | #region ErrorReplies enum | 353 | #region ErrorReplies enum |
354 | 354 | ||
355 | public enum ErrorReplies | 355 | public enum ErrorReplies |
356 | { | 356 | { |
357 | NotRegistered = 451, // ":You have not registered" | 357 | NotRegistered = 451, // ":You have not registered" |
358 | NicknameInUse = 433 // "<nick> :Nickname is already in use" | 358 | NicknameInUse = 433 // "<nick> :Nickname is already in use" |
359 | } | 359 | } |
360 | 360 | ||
361 | #endregion | 361 | #endregion |
362 | 362 | ||
363 | #region Replies enum | 363 | #region Replies enum |
364 | 364 | ||
365 | public enum Replies | 365 | public enum Replies |
366 | { | 366 | { |
367 | MotdStart = 375, // ":- <server> Message of the day - " | 367 | MotdStart = 375, // ":- <server> Message of the day - " |
368 | Motd = 372, // ":- <text>" | 368 | Motd = 372, // ":- <text>" |
369 | EndOfMotd = 376 // ":End of /MOTD command" | 369 | EndOfMotd = 376 // ":End of /MOTD command" |
370 | } | 370 | } |
371 | 371 | ||
372 | #endregion | 372 | #endregion |
373 | 373 | ||
374 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 374 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
375 | private Thread listener; | 375 | private Thread listener; |
376 | 376 | ||
377 | private string m_basenick = null; | 377 | private string m_basenick = null; |
378 | private string m_channel = null; | 378 | private string m_channel = null; |
379 | private bool m_connected = false; | 379 | private bool m_connected = false; |
380 | private bool m_enabled = false; | 380 | private bool m_enabled = false; |
381 | private List<Scene> m_last_scenes = null; | 381 | private List<Scene> m_last_scenes = null; |
382 | private string m_nick = null; | 382 | private string m_nick = null; |
383 | private uint m_port = 6668; | 383 | private uint m_port = 6668; |
384 | private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; | 384 | private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; |
385 | private StreamReader m_reader; | 385 | private StreamReader m_reader; |
386 | private List<Scene> m_scenes = null; | 386 | private List<Scene> m_scenes = null; |
387 | private string m_server = null; | 387 | private string m_server = null; |
388 | 388 | ||
389 | private NetworkStream m_stream; | 389 | private NetworkStream m_stream; |
390 | internal object m_syncConnect = new object(); | 390 | internal object m_syncConnect = new object(); |
391 | private TcpClient m_tcp; | 391 | private TcpClient m_tcp; |
392 | private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; | 392 | private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; |
393 | private StreamWriter m_writer; | 393 | private StreamWriter m_writer; |
394 | 394 | ||
395 | private Thread pingSender; | 395 | private Thread pingSender; |
396 | 396 | ||
397 | public IRCChatModule(IConfigSource config) | 397 | public IRCChatModule(IConfigSource config) |
398 | { | 398 | { |
399 | m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); | 399 | m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); |
400 | m_tcp = null; | 400 | m_tcp = null; |
401 | m_writer = null; | 401 | m_writer = null; |
402 | m_reader = null; | 402 | m_reader = null; |
403 | 403 | ||
404 | // configuration in OpenSim.ini | 404 | // configuration in OpenSim.ini |
405 | // [IRC] | 405 | // [IRC] |
406 | // server = chat.freenode.net | 406 | // server = chat.freenode.net |
407 | // nick = OSimBot_mysim | 407 | // nick = OSimBot_mysim |
408 | // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot | 408 | // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot |
409 | // ; username is the IRC command line sent | 409 | // ; username is the IRC command line sent |
410 | // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> | 410 | // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> |
411 | // channel = #opensim-regions | 411 | // channel = #opensim-regions |
412 | // port = 6667 | 412 | // port = 6667 |
413 | // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message | 413 | // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message |
414 | // ;for <bot>:<user in region> :<message> | 414 | // ;for <bot>:<user in region> :<message> |
415 | // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" | 415 | // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" |
416 | // ;for <bot>:<message> - <user of region> : | 416 | // ;for <bot>:<message> - <user of region> : |
417 | // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" | 417 | // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" |
418 | // ;for <bot>:<message> - from <user> : | 418 | // ;for <bot>:<message> - from <user> : |
419 | // ;msgformat = "PRIVMSG {0} : {3} - from {1}" | 419 | // ;msgformat = "PRIVMSG {0} : {3} - from {1}" |
420 | // Traps I/O disconnects so it does not crash the sim | 420 | // Traps I/O disconnects so it does not crash the sim |
421 | // Trys to reconnect if disconnected and someone says something | 421 | // Trys to reconnect if disconnected and someone says something |
422 | // Tells IRC server "QUIT" when doing a close (just to be nice) | 422 | // Tells IRC server "QUIT" when doing a close (just to be nice) |
423 | // Default port back to 6667 | 423 | // Default port back to 6667 |
424 | 424 | ||
425 | try | 425 | try |
426 | { | 426 | { |
427 | m_server = config.Configs["IRC"].GetString("server"); | 427 | m_server = config.Configs["IRC"].GetString("server"); |
428 | m_nick = config.Configs["IRC"].GetString("nick"); | 428 | m_nick = config.Configs["IRC"].GetString("nick"); |
429 | m_basenick = m_nick; | 429 | m_basenick = m_nick; |
430 | m_channel = config.Configs["IRC"].GetString("channel"); | 430 | m_channel = config.Configs["IRC"].GetString("channel"); |
431 | m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); | 431 | m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); |
432 | m_user = config.Configs["IRC"].GetString("username", m_user); | 432 | m_user = config.Configs["IRC"].GetString("username", m_user); |
433 | m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); | 433 | m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); |
434 | if (m_server != null && m_nick != null && m_channel != null) | 434 | if (m_server != null && m_nick != null && m_channel != null) |
435 | { | 435 | { |
436 | m_nick = m_nick + Util.RandomClass.Next(1, 99); | 436 | m_nick = m_nick + Util.RandomClass.Next(1, 99); |
437 | m_enabled = true; | 437 | m_enabled = true; |
438 | } | 438 | } |
439 | } | 439 | } |
440 | catch (Exception) | 440 | catch (Exception) |
441 | { | 441 | { |
442 | m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); | 442 | m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); |
443 | } | 443 | } |
444 | } | 444 | } |
445 | 445 | ||
446 | public bool Enabled | 446 | public bool Enabled |
447 | { | 447 | { |
448 | get { return m_enabled; } | 448 | get { return m_enabled; } |
449 | } | 449 | } |
450 | 450 | ||
451 | public bool Connected | 451 | public bool Connected |
452 | { | 452 | { |
453 | get { return m_connected; } | 453 | get { return m_connected; } |
454 | } | 454 | } |
455 | 455 | ||
456 | public string Nick | 456 | public string Nick |
457 | { | 457 | { |
458 | get { return m_nick; } | 458 | get { return m_nick; } |
459 | } | 459 | } |
460 | 460 | ||
461 | public bool Connect(List<Scene> scenes) | 461 | public bool Connect(List<Scene> scenes) |
462 | { | 462 | { |
463 | lock (m_syncConnect) | 463 | lock (m_syncConnect) |
464 | { | 464 | { |
465 | try | 465 | try |
466 | { | 466 | { |
467 | if (m_connected) return true; | 467 | if (m_connected) return true; |
468 | m_scenes = scenes; | 468 | m_scenes = scenes; |
469 | if (m_last_scenes == null) | 469 | if (m_last_scenes == null) |
470 | { | 470 | { |
471 | m_last_scenes = scenes; | 471 | m_last_scenes = scenes; |
472 | } | 472 | } |
473 | 473 | ||
474 | m_tcp = new TcpClient(m_server, (int) m_port); | 474 | m_tcp = new TcpClient(m_server, (int) m_port); |
475 | m_log.Info("[IRC]: Connecting..."); | 475 | m_log.Info("[IRC]: Connecting..."); |
476 | m_stream = m_tcp.GetStream(); | 476 | m_stream = m_tcp.GetStream(); |
477 | m_log.Info("[IRC]: Connected to " + m_server); | 477 | m_log.Info("[IRC]: Connected to " + m_server); |
478 | m_reader = new StreamReader(m_stream); | 478 | m_reader = new StreamReader(m_stream); |
479 | m_writer = new StreamWriter(m_stream); | 479 | m_writer = new StreamWriter(m_stream); |
480 | 480 | ||
481 | pingSender = new Thread(new ThreadStart(PingRun)); | 481 | pingSender = new Thread(new ThreadStart(PingRun)); |
482 | pingSender.Name = "PingSenderThread"; | 482 | pingSender.Name = "PingSenderThread"; |
483 | pingSender.IsBackground = true; | 483 | pingSender.IsBackground = true; |
484 | pingSender.Start(); | 484 | pingSender.Start(); |
485 | ThreadTracker.Add(pingSender); | 485 | ThreadTracker.Add(pingSender); |
486 | 486 | ||
487 | listener = new Thread(new ThreadStart(ListenerRun)); | 487 | listener = new Thread(new ThreadStart(ListenerRun)); |
488 | listener.Name = "IRCChatModuleListenerThread"; | 488 | listener.Name = "IRCChatModuleListenerThread"; |
489 | listener.IsBackground = true; | 489 | listener.IsBackground = true; |
490 | listener.Start(); | 490 | listener.Start(); |
491 | ThreadTracker.Add(listener); | 491 | ThreadTracker.Add(listener); |
492 | 492 | ||
493 | m_writer.WriteLine(m_user); | 493 | m_writer.WriteLine(m_user); |
494 | m_writer.Flush(); | 494 | m_writer.Flush(); |
495 | m_writer.WriteLine("NICK " + m_nick); | 495 | m_writer.WriteLine("NICK " + m_nick); |
496 | m_writer.Flush(); | 496 | m_writer.Flush(); |
497 | m_writer.WriteLine("JOIN " + m_channel); | 497 | m_writer.WriteLine("JOIN " + m_channel); |
498 | m_writer.Flush(); | 498 | m_writer.Flush(); |
499 | m_log.Info("[IRC]: Connection fully established"); | 499 | m_log.Info("[IRC]: Connection fully established"); |
500 | m_connected = true; | 500 | m_connected = true; |
501 | } | 501 | } |
502 | catch (Exception e) | 502 | catch (Exception e) |
503 | { | 503 | { |
504 | Console.WriteLine(e.ToString()); | 504 | Console.WriteLine(e.ToString()); |
505 | } | 505 | } |
506 | return m_connected; | 506 | return m_connected; |
507 | } | 507 | } |
508 | } | 508 | } |
509 | 509 | ||
510 | public void Reconnect() | 510 | public void Reconnect() |
511 | { | 511 | { |
512 | m_connected = false; | 512 | m_connected = false; |
513 | listener.Abort(); | 513 | listener.Abort(); |
514 | pingSender.Abort(); | 514 | pingSender.Abort(); |
515 | m_writer.Close(); | 515 | m_writer.Close(); |
516 | m_reader.Close(); | 516 | m_reader.Close(); |
517 | m_tcp.Close(); | 517 | m_tcp.Close(); |
518 | if (m_enabled) | 518 | if (m_enabled) |
519 | { | 519 | { |
520 | Connect(m_last_scenes); | 520 | Connect(m_last_scenes); |
521 | } | 521 | } |
522 | } | 522 | } |
523 | 523 | ||
524 | public void PrivMsg(string from, string region, string msg) | 524 | public void PrivMsg(string from, string region, string msg) |
525 | { | 525 | { |
526 | // One message to the IRC server | 526 | // One message to the IRC server |
527 | 527 | ||
528 | try | 528 | try |
529 | { | 529 | { |
530 | if (m_privmsgformat == null) | 530 | if (m_privmsgformat == null) |
531 | { | 531 | { |
532 | m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); | 532 | m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); |
533 | } | 533 | } |
534 | else | 534 | else |
535 | { | 535 | { |
536 | m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); | 536 | m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); |
537 | } | 537 | } |
538 | m_writer.Flush(); | 538 | m_writer.Flush(); |
539 | m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); | 539 | m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); |
540 | } | 540 | } |
541 | catch (IOException) | 541 | catch (IOException) |
542 | { | 542 | { |
543 | m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); | 543 | m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); |
544 | Reconnect(); | 544 | Reconnect(); |
545 | } | 545 | } |
546 | catch (Exception ex) | 546 | catch (Exception ex) |
547 | { | 547 | { |
548 | m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); | 548 | m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); |
549 | } | 549 | } |
550 | } | 550 | } |
551 | 551 | ||
552 | private Dictionary<string, string> ExtractMsg(string input) | 552 | private Dictionary<string, string> ExtractMsg(string input) |
553 | { | 553 | { |
554 | //examines IRC commands and extracts any private messages | 554 | //examines IRC commands and extracts any private messages |
555 | // which will then be reboadcast in the Sim | 555 | // which will then be reboadcast in the Sim |
556 | 556 | ||
557 | m_log.Info("[IRC]: ExtractMsg: " + input); | 557 | m_log.Info("[IRC]: ExtractMsg: " + input); |
558 | Dictionary<string, string> result = null; | 558 | Dictionary<string, string> result = null; |
559 | //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; | 559 | //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; |
560 | string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; | 560 | string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; |
561 | Regex RE = new Regex(regex, RegexOptions.Multiline); | 561 | Regex RE = new Regex(regex, RegexOptions.Multiline); |
562 | MatchCollection matches = RE.Matches(input); | 562 | MatchCollection matches = RE.Matches(input); |
563 | // Get some direct matches $1 $4 is a | 563 | // Get some direct matches $1 $4 is a |
564 | if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) | 564 | if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) |
565 | { | 565 | { |
566 | result = new Dictionary<string, string>(); | 566 | result = new Dictionary<string, string>(); |
567 | result.Add("nick", matches[0].Groups[1].Value); | 567 | result.Add("nick", matches[0].Groups[1].Value); |
568 | result.Add("user", matches[0].Groups[2].Value); | 568 | result.Add("user", matches[0].Groups[2].Value); |
569 | result.Add("channel", matches[0].Groups[3].Value); | 569 | result.Add("channel", matches[0].Groups[3].Value); |
570 | result.Add("msg", matches[0].Groups[4].Value); | 570 | result.Add("msg", matches[0].Groups[4].Value); |
571 | } | 571 | } |
572 | else | 572 | else |
573 | { | 573 | { |
574 | m_log.Info("[IRC]: Number of matches: " + matches.Count); | 574 | m_log.Info("[IRC]: Number of matches: " + matches.Count); |
575 | if (matches.Count > 0) | 575 | if (matches.Count > 0) |
576 | { | 576 | { |
577 | m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); | 577 | m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); |
578 | } | 578 | } |
579 | } | 579 | } |
580 | return result; | 580 | return result; |
581 | } | 581 | } |
582 | 582 | ||
583 | public void PingRun() | 583 | public void PingRun() |
584 | { | 584 | { |
585 | // IRC keep alive thread | 585 | // IRC keep alive thread |
586 | // send PING ever 15 seconds | 586 | // send PING ever 15 seconds |
587 | while (true) | 587 | while (true) |
588 | { | 588 | { |
589 | try | 589 | try |
590 | { | 590 | { |
591 | if (m_connected == true) | 591 | if (m_connected == true) |
592 | { | 592 | { |
593 | m_writer.WriteLine("PING :" + m_server); | 593 | m_writer.WriteLine("PING :" + m_server); |
594 | m_writer.Flush(); | 594 | m_writer.Flush(); |
595 | Thread.Sleep(15000); | 595 | Thread.Sleep(15000); |
596 | } | 596 | } |
597 | } | 597 | } |
598 | catch (IOException) | 598 | catch (IOException) |
599 | { | 599 | { |
600 | m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); | 600 | m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); |
601 | Reconnect(); | 601 | Reconnect(); |
602 | } | 602 | } |
603 | catch (Exception ex) | 603 | catch (Exception ex) |
604 | { | 604 | { |
605 | m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); | 605 | m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); |
606 | } | 606 | } |
607 | } | 607 | } |
608 | } | 608 | } |
609 | 609 | ||
610 | public void ListenerRun() | 610 | public void ListenerRun() |
611 | { | 611 | { |
612 | string inputLine; | 612 | string inputLine; |
613 | LLVector3 pos = new LLVector3(128, 128, 20); | 613 | LLVector3 pos = new LLVector3(128, 128, 20); |
614 | while (true) | 614 | while (true) |
615 | { | 615 | { |
616 | try | 616 | try |
617 | { | 617 | { |
618 | while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) | 618 | while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) |
619 | { | 619 | { |
620 | // Console.WriteLine(inputLine); | 620 | // Console.WriteLine(inputLine); |
621 | if (inputLine.Contains(m_channel)) | 621 | if (inputLine.Contains(m_channel)) |
622 | { | 622 | { |
623 | Dictionary<string, string> data = ExtractMsg(inputLine); | 623 | Dictionary<string, string> data = ExtractMsg(inputLine); |
624 | // Any chat ??? | 624 | // Any chat ??? |
625 | if (data != null) | 625 | if (data != null) |
626 | { | 626 | { |
627 | foreach (Scene m_scene in m_scenes) | 627 | foreach (Scene m_scene in m_scenes) |
628 | { | 628 | { |
629 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 629 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
630 | { | 630 | { |
631 | if (!avatar.IsChildAgent) | 631 | if (!avatar.IsChildAgent) |
632 | { | 632 | { |
633 | avatar.ControllingClient.SendChatMessage( | 633 | avatar.ControllingClient.SendChatMessage( |
634 | Helpers.StringToField(data["msg"]), 255, | 634 | Helpers.StringToField(data["msg"]), 255, |
635 | pos, data["nick"], | 635 | pos, data["nick"], |
636 | LLUUID.Zero); | 636 | LLUUID.Zero); |
637 | } | 637 | } |
638 | }); | 638 | }); |
639 | } | 639 | } |
640 | } | 640 | } |
641 | else | 641 | else |
642 | { | 642 | { |
643 | // Was an command from the IRC server | 643 | // Was an command from the IRC server |
644 | ProcessIRCCommand(inputLine); | 644 | ProcessIRCCommand(inputLine); |
645 | } | 645 | } |
646 | } | 646 | } |
647 | else | 647 | else |
648 | { | 648 | { |
649 | // Was an command from the IRC server | 649 | // Was an command from the IRC server |
650 | ProcessIRCCommand(inputLine); | 650 | ProcessIRCCommand(inputLine); |
651 | } | 651 | } |
652 | Thread.Sleep(150); | 652 | Thread.Sleep(150); |
653 | } | 653 | } |
654 | } | 654 | } |
655 | catch (IOException) | 655 | catch (IOException) |
656 | { | 656 | { |
657 | m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); | 657 | m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); |
658 | Reconnect(); | 658 | Reconnect(); |
659 | } | 659 | } |
660 | catch (Exception ex) | 660 | catch (Exception ex) |
661 | { | 661 | { |
662 | m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); | 662 | m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); |
663 | } | 663 | } |
664 | } | 664 | } |
665 | } | 665 | } |
666 | 666 | ||
667 | public void BroadcastSim(string message, string sender) | 667 | public void BroadcastSim(string message, string sender) |
668 | { | 668 | { |
669 | LLVector3 pos = new LLVector3(128, 128, 20); | 669 | LLVector3 pos = new LLVector3(128, 128, 20); |
670 | try | 670 | try |
671 | { | 671 | { |
672 | foreach (Scene m_scene in m_scenes) | 672 | foreach (Scene m_scene in m_scenes) |
673 | { | 673 | { |
674 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 674 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
675 | { | 675 | { |
676 | if (!avatar.IsChildAgent) | 676 | if (!avatar.IsChildAgent) |
677 | { | 677 | { |
678 | avatar.ControllingClient.SendChatMessage( | 678 | avatar.ControllingClient.SendChatMessage( |
679 | Helpers.StringToField(message), 255, | 679 | Helpers.StringToField(message), 255, |
680 | pos, sender, | 680 | pos, sender, |
681 | LLUUID.Zero); | 681 | LLUUID.Zero); |
682 | } | 682 | } |
683 | }); | 683 | }); |
684 | } | 684 | } |
685 | } | 685 | } |
686 | catch (Exception ex) // IRC gate should not crash Sim | 686 | catch (Exception ex) // IRC gate should not crash Sim |
687 | { | 687 | { |
688 | m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); | 688 | m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); |
689 | } | 689 | } |
690 | } | 690 | } |
691 | 691 | ||
692 | public void ProcessIRCCommand(string command) | 692 | public void ProcessIRCCommand(string command) |
693 | { | 693 | { |
694 | //m_log.Info("[IRC]: ProcessIRCCommand:" + command); | 694 | //m_log.Info("[IRC]: ProcessIRCCommand:" + command); |
695 | 695 | ||
696 | string[] commArgs = new string[command.Split(' ').Length]; | 696 | string[] commArgs = new string[command.Split(' ').Length]; |
697 | string c_server = m_server; | 697 | string c_server = m_server; |
698 | 698 | ||
699 | commArgs = command.Split(' '); | 699 | commArgs = command.Split(' '); |
700 | if (commArgs[0].Substring(0, 1) == ":") | 700 | if (commArgs[0].Substring(0, 1) == ":") |
701 | { | 701 | { |
702 | commArgs[0] = commArgs[0].Remove(0, 1); | 702 | commArgs[0] = commArgs[0].Remove(0, 1); |
703 | } | 703 | } |
704 | 704 | ||
705 | if (commArgs[1] == "002") | 705 | if (commArgs[1] == "002") |
706 | { | 706 | { |
707 | // fetch the correct servername | 707 | // fetch the correct servername |
708 | // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... | 708 | // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... |
709 | // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch | 709 | // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch |
710 | 710 | ||
711 | c_server = (commArgs[6].Split('['))[0]; | 711 | c_server = (commArgs[6].Split('['))[0]; |
712 | m_server = c_server; | 712 | m_server = c_server; |
713 | } | 713 | } |
714 | 714 | ||
715 | if (commArgs[0] == "ERROR") | 715 | if (commArgs[0] == "ERROR") |
716 | { | 716 | { |
717 | m_log.Error("[IRC]: IRC SERVER ERROR:" + command); | 717 | m_log.Error("[IRC]: IRC SERVER ERROR:" + command); |
718 | } | 718 | } |
719 | 719 | ||
720 | if (commArgs[0] == "PING") | 720 | if (commArgs[0] == "PING") |
721 | { | 721 | { |
722 | string p_reply = ""; | 722 | string p_reply = ""; |
723 | 723 | ||
724 | for (int i = 1; i < commArgs.Length; i++) | 724 | for (int i = 1; i < commArgs.Length; i++) |
725 | { | 725 | { |
726 | p_reply += commArgs[i] + " "; | 726 | p_reply += commArgs[i] + " "; |
727 | } | 727 | } |
728 | 728 | ||
729 | m_writer.WriteLine("PONG " + p_reply); | 729 | m_writer.WriteLine("PONG " + p_reply); |
730 | m_writer.Flush(); | 730 | m_writer.Flush(); |
731 | } | 731 | } |
732 | else if (commArgs[0] == c_server) | 732 | else if (commArgs[0] == c_server) |
733 | { | 733 | { |
734 | // server message | 734 | // server message |
735 | try | 735 | try |
736 | { | 736 | { |
737 | Int32 commandCode = Int32.Parse(commArgs[1]); | 737 | Int32 commandCode = Int32.Parse(commArgs[1]); |
738 | switch (commandCode) | 738 | switch (commandCode) |
739 | { | 739 | { |
740 | case (int) ErrorReplies.NicknameInUse: | 740 | case (int) ErrorReplies.NicknameInUse: |
741 | // Gen a new name | 741 | // Gen a new name |
742 | m_nick = m_basenick + Util.RandomClass.Next(1, 99); | 742 | m_nick = m_basenick + Util.RandomClass.Next(1, 99); |
743 | m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); | 743 | m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); |
744 | // Retry | 744 | // Retry |
745 | m_writer.WriteLine("NICK " + m_nick); | 745 | m_writer.WriteLine("NICK " + m_nick); |
746 | m_writer.Flush(); | 746 | m_writer.Flush(); |
747 | m_writer.WriteLine("JOIN " + m_channel); | 747 | m_writer.WriteLine("JOIN " + m_channel); |
748 | m_writer.Flush(); | 748 | m_writer.Flush(); |
749 | break; | 749 | break; |
750 | case (int) ErrorReplies.NotRegistered: | 750 | case (int) ErrorReplies.NotRegistered: |
751 | break; | 751 | break; |
752 | case (int) Replies.EndOfMotd: | 752 | case (int) Replies.EndOfMotd: |
753 | break; | 753 | break; |
754 | } | 754 | } |
755 | } | 755 | } |
756 | catch (Exception) | 756 | catch (Exception) |
757 | { | 757 | { |
758 | } | 758 | } |
759 | } | 759 | } |
760 | else | 760 | else |
761 | { | 761 | { |
762 | // Normal message | 762 | // Normal message |
763 | string commAct = commArgs[1]; | 763 | string commAct = commArgs[1]; |
764 | switch (commAct) | 764 | switch (commAct) |
765 | { | 765 | { |
766 | case "JOIN": | 766 | case "JOIN": |
767 | eventIrcJoin(commArgs); | 767 | eventIrcJoin(commArgs); |
768 | break; | 768 | break; |
769 | case "PART": | 769 | case "PART": |
770 | eventIrcPart(commArgs); | 770 | eventIrcPart(commArgs); |
771 | break; | 771 | break; |
772 | case "MODE": | 772 | case "MODE": |
773 | eventIrcMode(commArgs); | 773 | eventIrcMode(commArgs); |
774 | break; | 774 | break; |
775 | case "NICK": | 775 | case "NICK": |
776 | eventIrcNickChange(commArgs); | 776 | eventIrcNickChange(commArgs); |
777 | break; | 777 | break; |
778 | case "KICK": | 778 | case "KICK": |
779 | eventIrcKick(commArgs); | 779 | eventIrcKick(commArgs); |
780 | break; | 780 | break; |
781 | case "QUIT": | 781 | case "QUIT": |
782 | eventIrcQuit(commArgs); | 782 | eventIrcQuit(commArgs); |
783 | break; | 783 | break; |
784 | case "PONG": | 784 | case "PONG": |
785 | break; // that's nice | 785 | break; // that's nice |
786 | } | 786 | } |
787 | } | 787 | } |
788 | } | 788 | } |
789 | 789 | ||
790 | public void eventIrcJoin(string[] commArgs) | 790 | public void eventIrcJoin(string[] commArgs) |
791 | { | 791 | { |
792 | string IrcChannel = commArgs[2]; | 792 | string IrcChannel = commArgs[2]; |
793 | string IrcUser = commArgs[0].Split('!')[0]; | 793 | string IrcUser = commArgs[0].Split('!')[0]; |
794 | BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); | 794 | BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); |
795 | } | 795 | } |
796 | 796 | ||
797 | public void eventIrcPart(string[] commArgs) | 797 | public void eventIrcPart(string[] commArgs) |
798 | { | 798 | { |
799 | string IrcChannel = commArgs[2]; | 799 | string IrcChannel = commArgs[2]; |
800 | string IrcUser = commArgs[0].Split('!')[0]; | 800 | string IrcUser = commArgs[0].Split('!')[0]; |
801 | BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); | 801 | BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); |
802 | } | 802 | } |
803 | 803 | ||
804 | public void eventIrcMode(string[] commArgs) | 804 | public void eventIrcMode(string[] commArgs) |
805 | { | 805 | { |
806 | string IrcChannel = commArgs[2]; | 806 | string IrcChannel = commArgs[2]; |
807 | string IrcUser = commArgs[0].Split('!')[0]; | 807 | string IrcUser = commArgs[0].Split('!')[0]; |
808 | string UserMode = ""; | 808 | string UserMode = ""; |
809 | for (int i = 3; i < commArgs.Length; i++) | 809 | for (int i = 3; i < commArgs.Length; i++) |
810 | { | 810 | { |
811 | UserMode += commArgs[i] + " "; | 811 | UserMode += commArgs[i] + " "; |
812 | } | 812 | } |
813 | 813 | ||
814 | if (UserMode.Substring(0, 1) == ":") | 814 | if (UserMode.Substring(0, 1) == ":") |
815 | { | 815 | { |
816 | UserMode = UserMode.Remove(0, 1); | 816 | UserMode = UserMode.Remove(0, 1); |
817 | } | 817 | } |
818 | } | 818 | } |
819 | 819 | ||
820 | public void eventIrcNickChange(string[] commArgs) | 820 | public void eventIrcNickChange(string[] commArgs) |
821 | { | 821 | { |
822 | string UserOldNick = commArgs[0].Split('!')[0]; | 822 | string UserOldNick = commArgs[0].Split('!')[0]; |
823 | string UserNewNick = commArgs[2].Remove(0, 1); | 823 | string UserNewNick = commArgs[2].Remove(0, 1); |
824 | BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); | 824 | BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); |
825 | } | 825 | } |
826 | 826 | ||
827 | public void eventIrcKick(string[] commArgs) | 827 | public void eventIrcKick(string[] commArgs) |
828 | { | 828 | { |
829 | string UserKicker = commArgs[0].Split('!')[0]; | 829 | string UserKicker = commArgs[0].Split('!')[0]; |
830 | string UserKicked = commArgs[3]; | 830 | string UserKicked = commArgs[3]; |
831 | string IrcChannel = commArgs[2]; | 831 | string IrcChannel = commArgs[2]; |
832 | string KickMessage = ""; | 832 | string KickMessage = ""; |
833 | for (int i = 4; i < commArgs.Length; i++) | 833 | for (int i = 4; i < commArgs.Length; i++) |
834 | { | 834 | { |
835 | KickMessage += commArgs[i] + " "; | 835 | KickMessage += commArgs[i] + " "; |
836 | } | 836 | } |
837 | BroadcastSim(UserKicker + " kicked " + UserKicked + " on " + IrcChannel + " saying " + KickMessage, m_nick); | 837 | BroadcastSim(UserKicker + " kicked " + UserKicked + " on " + IrcChannel + " saying " + KickMessage, m_nick); |
838 | if (UserKicked == m_nick) | 838 | if (UserKicked == m_nick) |
839 | { | 839 | { |
840 | BroadcastSim("Hey, that was me!!!", m_nick); | 840 | BroadcastSim("Hey, that was me!!!", m_nick); |
841 | } | 841 | } |
842 | } | 842 | } |
843 | 843 | ||
844 | public void eventIrcQuit(string[] commArgs) | 844 | public void eventIrcQuit(string[] commArgs) |
845 | { | 845 | { |
846 | string IrcUser = commArgs[0].Split('!')[0]; | 846 | string IrcUser = commArgs[0].Split('!')[0]; |
847 | string QuitMessage = ""; | 847 | string QuitMessage = ""; |
848 | 848 | ||
849 | for (int i = 2; i < commArgs.Length; i++) | 849 | for (int i = 2; i < commArgs.Length; i++) |
850 | { | 850 | { |
851 | QuitMessage += commArgs[i] + " "; | 851 | QuitMessage += commArgs[i] + " "; |
852 | } | 852 | } |
853 | BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); | 853 | BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); |
854 | } | 854 | } |
855 | 855 | ||
856 | public void Close() | 856 | public void Close() |
857 | { | 857 | { |
858 | m_connected = false; | 858 | m_connected = false; |
859 | m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); | 859 | m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); |
860 | m_writer.Flush(); | 860 | m_writer.Flush(); |
861 | listener.Abort(); | 861 | listener.Abort(); |
862 | pingSender.Abort(); | 862 | pingSender.Abort(); |
863 | m_writer.Close(); | 863 | m_writer.Close(); |
864 | m_reader.Close(); | 864 | m_reader.Close(); |
865 | m_tcp.Close(); | 865 | m_tcp.Close(); |
866 | } | 866 | } |
867 | } | 867 | } |
868 | } \ No newline at end of file | 868 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs index 181984e..966c5e2 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs | |||
@@ -1,1470 +1,1470 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Net.Sockets; | 32 | using System.Net.Sockets; |
33 | using System.Reflection; | 33 | using System.Reflection; |
34 | using System.Xml; | 34 | using System.Xml; |
35 | using libsecondlife; | 35 | using libsecondlife; |
36 | using log4net; | 36 | using log4net; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using Nwc.XmlRpc; | 38 | using Nwc.XmlRpc; |
39 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Region.Environment.Interfaces; | 40 | using OpenSim.Region.Environment.Interfaces; |
41 | using OpenSim.Region.Environment.Scenes; | 41 | using OpenSim.Region.Environment.Scenes; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney | 43 | namespace OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney |
44 | { | 44 | { |
45 | /// <summary> | 45 | /// <summary> |
46 | /// Demo Economy/Money Module. This is not a production quality money/economy module! | 46 | /// Demo Economy/Money Module. This is not a production quality money/economy module! |
47 | /// This is a demo for you to use when making one that works for you. | 47 | /// This is a demo for you to use when making one that works for you. |
48 | /// // To use the following you need to add: | 48 | /// // To use the following you need to add: |
49 | /// -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> | 49 | /// -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> |
50 | /// to the command line parameters you use to start up your client | 50 | /// to the command line parameters you use to start up your client |
51 | /// This commonly looks like -helperuri http://127.0.0.1:9000/ | 51 | /// This commonly looks like -helperuri http://127.0.0.1:9000/ |
52 | /// | 52 | /// |
53 | /// Centralized grid structure example using OpenSimWi Redux revision 9+ | 53 | /// Centralized grid structure example using OpenSimWi Redux revision 9+ |
54 | /// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux | 54 | /// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux |
55 | /// </summary> | 55 | /// </summary> |
56 | public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount); | 56 | public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount); |
57 | 57 | ||
58 | public interface IMoneyModule : IRegionModule | 58 | public interface IMoneyModule : IRegionModule |
59 | { | 59 | { |
60 | bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount); | 60 | bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount); |
61 | 61 | ||
62 | event ObjectPaid OnObjectPaid; | 62 | event ObjectPaid OnObjectPaid; |
63 | } | 63 | } |
64 | 64 | ||
65 | public class SampleMoneyModule : IMoneyModule | 65 | public class SampleMoneyModule : IMoneyModule |
66 | { | 66 | { |
67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
68 | 68 | ||
69 | /// <summary> | 69 | /// <summary> |
70 | /// Where Stipends come from and Fees go to. | 70 | /// Where Stipends come from and Fees go to. |
71 | /// </summary> | 71 | /// </summary> |
72 | private LLUUID EconomyBaseAccount = LLUUID.Zero; | 72 | private LLUUID EconomyBaseAccount = LLUUID.Zero; |
73 | 73 | ||
74 | private float EnergyEfficiency = 0f; | 74 | private float EnergyEfficiency = 0f; |
75 | private bool gridmode = false; | 75 | private bool gridmode = false; |
76 | private ObjectPaid handerOnObjectPaid; | 76 | private ObjectPaid handerOnObjectPaid; |
77 | private bool m_enabled = true; | 77 | private bool m_enabled = true; |
78 | 78 | ||
79 | private IConfigSource m_gConfig; | 79 | private IConfigSource m_gConfig; |
80 | 80 | ||
81 | private bool m_keepMoneyAcrossLogins = true; | 81 | private bool m_keepMoneyAcrossLogins = true; |
82 | private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>(); | 82 | private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>(); |
83 | private string m_LandAddress = String.Empty; | 83 | private string m_LandAddress = String.Empty; |
84 | 84 | ||
85 | private int m_minFundsBeforeRefresh = 100; | 85 | private int m_minFundsBeforeRefresh = 100; |
86 | private string m_MoneyAddress = String.Empty; | 86 | private string m_MoneyAddress = String.Empty; |
87 | 87 | ||
88 | /// <summary> | 88 | /// <summary> |
89 | /// Region UUIDS indexed by AgentID | 89 | /// Region UUIDS indexed by AgentID |
90 | /// </summary> | 90 | /// </summary> |
91 | private Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>(); | 91 | private Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>(); |
92 | 92 | ||
93 | /// <summary> | 93 | /// <summary> |
94 | /// Scenes by Region Handle | 94 | /// Scenes by Region Handle |
95 | /// </summary> | 95 | /// </summary> |
96 | private Dictionary<ulong, Scene> m_scenel = new Dictionary<ulong, Scene>(); | 96 | private Dictionary<ulong, Scene> m_scenel = new Dictionary<ulong, Scene>(); |
97 | 97 | ||
98 | private int m_stipend = 1000; | 98 | private int m_stipend = 1000; |
99 | 99 | ||
100 | private int ObjectCapacity = 45000; | 100 | private int ObjectCapacity = 45000; |
101 | private int ObjectCount = 0; | 101 | private int ObjectCount = 0; |
102 | private int PriceEnergyUnit = 0; | 102 | private int PriceEnergyUnit = 0; |
103 | private int PriceGroupCreate = 0; | 103 | private int PriceGroupCreate = 0; |
104 | private int PriceObjectClaim = 0; | 104 | private int PriceObjectClaim = 0; |
105 | private float PriceObjectRent = 0f; | 105 | private float PriceObjectRent = 0f; |
106 | private float PriceObjectScaleFactor = 0f; | 106 | private float PriceObjectScaleFactor = 0f; |
107 | private int PriceParcelClaim = 0; | 107 | private int PriceParcelClaim = 0; |
108 | private float PriceParcelClaimFactor = 0f; | 108 | private float PriceParcelClaimFactor = 0f; |
109 | private int PriceParcelRent = 0; | 109 | private int PriceParcelRent = 0; |
110 | private int PricePublicObjectDecay = 0; | 110 | private int PricePublicObjectDecay = 0; |
111 | private int PricePublicObjectDelete = 0; | 111 | private int PricePublicObjectDelete = 0; |
112 | private int PriceRentLight = 0; | 112 | private int PriceRentLight = 0; |
113 | private int PriceUpload = 0; | 113 | private int PriceUpload = 0; |
114 | private int TeleportMinPrice = 0; | 114 | private int TeleportMinPrice = 0; |
115 | 115 | ||
116 | private float TeleportPriceExponent = 0f; | 116 | private float TeleportPriceExponent = 0f; |
117 | private int UserLevelPaysFees = 2; | 117 | private int UserLevelPaysFees = 2; |
118 | private Scene XMLRPCHandler; | 118 | private Scene XMLRPCHandler; |
119 | 119 | ||
120 | #region IMoneyModule Members | 120 | #region IMoneyModule Members |
121 | 121 | ||
122 | public event ObjectPaid OnObjectPaid; | 122 | public event ObjectPaid OnObjectPaid; |
123 | 123 | ||
124 | /// <summary> | 124 | /// <summary> |
125 | /// Startup | 125 | /// Startup |
126 | /// </summary> | 126 | /// </summary> |
127 | /// <param name="scene"></param> | 127 | /// <param name="scene"></param> |
128 | /// <param name="config"></param> | 128 | /// <param name="config"></param> |
129 | public void Initialise(Scene scene, IConfigSource config) | 129 | public void Initialise(Scene scene, IConfigSource config) |
130 | { | 130 | { |
131 | m_gConfig = config; | 131 | m_gConfig = config; |
132 | 132 | ||
133 | IConfig startupConfig = m_gConfig.Configs["Startup"]; | 133 | IConfig startupConfig = m_gConfig.Configs["Startup"]; |
134 | IConfig economyConfig = m_gConfig.Configs["Economy"]; | 134 | IConfig economyConfig = m_gConfig.Configs["Economy"]; |
135 | 135 | ||
136 | scene.RegisterModuleInterface<IMoneyModule>(this); | 136 | scene.RegisterModuleInterface<IMoneyModule>(this); |
137 | 137 | ||
138 | ReadConfigAndPopulate(scene, startupConfig, "Startup"); | 138 | ReadConfigAndPopulate(scene, startupConfig, "Startup"); |
139 | ReadConfigAndPopulate(scene, economyConfig, "Economy"); | 139 | ReadConfigAndPopulate(scene, economyConfig, "Economy"); |
140 | 140 | ||
141 | if (m_enabled) | 141 | if (m_enabled) |
142 | { | 142 | { |
143 | lock (m_scenel) | 143 | lock (m_scenel) |
144 | { | 144 | { |
145 | if (m_scenel.Count == 0) | 145 | if (m_scenel.Count == 0) |
146 | { | 146 | { |
147 | XMLRPCHandler = scene; | 147 | XMLRPCHandler = scene; |
148 | 148 | ||
149 | // To use the following you need to add: | 149 | // To use the following you need to add: |
150 | // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> | 150 | // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> |
151 | // to the command line parameters you use to start up your client | 151 | // to the command line parameters you use to start up your client |
152 | // This commonly looks like -helperuri http://127.0.0.1:9000/ | 152 | // This commonly looks like -helperuri http://127.0.0.1:9000/ |
153 | 153 | ||
154 | if (m_MoneyAddress.Length > 0) | 154 | if (m_MoneyAddress.Length > 0) |
155 | { | 155 | { |
156 | // Centralized grid structure using OpenSimWi Redux revision 9+ | 156 | // Centralized grid structure using OpenSimWi Redux revision 9+ |
157 | // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux | 157 | // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux |
158 | scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate); | 158 | scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate); |
159 | scene.AddXmlRPCHandler("userAlert", UserAlert); | 159 | scene.AddXmlRPCHandler("userAlert", UserAlert); |
160 | } | 160 | } |
161 | else | 161 | else |
162 | { | 162 | { |
163 | // Local Server.. enables functionality only. | 163 | // Local Server.. enables functionality only. |
164 | scene.AddXmlRPCHandler("getCurrencyQuote", quote_func); | 164 | scene.AddXmlRPCHandler("getCurrencyQuote", quote_func); |
165 | scene.AddXmlRPCHandler("buyCurrency", buy_func); | 165 | scene.AddXmlRPCHandler("buyCurrency", buy_func); |
166 | scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); | 166 | scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); |
167 | scene.AddXmlRPCHandler("buyLandPrep", landBuy_func); | 167 | scene.AddXmlRPCHandler("buyLandPrep", landBuy_func); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) | 171 | if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) |
172 | { | 172 | { |
173 | m_scenel[scene.RegionInfo.RegionHandle] = scene; | 173 | m_scenel[scene.RegionInfo.RegionHandle] = scene; |
174 | } | 174 | } |
175 | else | 175 | else |
176 | { | 176 | { |
177 | m_scenel.Add(scene.RegionInfo.RegionHandle, scene); | 177 | m_scenel.Add(scene.RegionInfo.RegionHandle, scene); |
178 | } | 178 | } |
179 | } | 179 | } |
180 | 180 | ||
181 | scene.EventManager.OnNewClient += OnNewClient; | 181 | scene.EventManager.OnNewClient += OnNewClient; |
182 | scene.EventManager.OnMoneyTransfer += MoneyTransferAction; | 182 | scene.EventManager.OnMoneyTransfer += MoneyTransferAction; |
183 | scene.EventManager.OnClientClosed += ClientClosed; | 183 | scene.EventManager.OnClientClosed += ClientClosed; |
184 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | 184 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; |
185 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; | 185 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; |
186 | scene.EventManager.OnClientClosed += ClientLoggedOut; | 186 | scene.EventManager.OnClientClosed += ClientLoggedOut; |
187 | scene.EventManager.OnValidateLandBuy += ValidateLandBuy; | 187 | scene.EventManager.OnValidateLandBuy += ValidateLandBuy; |
188 | scene.EventManager.OnLandBuy += processLandBuy; | 188 | scene.EventManager.OnLandBuy += processLandBuy; |
189 | } | 189 | } |
190 | } | 190 | } |
191 | 191 | ||
192 | public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount) | 192 | public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount) |
193 | { | 193 | { |
194 | string description = String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID)); | 194 | string description = String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID)); |
195 | 195 | ||
196 | bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description); | 196 | bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description); |
197 | 197 | ||
198 | if (m_MoneyAddress.Length == 0) | 198 | if (m_MoneyAddress.Length == 0) |
199 | BalanceUpdate(fromID, toID, give_result, description); | 199 | BalanceUpdate(fromID, toID, give_result, description); |
200 | 200 | ||
201 | return give_result; | 201 | return give_result; |
202 | } | 202 | } |
203 | 203 | ||
204 | public void PostInitialise() | 204 | public void PostInitialise() |
205 | { | 205 | { |
206 | } | 206 | } |
207 | 207 | ||
208 | public void Close() | 208 | public void Close() |
209 | { | 209 | { |
210 | } | 210 | } |
211 | 211 | ||
212 | public string Name | 212 | public string Name |
213 | { | 213 | { |
214 | get { return "BetaGridLikeMoneyModule"; } | 214 | get { return "BetaGridLikeMoneyModule"; } |
215 | } | 215 | } |
216 | 216 | ||
217 | public bool IsSharedModule | 217 | public bool IsSharedModule |
218 | { | 218 | { |
219 | get { return true; } | 219 | get { return true; } |
220 | } | 220 | } |
221 | 221 | ||
222 | #endregion | 222 | #endregion |
223 | 223 | ||
224 | /// <summary> | 224 | /// <summary> |
225 | /// Parse Configuration | 225 | /// Parse Configuration |
226 | /// </summary> | 226 | /// </summary> |
227 | /// <param name="scene"></param> | 227 | /// <param name="scene"></param> |
228 | /// <param name="startupConfig"></param> | 228 | /// <param name="startupConfig"></param> |
229 | /// <param name="config"></param> | 229 | /// <param name="config"></param> |
230 | private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config) | 230 | private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config) |
231 | { | 231 | { |
232 | if (config == "Startup" && startupConfig != null) | 232 | if (config == "Startup" && startupConfig != null) |
233 | { | 233 | { |
234 | gridmode = startupConfig.GetBoolean("gridmode", false); | 234 | gridmode = startupConfig.GetBoolean("gridmode", false); |
235 | m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); | 235 | m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); |
236 | } | 236 | } |
237 | 237 | ||
238 | if (config == "Economy" && startupConfig != null) | 238 | if (config == "Economy" && startupConfig != null) |
239 | { | 239 | { |
240 | ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000); | 240 | ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000); |
241 | PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); | 241 | PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); |
242 | PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); | 242 | PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); |
243 | PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); | 243 | PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); |
244 | PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4); | 244 | PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4); |
245 | PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1); | 245 | PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1); |
246 | PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f); | 246 | PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f); |
247 | PriceUpload = startupConfig.GetInt("PriceUpload", 0); | 247 | PriceUpload = startupConfig.GetInt("PriceUpload", 0); |
248 | PriceRentLight = startupConfig.GetInt("PriceRentLight", 5); | 248 | PriceRentLight = startupConfig.GetInt("PriceRentLight", 5); |
249 | TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2); | 249 | TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2); |
250 | TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f); | 250 | TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f); |
251 | EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1); | 251 | EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1); |
252 | PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1); | 252 | PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1); |
253 | PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10); | 253 | PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10); |
254 | PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1); | 254 | PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1); |
255 | PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1); | 255 | PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1); |
256 | string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString()); | 256 | string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString()); |
257 | Helpers.TryParse(EBA, out EconomyBaseAccount); | 257 | Helpers.TryParse(EBA, out EconomyBaseAccount); |
258 | 258 | ||
259 | UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1); | 259 | UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1); |
260 | m_stipend = startupConfig.GetInt("UserStipend", 500); | 260 | m_stipend = startupConfig.GetInt("UserStipend", 500); |
261 | m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10); | 261 | m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10); |
262 | m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true); | 262 | m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true); |
263 | m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty); | 263 | m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty); |
264 | m_LandAddress = startupConfig.GetString("LandServer", String.Empty); | 264 | m_LandAddress = startupConfig.GetString("LandServer", String.Empty); |
265 | } | 265 | } |
266 | 266 | ||
267 | // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter. | 267 | // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter. |
268 | scene.SetObjectCapacity(ObjectCapacity); | 268 | scene.SetObjectCapacity(ObjectCapacity); |
269 | } | 269 | } |
270 | 270 | ||
271 | /// <summary> | 271 | /// <summary> |
272 | /// New Client Event Handler | 272 | /// New Client Event Handler |
273 | /// </summary> | 273 | /// </summary> |
274 | /// <param name="client"></param> | 274 | /// <param name="client"></param> |
275 | private void OnNewClient(IClientAPI client) | 275 | private void OnNewClient(IClientAPI client) |
276 | { | 276 | { |
277 | // Here we check if we're in grid mode | 277 | // Here we check if we're in grid mode |
278 | // I imagine that the 'check balance' | 278 | // I imagine that the 'check balance' |
279 | // function for the client should be here or shortly after | 279 | // function for the client should be here or shortly after |
280 | 280 | ||
281 | if (gridmode) | 281 | if (gridmode) |
282 | { | 282 | { |
283 | if (m_MoneyAddress.Length == 0) | 283 | if (m_MoneyAddress.Length == 0) |
284 | { | 284 | { |
285 | CheckExistAndRefreshFunds(client.AgentId); | 285 | CheckExistAndRefreshFunds(client.AgentId); |
286 | } | 286 | } |
287 | else | 287 | else |
288 | { | 288 | { |
289 | bool childYN = true; | 289 | bool childYN = true; |
290 | ScenePresence agent = null; | 290 | ScenePresence agent = null; |
291 | //client.SecureSessionId; | 291 | //client.SecureSessionId; |
292 | Scene s = LocateSceneClientIn(client.AgentId); | 292 | Scene s = LocateSceneClientIn(client.AgentId); |
293 | if (s != null) | 293 | if (s != null) |
294 | { | 294 | { |
295 | agent = s.GetScenePresence(client.AgentId); | 295 | agent = s.GetScenePresence(client.AgentId); |
296 | if (agent != null) | 296 | if (agent != null) |
297 | childYN = agent.IsChildAgent; | 297 | childYN = agent.IsChildAgent; |
298 | } | 298 | } |
299 | if (s != null && agent != null && childYN == false) | 299 | if (s != null && agent != null && childYN == false) |
300 | { | 300 | { |
301 | //s.RegionInfo.RegionHandle; | 301 | //s.RegionInfo.RegionHandle; |
302 | LLUUID agentID = LLUUID.Zero; | 302 | LLUUID agentID = LLUUID.Zero; |
303 | int funds = 0; | 303 | int funds = 0; |
304 | 304 | ||
305 | Hashtable hbinfo = | 305 | Hashtable hbinfo = |
306 | GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), | 306 | GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), |
307 | s.RegionInfo.regionSecret); | 307 | s.RegionInfo.regionSecret); |
308 | if ((bool) hbinfo["success"] == true) | 308 | if ((bool) hbinfo["success"] == true) |
309 | { | 309 | { |
310 | Helpers.TryParse((string) hbinfo["agentId"], out agentID); | 310 | Helpers.TryParse((string) hbinfo["agentId"], out agentID); |
311 | try | 311 | try |
312 | { | 312 | { |
313 | funds = (Int32) hbinfo["funds"]; | 313 | funds = (Int32) hbinfo["funds"]; |
314 | } | 314 | } |
315 | catch (ArgumentException) | 315 | catch (ArgumentException) |
316 | { | 316 | { |
317 | } | 317 | } |
318 | catch (FormatException) | 318 | catch (FormatException) |
319 | { | 319 | { |
320 | } | 320 | } |
321 | catch (OverflowException) | 321 | catch (OverflowException) |
322 | { | 322 | { |
323 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID); | 323 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID); |
324 | client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); | 324 | client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); |
325 | } | 325 | } |
326 | catch (InvalidCastException) | 326 | catch (InvalidCastException) |
327 | { | 327 | { |
328 | funds = 0; | 328 | funds = 0; |
329 | } | 329 | } |
330 | 330 | ||
331 | m_KnownClientFunds[agentID] = funds; | 331 | m_KnownClientFunds[agentID] = funds; |
332 | } | 332 | } |
333 | else | 333 | else |
334 | { | 334 | { |
335 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, | 335 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, |
336 | (string) hbinfo["errorMessage"]); | 336 | (string) hbinfo["errorMessage"]); |
337 | client.SendAlertMessage((string) hbinfo["errorMessage"]); | 337 | client.SendAlertMessage((string) hbinfo["errorMessage"]); |
338 | } | 338 | } |
339 | SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero); | 339 | SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero); |
340 | } | 340 | } |
341 | } | 341 | } |
342 | } | 342 | } |
343 | else | 343 | else |
344 | { | 344 | { |
345 | CheckExistAndRefreshFunds(client.AgentId); | 345 | CheckExistAndRefreshFunds(client.AgentId); |
346 | } | 346 | } |
347 | 347 | ||
348 | // Subscribe to Money messages | 348 | // Subscribe to Money messages |
349 | client.OnEconomyDataRequest += EconomyDataRequestHandler; | 349 | client.OnEconomyDataRequest += EconomyDataRequestHandler; |
350 | client.OnMoneyBalanceRequest += SendMoneyBalance; | 350 | client.OnMoneyBalanceRequest += SendMoneyBalance; |
351 | client.OnRequestPayPrice += requestPayPrice; | 351 | client.OnRequestPayPrice += requestPayPrice; |
352 | client.OnLogout += ClientClosed; | 352 | client.OnLogout += ClientClosed; |
353 | } | 353 | } |
354 | 354 | ||
355 | /// <summary> | 355 | /// <summary> |
356 | /// Transfer money | 356 | /// Transfer money |
357 | /// </summary> | 357 | /// </summary> |
358 | /// <param name="Sender"></param> | 358 | /// <param name="Sender"></param> |
359 | /// <param name="Receiver"></param> | 359 | /// <param name="Receiver"></param> |
360 | /// <param name="amount"></param> | 360 | /// <param name="amount"></param> |
361 | /// <returns></returns> | 361 | /// <returns></returns> |
362 | private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description) | 362 | private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description) |
363 | { | 363 | { |
364 | bool result = false; | 364 | bool result = false; |
365 | if (amount >= 0) | 365 | if (amount >= 0) |
366 | { | 366 | { |
367 | lock (m_KnownClientFunds) | 367 | lock (m_KnownClientFunds) |
368 | { | 368 | { |
369 | // If we don't know about the sender, then the sender can't | 369 | // If we don't know about the sender, then the sender can't |
370 | // actually be here and therefore this is likely fraud or outdated. | 370 | // actually be here and therefore this is likely fraud or outdated. |
371 | if (m_MoneyAddress.Length == 0) | 371 | if (m_MoneyAddress.Length == 0) |
372 | { | 372 | { |
373 | if (m_KnownClientFunds.ContainsKey(Sender)) | 373 | if (m_KnownClientFunds.ContainsKey(Sender)) |
374 | { | 374 | { |
375 | // Does the sender have enough funds to give? | 375 | // Does the sender have enough funds to give? |
376 | if (m_KnownClientFunds[Sender] >= amount) | 376 | if (m_KnownClientFunds[Sender] >= amount) |
377 | { | 377 | { |
378 | // Subtract the funds from the senders account | 378 | // Subtract the funds from the senders account |
379 | m_KnownClientFunds[Sender] -= amount; | 379 | m_KnownClientFunds[Sender] -= amount; |
380 | 380 | ||
381 | // do we know about the receiver? | 381 | // do we know about the receiver? |
382 | if (!m_KnownClientFunds.ContainsKey(Receiver)) | 382 | if (!m_KnownClientFunds.ContainsKey(Receiver)) |
383 | { | 383 | { |
384 | // Make a record for them so they get the updated balance when they login | 384 | // Make a record for them so they get the updated balance when they login |
385 | CheckExistAndRefreshFunds(Receiver); | 385 | CheckExistAndRefreshFunds(Receiver); |
386 | } | 386 | } |
387 | if (m_enabled) | 387 | if (m_enabled) |
388 | { | 388 | { |
389 | //Add the amount to the Receiver's funds | 389 | //Add the amount to the Receiver's funds |
390 | m_KnownClientFunds[Receiver] += amount; | 390 | m_KnownClientFunds[Receiver] += amount; |
391 | result = true; | 391 | result = true; |
392 | } | 392 | } |
393 | } | 393 | } |
394 | else | 394 | else |
395 | { | 395 | { |
396 | // These below are redundant to make this clearer to read | 396 | // These below are redundant to make this clearer to read |
397 | result = false; | 397 | result = false; |
398 | } | 398 | } |
399 | } | 399 | } |
400 | else | 400 | else |
401 | { | 401 | { |
402 | result = false; | 402 | result = false; |
403 | } | 403 | } |
404 | } | 404 | } |
405 | else | 405 | else |
406 | { | 406 | { |
407 | result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description); | 407 | result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description); |
408 | } | 408 | } |
409 | } | 409 | } |
410 | } | 410 | } |
411 | return result; | 411 | return result; |
412 | } | 412 | } |
413 | 413 | ||
414 | 414 | ||
415 | /// <summary> | 415 | /// <summary> |
416 | /// Sends the the stored money balance to the client | 416 | /// Sends the the stored money balance to the client |
417 | /// </summary> | 417 | /// </summary> |
418 | /// <param name="client"></param> | 418 | /// <param name="client"></param> |
419 | /// <param name="agentID"></param> | 419 | /// <param name="agentID"></param> |
420 | /// <param name="SessionID"></param> | 420 | /// <param name="SessionID"></param> |
421 | /// <param name="TransactionID"></param> | 421 | /// <param name="TransactionID"></param> |
422 | public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID) | 422 | public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID) |
423 | { | 423 | { |
424 | if (client.AgentId == agentID && client.SessionId == SessionID) | 424 | if (client.AgentId == agentID && client.SessionId == SessionID) |
425 | { | 425 | { |
426 | int returnfunds = 0; | 426 | int returnfunds = 0; |
427 | 427 | ||
428 | try | 428 | try |
429 | { | 429 | { |
430 | returnfunds = GetFundsForAgentID(agentID); | 430 | returnfunds = GetFundsForAgentID(agentID); |
431 | } | 431 | } |
432 | catch (Exception e) | 432 | catch (Exception e) |
433 | { | 433 | { |
434 | client.SendAlertMessage(e.Message + " "); | 434 | client.SendAlertMessage(e.Message + " "); |
435 | } | 435 | } |
436 | 436 | ||
437 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); | 437 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); |
438 | } | 438 | } |
439 | else | 439 | else |
440 | { | 440 | { |
441 | client.SendAlertMessage("Unable to send your money balance to you!"); | 441 | client.SendAlertMessage("Unable to send your money balance to you!"); |
442 | } | 442 | } |
443 | } | 443 | } |
444 | 444 | ||
445 | /// <summary> | 445 | /// <summary> |
446 | /// Gets the current balance for the user from the Grid Money Server | 446 | /// Gets the current balance for the user from the Grid Money Server |
447 | /// </summary> | 447 | /// </summary> |
448 | /// <param name="agentId"></param> | 448 | /// <param name="agentId"></param> |
449 | /// <param name="secureSessionID"></param> | 449 | /// <param name="secureSessionID"></param> |
450 | /// <param name="regionId"></param> | 450 | /// <param name="regionId"></param> |
451 | /// <param name="regionSecret"></param> | 451 | /// <param name="regionSecret"></param> |
452 | /// <returns></returns> | 452 | /// <returns></returns> |
453 | public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) | 453 | public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) |
454 | { | 454 | { |
455 | Hashtable MoneyBalanceRequestParams = new Hashtable(); | 455 | Hashtable MoneyBalanceRequestParams = new Hashtable(); |
456 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); | 456 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); |
457 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); | 457 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); |
458 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); | 458 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); |
459 | MoneyBalanceRequestParams["secret"] = regionSecret; | 459 | MoneyBalanceRequestParams["secret"] = regionSecret; |
460 | MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system | 460 | MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system |
461 | 461 | ||
462 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest"); | 462 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest"); |
463 | 463 | ||
464 | return MoneyRespData; | 464 | return MoneyRespData; |
465 | } | 465 | } |
466 | 466 | ||
467 | 467 | ||
468 | /// <summary> | 468 | /// <summary> |
469 | /// Generic XMLRPC client abstraction | 469 | /// Generic XMLRPC client abstraction |
470 | /// </summary> | 470 | /// </summary> |
471 | /// <param name="ReqParams">Hashtable containing parameters to the method</param> | 471 | /// <param name="ReqParams">Hashtable containing parameters to the method</param> |
472 | /// <param name="method">Method to invoke</param> | 472 | /// <param name="method">Method to invoke</param> |
473 | /// <returns>Hashtable with success=>bool and other values</returns> | 473 | /// <returns>Hashtable with success=>bool and other values</returns> |
474 | public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method) | 474 | public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method) |
475 | { | 475 | { |
476 | ArrayList SendParams = new ArrayList(); | 476 | ArrayList SendParams = new ArrayList(); |
477 | SendParams.Add(ReqParams); | 477 | SendParams.Add(ReqParams); |
478 | // Send Request | 478 | // Send Request |
479 | XmlRpcResponse MoneyResp; | 479 | XmlRpcResponse MoneyResp; |
480 | try | 480 | try |
481 | { | 481 | { |
482 | XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams); | 482 | XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams); |
483 | MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000); | 483 | MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000); |
484 | } | 484 | } |
485 | catch (WebException ex) | 485 | catch (WebException ex) |
486 | { | 486 | { |
487 | m_log.ErrorFormat( | 487 | m_log.ErrorFormat( |
488 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", | 488 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", |
489 | m_MoneyAddress, ex); | 489 | m_MoneyAddress, ex); |
490 | 490 | ||
491 | Hashtable ErrorHash = new Hashtable(); | 491 | Hashtable ErrorHash = new Hashtable(); |
492 | ErrorHash["success"] = false; | 492 | ErrorHash["success"] = false; |
493 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 493 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
494 | ErrorHash["errorURI"] = ""; | 494 | ErrorHash["errorURI"] = ""; |
495 | 495 | ||
496 | return ErrorHash; | 496 | return ErrorHash; |
497 | //throw (ex); | 497 | //throw (ex); |
498 | } | 498 | } |
499 | catch (SocketException ex) | 499 | catch (SocketException ex) |
500 | { | 500 | { |
501 | m_log.ErrorFormat( | 501 | m_log.ErrorFormat( |
502 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", | 502 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", |
503 | m_MoneyAddress, ex); | 503 | m_MoneyAddress, ex); |
504 | 504 | ||
505 | Hashtable ErrorHash = new Hashtable(); | 505 | Hashtable ErrorHash = new Hashtable(); |
506 | ErrorHash["success"] = false; | 506 | ErrorHash["success"] = false; |
507 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 507 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
508 | ErrorHash["errorURI"] = ""; | 508 | ErrorHash["errorURI"] = ""; |
509 | 509 | ||
510 | return ErrorHash; | 510 | return ErrorHash; |
511 | //throw (ex); | 511 | //throw (ex); |
512 | } | 512 | } |
513 | catch (XmlException ex) | 513 | catch (XmlException ex) |
514 | { | 514 | { |
515 | m_log.ErrorFormat( | 515 | m_log.ErrorFormat( |
516 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", | 516 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", |
517 | m_MoneyAddress, ex); | 517 | m_MoneyAddress, ex); |
518 | 518 | ||
519 | Hashtable ErrorHash = new Hashtable(); | 519 | Hashtable ErrorHash = new Hashtable(); |
520 | ErrorHash["success"] = false; | 520 | ErrorHash["success"] = false; |
521 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 521 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
522 | ErrorHash["errorURI"] = ""; | 522 | ErrorHash["errorURI"] = ""; |
523 | 523 | ||
524 | return ErrorHash; | 524 | return ErrorHash; |
525 | } | 525 | } |
526 | if (MoneyResp.IsFault) | 526 | if (MoneyResp.IsFault) |
527 | { | 527 | { |
528 | Hashtable ErrorHash = new Hashtable(); | 528 | Hashtable ErrorHash = new Hashtable(); |
529 | ErrorHash["success"] = false; | 529 | ErrorHash["success"] = false; |
530 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 530 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
531 | ErrorHash["errorURI"] = ""; | 531 | ErrorHash["errorURI"] = ""; |
532 | 532 | ||
533 | return ErrorHash; | 533 | return ErrorHash; |
534 | } | 534 | } |
535 | Hashtable MoneyRespData = (Hashtable) MoneyResp.Value; | 535 | Hashtable MoneyRespData = (Hashtable) MoneyResp.Value; |
536 | 536 | ||
537 | return MoneyRespData; | 537 | return MoneyRespData; |
538 | } | 538 | } |
539 | 539 | ||
540 | /// <summary> | 540 | /// <summary> |
541 | /// This informs the Money Grid Server that the avatar is in this simulator | 541 | /// This informs the Money Grid Server that the avatar is in this simulator |
542 | /// </summary> | 542 | /// </summary> |
543 | /// <param name="agentId"></param> | 543 | /// <param name="agentId"></param> |
544 | /// <param name="secureSessionID"></param> | 544 | /// <param name="secureSessionID"></param> |
545 | /// <param name="regionId"></param> | 545 | /// <param name="regionId"></param> |
546 | /// <param name="regionSecret"></param> | 546 | /// <param name="regionSecret"></param> |
547 | /// <returns></returns> | 547 | /// <returns></returns> |
548 | public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) | 548 | public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) |
549 | { | 549 | { |
550 | Hashtable MoneyBalanceRequestParams = new Hashtable(); | 550 | Hashtable MoneyBalanceRequestParams = new Hashtable(); |
551 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); | 551 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); |
552 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); | 552 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); |
553 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); | 553 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); |
554 | MoneyBalanceRequestParams["secret"] = regionSecret; | 554 | MoneyBalanceRequestParams["secret"] = regionSecret; |
555 | 555 | ||
556 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest"); | 556 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest"); |
557 | IClientAPI sendMoneyBal = LocateClientObject(agentId); | 557 | IClientAPI sendMoneyBal = LocateClientObject(agentId); |
558 | if (sendMoneyBal != null) | 558 | if (sendMoneyBal != null) |
559 | { | 559 | { |
560 | SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero); | 560 | SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero); |
561 | } | 561 | } |
562 | return MoneyRespData; | 562 | return MoneyRespData; |
563 | } | 563 | } |
564 | 564 | ||
565 | private SceneObjectPart findPrim(LLUUID objectID) | 565 | private SceneObjectPart findPrim(LLUUID objectID) |
566 | { | 566 | { |
567 | lock (m_scenel) | 567 | lock (m_scenel) |
568 | { | 568 | { |
569 | foreach (Scene s in m_scenel.Values) | 569 | foreach (Scene s in m_scenel.Values) |
570 | { | 570 | { |
571 | SceneObjectPart part = s.GetSceneObjectPart(objectID); | 571 | SceneObjectPart part = s.GetSceneObjectPart(objectID); |
572 | if (part != null) | 572 | if (part != null) |
573 | { | 573 | { |
574 | return part; | 574 | return part; |
575 | } | 575 | } |
576 | } | 576 | } |
577 | } | 577 | } |
578 | return null; | 578 | return null; |
579 | } | 579 | } |
580 | 580 | ||
581 | private string resolveObjectName(LLUUID objectID) | 581 | private string resolveObjectName(LLUUID objectID) |
582 | { | 582 | { |
583 | SceneObjectPart part = findPrim(objectID); | 583 | SceneObjectPart part = findPrim(objectID); |
584 | if (part != null) | 584 | if (part != null) |
585 | { | 585 | { |
586 | return part.Name; | 586 | return part.Name; |
587 | } | 587 | } |
588 | return String.Empty; | 588 | return String.Empty; |
589 | } | 589 | } |
590 | 590 | ||
591 | private string resolveAgentName(LLUUID agentID) | 591 | private string resolveAgentName(LLUUID agentID) |
592 | { | 592 | { |
593 | // try avatar username surname | 593 | // try avatar username surname |
594 | Scene scene = GetRandomScene(); | 594 | Scene scene = GetRandomScene(); |
595 | UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID); | 595 | UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID); |
596 | if (profile != null) | 596 | if (profile != null) |
597 | { | 597 | { |
598 | string avatarname = profile.FirstName + " " + profile.SurName; | 598 | string avatarname = profile.FirstName + " " + profile.SurName; |
599 | return avatarname; | 599 | return avatarname; |
600 | } | 600 | } |
601 | return String.Empty; | 601 | return String.Empty; |
602 | } | 602 | } |
603 | 603 | ||
604 | private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description) | 604 | private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description) |
605 | { | 605 | { |
606 | IClientAPI sender = LocateClientObject(senderID); | 606 | IClientAPI sender = LocateClientObject(senderID); |
607 | IClientAPI receiver = LocateClientObject(receiverID); | 607 | IClientAPI receiver = LocateClientObject(receiverID); |
608 | 608 | ||
609 | if (senderID != receiverID) | 609 | if (senderID != receiverID) |
610 | { | 610 | { |
611 | if (sender != null) | 611 | if (sender != null) |
612 | { | 612 | { |
613 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID)); | 613 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID)); |
614 | } | 614 | } |
615 | 615 | ||
616 | if (receiver != null) | 616 | if (receiver != null) |
617 | { | 617 | { |
618 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID)); | 618 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID)); |
619 | } | 619 | } |
620 | } | 620 | } |
621 | } | 621 | } |
622 | 622 | ||
623 | /// <summary> | 623 | /// <summary> |
624 | /// Informs the Money Grid Server of a transfer. | 624 | /// Informs the Money Grid Server of a transfer. |
625 | /// </summary> | 625 | /// </summary> |
626 | /// <param name="sourceId"></param> | 626 | /// <param name="sourceId"></param> |
627 | /// <param name="destId"></param> | 627 | /// <param name="destId"></param> |
628 | /// <param name="amount"></param> | 628 | /// <param name="amount"></param> |
629 | /// <returns></returns> | 629 | /// <returns></returns> |
630 | public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description) | 630 | public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description) |
631 | { | 631 | { |
632 | int aggregatePermInventory = 0; | 632 | int aggregatePermInventory = 0; |
633 | int aggregatePermNextOwner = 0; | 633 | int aggregatePermNextOwner = 0; |
634 | int flags = 0; | 634 | int flags = 0; |
635 | bool rvalue = false; | 635 | bool rvalue = false; |
636 | 636 | ||
637 | IClientAPI cli = LocateClientObject(sourceId); | 637 | IClientAPI cli = LocateClientObject(sourceId); |
638 | if (cli != null) | 638 | if (cli != null) |
639 | { | 639 | { |
640 | Scene userScene = null; | 640 | Scene userScene = null; |
641 | lock (m_rootAgents) | 641 | lock (m_rootAgents) |
642 | { | 642 | { |
643 | userScene = GetSceneByUUID(m_rootAgents[sourceId]); | 643 | userScene = GetSceneByUUID(m_rootAgents[sourceId]); |
644 | } | 644 | } |
645 | if (userScene != null) | 645 | if (userScene != null) |
646 | { | 646 | { |
647 | Hashtable ht = new Hashtable(); | 647 | Hashtable ht = new Hashtable(); |
648 | ht["agentId"] = sourceId.ToString(); | 648 | ht["agentId"] = sourceId.ToString(); |
649 | ht["secureSessionId"] = cli.SecureSessionId.ToString(); | 649 | ht["secureSessionId"] = cli.SecureSessionId.ToString(); |
650 | ht["regionId"] = userScene.RegionInfo.originRegionID.ToString(); | 650 | ht["regionId"] = userScene.RegionInfo.originRegionID.ToString(); |
651 | ht["secret"] = userScene.RegionInfo.regionSecret; | 651 | ht["secret"] = userScene.RegionInfo.regionSecret; |
652 | ht["currencySecret"] = " "; | 652 | ht["currencySecret"] = " "; |
653 | ht["destId"] = destId.ToString(); | 653 | ht["destId"] = destId.ToString(); |
654 | ht["cash"] = amount; | 654 | ht["cash"] = amount; |
655 | ht["aggregatePermInventory"] = aggregatePermInventory; | 655 | ht["aggregatePermInventory"] = aggregatePermInventory; |
656 | ht["aggregatePermNextOwner"] = aggregatePermNextOwner; | 656 | ht["aggregatePermNextOwner"] = aggregatePermNextOwner; |
657 | ht["flags"] = flags; | 657 | ht["flags"] = flags; |
658 | ht["transactionType"] = transactiontype; | 658 | ht["transactionType"] = transactiontype; |
659 | ht["description"] = description; | 659 | ht["description"] = description; |
660 | 660 | ||
661 | Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney"); | 661 | Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney"); |
662 | 662 | ||
663 | if ((bool) hresult["success"] == true) | 663 | if ((bool) hresult["success"] == true) |
664 | { | 664 | { |
665 | int funds1 = 0; | 665 | int funds1 = 0; |
666 | int funds2 = 0; | 666 | int funds2 = 0; |
667 | try | 667 | try |
668 | { | 668 | { |
669 | funds1 = (Int32) hresult["funds"]; | 669 | funds1 = (Int32) hresult["funds"]; |
670 | } | 670 | } |
671 | catch (InvalidCastException) | 671 | catch (InvalidCastException) |
672 | { | 672 | { |
673 | funds1 = 0; | 673 | funds1 = 0; |
674 | } | 674 | } |
675 | SetLocalFundsForAgentID(sourceId, funds1); | 675 | SetLocalFundsForAgentID(sourceId, funds1); |
676 | if (m_KnownClientFunds.ContainsKey(destId)) | 676 | if (m_KnownClientFunds.ContainsKey(destId)) |
677 | { | 677 | { |
678 | try | 678 | try |
679 | { | 679 | { |
680 | funds2 = (Int32) hresult["funds2"]; | 680 | funds2 = (Int32) hresult["funds2"]; |
681 | } | 681 | } |
682 | catch (InvalidCastException) | 682 | catch (InvalidCastException) |
683 | { | 683 | { |
684 | funds2 = 0; | 684 | funds2 = 0; |
685 | } | 685 | } |
686 | SetLocalFundsForAgentID(destId, funds2); | 686 | SetLocalFundsForAgentID(destId, funds2); |
687 | } | 687 | } |
688 | 688 | ||
689 | 689 | ||
690 | rvalue = true; | 690 | rvalue = true; |
691 | } | 691 | } |
692 | else | 692 | else |
693 | { | 693 | { |
694 | cli.SendAgentAlertMessage((string) hresult["errorMessage"], true); | 694 | cli.SendAgentAlertMessage((string) hresult["errorMessage"], true); |
695 | } | 695 | } |
696 | } | 696 | } |
697 | } | 697 | } |
698 | else | 698 | else |
699 | { | 699 | { |
700 | m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString()); | 700 | m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString()); |
701 | } | 701 | } |
702 | 702 | ||
703 | return rvalue; | 703 | return rvalue; |
704 | } | 704 | } |
705 | 705 | ||
706 | public int GetRemoteBalance(LLUUID agentId) | 706 | public int GetRemoteBalance(LLUUID agentId) |
707 | { | 707 | { |
708 | int funds = 0; | 708 | int funds = 0; |
709 | 709 | ||
710 | IClientAPI aClient = LocateClientObject(agentId); | 710 | IClientAPI aClient = LocateClientObject(agentId); |
711 | if (aClient != null) | 711 | if (aClient != null) |
712 | { | 712 | { |
713 | Scene s = LocateSceneClientIn(agentId); | 713 | Scene s = LocateSceneClientIn(agentId); |
714 | if (s != null) | 714 | if (s != null) |
715 | { | 715 | { |
716 | if (m_MoneyAddress.Length > 0) | 716 | if (m_MoneyAddress.Length > 0) |
717 | { | 717 | { |
718 | Hashtable hbinfo = | 718 | Hashtable hbinfo = |
719 | GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), | 719 | GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), |
720 | s.RegionInfo.regionSecret); | 720 | s.RegionInfo.regionSecret); |
721 | if ((bool) hbinfo["success"] == true) | 721 | if ((bool) hbinfo["success"] == true) |
722 | { | 722 | { |
723 | try | 723 | try |
724 | { | 724 | { |
725 | funds = (Int32) hbinfo["funds"]; | 725 | funds = (Int32) hbinfo["funds"]; |
726 | } | 726 | } |
727 | catch (ArgumentException) | 727 | catch (ArgumentException) |
728 | { | 728 | { |
729 | } | 729 | } |
730 | catch (FormatException) | 730 | catch (FormatException) |
731 | { | 731 | { |
732 | } | 732 | } |
733 | catch (OverflowException) | 733 | catch (OverflowException) |
734 | { | 734 | { |
735 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId); | 735 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId); |
736 | aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); | 736 | aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); |
737 | } | 737 | } |
738 | catch (InvalidCastException) | 738 | catch (InvalidCastException) |
739 | { | 739 | { |
740 | funds = 0; | 740 | funds = 0; |
741 | } | 741 | } |
742 | } | 742 | } |
743 | else | 743 | else |
744 | { | 744 | { |
745 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, | 745 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, |
746 | (string) hbinfo["errorMessage"]); | 746 | (string) hbinfo["errorMessage"]); |
747 | aClient.SendAlertMessage((string) hbinfo["errorMessage"]); | 747 | aClient.SendAlertMessage((string) hbinfo["errorMessage"]); |
748 | } | 748 | } |
749 | } | 749 | } |
750 | 750 | ||
751 | SetLocalFundsForAgentID(agentId, funds); | 751 | SetLocalFundsForAgentID(agentId, funds); |
752 | SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero); | 752 | SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero); |
753 | } | 753 | } |
754 | else | 754 | else |
755 | { | 755 | { |
756 | m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene."); | 756 | m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene."); |
757 | } | 757 | } |
758 | } | 758 | } |
759 | else | 759 | else |
760 | { | 760 | { |
761 | m_log.Debug("[MONEY]: Got balance request update for agent that isn't here."); | 761 | m_log.Debug("[MONEY]: Got balance request update for agent that isn't here."); |
762 | } | 762 | } |
763 | return funds; | 763 | return funds; |
764 | } | 764 | } |
765 | 765 | ||
766 | public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request) | 766 | public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request) |
767 | { | 767 | { |
768 | m_log.Debug("[MONEY]: Dynamic balance update called."); | 768 | m_log.Debug("[MONEY]: Dynamic balance update called."); |
769 | Hashtable requestData = (Hashtable) request.Params[0]; | 769 | Hashtable requestData = (Hashtable) request.Params[0]; |
770 | 770 | ||
771 | if (requestData.ContainsKey("agentId")) | 771 | if (requestData.ContainsKey("agentId")) |
772 | { | 772 | { |
773 | LLUUID agentId = LLUUID.Zero; | 773 | LLUUID agentId = LLUUID.Zero; |
774 | 774 | ||
775 | Helpers.TryParse((string) requestData["agentId"], out agentId); | 775 | Helpers.TryParse((string) requestData["agentId"], out agentId); |
776 | if (agentId != LLUUID.Zero) | 776 | if (agentId != LLUUID.Zero) |
777 | { | 777 | { |
778 | GetRemoteBalance(agentId); | 778 | GetRemoteBalance(agentId); |
779 | } | 779 | } |
780 | else | 780 | else |
781 | { | 781 | { |
782 | m_log.Debug("[MONEY]: invalid agentId specified, dropping."); | 782 | m_log.Debug("[MONEY]: invalid agentId specified, dropping."); |
783 | } | 783 | } |
784 | } | 784 | } |
785 | else | 785 | else |
786 | { | 786 | { |
787 | m_log.Debug("[MONEY]: no agentId specified, dropping."); | 787 | m_log.Debug("[MONEY]: no agentId specified, dropping."); |
788 | } | 788 | } |
789 | XmlRpcResponse r = new XmlRpcResponse(); | 789 | XmlRpcResponse r = new XmlRpcResponse(); |
790 | Hashtable rparms = new Hashtable(); | 790 | Hashtable rparms = new Hashtable(); |
791 | rparms["success"] = true; | 791 | rparms["success"] = true; |
792 | 792 | ||
793 | r.Value = rparms; | 793 | r.Value = rparms; |
794 | return r; | 794 | return r; |
795 | } | 795 | } |
796 | 796 | ||
797 | /// <summary> | 797 | /// <summary> |
798 | /// XMLRPC handler to send alert message and sound to client | 798 | /// XMLRPC handler to send alert message and sound to client |
799 | /// </summary> | 799 | /// </summary> |
800 | public XmlRpcResponse UserAlert(XmlRpcRequest request) | 800 | public XmlRpcResponse UserAlert(XmlRpcRequest request) |
801 | { | 801 | { |
802 | XmlRpcResponse ret = new XmlRpcResponse(); | 802 | XmlRpcResponse ret = new XmlRpcResponse(); |
803 | Hashtable retparam = new Hashtable(); | 803 | Hashtable retparam = new Hashtable(); |
804 | Hashtable requestData = (Hashtable) request.Params[0]; | 804 | Hashtable requestData = (Hashtable) request.Params[0]; |
805 | 805 | ||
806 | LLUUID agentId = LLUUID.Zero; | 806 | LLUUID agentId = LLUUID.Zero; |
807 | LLUUID soundId = LLUUID.Zero; | 807 | LLUUID soundId = LLUUID.Zero; |
808 | 808 | ||
809 | Helpers.TryParse((string) requestData["agentId"], out agentId); | 809 | Helpers.TryParse((string) requestData["agentId"], out agentId); |
810 | Helpers.TryParse((string) requestData["soundId"], out soundId); | 810 | Helpers.TryParse((string) requestData["soundId"], out soundId); |
811 | string text = (string) requestData["text"]; | 811 | string text = (string) requestData["text"]; |
812 | string secret = (string) requestData["secret"]; | 812 | string secret = (string) requestData["secret"]; |
813 | 813 | ||
814 | Scene userScene = GetRandomScene(); | 814 | Scene userScene = GetRandomScene(); |
815 | if (userScene.RegionInfo.regionSecret.ToString() == secret) | 815 | if (userScene.RegionInfo.regionSecret.ToString() == secret) |
816 | { | 816 | { |
817 | IClientAPI client = LocateClientObject(agentId); | 817 | IClientAPI client = LocateClientObject(agentId); |
818 | 818 | ||
819 | if (client != null) | 819 | if (client != null) |
820 | { | 820 | { |
821 | if (soundId != LLUUID.Zero) | 821 | if (soundId != LLUUID.Zero) |
822 | client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0); | 822 | client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0); |
823 | client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text); | 823 | client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text); |
824 | retparam.Add("success", true); | 824 | retparam.Add("success", true); |
825 | } | 825 | } |
826 | else | 826 | else |
827 | { | 827 | { |
828 | retparam.Add("success", false); | 828 | retparam.Add("success", false); |
829 | } | 829 | } |
830 | } | 830 | } |
831 | else | 831 | else |
832 | { | 832 | { |
833 | retparam.Add("success", false); | 833 | retparam.Add("success", false); |
834 | } | 834 | } |
835 | ret.Value = retparam; | 835 | ret.Value = retparam; |
836 | 836 | ||
837 | return ret; | 837 | return ret; |
838 | } | 838 | } |
839 | 839 | ||
840 | # region Standalone box enablers only | 840 | # region Standalone box enablers only |
841 | 841 | ||
842 | public XmlRpcResponse quote_func(XmlRpcRequest request) | 842 | public XmlRpcResponse quote_func(XmlRpcRequest request) |
843 | { | 843 | { |
844 | Hashtable requestData = (Hashtable) request.Params[0]; | 844 | Hashtable requestData = (Hashtable) request.Params[0]; |
845 | LLUUID agentId = LLUUID.Zero; | 845 | LLUUID agentId = LLUUID.Zero; |
846 | int amount = 0; | 846 | int amount = 0; |
847 | Hashtable quoteResponse = new Hashtable(); | 847 | Hashtable quoteResponse = new Hashtable(); |
848 | XmlRpcResponse returnval = new XmlRpcResponse(); | 848 | XmlRpcResponse returnval = new XmlRpcResponse(); |
849 | 849 | ||
850 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) | 850 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) |
851 | { | 851 | { |
852 | Helpers.TryParse((string) requestData["agentId"], out agentId); | 852 | Helpers.TryParse((string) requestData["agentId"], out agentId); |
853 | try | 853 | try |
854 | { | 854 | { |
855 | amount = (Int32) requestData["currencyBuy"]; | 855 | amount = (Int32) requestData["currencyBuy"]; |
856 | } | 856 | } |
857 | catch (InvalidCastException) | 857 | catch (InvalidCastException) |
858 | { | 858 | { |
859 | } | 859 | } |
860 | Hashtable currencyResponse = new Hashtable(); | 860 | Hashtable currencyResponse = new Hashtable(); |
861 | currencyResponse.Add("estimatedCost", 0); | 861 | currencyResponse.Add("estimatedCost", 0); |
862 | currencyResponse.Add("currencyBuy", amount); | 862 | currencyResponse.Add("currencyBuy", amount); |
863 | 863 | ||
864 | quoteResponse.Add("success", true); | 864 | quoteResponse.Add("success", true); |
865 | quoteResponse.Add("currency", currencyResponse); | 865 | quoteResponse.Add("currency", currencyResponse); |
866 | quoteResponse.Add("confirm", "asdfad9fj39ma9fj"); | 866 | quoteResponse.Add("confirm", "asdfad9fj39ma9fj"); |
867 | 867 | ||
868 | returnval.Value = quoteResponse; | 868 | returnval.Value = quoteResponse; |
869 | return returnval; | 869 | return returnval; |
870 | } | 870 | } |
871 | 871 | ||
872 | 872 | ||
873 | quoteResponse.Add("success", false); | 873 | quoteResponse.Add("success", false); |
874 | quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box"); | 874 | quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box"); |
875 | quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki"); | 875 | quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki"); |
876 | returnval.Value = quoteResponse; | 876 | returnval.Value = quoteResponse; |
877 | return returnval; | 877 | return returnval; |
878 | } | 878 | } |
879 | 879 | ||
880 | public XmlRpcResponse buy_func(XmlRpcRequest request) | 880 | public XmlRpcResponse buy_func(XmlRpcRequest request) |
881 | { | 881 | { |
882 | Hashtable requestData = (Hashtable) request.Params[0]; | 882 | Hashtable requestData = (Hashtable) request.Params[0]; |
883 | LLUUID agentId = LLUUID.Zero; | 883 | LLUUID agentId = LLUUID.Zero; |
884 | int amount = 0; | 884 | int amount = 0; |
885 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) | 885 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) |
886 | { | 886 | { |
887 | Helpers.TryParse((string) requestData["agentId"], out agentId); | 887 | Helpers.TryParse((string) requestData["agentId"], out agentId); |
888 | try | 888 | try |
889 | { | 889 | { |
890 | amount = (Int32) requestData["currencyBuy"]; | 890 | amount = (Int32) requestData["currencyBuy"]; |
891 | } | 891 | } |
892 | catch (InvalidCastException) | 892 | catch (InvalidCastException) |
893 | { | 893 | { |
894 | } | 894 | } |
895 | if (agentId != LLUUID.Zero) | 895 | if (agentId != LLUUID.Zero) |
896 | { | 896 | { |
897 | lock (m_KnownClientFunds) | 897 | lock (m_KnownClientFunds) |
898 | { | 898 | { |
899 | if (m_KnownClientFunds.ContainsKey(agentId)) | 899 | if (m_KnownClientFunds.ContainsKey(agentId)) |
900 | { | 900 | { |
901 | m_KnownClientFunds[agentId] += amount; | 901 | m_KnownClientFunds[agentId] += amount; |
902 | } | 902 | } |
903 | else | 903 | else |
904 | { | 904 | { |
905 | m_KnownClientFunds.Add(agentId, amount); | 905 | m_KnownClientFunds.Add(agentId, amount); |
906 | } | 906 | } |
907 | } | 907 | } |
908 | IClientAPI client = LocateClientObject(agentId); | 908 | IClientAPI client = LocateClientObject(agentId); |
909 | if (client != null) | 909 | if (client != null) |
910 | { | 910 | { |
911 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); | 911 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); |
912 | } | 912 | } |
913 | } | 913 | } |
914 | } | 914 | } |
915 | XmlRpcResponse returnval = new XmlRpcResponse(); | 915 | XmlRpcResponse returnval = new XmlRpcResponse(); |
916 | Hashtable returnresp = new Hashtable(); | 916 | Hashtable returnresp = new Hashtable(); |
917 | returnresp.Add("success", true); | 917 | returnresp.Add("success", true); |
918 | returnval.Value = returnresp; | 918 | returnval.Value = returnresp; |
919 | return returnval; | 919 | return returnval; |
920 | } | 920 | } |
921 | 921 | ||
922 | public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request) | 922 | public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request) |
923 | { | 923 | { |
924 | XmlRpcResponse ret = new XmlRpcResponse(); | 924 | XmlRpcResponse ret = new XmlRpcResponse(); |
925 | Hashtable retparam = new Hashtable(); | 925 | Hashtable retparam = new Hashtable(); |
926 | Hashtable membershiplevels = new Hashtable(); | 926 | Hashtable membershiplevels = new Hashtable(); |
927 | ArrayList levels = new ArrayList(); | 927 | ArrayList levels = new ArrayList(); |
928 | Hashtable level = new Hashtable(); | 928 | Hashtable level = new Hashtable(); |
929 | level.Add("id", "00000000-0000-0000-0000-000000000000"); | 929 | level.Add("id", "00000000-0000-0000-0000-000000000000"); |
930 | level.Add("description", "some level"); | 930 | level.Add("description", "some level"); |
931 | levels.Add(level); | 931 | levels.Add(level); |
932 | //membershiplevels.Add("levels",levels); | 932 | //membershiplevels.Add("levels",levels); |
933 | 933 | ||
934 | Hashtable landuse = new Hashtable(); | 934 | Hashtable landuse = new Hashtable(); |
935 | landuse.Add("upgrade", false); | 935 | landuse.Add("upgrade", false); |
936 | landuse.Add("action", "http://invaliddomaininvalid.com/"); | 936 | landuse.Add("action", "http://invaliddomaininvalid.com/"); |
937 | 937 | ||
938 | Hashtable currency = new Hashtable(); | 938 | Hashtable currency = new Hashtable(); |
939 | currency.Add("estimatedCost", 0); | 939 | currency.Add("estimatedCost", 0); |
940 | 940 | ||
941 | Hashtable membership = new Hashtable(); | 941 | Hashtable membership = new Hashtable(); |
942 | membershiplevels.Add("upgrade", false); | 942 | membershiplevels.Add("upgrade", false); |
943 | membershiplevels.Add("action", "http://invaliddomaininvalid.com/"); | 943 | membershiplevels.Add("action", "http://invaliddomaininvalid.com/"); |
944 | membershiplevels.Add("levels", membershiplevels); | 944 | membershiplevels.Add("levels", membershiplevels); |
945 | 945 | ||
946 | retparam.Add("success", true); | 946 | retparam.Add("success", true); |
947 | retparam.Add("currency", currency); | 947 | retparam.Add("currency", currency); |
948 | retparam.Add("membership", membership); | 948 | retparam.Add("membership", membership); |
949 | retparam.Add("landuse", landuse); | 949 | retparam.Add("landuse", landuse); |
950 | retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf"); | 950 | retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf"); |
951 | 951 | ||
952 | ret.Value = retparam; | 952 | ret.Value = retparam; |
953 | 953 | ||
954 | return ret; | 954 | return ret; |
955 | } | 955 | } |
956 | 956 | ||
957 | public XmlRpcResponse landBuy_func(XmlRpcRequest request) | 957 | public XmlRpcResponse landBuy_func(XmlRpcRequest request) |
958 | { | 958 | { |
959 | XmlRpcResponse ret = new XmlRpcResponse(); | 959 | XmlRpcResponse ret = new XmlRpcResponse(); |
960 | Hashtable retparam = new Hashtable(); | 960 | Hashtable retparam = new Hashtable(); |
961 | Hashtable requestData = (Hashtable) request.Params[0]; | 961 | Hashtable requestData = (Hashtable) request.Params[0]; |
962 | 962 | ||
963 | LLUUID agentId = LLUUID.Zero; | 963 | LLUUID agentId = LLUUID.Zero; |
964 | int amount = 0; | 964 | int amount = 0; |
965 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) | 965 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) |
966 | { | 966 | { |
967 | Helpers.TryParse((string) requestData["agentId"], out agentId); | 967 | Helpers.TryParse((string) requestData["agentId"], out agentId); |
968 | try | 968 | try |
969 | { | 969 | { |
970 | amount = (Int32) requestData["currencyBuy"]; | 970 | amount = (Int32) requestData["currencyBuy"]; |
971 | } | 971 | } |
972 | catch (InvalidCastException) | 972 | catch (InvalidCastException) |
973 | { | 973 | { |
974 | } | 974 | } |
975 | if (agentId != LLUUID.Zero) | 975 | if (agentId != LLUUID.Zero) |
976 | { | 976 | { |
977 | lock (m_KnownClientFunds) | 977 | lock (m_KnownClientFunds) |
978 | { | 978 | { |
979 | if (m_KnownClientFunds.ContainsKey(agentId)) | 979 | if (m_KnownClientFunds.ContainsKey(agentId)) |
980 | { | 980 | { |
981 | m_KnownClientFunds[agentId] += amount; | 981 | m_KnownClientFunds[agentId] += amount; |
982 | } | 982 | } |
983 | else | 983 | else |
984 | { | 984 | { |
985 | m_KnownClientFunds.Add(agentId, amount); | 985 | m_KnownClientFunds.Add(agentId, amount); |
986 | } | 986 | } |
987 | } | 987 | } |
988 | IClientAPI client = LocateClientObject(agentId); | 988 | IClientAPI client = LocateClientObject(agentId); |
989 | if (client != null) | 989 | if (client != null) |
990 | { | 990 | { |
991 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); | 991 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); |
992 | } | 992 | } |
993 | } | 993 | } |
994 | } | 994 | } |
995 | retparam.Add("success", true); | 995 | retparam.Add("success", true); |
996 | ret.Value = retparam; | 996 | ret.Value = retparam; |
997 | 997 | ||
998 | return ret; | 998 | return ret; |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | #endregion | 1001 | #endregion |
1002 | 1002 | ||
1003 | #region local Fund Management | 1003 | #region local Fund Management |
1004 | 1004 | ||
1005 | /// <summary> | 1005 | /// <summary> |
1006 | /// Ensures that the agent accounting data is set up in this instance. | 1006 | /// Ensures that the agent accounting data is set up in this instance. |
1007 | /// </summary> | 1007 | /// </summary> |
1008 | /// <param name="agentID"></param> | 1008 | /// <param name="agentID"></param> |
1009 | private void CheckExistAndRefreshFunds(LLUUID agentID) | 1009 | private void CheckExistAndRefreshFunds(LLUUID agentID) |
1010 | { | 1010 | { |
1011 | lock (m_KnownClientFunds) | 1011 | lock (m_KnownClientFunds) |
1012 | { | 1012 | { |
1013 | if (!m_KnownClientFunds.ContainsKey(agentID)) | 1013 | if (!m_KnownClientFunds.ContainsKey(agentID)) |
1014 | { | 1014 | { |
1015 | m_KnownClientFunds.Add(agentID, m_stipend); | 1015 | m_KnownClientFunds.Add(agentID, m_stipend); |
1016 | } | 1016 | } |
1017 | else | 1017 | else |
1018 | { | 1018 | { |
1019 | if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh) | 1019 | if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh) |
1020 | { | 1020 | { |
1021 | m_KnownClientFunds[agentID] = m_stipend; | 1021 | m_KnownClientFunds[agentID] = m_stipend; |
1022 | } | 1022 | } |
1023 | } | 1023 | } |
1024 | } | 1024 | } |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | /// <summary> | 1027 | /// <summary> |
1028 | /// Gets the amount of Funds for an agent | 1028 | /// Gets the amount of Funds for an agent |
1029 | /// </summary> | 1029 | /// </summary> |
1030 | /// <param name="AgentID"></param> | 1030 | /// <param name="AgentID"></param> |
1031 | /// <returns></returns> | 1031 | /// <returns></returns> |
1032 | private int GetFundsForAgentID(LLUUID AgentID) | 1032 | private int GetFundsForAgentID(LLUUID AgentID) |
1033 | { | 1033 | { |
1034 | int returnfunds = 0; | 1034 | int returnfunds = 0; |
1035 | lock (m_KnownClientFunds) | 1035 | lock (m_KnownClientFunds) |
1036 | { | 1036 | { |
1037 | if (m_KnownClientFunds.ContainsKey(AgentID)) | 1037 | if (m_KnownClientFunds.ContainsKey(AgentID)) |
1038 | { | 1038 | { |
1039 | returnfunds = m_KnownClientFunds[AgentID]; | 1039 | returnfunds = m_KnownClientFunds[AgentID]; |
1040 | } | 1040 | } |
1041 | else | 1041 | else |
1042 | { | 1042 | { |
1043 | //throw new Exception("Unable to get funds."); | 1043 | //throw new Exception("Unable to get funds."); |
1044 | } | 1044 | } |
1045 | } | 1045 | } |
1046 | return returnfunds; | 1046 | return returnfunds; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | private void SetLocalFundsForAgentID(LLUUID AgentID, int amount) | 1049 | private void SetLocalFundsForAgentID(LLUUID AgentID, int amount) |
1050 | { | 1050 | { |
1051 | lock (m_KnownClientFunds) | 1051 | lock (m_KnownClientFunds) |
1052 | { | 1052 | { |
1053 | if (m_KnownClientFunds.ContainsKey(AgentID)) | 1053 | if (m_KnownClientFunds.ContainsKey(AgentID)) |
1054 | { | 1054 | { |
1055 | m_KnownClientFunds[AgentID] = amount; | 1055 | m_KnownClientFunds[AgentID] = amount; |
1056 | } | 1056 | } |
1057 | else | 1057 | else |
1058 | { | 1058 | { |
1059 | m_KnownClientFunds.Add(AgentID, amount); | 1059 | m_KnownClientFunds.Add(AgentID, amount); |
1060 | } | 1060 | } |
1061 | } | 1061 | } |
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | #endregion | 1064 | #endregion |
1065 | 1065 | ||
1066 | #region Utility Helpers | 1066 | #region Utility Helpers |
1067 | 1067 | ||
1068 | /// <summary> | 1068 | /// <summary> |
1069 | /// Locates a IClientAPI for the client specified | 1069 | /// Locates a IClientAPI for the client specified |
1070 | /// </summary> | 1070 | /// </summary> |
1071 | /// <param name="AgentID"></param> | 1071 | /// <param name="AgentID"></param> |
1072 | /// <returns></returns> | 1072 | /// <returns></returns> |
1073 | private IClientAPI LocateClientObject(LLUUID AgentID) | 1073 | private IClientAPI LocateClientObject(LLUUID AgentID) |
1074 | { | 1074 | { |
1075 | ScenePresence tPresence = null; | 1075 | ScenePresence tPresence = null; |
1076 | IClientAPI rclient = null; | 1076 | IClientAPI rclient = null; |
1077 | 1077 | ||
1078 | lock (m_scenel) | 1078 | lock (m_scenel) |
1079 | { | 1079 | { |
1080 | foreach (Scene _scene in m_scenel.Values) | 1080 | foreach (Scene _scene in m_scenel.Values) |
1081 | { | 1081 | { |
1082 | tPresence = _scene.GetScenePresence(AgentID); | 1082 | tPresence = _scene.GetScenePresence(AgentID); |
1083 | if (tPresence != null) | 1083 | if (tPresence != null) |
1084 | { | 1084 | { |
1085 | if (!tPresence.IsChildAgent) | 1085 | if (!tPresence.IsChildAgent) |
1086 | { | 1086 | { |
1087 | rclient = tPresence.ControllingClient; | 1087 | rclient = tPresence.ControllingClient; |
1088 | } | 1088 | } |
1089 | } | 1089 | } |
1090 | if (rclient != null) | 1090 | if (rclient != null) |
1091 | { | 1091 | { |
1092 | return rclient; | 1092 | return rclient; |
1093 | } | 1093 | } |
1094 | } | 1094 | } |
1095 | } | 1095 | } |
1096 | return null; | 1096 | return null; |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | private Scene LocateSceneClientIn(LLUUID AgentId) | 1099 | private Scene LocateSceneClientIn(LLUUID AgentId) |
1100 | { | 1100 | { |
1101 | lock (m_scenel) | 1101 | lock (m_scenel) |
1102 | { | 1102 | { |
1103 | foreach (Scene _scene in m_scenel.Values) | 1103 | foreach (Scene _scene in m_scenel.Values) |
1104 | { | 1104 | { |
1105 | ScenePresence tPresence = _scene.GetScenePresence(AgentId); | 1105 | ScenePresence tPresence = _scene.GetScenePresence(AgentId); |
1106 | if (tPresence != null) | 1106 | if (tPresence != null) |
1107 | { | 1107 | { |
1108 | if (!tPresence.IsChildAgent) | 1108 | if (!tPresence.IsChildAgent) |
1109 | { | 1109 | { |
1110 | return _scene; | 1110 | return _scene; |
1111 | } | 1111 | } |
1112 | } | 1112 | } |
1113 | } | 1113 | } |
1114 | } | 1114 | } |
1115 | return null; | 1115 | return null; |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | /// <summary> | 1118 | /// <summary> |
1119 | /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter | 1119 | /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter |
1120 | /// </summary> | 1120 | /// </summary> |
1121 | /// <returns></returns> | 1121 | /// <returns></returns> |
1122 | public Scene GetRandomScene() | 1122 | public Scene GetRandomScene() |
1123 | { | 1123 | { |
1124 | lock (m_scenel) | 1124 | lock (m_scenel) |
1125 | { | 1125 | { |
1126 | foreach (Scene rs in m_scenel.Values) | 1126 | foreach (Scene rs in m_scenel.Values) |
1127 | return rs; | 1127 | return rs; |
1128 | } | 1128 | } |
1129 | return null; | 1129 | return null; |
1130 | } | 1130 | } |
1131 | 1131 | ||
1132 | /// <summary> | 1132 | /// <summary> |
1133 | /// Utility function to get a Scene by RegionID in a module | 1133 | /// Utility function to get a Scene by RegionID in a module |
1134 | /// </summary> | 1134 | /// </summary> |
1135 | /// <param name="RegionID"></param> | 1135 | /// <param name="RegionID"></param> |
1136 | /// <returns></returns> | 1136 | /// <returns></returns> |
1137 | public Scene GetSceneByUUID(LLUUID RegionID) | 1137 | public Scene GetSceneByUUID(LLUUID RegionID) |
1138 | { | 1138 | { |
1139 | lock (m_scenel) | 1139 | lock (m_scenel) |
1140 | { | 1140 | { |
1141 | foreach (Scene rs in m_scenel.Values) | 1141 | foreach (Scene rs in m_scenel.Values) |
1142 | { | 1142 | { |
1143 | if (rs.RegionInfo.originRegionID == RegionID) | 1143 | if (rs.RegionInfo.originRegionID == RegionID) |
1144 | { | 1144 | { |
1145 | return rs; | 1145 | return rs; |
1146 | } | 1146 | } |
1147 | } | 1147 | } |
1148 | } | 1148 | } |
1149 | return null; | 1149 | return null; |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | #endregion | 1152 | #endregion |
1153 | 1153 | ||
1154 | #region event Handlers | 1154 | #region event Handlers |
1155 | 1155 | ||
1156 | public void requestPayPrice(IClientAPI client, LLUUID objectID) | 1156 | public void requestPayPrice(IClientAPI client, LLUUID objectID) |
1157 | { | 1157 | { |
1158 | Scene scene = LocateSceneClientIn(client.AgentId); | 1158 | Scene scene = LocateSceneClientIn(client.AgentId); |
1159 | if (scene == null) | 1159 | if (scene == null) |
1160 | return; | 1160 | return; |
1161 | 1161 | ||
1162 | SceneObjectPart task = scene.GetSceneObjectPart(objectID); | 1162 | SceneObjectPart task = scene.GetSceneObjectPart(objectID); |
1163 | if (task == null) | 1163 | if (task == null) |
1164 | return; | 1164 | return; |
1165 | SceneObjectGroup group = task.ParentGroup; | 1165 | SceneObjectGroup group = task.ParentGroup; |
1166 | SceneObjectPart root = group.RootPart; | 1166 | SceneObjectPart root = group.RootPart; |
1167 | 1167 | ||
1168 | client.SendPayPrice(objectID, root.PayPrice); | 1168 | client.SendPayPrice(objectID, root.PayPrice); |
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | /// <summary> | 1171 | /// <summary> |
1172 | /// When the client closes the connection we remove their accounting info from memory to free up resources. | 1172 | /// When the client closes the connection we remove their accounting info from memory to free up resources. |
1173 | /// </summary> | 1173 | /// </summary> |
1174 | /// <param name="AgentID"></param> | 1174 | /// <param name="AgentID"></param> |
1175 | public void ClientClosed(LLUUID AgentID) | 1175 | public void ClientClosed(LLUUID AgentID) |
1176 | { | 1176 | { |
1177 | lock (m_KnownClientFunds) | 1177 | lock (m_KnownClientFunds) |
1178 | { | 1178 | { |
1179 | if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0) | 1179 | if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0) |
1180 | { | 1180 | { |
1181 | } | 1181 | } |
1182 | else | 1182 | else |
1183 | { | 1183 | { |
1184 | m_KnownClientFunds.Remove(AgentID); | 1184 | m_KnownClientFunds.Remove(AgentID); |
1185 | } | 1185 | } |
1186 | } | 1186 | } |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | /// <summary> | 1189 | /// <summary> |
1190 | /// Event called Economy Data Request handler. | 1190 | /// Event called Economy Data Request handler. |
1191 | /// </summary> | 1191 | /// </summary> |
1192 | /// <param name="agentId"></param> | 1192 | /// <param name="agentId"></param> |
1193 | public void EconomyDataRequestHandler(LLUUID agentId) | 1193 | public void EconomyDataRequestHandler(LLUUID agentId) |
1194 | { | 1194 | { |
1195 | IClientAPI user = LocateClientObject(agentId); | 1195 | IClientAPI user = LocateClientObject(agentId); |
1196 | 1196 | ||
1197 | if (user != null) | 1197 | if (user != null) |
1198 | { | 1198 | { |
1199 | user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, | 1199 | user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, |
1200 | PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, | 1200 | PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, |
1201 | PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, | 1201 | PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, |
1202 | TeleportMinPrice, TeleportPriceExponent); | 1202 | TeleportMinPrice, TeleportPriceExponent); |
1203 | } | 1203 | } |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | private void ValidateLandBuy(Object osender, EventManager.LandBuyArgs e) | 1206 | private void ValidateLandBuy(Object osender, EventManager.LandBuyArgs e) |
1207 | { | 1207 | { |
1208 | if (m_MoneyAddress.Length == 0) | 1208 | if (m_MoneyAddress.Length == 0) |
1209 | { | 1209 | { |
1210 | lock (m_KnownClientFunds) | 1210 | lock (m_KnownClientFunds) |
1211 | { | 1211 | { |
1212 | if (m_KnownClientFunds.ContainsKey(e.agentId)) | 1212 | if (m_KnownClientFunds.ContainsKey(e.agentId)) |
1213 | { | 1213 | { |
1214 | // Does the sender have enough funds to give? | 1214 | // Does the sender have enough funds to give? |
1215 | if (m_KnownClientFunds[e.agentId] >= e.parcelPrice) | 1215 | if (m_KnownClientFunds[e.agentId] >= e.parcelPrice) |
1216 | { | 1216 | { |
1217 | lock (e) | 1217 | lock (e) |
1218 | { | 1218 | { |
1219 | e.economyValidated = true; | 1219 | e.economyValidated = true; |
1220 | } | 1220 | } |
1221 | } | 1221 | } |
1222 | } | 1222 | } |
1223 | } | 1223 | } |
1224 | } | 1224 | } |
1225 | else | 1225 | else |
1226 | { | 1226 | { |
1227 | if (GetRemoteBalance(e.agentId) >= e.parcelPrice) | 1227 | if (GetRemoteBalance(e.agentId) >= e.parcelPrice) |
1228 | { | 1228 | { |
1229 | lock (e) | 1229 | lock (e) |
1230 | { | 1230 | { |
1231 | e.economyValidated = true; | 1231 | e.economyValidated = true; |
1232 | } | 1232 | } |
1233 | } | 1233 | } |
1234 | } | 1234 | } |
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | private void processLandBuy(Object osender, EventManager.LandBuyArgs e) | 1237 | private void processLandBuy(Object osender, EventManager.LandBuyArgs e) |
1238 | { | 1238 | { |
1239 | lock (e) | 1239 | lock (e) |
1240 | { | 1240 | { |
1241 | if (e.economyValidated == true && e.transactionID == 0) | 1241 | if (e.economyValidated == true && e.transactionID == 0) |
1242 | { | 1242 | { |
1243 | e.transactionID = Util.UnixTimeSinceEpoch(); | 1243 | e.transactionID = Util.UnixTimeSinceEpoch(); |
1244 | 1244 | ||
1245 | if (doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase")) | 1245 | if (doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase")) |
1246 | { | 1246 | { |
1247 | lock (e) | 1247 | lock (e) |
1248 | { | 1248 | { |
1249 | e.amountDebited = e.parcelPrice; | 1249 | e.amountDebited = e.parcelPrice; |
1250 | } | 1250 | } |
1251 | } | 1251 | } |
1252 | } | 1252 | } |
1253 | } | 1253 | } |
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | /// <summary> | 1256 | /// <summary> |
1257 | /// THis method gets called when someone pays someone else as a gift. | 1257 | /// THis method gets called when someone pays someone else as a gift. |
1258 | /// </summary> | 1258 | /// </summary> |
1259 | /// <param name="osender"></param> | 1259 | /// <param name="osender"></param> |
1260 | /// <param name="e"></param> | 1260 | /// <param name="e"></param> |
1261 | private void MoneyTransferAction(Object osender, EventManager.MoneyTransferArgs e) | 1261 | private void MoneyTransferAction(Object osender, EventManager.MoneyTransferArgs e) |
1262 | { | 1262 | { |
1263 | IClientAPI sender = null; | 1263 | IClientAPI sender = null; |
1264 | IClientAPI receiver = null; | 1264 | IClientAPI receiver = null; |
1265 | 1265 | ||
1266 | if (m_MoneyAddress.Length > 0) // Handled on server | 1266 | if (m_MoneyAddress.Length > 0) // Handled on server |
1267 | e.description = String.Empty; | 1267 | e.description = String.Empty; |
1268 | 1268 | ||
1269 | if (e.transactiontype == 5008) // Object gets paid | 1269 | if (e.transactiontype == 5008) // Object gets paid |
1270 | { | 1270 | { |
1271 | sender = LocateClientObject(e.sender); | 1271 | sender = LocateClientObject(e.sender); |
1272 | if (sender != null) | 1272 | if (sender != null) |
1273 | { | 1273 | { |
1274 | SceneObjectPart part = findPrim(e.receiver); | 1274 | SceneObjectPart part = findPrim(e.receiver); |
1275 | if (part == null) | 1275 | if (part == null) |
1276 | return; | 1276 | return; |
1277 | 1277 | ||
1278 | string name = resolveAgentName(part.OwnerID); | 1278 | string name = resolveAgentName(part.OwnerID); |
1279 | if (name == String.Empty) | 1279 | if (name == String.Empty) |
1280 | name = "(hippos)"; | 1280 | name = "(hippos)"; |
1281 | 1281 | ||
1282 | receiver = LocateClientObject(part.OwnerID); | 1282 | receiver = LocateClientObject(part.OwnerID); |
1283 | 1283 | ||
1284 | string description = String.Format("Paid {0} via object {1}", name, e.description); | 1284 | string description = String.Format("Paid {0} via object {1}", name, e.description); |
1285 | bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description); | 1285 | bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description); |
1286 | 1286 | ||
1287 | if (transactionresult) | 1287 | if (transactionresult) |
1288 | { | 1288 | { |
1289 | ObjectPaid handlerOnObjectPaid = OnObjectPaid; | 1289 | ObjectPaid handlerOnObjectPaid = OnObjectPaid; |
1290 | if (handlerOnObjectPaid != null) | 1290 | if (handlerOnObjectPaid != null) |
1291 | { | 1291 | { |
1292 | handlerOnObjectPaid(e.receiver, e.sender, e.amount); | 1292 | handlerOnObjectPaid(e.receiver, e.sender, e.amount); |
1293 | } | 1293 | } |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | if (e.sender != e.receiver) | 1296 | if (e.sender != e.receiver) |
1297 | { | 1297 | { |
1298 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); | 1298 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); |
1299 | } | 1299 | } |
1300 | if (receiver != null) | 1300 | if (receiver != null) |
1301 | { | 1301 | { |
1302 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID)); | 1302 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID)); |
1303 | } | 1303 | } |
1304 | } | 1304 | } |
1305 | return; | 1305 | return; |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | sender = LocateClientObject(e.sender); | 1308 | sender = LocateClientObject(e.sender); |
1309 | if (sender != null) | 1309 | if (sender != null) |
1310 | { | 1310 | { |
1311 | receiver = LocateClientObject(e.receiver); | 1311 | receiver = LocateClientObject(e.receiver); |
1312 | 1312 | ||
1313 | bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description); | 1313 | bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description); |
1314 | 1314 | ||
1315 | if (e.sender != e.receiver) | 1315 | if (e.sender != e.receiver) |
1316 | { | 1316 | { |
1317 | if (sender != null) | 1317 | if (sender != null) |
1318 | { | 1318 | { |
1319 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); | 1319 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); |
1320 | } | 1320 | } |
1321 | } | 1321 | } |
1322 | 1322 | ||
1323 | if (receiver != null) | 1323 | if (receiver != null) |
1324 | { | 1324 | { |
1325 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver)); | 1325 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver)); |
1326 | } | 1326 | } |
1327 | } | 1327 | } |
1328 | else | 1328 | else |
1329 | { | 1329 | { |
1330 | m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + | 1330 | m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + |
1331 | e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString()); | 1331 | e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString()); |
1332 | } | 1332 | } |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | /// <summary> | 1335 | /// <summary> |
1336 | /// Event Handler for when a root agent becomes a child agent | 1336 | /// Event Handler for when a root agent becomes a child agent |
1337 | /// </summary> | 1337 | /// </summary> |
1338 | /// <param name="avatar"></param> | 1338 | /// <param name="avatar"></param> |
1339 | private void MakeChildAgent(ScenePresence avatar) | 1339 | private void MakeChildAgent(ScenePresence avatar) |
1340 | { | 1340 | { |
1341 | lock (m_rootAgents) | 1341 | lock (m_rootAgents) |
1342 | { | 1342 | { |
1343 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 1343 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
1344 | { | 1344 | { |
1345 | if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID) | 1345 | if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID) |
1346 | { | 1346 | { |
1347 | m_rootAgents.Remove(avatar.UUID); | 1347 | m_rootAgents.Remove(avatar.UUID); |
1348 | m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); | 1348 | m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); |
1349 | } | 1349 | } |
1350 | } | 1350 | } |
1351 | } | 1351 | } |
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | /// <summary> | 1354 | /// <summary> |
1355 | /// Event Handler for when the client logs out. | 1355 | /// Event Handler for when the client logs out. |
1356 | /// </summary> | 1356 | /// </summary> |
1357 | /// <param name="AgentId"></param> | 1357 | /// <param name="AgentId"></param> |
1358 | private void ClientLoggedOut(LLUUID AgentId) | 1358 | private void ClientLoggedOut(LLUUID AgentId) |
1359 | { | 1359 | { |
1360 | lock (m_rootAgents) | 1360 | lock (m_rootAgents) |
1361 | { | 1361 | { |
1362 | if (m_rootAgents.ContainsKey(AgentId)) | 1362 | if (m_rootAgents.ContainsKey(AgentId)) |
1363 | { | 1363 | { |
1364 | m_rootAgents.Remove(AgentId); | 1364 | m_rootAgents.Remove(AgentId); |
1365 | //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out."); | 1365 | //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out."); |
1366 | } | 1366 | } |
1367 | } | 1367 | } |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | /// <summary> | 1370 | /// <summary> |
1371 | /// Call this when the client disconnects. | 1371 | /// Call this when the client disconnects. |
1372 | /// </summary> | 1372 | /// </summary> |
1373 | /// <param name="client"></param> | 1373 | /// <param name="client"></param> |
1374 | public void ClientClosed(IClientAPI client) | 1374 | public void ClientClosed(IClientAPI client) |
1375 | { | 1375 | { |
1376 | ClientClosed(client.AgentId); | 1376 | ClientClosed(client.AgentId); |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | /// <summary> | 1379 | /// <summary> |
1380 | /// Event Handler for when an Avatar enters one of the parcels in the simulator. | 1380 | /// Event Handler for when an Avatar enters one of the parcels in the simulator. |
1381 | /// </summary> | 1381 | /// </summary> |
1382 | /// <param name="avatar"></param> | 1382 | /// <param name="avatar"></param> |
1383 | /// <param name="localLandID"></param> | 1383 | /// <param name="localLandID"></param> |
1384 | /// <param name="regionID"></param> | 1384 | /// <param name="regionID"></param> |
1385 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) | 1385 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) |
1386 | { | 1386 | { |
1387 | lock (m_rootAgents) | 1387 | lock (m_rootAgents) |
1388 | { | 1388 | { |
1389 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 1389 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
1390 | { | 1390 | { |
1391 | if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID]) | 1391 | if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID]) |
1392 | { | 1392 | { |
1393 | m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID; | 1393 | m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID; |
1394 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 1394 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
1395 | // Claim User! my user! Mine mine mine! | 1395 | // Claim User! my user! Mine mine mine! |
1396 | if (m_MoneyAddress.Length > 0) | 1396 | if (m_MoneyAddress.Length > 0) |
1397 | { | 1397 | { |
1398 | Scene RegionItem = GetSceneByUUID(regionID); | 1398 | Scene RegionItem = GetSceneByUUID(regionID); |
1399 | if (RegionItem != null) | 1399 | if (RegionItem != null) |
1400 | { | 1400 | { |
1401 | Hashtable hresult = | 1401 | Hashtable hresult = |
1402 | claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); | 1402 | claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); |
1403 | if ((bool) hresult["success"] == true) | 1403 | if ((bool) hresult["success"] == true) |
1404 | { | 1404 | { |
1405 | int funds = 0; | 1405 | int funds = 0; |
1406 | try | 1406 | try |
1407 | { | 1407 | { |
1408 | funds = (Int32) hresult["funds"]; | 1408 | funds = (Int32) hresult["funds"]; |
1409 | } | 1409 | } |
1410 | catch (InvalidCastException) | 1410 | catch (InvalidCastException) |
1411 | { | 1411 | { |
1412 | } | 1412 | } |
1413 | SetLocalFundsForAgentID(avatar.UUID, funds); | 1413 | SetLocalFundsForAgentID(avatar.UUID, funds); |
1414 | } | 1414 | } |
1415 | else | 1415 | else |
1416 | { | 1416 | { |
1417 | avatar.ControllingClient.SendAgentAlertMessage((string) hresult["errorMessage"], true); | 1417 | avatar.ControllingClient.SendAgentAlertMessage((string) hresult["errorMessage"], true); |
1418 | } | 1418 | } |
1419 | } | 1419 | } |
1420 | } | 1420 | } |
1421 | } | 1421 | } |
1422 | } | 1422 | } |
1423 | else | 1423 | else |
1424 | { | 1424 | { |
1425 | lock (m_rootAgents) | 1425 | lock (m_rootAgents) |
1426 | { | 1426 | { |
1427 | m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID); | 1427 | m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID); |
1428 | } | 1428 | } |
1429 | if (m_MoneyAddress.Length > 0) | 1429 | if (m_MoneyAddress.Length > 0) |
1430 | { | 1430 | { |
1431 | Scene RegionItem = GetSceneByUUID(regionID); | 1431 | Scene RegionItem = GetSceneByUUID(regionID); |
1432 | if (RegionItem != null) | 1432 | if (RegionItem != null) |
1433 | { | 1433 | { |
1434 | Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); | 1434 | Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); |
1435 | if ((bool) hresult["success"] == true) | 1435 | if ((bool) hresult["success"] == true) |
1436 | { | 1436 | { |
1437 | int funds = 0; | 1437 | int funds = 0; |
1438 | try | 1438 | try |
1439 | { | 1439 | { |
1440 | funds = (Int32) hresult["funds"]; | 1440 | funds = (Int32) hresult["funds"]; |
1441 | } | 1441 | } |
1442 | catch (InvalidCastException) | 1442 | catch (InvalidCastException) |
1443 | { | 1443 | { |
1444 | } | 1444 | } |
1445 | SetLocalFundsForAgentID(avatar.UUID, funds); | 1445 | SetLocalFundsForAgentID(avatar.UUID, funds); |
1446 | } | 1446 | } |
1447 | else | 1447 | else |
1448 | { | 1448 | { |
1449 | avatar.ControllingClient.SendAgentAlertMessage((string) hresult["errorMessage"], true); | 1449 | avatar.ControllingClient.SendAgentAlertMessage((string) hresult["errorMessage"], true); |
1450 | } | 1450 | } |
1451 | } | 1451 | } |
1452 | } | 1452 | } |
1453 | 1453 | ||
1454 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 1454 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
1455 | } | 1455 | } |
1456 | } | 1456 | } |
1457 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); | 1457 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); |
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | #endregion | 1460 | #endregion |
1461 | } | 1461 | } |
1462 | 1462 | ||
1463 | public enum TransactionType : int | 1463 | public enum TransactionType : int |
1464 | { | 1464 | { |
1465 | SystemGenerated = 0, | 1465 | SystemGenerated = 0, |
1466 | RegionMoneyRequest = 1, | 1466 | RegionMoneyRequest = 1, |
1467 | Gift = 2, | 1467 | Gift = 2, |
1468 | Purchase = 3 | 1468 | Purchase = 3 |
1469 | } | 1469 | } |
1470 | } \ No newline at end of file | 1470 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs index db38d87..dd6a92e 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs | |||
@@ -1,501 +1,501 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using libsecondlife.Packets; | 31 | using libsecondlife.Packets; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using Nwc.XmlRpc; | 34 | using Nwc.XmlRpc; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
37 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
38 | 38 | ||
39 | namespace OpenSim.Region.Environment.Modules.Avatar.Friends | 39 | namespace OpenSim.Region.Environment.Modules.Avatar.Friends |
40 | { | 40 | { |
41 | public class FriendsModule : IRegionModule | 41 | public class FriendsModule : IRegionModule |
42 | { | 42 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | 44 | ||
45 | private Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>(); | 45 | private Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>(); |
46 | private Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); | 46 | private Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); |
47 | private Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); | 47 | private Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); |
48 | private List<Scene> m_scene = new List<Scene>(); | 48 | private List<Scene> m_scene = new List<Scene>(); |
49 | 49 | ||
50 | #region IRegionModule Members | 50 | #region IRegionModule Members |
51 | 51 | ||
52 | public void Initialise(Scene scene, IConfigSource config) | 52 | public void Initialise(Scene scene, IConfigSource config) |
53 | { | 53 | { |
54 | lock (m_scene) | 54 | lock (m_scene) |
55 | { | 55 | { |
56 | if (m_scene.Count == 0) | 56 | if (m_scene.Count == 0) |
57 | { | 57 | { |
58 | scene.AddXmlRPCHandler("presence_update", processPresenceUpdate); | 58 | scene.AddXmlRPCHandler("presence_update", processPresenceUpdate); |
59 | } | 59 | } |
60 | 60 | ||
61 | if (!m_scene.Contains(scene)) | 61 | if (!m_scene.Contains(scene)) |
62 | m_scene.Add(scene); | 62 | m_scene.Add(scene); |
63 | } | 63 | } |
64 | scene.EventManager.OnNewClient += OnNewClient; | 64 | scene.EventManager.OnNewClient += OnNewClient; |
65 | scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; | 65 | scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; |
66 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | 66 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; |
67 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; | 67 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; |
68 | scene.EventManager.OnClientClosed += ClientLoggedOut; | 68 | scene.EventManager.OnClientClosed += ClientLoggedOut; |
69 | } | 69 | } |
70 | 70 | ||
71 | public void PostInitialise() | 71 | public void PostInitialise() |
72 | { | 72 | { |
73 | } | 73 | } |
74 | 74 | ||
75 | public void Close() | 75 | public void Close() |
76 | { | 76 | { |
77 | } | 77 | } |
78 | 78 | ||
79 | public string Name | 79 | public string Name |
80 | { | 80 | { |
81 | get { return "FriendsModule"; } | 81 | get { return "FriendsModule"; } |
82 | } | 82 | } |
83 | 83 | ||
84 | public bool IsSharedModule | 84 | public bool IsSharedModule |
85 | { | 85 | { |
86 | get { return true; } | 86 | get { return true; } |
87 | } | 87 | } |
88 | 88 | ||
89 | #endregion | 89 | #endregion |
90 | 90 | ||
91 | public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) | 91 | public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) |
92 | { | 92 | { |
93 | m_log.Info("[FRIENDS]: Got Notification about a user! OMG"); | 93 | m_log.Info("[FRIENDS]: Got Notification about a user! OMG"); |
94 | return new XmlRpcResponse(); | 94 | return new XmlRpcResponse(); |
95 | } | 95 | } |
96 | 96 | ||
97 | private void OnNewClient(IClientAPI client) | 97 | private void OnNewClient(IClientAPI client) |
98 | { | 98 | { |
99 | // All friends establishment protocol goes over instant message | 99 | // All friends establishment protocol goes over instant message |
100 | // There's no way to send a message from the sim | 100 | // There's no way to send a message from the sim |
101 | // to a user to 'add a friend' without causing dialog box spam | 101 | // to a user to 'add a friend' without causing dialog box spam |
102 | // | 102 | // |
103 | // The base set of friends are added when the user signs on in their XMLRPC response | 103 | // The base set of friends are added when the user signs on in their XMLRPC response |
104 | // Generated by LoginService. The friends are retreived from the database by the UserManager | 104 | // Generated by LoginService. The friends are retreived from the database by the UserManager |
105 | 105 | ||
106 | // Subscribe to instant messages | 106 | // Subscribe to instant messages |
107 | 107 | ||
108 | client.OnInstantMessage += OnInstantMessage; | 108 | client.OnInstantMessage += OnInstantMessage; |
109 | client.OnApproveFriendRequest += OnApprovedFriendRequest; | 109 | client.OnApproveFriendRequest += OnApprovedFriendRequest; |
110 | client.OnDenyFriendRequest += OnDenyFriendRequest; | 110 | client.OnDenyFriendRequest += OnDenyFriendRequest; |
111 | client.OnTerminateFriendship += OnTerminateFriendship; | 111 | client.OnTerminateFriendship += OnTerminateFriendship; |
112 | 112 | ||
113 | List<FriendListItem> fl = new List<FriendListItem>(); | 113 | List<FriendListItem> fl = new List<FriendListItem>(); |
114 | 114 | ||
115 | //bool addFLback = false; | 115 | //bool addFLback = false; |
116 | 116 | ||
117 | lock (FriendLists) | 117 | lock (FriendLists) |
118 | { | 118 | { |
119 | if (FriendLists.ContainsKey(client.AgentId)) | 119 | if (FriendLists.ContainsKey(client.AgentId)) |
120 | { | 120 | { |
121 | fl = FriendLists[client.AgentId]; | 121 | fl = FriendLists[client.AgentId]; |
122 | } | 122 | } |
123 | else | 123 | else |
124 | { | 124 | { |
125 | fl = m_scene[0].GetFriendList(client.AgentId); | 125 | fl = m_scene[0].GetFriendList(client.AgentId); |
126 | 126 | ||
127 | //lock (FriendLists) | 127 | //lock (FriendLists) |
128 | //{ | 128 | //{ |
129 | if (!FriendLists.ContainsKey(client.AgentId)) | 129 | if (!FriendLists.ContainsKey(client.AgentId)) |
130 | FriendLists.Add(client.AgentId, fl); | 130 | FriendLists.Add(client.AgentId, fl); |
131 | //} | 131 | //} |
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | List<LLUUID> UpdateUsers = new List<LLUUID>(); | 135 | List<LLUUID> UpdateUsers = new List<LLUUID>(); |
136 | 136 | ||
137 | foreach (FriendListItem f in fl) | 137 | foreach (FriendListItem f in fl) |
138 | { | 138 | { |
139 | if (m_rootAgents.ContainsKey(f.Friend)) | 139 | if (m_rootAgents.ContainsKey(f.Friend)) |
140 | { | 140 | { |
141 | if (f.onlinestatus == false) | 141 | if (f.onlinestatus == false) |
142 | { | 142 | { |
143 | UpdateUsers.Add(f.Friend); | 143 | UpdateUsers.Add(f.Friend); |
144 | f.onlinestatus = true; | 144 | f.onlinestatus = true; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | } | 147 | } |
148 | foreach (LLUUID user in UpdateUsers) | 148 | foreach (LLUUID user in UpdateUsers) |
149 | { | 149 | { |
150 | ScenePresence av = GetPresenceFromAgentID(user); | 150 | ScenePresence av = GetPresenceFromAgentID(user); |
151 | if (av != null) | 151 | if (av != null) |
152 | { | 152 | { |
153 | List<FriendListItem> usrfl = new List<FriendListItem>(); | 153 | List<FriendListItem> usrfl = new List<FriendListItem>(); |
154 | 154 | ||
155 | lock (FriendLists) | 155 | lock (FriendLists) |
156 | { | 156 | { |
157 | usrfl = FriendLists[user]; | 157 | usrfl = FriendLists[user]; |
158 | } | 158 | } |
159 | 159 | ||
160 | lock (usrfl) | 160 | lock (usrfl) |
161 | { | 161 | { |
162 | foreach (FriendListItem fli in usrfl) | 162 | foreach (FriendListItem fli in usrfl) |
163 | { | 163 | { |
164 | if (fli.Friend == client.AgentId) | 164 | if (fli.Friend == client.AgentId) |
165 | { | 165 | { |
166 | fli.onlinestatus = true; | 166 | fli.onlinestatus = true; |
167 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); | 167 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); |
168 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1]; | 168 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1]; |
169 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); | 169 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); |
170 | onpbl.AgentID = client.AgentId; | 170 | onpbl.AgentID = client.AgentId; |
171 | onpb[0] = onpbl; | 171 | onpb[0] = onpbl; |
172 | onp.AgentBlock = onpb; | 172 | onp.AgentBlock = onpb; |
173 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); | 173 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); |
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | if (UpdateUsers.Count > 0) | 180 | if (UpdateUsers.Count > 0) |
181 | { | 181 | { |
182 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); | 182 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); |
183 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count]; | 183 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count]; |
184 | for (int i = 0; i < UpdateUsers.Count; i++) | 184 | for (int i = 0; i < UpdateUsers.Count; i++) |
185 | { | 185 | { |
186 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); | 186 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); |
187 | onpbl.AgentID = UpdateUsers[i]; | 187 | onpbl.AgentID = UpdateUsers[i]; |
188 | onpb[i] = onpbl; | 188 | onpb[i] = onpbl; |
189 | } | 189 | } |
190 | onp.AgentBlock = onpb; | 190 | onp.AgentBlock = onpb; |
191 | client.OutPacket(onp, ThrottleOutPacketType.Task); | 191 | client.OutPacket(onp, ThrottleOutPacketType.Task); |
192 | } | 192 | } |
193 | } | 193 | } |
194 | 194 | ||
195 | private void ClientLoggedOut(LLUUID AgentId) | 195 | private void ClientLoggedOut(LLUUID AgentId) |
196 | { | 196 | { |
197 | lock (m_rootAgents) | 197 | lock (m_rootAgents) |
198 | { | 198 | { |
199 | if (m_rootAgents.ContainsKey(AgentId)) | 199 | if (m_rootAgents.ContainsKey(AgentId)) |
200 | { | 200 | { |
201 | m_rootAgents.Remove(AgentId); | 201 | m_rootAgents.Remove(AgentId); |
202 | m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out."); | 202 | m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out."); |
203 | } | 203 | } |
204 | } | 204 | } |
205 | List<FriendListItem> lfli = new List<FriendListItem>(); | 205 | List<FriendListItem> lfli = new List<FriendListItem>(); |
206 | lock (FriendLists) | 206 | lock (FriendLists) |
207 | { | 207 | { |
208 | if (FriendLists.ContainsKey(AgentId)) | 208 | if (FriendLists.ContainsKey(AgentId)) |
209 | { | 209 | { |
210 | lfli = FriendLists[AgentId]; | 210 | lfli = FriendLists[AgentId]; |
211 | } | 211 | } |
212 | } | 212 | } |
213 | List<LLUUID> updateUsers = new List<LLUUID>(); | 213 | List<LLUUID> updateUsers = new List<LLUUID>(); |
214 | foreach (FriendListItem fli in lfli) | 214 | foreach (FriendListItem fli in lfli) |
215 | { | 215 | { |
216 | if (fli.onlinestatus == true) | 216 | if (fli.onlinestatus == true) |
217 | { | 217 | { |
218 | updateUsers.Add(fli.Friend); | 218 | updateUsers.Add(fli.Friend); |
219 | } | 219 | } |
220 | } | 220 | } |
221 | lock (updateUsers) | 221 | lock (updateUsers) |
222 | { | 222 | { |
223 | for (int i = 0; i < updateUsers.Count; i++) | 223 | for (int i = 0; i < updateUsers.Count; i++) |
224 | { | 224 | { |
225 | List<FriendListItem> flfli = new List<FriendListItem>(); | 225 | List<FriendListItem> flfli = new List<FriendListItem>(); |
226 | try | 226 | try |
227 | { | 227 | { |
228 | lock (FriendLists) | 228 | lock (FriendLists) |
229 | { | 229 | { |
230 | if (FriendLists.ContainsKey(updateUsers[i])) | 230 | if (FriendLists.ContainsKey(updateUsers[i])) |
231 | flfli = FriendLists[updateUsers[i]]; | 231 | flfli = FriendLists[updateUsers[i]]; |
232 | } | 232 | } |
233 | } | 233 | } |
234 | catch (IndexOutOfRangeException) | 234 | catch (IndexOutOfRangeException) |
235 | { | 235 | { |
236 | // Ignore the index out of range exception. | 236 | // Ignore the index out of range exception. |
237 | // This causes friend lists to get out of sync slightly.. however | 237 | // This causes friend lists to get out of sync slightly.. however |
238 | // prevents a sim crash. | 238 | // prevents a sim crash. |
239 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); | 239 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); |
240 | } | 240 | } |
241 | 241 | ||
242 | for (int j = 0; j < flfli.Count; j++) | 242 | for (int j = 0; j < flfli.Count; j++) |
243 | { | 243 | { |
244 | try | 244 | try |
245 | { | 245 | { |
246 | if (flfli[i].Friend == AgentId) | 246 | if (flfli[i].Friend == AgentId) |
247 | { | 247 | { |
248 | flfli[i].onlinestatus = false; | 248 | flfli[i].onlinestatus = false; |
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
252 | catch (IndexOutOfRangeException) | 252 | catch (IndexOutOfRangeException) |
253 | { | 253 | { |
254 | // Ignore the index out of range exception. | 254 | // Ignore the index out of range exception. |
255 | // This causes friend lists to get out of sync slightly.. however | 255 | // This causes friend lists to get out of sync slightly.. however |
256 | // prevents a sim crash. | 256 | // prevents a sim crash. |
257 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); | 257 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | } | 260 | } |
261 | 261 | ||
262 | for (int i = 0; i < updateUsers.Count; i++) | 262 | for (int i = 0; i < updateUsers.Count; i++) |
263 | { | 263 | { |
264 | ScenePresence av = GetPresenceFromAgentID(updateUsers[i]); | 264 | ScenePresence av = GetPresenceFromAgentID(updateUsers[i]); |
265 | if (av != null) | 265 | if (av != null) |
266 | { | 266 | { |
267 | OfflineNotificationPacket onp = new OfflineNotificationPacket(); | 267 | OfflineNotificationPacket onp = new OfflineNotificationPacket(); |
268 | OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1]; | 268 | OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1]; |
269 | OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); | 269 | OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); |
270 | onpbl.AgentID = AgentId; | 270 | onpbl.AgentID = AgentId; |
271 | onpb[0] = onpbl; | 271 | onpb[0] = onpbl; |
272 | onp.AgentBlock = onpb; | 272 | onp.AgentBlock = onpb; |
273 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); | 273 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | } | 276 | } |
277 | lock (FriendLists) | 277 | lock (FriendLists) |
278 | { | 278 | { |
279 | FriendLists.Remove(AgentId); | 279 | FriendLists.Remove(AgentId); |
280 | } | 280 | } |
281 | } | 281 | } |
282 | 282 | ||
283 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) | 283 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) |
284 | { | 284 | { |
285 | lock (m_rootAgents) | 285 | lock (m_rootAgents) |
286 | { | 286 | { |
287 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 287 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
288 | { | 288 | { |
289 | if (avatar.RegionHandle != m_rootAgents[avatar.UUID]) | 289 | if (avatar.RegionHandle != m_rootAgents[avatar.UUID]) |
290 | { | 290 | { |
291 | m_rootAgents[avatar.UUID] = avatar.RegionHandle; | 291 | m_rootAgents[avatar.UUID] = avatar.RegionHandle; |
292 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 292 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
293 | if (avatar.JID.Length > 0) | 293 | if (avatar.JID.Length > 0) |
294 | { | 294 | { |
295 | JId avatarID = new JId(avatar.JID); | 295 | JId avatarID = new JId(avatar.JID); |
296 | // REST Post XMPP Stanzas! | 296 | // REST Post XMPP Stanzas! |
297 | } | 297 | } |
298 | // Claim User! my user! Mine mine mine! | 298 | // Claim User! my user! Mine mine mine! |
299 | } | 299 | } |
300 | } | 300 | } |
301 | else | 301 | else |
302 | { | 302 | { |
303 | m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); | 303 | m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); |
304 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 304 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
305 | } | 305 | } |
306 | } | 306 | } |
307 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); | 307 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); |
308 | } | 308 | } |
309 | 309 | ||
310 | private void MakeChildAgent(ScenePresence avatar) | 310 | private void MakeChildAgent(ScenePresence avatar) |
311 | { | 311 | { |
312 | lock (m_rootAgents) | 312 | lock (m_rootAgents) |
313 | { | 313 | { |
314 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 314 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
315 | { | 315 | { |
316 | if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) | 316 | if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) |
317 | { | 317 | { |
318 | m_rootAgents.Remove(avatar.UUID); | 318 | m_rootAgents.Remove(avatar.UUID); |
319 | m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); | 319 | m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); |
320 | } | 320 | } |
321 | } | 321 | } |
322 | } | 322 | } |
323 | } | 323 | } |
324 | 324 | ||
325 | private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) | 325 | private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) |
326 | { | 326 | { |
327 | ScenePresence returnAgent = null; | 327 | ScenePresence returnAgent = null; |
328 | lock (m_scene) | 328 | lock (m_scene) |
329 | { | 329 | { |
330 | ScenePresence queryagent = null; | 330 | ScenePresence queryagent = null; |
331 | for (int i = 0; i < m_scene.Count; i++) | 331 | for (int i = 0; i < m_scene.Count; i++) |
332 | { | 332 | { |
333 | queryagent = m_scene[i].GetScenePresence(AgentID); | 333 | queryagent = m_scene[i].GetScenePresence(AgentID); |
334 | if (queryagent != null) | 334 | if (queryagent != null) |
335 | { | 335 | { |
336 | if (!queryagent.IsChildAgent) | 336 | if (!queryagent.IsChildAgent) |
337 | { | 337 | { |
338 | returnAgent = queryagent; | 338 | returnAgent = queryagent; |
339 | break; | 339 | break; |
340 | } | 340 | } |
341 | } | 341 | } |
342 | } | 342 | } |
343 | } | 343 | } |
344 | return returnAgent; | 344 | return returnAgent; |
345 | } | 345 | } |
346 | 346 | ||
347 | #region FriendRequestHandling | 347 | #region FriendRequestHandling |
348 | 348 | ||
349 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, | 349 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, |
350 | LLUUID fromAgentSession, LLUUID toAgentID, | 350 | LLUUID fromAgentSession, LLUUID toAgentID, |
351 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 351 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
352 | string message, byte dialog, bool fromGroup, byte offline, | 352 | string message, byte dialog, bool fromGroup, byte offline, |
353 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 353 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
354 | byte[] binaryBucket) | 354 | byte[] binaryBucket) |
355 | { | 355 | { |
356 | // Friend Requests go by Instant Message.. using the dialog param | 356 | // Friend Requests go by Instant Message.. using the dialog param |
357 | // https://wiki.secondlife.com/wiki/ImprovedInstantMessage | 357 | // https://wiki.secondlife.com/wiki/ImprovedInstantMessage |
358 | 358 | ||
359 | // 38 == Offer friendship | 359 | // 38 == Offer friendship |
360 | if (dialog == (byte) 38) | 360 | if (dialog == (byte) 38) |
361 | { | 361 | { |
362 | LLUUID friendTransactionID = LLUUID.Random(); | 362 | LLUUID friendTransactionID = LLUUID.Random(); |
363 | 363 | ||
364 | m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); | 364 | m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); |
365 | 365 | ||
366 | m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + | 366 | m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + |
367 | message); | 367 | message); |
368 | GridInstantMessage msg = new GridInstantMessage(); | 368 | GridInstantMessage msg = new GridInstantMessage(); |
369 | msg.fromAgentID = fromAgentID.UUID; | 369 | msg.fromAgentID = fromAgentID.UUID; |
370 | msg.fromAgentSession = fromAgentSession.UUID; | 370 | msg.fromAgentSession = fromAgentSession.UUID; |
371 | msg.toAgentID = toAgentID.UUID; | 371 | msg.toAgentID = toAgentID.UUID; |
372 | msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here | 372 | msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here |
373 | m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString()); | 373 | m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString()); |
374 | msg.timestamp = timestamp; | 374 | msg.timestamp = timestamp; |
375 | if (client != null) | 375 | if (client != null) |
376 | { | 376 | { |
377 | msg.fromAgentName = client.FirstName + " " + client.LastName; // fromAgentName; | 377 | msg.fromAgentName = client.FirstName + " " + client.LastName; // fromAgentName; |
378 | } | 378 | } |
379 | else | 379 | else |
380 | { | 380 | { |
381 | msg.fromAgentName = "(hippos)"; // Added for posterity. This means that we can't figure out who sent it | 381 | msg.fromAgentName = "(hippos)"; // Added for posterity. This means that we can't figure out who sent it |
382 | } | 382 | } |
383 | msg.message = message; | 383 | msg.message = message; |
384 | msg.dialog = dialog; | 384 | msg.dialog = dialog; |
385 | msg.fromGroup = fromGroup; | 385 | msg.fromGroup = fromGroup; |
386 | msg.offline = offline; | 386 | msg.offline = offline; |
387 | msg.ParentEstateID = ParentEstateID; | 387 | msg.ParentEstateID = ParentEstateID; |
388 | msg.Position = new sLLVector3(Position); | 388 | msg.Position = new sLLVector3(Position); |
389 | msg.RegionID = RegionID.UUID; | 389 | msg.RegionID = RegionID.UUID; |
390 | msg.binaryBucket = binaryBucket; | 390 | msg.binaryBucket = binaryBucket; |
391 | // We don't really care which scene we pipe it through. | 391 | // We don't really care which scene we pipe it through. |
392 | m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); | 392 | m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); |
393 | } | 393 | } |
394 | 394 | ||
395 | // 39 == Accept Friendship | 395 | // 39 == Accept Friendship |
396 | if (dialog == (byte) 39) | 396 | if (dialog == (byte) 39) |
397 | { | 397 | { |
398 | m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + | 398 | m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + |
399 | message); | 399 | message); |
400 | } | 400 | } |
401 | 401 | ||
402 | // 40 == Decline Friendship | 402 | // 40 == Decline Friendship |
403 | if (dialog == (byte) 40) | 403 | if (dialog == (byte) 40) |
404 | { | 404 | { |
405 | m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + | 405 | m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + |
406 | message); | 406 | message); |
407 | } | 407 | } |
408 | } | 408 | } |
409 | 409 | ||
410 | private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) | 410 | private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) |
411 | { | 411 | { |
412 | if (m_pendingFriendRequests.ContainsKey(transactionID)) | 412 | if (m_pendingFriendRequests.ContainsKey(transactionID)) |
413 | { | 413 | { |
414 | // Found Pending Friend Request with that Transaction.. | 414 | // Found Pending Friend Request with that Transaction.. |
415 | Scene SceneAgentIn = m_scene[0]; | 415 | Scene SceneAgentIn = m_scene[0]; |
416 | 416 | ||
417 | // Found Pending Friend Request with that Transaction.. | 417 | // Found Pending Friend Request with that Transaction.. |
418 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); | 418 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); |
419 | if (agentpresence != null) | 419 | if (agentpresence != null) |
420 | { | 420 | { |
421 | SceneAgentIn = agentpresence.Scene; | 421 | SceneAgentIn = agentpresence.Scene; |
422 | } | 422 | } |
423 | 423 | ||
424 | // Compose response to other agent. | 424 | // Compose response to other agent. |
425 | GridInstantMessage msg = new GridInstantMessage(); | 425 | GridInstantMessage msg = new GridInstantMessage(); |
426 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; | 426 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; |
427 | msg.fromAgentID = agentID.UUID; | 427 | msg.fromAgentID = agentID.UUID; |
428 | msg.fromAgentName = client.FirstName + " " + client.LastName; | 428 | msg.fromAgentName = client.FirstName + " " + client.LastName; |
429 | msg.fromAgentSession = client.SessionId.UUID; | 429 | msg.fromAgentSession = client.SessionId.UUID; |
430 | msg.fromGroup = false; | 430 | msg.fromGroup = false; |
431 | msg.imSessionID = transactionID.UUID; | 431 | msg.imSessionID = transactionID.UUID; |
432 | msg.message = agentID.UUID.ToString(); | 432 | msg.message = agentID.UUID.ToString(); |
433 | msg.ParentEstateID = 0; | 433 | msg.ParentEstateID = 0; |
434 | msg.timestamp = (uint) Util.UnixTimeSinceEpoch(); | 434 | msg.timestamp = (uint) Util.UnixTimeSinceEpoch(); |
435 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; | 435 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; |
436 | msg.dialog = (byte) 39; // Approved friend request | 436 | msg.dialog = (byte) 39; // Approved friend request |
437 | msg.Position = new sLLVector3(); | 437 | msg.Position = new sLLVector3(); |
438 | msg.offline = (byte) 0; | 438 | msg.offline = (byte) 0; |
439 | msg.binaryBucket = new byte[0]; | 439 | msg.binaryBucket = new byte[0]; |
440 | // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database | 440 | // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database |
441 | 441 | ||
442 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); | 442 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); |
443 | SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint) 1); | 443 | SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint) 1); |
444 | m_pendingFriendRequests.Remove(transactionID); | 444 | m_pendingFriendRequests.Remove(transactionID); |
445 | 445 | ||
446 | // TODO: Inform agent that the friend is online | 446 | // TODO: Inform agent that the friend is online |
447 | } | 447 | } |
448 | } | 448 | } |
449 | 449 | ||
450 | private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) | 450 | private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) |
451 | { | 451 | { |
452 | if (m_pendingFriendRequests.ContainsKey(transactionID)) | 452 | if (m_pendingFriendRequests.ContainsKey(transactionID)) |
453 | { | 453 | { |
454 | Scene SceneAgentIn = m_scene[0]; | 454 | Scene SceneAgentIn = m_scene[0]; |
455 | 455 | ||
456 | // Found Pending Friend Request with that Transaction.. | 456 | // Found Pending Friend Request with that Transaction.. |
457 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); | 457 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); |
458 | if (agentpresence != null) | 458 | if (agentpresence != null) |
459 | { | 459 | { |
460 | SceneAgentIn = agentpresence.Scene; | 460 | SceneAgentIn = agentpresence.Scene; |
461 | } | 461 | } |
462 | // Compose response to other agent. | 462 | // Compose response to other agent. |
463 | GridInstantMessage msg = new GridInstantMessage(); | 463 | GridInstantMessage msg = new GridInstantMessage(); |
464 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; | 464 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; |
465 | msg.fromAgentID = agentID.UUID; | 465 | msg.fromAgentID = agentID.UUID; |
466 | msg.fromAgentName = client.FirstName + " " + client.LastName; | 466 | msg.fromAgentName = client.FirstName + " " + client.LastName; |
467 | msg.fromAgentSession = client.SessionId.UUID; | 467 | msg.fromAgentSession = client.SessionId.UUID; |
468 | msg.fromGroup = false; | 468 | msg.fromGroup = false; |
469 | msg.imSessionID = transactionID.UUID; | 469 | msg.imSessionID = transactionID.UUID; |
470 | msg.message = agentID.UUID.ToString(); | 470 | msg.message = agentID.UUID.ToString(); |
471 | msg.ParentEstateID = 0; | 471 | msg.ParentEstateID = 0; |
472 | msg.timestamp = (uint) Util.UnixTimeSinceEpoch(); | 472 | msg.timestamp = (uint) Util.UnixTimeSinceEpoch(); |
473 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; | 473 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; |
474 | msg.dialog = (byte) 40; // Deny friend request | 474 | msg.dialog = (byte) 40; // Deny friend request |
475 | msg.Position = new sLLVector3(); | 475 | msg.Position = new sLLVector3(); |
476 | msg.offline = (byte) 0; | 476 | msg.offline = (byte) 0; |
477 | msg.binaryBucket = new byte[0]; | 477 | msg.binaryBucket = new byte[0]; |
478 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); | 478 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); |
479 | m_pendingFriendRequests.Remove(transactionID); | 479 | m_pendingFriendRequests.Remove(transactionID); |
480 | } | 480 | } |
481 | } | 481 | } |
482 | 482 | ||
483 | private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID) | 483 | private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID) |
484 | { | 484 | { |
485 | m_scene[0].StoreRemoveFriendship(agent, exfriendID); | 485 | m_scene[0].StoreRemoveFriendship(agent, exfriendID); |
486 | // TODO: Inform the client that the ExFriend is offline | 486 | // TODO: Inform the client that the ExFriend is offline |
487 | } | 487 | } |
488 | 488 | ||
489 | private void OnGridInstantMessage(GridInstantMessage msg) | 489 | private void OnGridInstantMessage(GridInstantMessage msg) |
490 | { | 490 | { |
491 | // Trigger the above event handler | 491 | // Trigger the above event handler |
492 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), | 492 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), |
493 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, | 493 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, |
494 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, | 494 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, |
495 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), | 495 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), |
496 | msg.binaryBucket); | 496 | msg.binaryBucket); |
497 | } | 497 | } |
498 | 498 | ||
499 | #endregion | 499 | #endregion |
500 | } | 500 | } |
501 | } \ No newline at end of file | 501 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs index c4906d2..6edc44d 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs | |||
@@ -1,273 +1,273 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
36 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules.Avatar.Groups | 38 | namespace OpenSim.Region.Environment.Modules.Avatar.Groups |
39 | { | 39 | { |
40 | public class GroupsModule : IRegionModule | 40 | public class GroupsModule : IRegionModule |
41 | { | 41 | { |
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | 43 | ||
44 | private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>(); | 44 | private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>(); |
45 | private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>(); | 45 | private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>(); |
46 | private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>(); | 46 | private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>(); |
47 | private List<Scene> m_scene = new List<Scene>(); | 47 | private List<Scene> m_scene = new List<Scene>(); |
48 | 48 | ||
49 | #region IRegionModule Members | 49 | #region IRegionModule Members |
50 | 50 | ||
51 | public void Initialise(Scene scene, IConfigSource config) | 51 | public void Initialise(Scene scene, IConfigSource config) |
52 | { | 52 | { |
53 | lock (m_scene) | 53 | lock (m_scene) |
54 | { | 54 | { |
55 | m_scene.Add(scene); | 55 | m_scene.Add(scene); |
56 | } | 56 | } |
57 | scene.EventManager.OnNewClient += OnNewClient; | 57 | scene.EventManager.OnNewClient += OnNewClient; |
58 | scene.EventManager.OnClientClosed += OnClientClosed; | 58 | scene.EventManager.OnClientClosed += OnClientClosed; |
59 | scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage; | 59 | scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage; |
60 | //scene.EventManager. | 60 | //scene.EventManager. |
61 | } | 61 | } |
62 | 62 | ||
63 | public void PostInitialise() | 63 | public void PostInitialise() |
64 | { | 64 | { |
65 | } | 65 | } |
66 | 66 | ||
67 | public void Close() | 67 | public void Close() |
68 | { | 68 | { |
69 | m_log.Info("[GROUP]: Shutting down group module."); | 69 | m_log.Info("[GROUP]: Shutting down group module."); |
70 | lock (m_iclientmap) | 70 | lock (m_iclientmap) |
71 | { | 71 | { |
72 | m_iclientmap.Clear(); | 72 | m_iclientmap.Clear(); |
73 | } | 73 | } |
74 | 74 | ||
75 | lock (m_groupmap) | 75 | lock (m_groupmap) |
76 | { | 76 | { |
77 | m_groupmap.Clear(); | 77 | m_groupmap.Clear(); |
78 | } | 78 | } |
79 | 79 | ||
80 | lock (m_grouplistmap) | 80 | lock (m_grouplistmap) |
81 | { | 81 | { |
82 | m_grouplistmap.Clear(); | 82 | m_grouplistmap.Clear(); |
83 | } | 83 | } |
84 | GC.Collect(); | 84 | GC.Collect(); |
85 | } | 85 | } |
86 | 86 | ||
87 | public string Name | 87 | public string Name |
88 | { | 88 | { |
89 | get { return "GroupsModule"; } | 89 | get { return "GroupsModule"; } |
90 | } | 90 | } |
91 | 91 | ||
92 | public bool IsSharedModule | 92 | public bool IsSharedModule |
93 | { | 93 | { |
94 | get { return true; } | 94 | get { return true; } |
95 | } | 95 | } |
96 | 96 | ||
97 | #endregion | 97 | #endregion |
98 | 98 | ||
99 | private void OnNewClient(IClientAPI client) | 99 | private void OnNewClient(IClientAPI client) |
100 | { | 100 | { |
101 | // All friends establishment protocol goes over instant message | 101 | // All friends establishment protocol goes over instant message |
102 | // There's no way to send a message from the sim | 102 | // There's no way to send a message from the sim |
103 | // to a user to 'add a friend' without causing dialog box spam | 103 | // to a user to 'add a friend' without causing dialog box spam |
104 | // | 104 | // |
105 | // The base set of friends are added when the user signs on in their XMLRPC response | 105 | // The base set of friends are added when the user signs on in their XMLRPC response |
106 | // Generated by LoginService. The friends are retreived from the database by the UserManager | 106 | // Generated by LoginService. The friends are retreived from the database by the UserManager |
107 | 107 | ||
108 | // Subscribe to instant messages | 108 | // Subscribe to instant messages |
109 | client.OnInstantMessage += OnInstantMessage; | 109 | client.OnInstantMessage += OnInstantMessage; |
110 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; | 110 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; |
111 | lock (m_iclientmap) | 111 | lock (m_iclientmap) |
112 | { | 112 | { |
113 | if (!m_iclientmap.ContainsKey(client.AgentId)) | 113 | if (!m_iclientmap.ContainsKey(client.AgentId)) |
114 | { | 114 | { |
115 | m_iclientmap.Add(client.AgentId, client); | 115 | m_iclientmap.Add(client.AgentId, client); |
116 | } | 116 | } |
117 | } | 117 | } |
118 | GroupData OpenSimulatorGroup = new GroupData(); | 118 | GroupData OpenSimulatorGroup = new GroupData(); |
119 | OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester"; | 119 | OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester"; |
120 | OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120"); | 120 | OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120"); |
121 | OpenSimulatorGroup.GroupMembers.Add(client.AgentId); | 121 | OpenSimulatorGroup.GroupMembers.Add(client.AgentId); |
122 | OpenSimulatorGroup.groupName = "OpenSimulator Testing"; | 122 | OpenSimulatorGroup.groupName = "OpenSimulator Testing"; |
123 | OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome; | 123 | OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome; |
124 | OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester"); | 124 | OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester"); |
125 | lock (m_groupmap) | 125 | lock (m_groupmap) |
126 | { | 126 | { |
127 | if (!m_groupmap.ContainsKey(client.AgentId)) | 127 | if (!m_groupmap.ContainsKey(client.AgentId)) |
128 | { | 128 | { |
129 | m_groupmap.Add(client.AgentId, OpenSimulatorGroup); | 129 | m_groupmap.Add(client.AgentId, OpenSimulatorGroup); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | GroupList testGroupList = new GroupList(); | 132 | GroupList testGroupList = new GroupList(); |
133 | testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120")); | 133 | testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120")); |
134 | 134 | ||
135 | lock (m_grouplistmap) | 135 | lock (m_grouplistmap) |
136 | { | 136 | { |
137 | if (!m_grouplistmap.ContainsKey(client.AgentId)) | 137 | if (!m_grouplistmap.ContainsKey(client.AgentId)) |
138 | { | 138 | { |
139 | m_grouplistmap.Add(client.AgentId, testGroupList); | 139 | m_grouplistmap.Add(client.AgentId, testGroupList); |
140 | } | 140 | } |
141 | } | 141 | } |
142 | m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group"); | 142 | m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group"); |
143 | } | 143 | } |
144 | 144 | ||
145 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID) | 145 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID) |
146 | { | 146 | { |
147 | string firstname = remoteClient.FirstName; | 147 | string firstname = remoteClient.FirstName; |
148 | string lastname = remoteClient.LastName; | 148 | string lastname = remoteClient.LastName; |
149 | 149 | ||
150 | LLUUID ActiveGroupID = LLUUID.Zero; | 150 | LLUUID ActiveGroupID = LLUUID.Zero; |
151 | uint ActiveGroupPowers = 0; | 151 | uint ActiveGroupPowers = 0; |
152 | string ActiveGroupName = ""; | 152 | string ActiveGroupName = ""; |
153 | string ActiveGroupTitle = ""; | 153 | string ActiveGroupTitle = ""; |
154 | 154 | ||
155 | bool foundUser = false; | 155 | bool foundUser = false; |
156 | 156 | ||
157 | lock (m_iclientmap) | 157 | lock (m_iclientmap) |
158 | { | 158 | { |
159 | if (m_iclientmap.ContainsKey(remoteClient.AgentId)) | 159 | if (m_iclientmap.ContainsKey(remoteClient.AgentId)) |
160 | { | 160 | { |
161 | foundUser = true; | 161 | foundUser = true; |
162 | } | 162 | } |
163 | } | 163 | } |
164 | if (foundUser) | 164 | if (foundUser) |
165 | { | 165 | { |
166 | lock (m_groupmap) | 166 | lock (m_groupmap) |
167 | { | 167 | { |
168 | if (m_groupmap.ContainsKey(remoteClient.AgentId)) | 168 | if (m_groupmap.ContainsKey(remoteClient.AgentId)) |
169 | { | 169 | { |
170 | GroupData grp = m_groupmap[remoteClient.AgentId]; | 170 | GroupData grp = m_groupmap[remoteClient.AgentId]; |
171 | if (grp != null) | 171 | if (grp != null) |
172 | { | 172 | { |
173 | ActiveGroupID = grp.GroupID; | 173 | ActiveGroupID = grp.GroupID; |
174 | ActiveGroupName = grp.groupName; | 174 | ActiveGroupName = grp.groupName; |
175 | ActiveGroupPowers = grp.groupPowers; | 175 | ActiveGroupPowers = grp.groupPowers; |
176 | ActiveGroupTitle = grp.ActiveGroupTitle; | 176 | ActiveGroupTitle = grp.ActiveGroupTitle; |
177 | } | 177 | } |
178 | 178 | ||
179 | //remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle); | 179 | //remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, | 185 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, |
186 | LLUUID fromAgentSession, LLUUID toAgentID, | 186 | LLUUID fromAgentSession, LLUUID toAgentID, |
187 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 187 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
188 | string message, byte dialog, bool fromGroup, byte offline, | 188 | string message, byte dialog, bool fromGroup, byte offline, |
189 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 189 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
190 | byte[] binaryBucket) | 190 | byte[] binaryBucket) |
191 | { | 191 | { |
192 | } | 192 | } |
193 | 193 | ||
194 | private void OnGridInstantMessage(GridInstantMessage msg) | 194 | private void OnGridInstantMessage(GridInstantMessage msg) |
195 | { | 195 | { |
196 | // Trigger the above event handler | 196 | // Trigger the above event handler |
197 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), | 197 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), |
198 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, | 198 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, |
199 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, | 199 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, |
200 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), | 200 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), |
201 | msg.binaryBucket); | 201 | msg.binaryBucket); |
202 | } | 202 | } |
203 | 203 | ||
204 | private void OnClientClosed(LLUUID agentID) | 204 | private void OnClientClosed(LLUUID agentID) |
205 | { | 205 | { |
206 | lock (m_iclientmap) | 206 | lock (m_iclientmap) |
207 | { | 207 | { |
208 | if (m_iclientmap.ContainsKey(agentID)) | 208 | if (m_iclientmap.ContainsKey(agentID)) |
209 | { | 209 | { |
210 | IClientAPI cli = m_iclientmap[agentID]; | 210 | IClientAPI cli = m_iclientmap[agentID]; |
211 | if (cli != null) | 211 | if (cli != null) |
212 | { | 212 | { |
213 | m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName); | 213 | m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName); |
214 | } | 214 | } |
215 | else | 215 | else |
216 | { | 216 | { |
217 | m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString()); | 217 | m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString()); |
218 | } | 218 | } |
219 | m_iclientmap.Remove(agentID); | 219 | m_iclientmap.Remove(agentID); |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
223 | lock (m_groupmap) | 223 | lock (m_groupmap) |
224 | { | 224 | { |
225 | if (m_groupmap.ContainsKey(agentID)) | 225 | if (m_groupmap.ContainsKey(agentID)) |
226 | { | 226 | { |
227 | m_groupmap.Remove(agentID); | 227 | m_groupmap.Remove(agentID); |
228 | } | 228 | } |
229 | } | 229 | } |
230 | 230 | ||
231 | lock (m_grouplistmap) | 231 | lock (m_grouplistmap) |
232 | { | 232 | { |
233 | if (m_grouplistmap.ContainsKey(agentID)) | 233 | if (m_grouplistmap.ContainsKey(agentID)) |
234 | { | 234 | { |
235 | m_grouplistmap.Remove(agentID); | 235 | m_grouplistmap.Remove(agentID); |
236 | } | 236 | } |
237 | } | 237 | } |
238 | GC.Collect(); | 238 | GC.Collect(); |
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | public class GroupData | 242 | public class GroupData |
243 | { | 243 | { |
244 | public string ActiveGroupTitle; | 244 | public string ActiveGroupTitle; |
245 | public LLUUID GroupID; | 245 | public LLUUID GroupID; |
246 | public List<LLUUID> GroupMembers; | 246 | public List<LLUUID> GroupMembers; |
247 | public string groupName; | 247 | public string groupName; |
248 | public uint groupPowers = (uint) (GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome); | 248 | public uint groupPowers = (uint) (GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome); |
249 | public List<string> GroupTitles; | 249 | public List<string> GroupTitles; |
250 | 250 | ||
251 | public GroupData() | 251 | public GroupData() |
252 | { | 252 | { |
253 | GroupTitles = new List<string>(); | 253 | GroupTitles = new List<string>(); |
254 | GroupMembers = new List<LLUUID>(); | 254 | GroupMembers = new List<LLUUID>(); |
255 | } | 255 | } |
256 | 256 | ||
257 | public GroupPowers ActiveGroupPowers | 257 | public GroupPowers ActiveGroupPowers |
258 | { | 258 | { |
259 | set { groupPowers = (uint) value; } | 259 | set { groupPowers = (uint) value; } |
260 | get { return (GroupPowers) groupPowers; } | 260 | get { return (GroupPowers) groupPowers; } |
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | public class GroupList | 264 | public class GroupList |
265 | { | 265 | { |
266 | public List<LLUUID> m_GroupList; | 266 | public List<LLUUID> m_GroupList; |
267 | 267 | ||
268 | public GroupList() | 268 | public GroupList() |
269 | { | 269 | { |
270 | m_GroupList = new List<LLUUID>(); | 270 | m_GroupList = new List<LLUUID>(); |
271 | } | 271 | } |
272 | } | 272 | } |
273 | } \ No newline at end of file | 273 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs index cb58b4c..26586a5 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs | |||
@@ -1,158 +1,158 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using libsecondlife; | 29 | using libsecondlife; |
30 | using Nini.Config; | 30 | using Nini.Config; |
31 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
32 | using OpenSim.Region.Environment.Interfaces; | 32 | using OpenSim.Region.Environment.Interfaces; |
33 | using OpenSim.Region.Environment.Scenes; | 33 | using OpenSim.Region.Environment.Scenes; |
34 | 34 | ||
35 | namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | 35 | namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage |
36 | { | 36 | { |
37 | public class InstantMessageModule : IRegionModule | 37 | public class InstantMessageModule : IRegionModule |
38 | { | 38 | { |
39 | private readonly List<Scene> m_scenes = new List<Scene>(); | 39 | private readonly List<Scene> m_scenes = new List<Scene>(); |
40 | 40 | ||
41 | #region IRegionModule Members | 41 | #region IRegionModule Members |
42 | 42 | ||
43 | public void Initialise(Scene scene, IConfigSource config) | 43 | public void Initialise(Scene scene, IConfigSource config) |
44 | { | 44 | { |
45 | lock (m_scenes) | 45 | lock (m_scenes) |
46 | { | 46 | { |
47 | if (m_scenes.Count == 0) | 47 | if (m_scenes.Count == 0) |
48 | { | 48 | { |
49 | //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate); | 49 | //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate); |
50 | } | 50 | } |
51 | 51 | ||
52 | if (!m_scenes.Contains(scene)) | 52 | if (!m_scenes.Contains(scene)) |
53 | { | 53 | { |
54 | m_scenes.Add(scene); | 54 | m_scenes.Add(scene); |
55 | scene.EventManager.OnNewClient += OnNewClient; | 55 | scene.EventManager.OnNewClient += OnNewClient; |
56 | scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; | 56 | scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; |
57 | } | 57 | } |
58 | } | 58 | } |
59 | } | 59 | } |
60 | 60 | ||
61 | public void PostInitialise() | 61 | public void PostInitialise() |
62 | { | 62 | { |
63 | } | 63 | } |
64 | 64 | ||
65 | public void Close() | 65 | public void Close() |
66 | { | 66 | { |
67 | } | 67 | } |
68 | 68 | ||
69 | public string Name | 69 | public string Name |
70 | { | 70 | { |
71 | get { return "InstantMessageModule"; } | 71 | get { return "InstantMessageModule"; } |
72 | } | 72 | } |
73 | 73 | ||
74 | public bool IsSharedModule | 74 | public bool IsSharedModule |
75 | { | 75 | { |
76 | get { return true; } | 76 | get { return true; } |
77 | } | 77 | } |
78 | 78 | ||
79 | #endregion | 79 | #endregion |
80 | 80 | ||
81 | private void OnNewClient(IClientAPI client) | 81 | private void OnNewClient(IClientAPI client) |
82 | { | 82 | { |
83 | client.OnInstantMessage += OnInstantMessage; | 83 | client.OnInstantMessage += OnInstantMessage; |
84 | } | 84 | } |
85 | 85 | ||
86 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, | 86 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, |
87 | LLUUID fromAgentSession, LLUUID toAgentID, | 87 | LLUUID fromAgentSession, LLUUID toAgentID, |
88 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 88 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
89 | string message, byte dialog, bool fromGroup, byte offline, | 89 | string message, byte dialog, bool fromGroup, byte offline, |
90 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 90 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
91 | byte[] binaryBucket) | 91 | byte[] binaryBucket) |
92 | { | 92 | { |
93 | bool dialogHandledElsewhere | 93 | bool dialogHandledElsewhere |
94 | = ((dialog == 38) || (dialog == 39) || (dialog == 40) | 94 | = ((dialog == 38) || (dialog == 39) || (dialog == 40) |
95 | || dialog == (byte) InstantMessageDialog.InventoryOffered | 95 | || dialog == (byte) InstantMessageDialog.InventoryOffered |
96 | || dialog == (byte) InstantMessageDialog.InventoryAccepted | 96 | || dialog == (byte) InstantMessageDialog.InventoryAccepted |
97 | || dialog == (byte) InstantMessageDialog.InventoryDeclined); | 97 | || dialog == (byte) InstantMessageDialog.InventoryDeclined); |
98 | 98 | ||
99 | // IM dialogs need to be pre-processed and have their sessionID filled by the server | 99 | // IM dialogs need to be pre-processed and have their sessionID filled by the server |
100 | // so the sim can match the transaction on the return packet. | 100 | // so the sim can match the transaction on the return packet. |
101 | 101 | ||
102 | // Don't send a Friend Dialog IM with a LLUUID.Zero session. | 102 | // Don't send a Friend Dialog IM with a LLUUID.Zero session. |
103 | if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero)) | 103 | if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero)) |
104 | { | 104 | { |
105 | // Try root avatar only first | 105 | // Try root avatar only first |
106 | foreach (Scene scene in m_scenes) | 106 | foreach (Scene scene in m_scenes) |
107 | { | 107 | { |
108 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) | 108 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) |
109 | { | 109 | { |
110 | // Local message | 110 | // Local message |
111 | ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; | 111 | ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; |
112 | if (!user.IsChildAgent) | 112 | if (!user.IsChildAgent) |
113 | { | 113 | { |
114 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, | 114 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, |
115 | toAgentID, imSessionID, fromAgentName, dialog, | 115 | toAgentID, imSessionID, fromAgentName, dialog, |
116 | timestamp); | 116 | timestamp); |
117 | // Message sent | 117 | // Message sent |
118 | return; | 118 | return; |
119 | } | 119 | } |
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | // try child avatar second | 123 | // try child avatar second |
124 | foreach (Scene scene in m_scenes) | 124 | foreach (Scene scene in m_scenes) |
125 | { | 125 | { |
126 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) | 126 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) |
127 | { | 127 | { |
128 | // Local message | 128 | // Local message |
129 | ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; | 129 | ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; |
130 | 130 | ||
131 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, | 131 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, |
132 | toAgentID, imSessionID, fromAgentName, dialog, | 132 | toAgentID, imSessionID, fromAgentName, dialog, |
133 | timestamp); | 133 | timestamp); |
134 | // Message sent | 134 | // Message sent |
135 | return; | 135 | return; |
136 | } | 136 | } |
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | 140 | ||
141 | // Still here, try send via Grid | 141 | // Still here, try send via Grid |
142 | // TODO | 142 | // TODO |
143 | } | 143 | } |
144 | 144 | ||
145 | // Trusty OSG1 called method. This method also gets called from the FriendsModule | 145 | // Trusty OSG1 called method. This method also gets called from the FriendsModule |
146 | // Turns out the sim has to send an instant message to the user to get it to show an accepted friend. | 146 | // Turns out the sim has to send an instant message to the user to get it to show an accepted friend. |
147 | 147 | ||
148 | private void OnGridInstantMessage(GridInstantMessage msg) | 148 | private void OnGridInstantMessage(GridInstantMessage msg) |
149 | { | 149 | { |
150 | // Trigger the above event handler | 150 | // Trigger the above event handler |
151 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), | 151 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), |
152 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, | 152 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, |
153 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, | 153 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, |
154 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), | 154 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), |
155 | msg.binaryBucket); | 155 | msg.binaryBucket); |
156 | } | 156 | } |
157 | } | 157 | } |
158 | } \ No newline at end of file | 158 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs index 2844450..624f307 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs | |||
@@ -1,220 +1,220 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules.Avatar.Inventory | 37 | namespace OpenSim.Region.Environment.Modules.Avatar.Inventory |
38 | { | 38 | { |
39 | public class InventoryModule : IRegionModule | 39 | public class InventoryModule : IRegionModule |
40 | { | 40 | { |
41 | private static readonly ILog m_log | 41 | private static readonly ILog m_log |
42 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | 43 | ||
44 | /// <summary> | 44 | /// <summary> |
45 | /// We need to keep track of the pending item offers between clients since the itemId offered only | 45 | /// We need to keep track of the pending item offers between clients since the itemId offered only |
46 | /// occurs in the initial offer message, not the accept message. So this dictionary links | 46 | /// occurs in the initial offer message, not the accept message. So this dictionary links |
47 | /// IM Session Ids to ItemIds | 47 | /// IM Session Ids to ItemIds |
48 | /// </summary> | 48 | /// </summary> |
49 | private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>(); | 49 | private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>(); |
50 | 50 | ||
51 | private Scene m_scene; | 51 | private Scene m_scene; |
52 | 52 | ||
53 | #region IRegionModule Members | 53 | #region IRegionModule Members |
54 | 54 | ||
55 | public void Initialise(Scene scene, IConfigSource config) | 55 | public void Initialise(Scene scene, IConfigSource config) |
56 | { | 56 | { |
57 | m_scene = scene; | 57 | m_scene = scene; |
58 | scene.EventManager.OnNewClient += OnNewClient; | 58 | scene.EventManager.OnNewClient += OnNewClient; |
59 | } | 59 | } |
60 | 60 | ||
61 | public void PostInitialise() | 61 | public void PostInitialise() |
62 | { | 62 | { |
63 | } | 63 | } |
64 | 64 | ||
65 | public void Close() | 65 | public void Close() |
66 | { | 66 | { |
67 | } | 67 | } |
68 | 68 | ||
69 | public string Name | 69 | public string Name |
70 | { | 70 | { |
71 | get { return "InventoryModule"; } | 71 | get { return "InventoryModule"; } |
72 | } | 72 | } |
73 | 73 | ||
74 | public bool IsSharedModule | 74 | public bool IsSharedModule |
75 | { | 75 | { |
76 | get { return false; } | 76 | get { return false; } |
77 | } | 77 | } |
78 | 78 | ||
79 | #endregion | 79 | #endregion |
80 | 80 | ||
81 | private void OnNewClient(IClientAPI client) | 81 | private void OnNewClient(IClientAPI client) |
82 | { | 82 | { |
83 | // Inventory giving is conducted via instant message | 83 | // Inventory giving is conducted via instant message |
84 | client.OnInstantMessage += OnInstantMessage; | 84 | client.OnInstantMessage += OnInstantMessage; |
85 | } | 85 | } |
86 | 86 | ||
87 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, | 87 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, |
88 | LLUUID fromAgentSession, LLUUID toAgentID, | 88 | LLUUID fromAgentSession, LLUUID toAgentID, |
89 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 89 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
90 | string message, byte dialog, bool fromGroup, byte offline, | 90 | string message, byte dialog, bool fromGroup, byte offline, |
91 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 91 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
92 | byte[] binaryBucket) | 92 | byte[] binaryBucket) |
93 | { | 93 | { |
94 | if (dialog == (byte) InstantMessageDialog.InventoryOffered) | 94 | if (dialog == (byte) InstantMessageDialog.InventoryOffered) |
95 | { | 95 | { |
96 | m_log.DebugFormat( | 96 | m_log.DebugFormat( |
97 | "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", | 97 | "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", |
98 | client.AgentId, client.Name, toAgentID); | 98 | client.AgentId, client.Name, toAgentID); |
99 | 99 | ||
100 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) | 100 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) |
101 | { | 101 | { |
102 | ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID]; | 102 | ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID]; |
103 | 103 | ||
104 | if (!user.IsChildAgent) | 104 | if (!user.IsChildAgent) |
105 | { | 105 | { |
106 | //byte[] rawId = new byte[16]; | 106 | //byte[] rawId = new byte[16]; |
107 | 107 | ||
108 | // First byte of the array is probably the item type | 108 | // First byte of the array is probably the item type |
109 | // Next 16 bytes are the UUID | 109 | // Next 16 bytes are the UUID |
110 | //Array.Copy(binaryBucket, 1, rawId, 0, 16); | 110 | //Array.Copy(binaryBucket, 1, rawId, 0, 16); |
111 | 111 | ||
112 | //LLUUID itemId = new LLUUID(new Guid(rawId)); | 112 | //LLUUID itemId = new LLUUID(new Guid(rawId)); |
113 | LLUUID itemId = new LLUUID(binaryBucket, 1); | 113 | LLUUID itemId = new LLUUID(binaryBucket, 1); |
114 | 114 | ||
115 | m_log.DebugFormat( | 115 | m_log.DebugFormat( |
116 | "[AGENT INVENTORY]: ItemId for giving is {0}", itemId); | 116 | "[AGENT INVENTORY]: ItemId for giving is {0}", itemId); |
117 | 117 | ||
118 | m_pendingOffers[imSessionID] = itemId; | 118 | m_pendingOffers[imSessionID] = itemId; |
119 | 119 | ||
120 | user.ControllingClient.SendInstantMessage( | 120 | user.ControllingClient.SendInstantMessage( |
121 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, | 121 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, |
122 | dialog, timestamp, binaryBucket); | 122 | dialog, timestamp, binaryBucket); |
123 | 123 | ||
124 | return; | 124 | return; |
125 | } | 125 | } |
126 | else | 126 | else |
127 | { | 127 | { |
128 | m_log.WarnFormat( | 128 | m_log.WarnFormat( |
129 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", | 129 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", |
130 | toAgentID, client.AgentId, client.Name, message); | 130 | toAgentID, client.AgentId, client.Name, message); |
131 | } | 131 | } |
132 | } | 132 | } |
133 | else | 133 | else |
134 | { | 134 | { |
135 | m_log.WarnFormat( | 135 | m_log.WarnFormat( |
136 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", | 136 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", |
137 | toAgentID, client.AgentId, client.Name, message); | 137 | toAgentID, client.AgentId, client.Name, message); |
138 | } | 138 | } |
139 | } | 139 | } |
140 | else if (dialog == (byte) InstantMessageDialog.InventoryAccepted) | 140 | else if (dialog == (byte) InstantMessageDialog.InventoryAccepted) |
141 | { | 141 | { |
142 | m_log.DebugFormat( | 142 | m_log.DebugFormat( |
143 | "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}", | 143 | "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}", |
144 | client.AgentId, client.Name, toAgentID); | 144 | client.AgentId, client.Name, toAgentID); |
145 | 145 | ||
146 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) | 146 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) |
147 | { | 147 | { |
148 | ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID]; | 148 | ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID]; |
149 | 149 | ||
150 | if (!user.IsChildAgent) | 150 | if (!user.IsChildAgent) |
151 | { | 151 | { |
152 | user.ControllingClient.SendInstantMessage( | 152 | user.ControllingClient.SendInstantMessage( |
153 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, | 153 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, |
154 | dialog, timestamp, binaryBucket); | 154 | dialog, timestamp, binaryBucket); |
155 | 155 | ||
156 | if (m_pendingOffers.ContainsKey(imSessionID)) | 156 | if (m_pendingOffers.ContainsKey(imSessionID)) |
157 | { | 157 | { |
158 | m_log.DebugFormat( | 158 | m_log.DebugFormat( |
159 | "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]); | 159 | "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]); |
160 | 160 | ||
161 | // Since the message originates from the accepting client, the toAgentID is | 161 | // Since the message originates from the accepting client, the toAgentID is |
162 | // the agent giving the item. | 162 | // the agent giving the item. |
163 | m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]); | 163 | m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]); |
164 | 164 | ||
165 | m_pendingOffers.Remove(imSessionID); | 165 | m_pendingOffers.Remove(imSessionID); |
166 | } | 166 | } |
167 | else | 167 | else |
168 | { | 168 | { |
169 | m_log.ErrorFormat( | 169 | m_log.ErrorFormat( |
170 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept", | 170 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept", |
171 | imSessionID); | 171 | imSessionID); |
172 | } | 172 | } |
173 | 173 | ||
174 | return; | 174 | return; |
175 | } | 175 | } |
176 | else | 176 | else |
177 | { | 177 | { |
178 | m_log.WarnFormat( | 178 | m_log.WarnFormat( |
179 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", | 179 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", |
180 | toAgentID, client.AgentId, client.Name, message); | 180 | toAgentID, client.AgentId, client.Name, message); |
181 | } | 181 | } |
182 | } | 182 | } |
183 | else | 183 | else |
184 | { | 184 | { |
185 | m_log.WarnFormat( | 185 | m_log.WarnFormat( |
186 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", | 186 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", |
187 | toAgentID, client.AgentId, client.Name, message); | 187 | toAgentID, client.AgentId, client.Name, message); |
188 | } | 188 | } |
189 | } | 189 | } |
190 | else if (dialog == (byte) InstantMessageDialog.InventoryDeclined) | 190 | else if (dialog == (byte) InstantMessageDialog.InventoryDeclined) |
191 | { | 191 | { |
192 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) | 192 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) |
193 | { | 193 | { |
194 | ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID]; | 194 | ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID]; |
195 | 195 | ||
196 | if (!user.IsChildAgent) | 196 | if (!user.IsChildAgent) |
197 | { | 197 | { |
198 | user.ControllingClient.SendInstantMessage( | 198 | user.ControllingClient.SendInstantMessage( |
199 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, | 199 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, |
200 | dialog, timestamp, binaryBucket); | 200 | dialog, timestamp, binaryBucket); |
201 | 201 | ||
202 | if (m_pendingOffers.ContainsKey(imSessionID)) | 202 | if (m_pendingOffers.ContainsKey(imSessionID)) |
203 | { | 203 | { |
204 | m_log.DebugFormat( | 204 | m_log.DebugFormat( |
205 | "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]); | 205 | "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]); |
206 | 206 | ||
207 | m_pendingOffers.Remove(imSessionID); | 207 | m_pendingOffers.Remove(imSessionID); |
208 | } | 208 | } |
209 | else | 209 | else |
210 | { | 210 | { |
211 | m_log.ErrorFormat( | 211 | m_log.ErrorFormat( |
212 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", | 212 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", |
213 | imSessionID); | 213 | imSessionID); |
214 | } | 214 | } |
215 | } | 215 | } |
216 | } | 216 | } |
217 | } | 217 | } |
218 | } | 218 | } |
219 | } | 219 | } |
220 | } \ No newline at end of file | 220 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs index 1955d2a..15825b6 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs | |||
@@ -1,133 +1,133 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules.Avatar.Profiles | 37 | namespace OpenSim.Region.Environment.Modules.Avatar.Profiles |
38 | { | 38 | { |
39 | public class AvatarProfilesModule : IRegionModule | 39 | public class AvatarProfilesModule : IRegionModule |
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | private Scene m_scene; | 42 | private Scene m_scene; |
43 | 43 | ||
44 | public AvatarProfilesModule() | 44 | public AvatarProfilesModule() |
45 | { | 45 | { |
46 | } | 46 | } |
47 | 47 | ||
48 | #region IRegionModule Members | 48 | #region IRegionModule Members |
49 | 49 | ||
50 | public void Initialise(Scene scene, IConfigSource config) | 50 | public void Initialise(Scene scene, IConfigSource config) |
51 | { | 51 | { |
52 | m_scene = scene; | 52 | m_scene = scene; |
53 | m_scene.EventManager.OnNewClient += NewClient; | 53 | m_scene.EventManager.OnNewClient += NewClient; |
54 | } | 54 | } |
55 | 55 | ||
56 | public void PostInitialise() | 56 | public void PostInitialise() |
57 | { | 57 | { |
58 | } | 58 | } |
59 | 59 | ||
60 | public void Close() | 60 | public void Close() |
61 | { | 61 | { |
62 | } | 62 | } |
63 | 63 | ||
64 | public string Name | 64 | public string Name |
65 | { | 65 | { |
66 | get { return "AvatarProfilesModule"; } | 66 | get { return "AvatarProfilesModule"; } |
67 | } | 67 | } |
68 | 68 | ||
69 | public bool IsSharedModule | 69 | public bool IsSharedModule |
70 | { | 70 | { |
71 | get { return false; } | 71 | get { return false; } |
72 | } | 72 | } |
73 | 73 | ||
74 | #endregion | 74 | #endregion |
75 | 75 | ||
76 | public void NewClient(IClientAPI client) | 76 | public void NewClient(IClientAPI client) |
77 | { | 77 | { |
78 | client.OnRequestAvatarProperties += RequestAvatarProperty; | 78 | client.OnRequestAvatarProperties += RequestAvatarProperty; |
79 | client.OnUpdateAvatarProperties += UpdateAvatarProperties; | 79 | client.OnUpdateAvatarProperties += UpdateAvatarProperties; |
80 | } | 80 | } |
81 | 81 | ||
82 | public void RemoveClient(IClientAPI client) | 82 | public void RemoveClient(IClientAPI client) |
83 | { | 83 | { |
84 | client.OnRequestAvatarProperties -= RequestAvatarProperty; | 84 | client.OnRequestAvatarProperties -= RequestAvatarProperty; |
85 | client.OnUpdateAvatarProperties -= UpdateAvatarProperties; | 85 | client.OnUpdateAvatarProperties -= UpdateAvatarProperties; |
86 | } | 86 | } |
87 | 87 | ||
88 | /// <summary> | 88 | /// <summary> |
89 | /// | 89 | /// |
90 | /// </summary> | 90 | /// </summary> |
91 | /// <param name="remoteClient"></param> | 91 | /// <param name="remoteClient"></param> |
92 | /// <param name="avatarID"></param> | 92 | /// <param name="avatarID"></param> |
93 | public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID) | 93 | public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID) |
94 | { | 94 | { |
95 | // FIXME: finish adding fields such as url, masking, etc. | 95 | // FIXME: finish adding fields such as url, masking, etc. |
96 | LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000"); | 96 | LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000"); |
97 | UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID); | 97 | UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID); |
98 | if (null != profile) | 98 | if (null != profile) |
99 | { | 99 | { |
100 | remoteClient.SendAvatarProperties(profile.ID, profile.AboutText, | 100 | remoteClient.SendAvatarProperties(profile.ID, profile.AboutText, |
101 | Util.ToDateTime(profile.Created).ToString(), | 101 | Util.ToDateTime(profile.Created).ToString(), |
102 | String.Empty, profile.FirstLifeAboutText, profile.CanDoMask, | 102 | String.Empty, profile.FirstLifeAboutText, profile.CanDoMask, |
103 | profile.FirstLifeImage, profile.Image, String.Empty, partner); | 103 | profile.FirstLifeImage, profile.Image, String.Empty, partner); |
104 | } | 104 | } |
105 | else | 105 | else |
106 | { | 106 | { |
107 | m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString()); | 107 | m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString()); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile) | 111 | public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile) |
112 | { | 112 | { |
113 | UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID); | 113 | UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID); |
114 | 114 | ||
115 | // if it's the profile of the user requesting the update, then we change only a few things. | 115 | // if it's the profile of the user requesting the update, then we change only a few things. |
116 | if (remoteClient.AgentId.CompareTo(Profile.ID) == 0) | 116 | if (remoteClient.AgentId.CompareTo(Profile.ID) == 0) |
117 | { | 117 | { |
118 | Profile.Image = newProfile.Image; | 118 | Profile.Image = newProfile.Image; |
119 | Profile.FirstLifeImage = newProfile.FirstLifeImage; | 119 | Profile.FirstLifeImage = newProfile.FirstLifeImage; |
120 | Profile.AboutText = newProfile.AboutText; | 120 | Profile.AboutText = newProfile.AboutText; |
121 | Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText; | 121 | Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText; |
122 | } | 122 | } |
123 | else | 123 | else |
124 | { | 124 | { |
125 | return; | 125 | return; |
126 | } | 126 | } |
127 | if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile)) | 127 | if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile)) |
128 | { | 128 | { |
129 | RequestAvatarProperty(remoteClient, newProfile.ID); | 129 | RequestAvatarProperty(remoteClient, newProfile.ID); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | } | 132 | } |
133 | } \ No newline at end of file | 133 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs index 44d67e6..f8f6ec2 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs | |||
@@ -1,290 +1,290 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using Nwc.XmlRpc; | 34 | using Nwc.XmlRpc; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Communications.Cache; | 36 | using OpenSim.Framework.Communications.Cache; |
37 | using OpenSim.Framework.Servers; | 37 | using OpenSim.Framework.Servers; |
38 | using OpenSim.Region.Capabilities; | 38 | using OpenSim.Region.Capabilities; |
39 | using OpenSim.Region.Environment.Interfaces; | 39 | using OpenSim.Region.Environment.Interfaces; |
40 | using OpenSim.Region.Environment.Scenes; | 40 | using OpenSim.Region.Environment.Scenes; |
41 | using Caps=OpenSim.Region.Capabilities.Caps; | 41 | using Caps=OpenSim.Region.Capabilities.Caps; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules.Avatar.Voice.AsterixVoice | 43 | namespace OpenSim.Region.Environment.Modules.Avatar.Voice.AsterixVoice |
44 | { | 44 | { |
45 | public class AsteriskVoiceModule : IRegionModule | 45 | public class AsteriskVoiceModule : IRegionModule |
46 | { | 46 | { |
47 | private static readonly ILog m_log = | 47 | private static readonly ILog m_log = |
48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; | 50 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; |
51 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; | 51 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; |
52 | 52 | ||
53 | private string m_asterisk; | 53 | private string m_asterisk; |
54 | private string m_asterisk_password; | 54 | private string m_asterisk_password; |
55 | private string m_asterisk_salt; | 55 | private string m_asterisk_salt; |
56 | private int m_asterisk_timeout; | 56 | private int m_asterisk_timeout; |
57 | private string m_confDomain; | 57 | private string m_confDomain; |
58 | private IConfig m_config; | 58 | private IConfig m_config; |
59 | private Scene m_scene; | 59 | private Scene m_scene; |
60 | private string m_sipDomain; | 60 | private string m_sipDomain; |
61 | 61 | ||
62 | #region IRegionModule Members | 62 | #region IRegionModule Members |
63 | 63 | ||
64 | public void Initialise(Scene scene, IConfigSource config) | 64 | public void Initialise(Scene scene, IConfigSource config) |
65 | { | 65 | { |
66 | m_scene = scene; | 66 | m_scene = scene; |
67 | m_config = config.Configs["AsteriskVoice"]; | 67 | m_config = config.Configs["AsteriskVoice"]; |
68 | 68 | ||
69 | if (null == m_config) | 69 | if (null == m_config) |
70 | { | 70 | { |
71 | m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); | 71 | m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); |
72 | return; | 72 | return; |
73 | } | 73 | } |
74 | 74 | ||
75 | if (!m_config.GetBoolean("enabled", false)) | 75 | if (!m_config.GetBoolean("enabled", false)) |
76 | { | 76 | { |
77 | m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); | 77 | m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); |
78 | return; | 78 | return; |
79 | } | 79 | } |
80 | m_log.Info("[ASTERISKVOICE] plugin enabled"); | 80 | m_log.Info("[ASTERISKVOICE] plugin enabled"); |
81 | 81 | ||
82 | try | 82 | try |
83 | { | 83 | { |
84 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); | 84 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); |
85 | m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); | 85 | m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); |
86 | 86 | ||
87 | m_confDomain = m_config.GetString("conf_domain", String.Empty); | 87 | m_confDomain = m_config.GetString("conf_domain", String.Empty); |
88 | m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); | 88 | m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); |
89 | 89 | ||
90 | m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); | 90 | m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); |
91 | m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); | 91 | m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); |
92 | m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); | 92 | m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); |
93 | m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); | 93 | m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); |
94 | if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); | 94 | if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); |
95 | if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); | 95 | if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); |
96 | m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); | 96 | m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); |
97 | 97 | ||
98 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | 98 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; |
99 | } | 99 | } |
100 | catch (Exception e) | 100 | catch (Exception e) |
101 | { | 101 | { |
102 | m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); | 102 | m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); |
103 | m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); | 103 | m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); |
104 | return; | 104 | return; |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | public void PostInitialise() | 108 | public void PostInitialise() |
109 | { | 109 | { |
110 | } | 110 | } |
111 | 111 | ||
112 | public void Close() | 112 | public void Close() |
113 | { | 113 | { |
114 | } | 114 | } |
115 | 115 | ||
116 | public string Name | 116 | public string Name |
117 | { | 117 | { |
118 | get { return "AsteriskVoiceModule"; } | 118 | get { return "AsteriskVoiceModule"; } |
119 | } | 119 | } |
120 | 120 | ||
121 | public bool IsSharedModule | 121 | public bool IsSharedModule |
122 | { | 122 | { |
123 | get { return false; } | 123 | get { return false; } |
124 | } | 124 | } |
125 | 125 | ||
126 | #endregion | 126 | #endregion |
127 | 127 | ||
128 | public void OnRegisterCaps(LLUUID agentID, Caps caps) | 128 | public void OnRegisterCaps(LLUUID agentID, Caps caps) |
129 | { | 129 | { |
130 | m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 130 | m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); |
131 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 131 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
132 | caps.RegisterHandler("ParcelVoiceInfoRequest", | 132 | caps.RegisterHandler("ParcelVoiceInfoRequest", |
133 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, | 133 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, |
134 | delegate(string request, string path, string param) | 134 | delegate(string request, string path, string param) |
135 | { | 135 | { |
136 | return ParcelVoiceInfoRequest(request, path, param, | 136 | return ParcelVoiceInfoRequest(request, path, param, |
137 | agentID, caps); | 137 | agentID, caps); |
138 | })); | 138 | })); |
139 | caps.RegisterHandler("ProvisionVoiceAccountRequest", | 139 | caps.RegisterHandler("ProvisionVoiceAccountRequest", |
140 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, | 140 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, |
141 | delegate(string request, string path, string param) | 141 | delegate(string request, string path, string param) |
142 | { | 142 | { |
143 | return ProvisionVoiceAccountRequest(request, path, param, | 143 | return ProvisionVoiceAccountRequest(request, path, param, |
144 | agentID, caps); | 144 | agentID, caps); |
145 | })); | 145 | })); |
146 | } | 146 | } |
147 | 147 | ||
148 | /// <summary> | 148 | /// <summary> |
149 | /// Callback for a client request for ParcelVoiceInfo | 149 | /// Callback for a client request for ParcelVoiceInfo |
150 | /// </summary> | 150 | /// </summary> |
151 | /// <param name="request"></param> | 151 | /// <param name="request"></param> |
152 | /// <param name="path"></param> | 152 | /// <param name="path"></param> |
153 | /// <param name="param"></param> | 153 | /// <param name="param"></param> |
154 | /// <param name="agentID"></param> | 154 | /// <param name="agentID"></param> |
155 | /// <param name="caps"></param> | 155 | /// <param name="caps"></param> |
156 | /// <returns></returns> | 156 | /// <returns></returns> |
157 | public string ParcelVoiceInfoRequest(string request, string path, string param, | 157 | public string ParcelVoiceInfoRequest(string request, string path, string param, |
158 | LLUUID agentID, Caps caps) | 158 | LLUUID agentID, Caps caps) |
159 | { | 159 | { |
160 | // we need to do: | 160 | // we need to do: |
161 | // - send channel_uri: as "sip:regionID@m_sipDomain" | 161 | // - send channel_uri: as "sip:regionID@m_sipDomain" |
162 | try | 162 | try |
163 | { | 163 | { |
164 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", | 164 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", |
165 | request, path, param); | 165 | request, path, param); |
166 | 166 | ||
167 | 167 | ||
168 | // setup response to client | 168 | // setup response to client |
169 | Hashtable creds = new Hashtable(); | 169 | Hashtable creds = new Hashtable(); |
170 | creds["channel_uri"] = String.Format("sip:{0}@{1}", | 170 | creds["channel_uri"] = String.Format("sip:{0}@{1}", |
171 | m_scene.RegionInfo.RegionID, m_sipDomain); | 171 | m_scene.RegionInfo.RegionID, m_sipDomain); |
172 | 172 | ||
173 | string regionName = m_scene.RegionInfo.RegionName; | 173 | string regionName = m_scene.RegionInfo.RegionName; |
174 | ScenePresence avatar = m_scene.GetScenePresence(agentID); | 174 | ScenePresence avatar = m_scene.GetScenePresence(agentID); |
175 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); | 175 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); |
176 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 176 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
177 | 177 | ||
178 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = | 178 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = |
179 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); | 179 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); |
180 | 180 | ||
181 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); | 181 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); |
182 | 182 | ||
183 | 183 | ||
184 | // update region on asterisk-opensim frontend | 184 | // update region on asterisk-opensim frontend |
185 | Hashtable requestData = new Hashtable(); | 185 | Hashtable requestData = new Hashtable(); |
186 | requestData["admin_password"] = m_asterisk_password; | 186 | requestData["admin_password"] = m_asterisk_password; |
187 | requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); | 187 | requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); |
188 | if (!String.IsNullOrEmpty(m_confDomain)) | 188 | if (!String.IsNullOrEmpty(m_confDomain)) |
189 | { | 189 | { |
190 | requestData["region"] += String.Format("@{0}", m_confDomain); | 190 | requestData["region"] += String.Format("@{0}", m_confDomain); |
191 | } | 191 | } |
192 | 192 | ||
193 | ArrayList SendParams = new ArrayList(); | 193 | ArrayList SendParams = new ArrayList(); |
194 | SendParams.Add(requestData); | 194 | SendParams.Add(requestData); |
195 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); | 195 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); |
196 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); | 196 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); |
197 | Hashtable responseData = (Hashtable) updateAccountResponse.Value; | 197 | Hashtable responseData = (Hashtable) updateAccountResponse.Value; |
198 | 198 | ||
199 | if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); | 199 | if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); |
200 | 200 | ||
201 | bool success = Convert.ToBoolean((string) responseData["success"]); | 201 | bool success = Convert.ToBoolean((string) responseData["success"]); |
202 | if (!success) throw new Exception("region_update failed"); | 202 | if (!success) throw new Exception("region_update failed"); |
203 | 203 | ||
204 | 204 | ||
205 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); | 205 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); |
206 | return r; | 206 | return r; |
207 | } | 207 | } |
208 | catch (Exception e) | 208 | catch (Exception e) |
209 | { | 209 | { |
210 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); | 210 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); |
211 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); | 211 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); |
212 | 212 | ||
213 | return "<llsd>undef</llsd>"; | 213 | return "<llsd>undef</llsd>"; |
214 | } | 214 | } |
215 | } | 215 | } |
216 | 216 | ||
217 | /// <summary> | 217 | /// <summary> |
218 | /// Callback for a client request for Voice Account Details | 218 | /// Callback for a client request for Voice Account Details |
219 | /// </summary> | 219 | /// </summary> |
220 | /// <param name="request"></param> | 220 | /// <param name="request"></param> |
221 | /// <param name="path"></param> | 221 | /// <param name="path"></param> |
222 | /// <param name="param"></param> | 222 | /// <param name="param"></param> |
223 | /// <param name="agentID"></param> | 223 | /// <param name="agentID"></param> |
224 | /// <param name="caps"></param> | 224 | /// <param name="caps"></param> |
225 | /// <returns></returns> | 225 | /// <returns></returns> |
226 | public string ProvisionVoiceAccountRequest(string request, string path, string param, | 226 | public string ProvisionVoiceAccountRequest(string request, string path, string param, |
227 | LLUUID agentID, Caps caps) | 227 | LLUUID agentID, Caps caps) |
228 | { | 228 | { |
229 | // we need to | 229 | // we need to |
230 | // - get user data from UserProfileCacheService | 230 | // - get user data from UserProfileCacheService |
231 | // - generate nonce for user voice account password | 231 | // - generate nonce for user voice account password |
232 | // - issue XmlRpc request to asterisk opensim front end: | 232 | // - issue XmlRpc request to asterisk opensim front end: |
233 | // + user: base 64 encoded user name (otherwise SL | 233 | // + user: base 64 encoded user name (otherwise SL |
234 | // client is unhappy) | 234 | // client is unhappy) |
235 | // + password: nonce | 235 | // + password: nonce |
236 | // - the XmlRpc call to asteris-opensim was successful: | 236 | // - the XmlRpc call to asteris-opensim was successful: |
237 | // send account details back to client | 237 | // send account details back to client |
238 | try | 238 | try |
239 | { | 239 | { |
240 | m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | 240 | m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", |
241 | request, path, param); | 241 | request, path, param); |
242 | 242 | ||
243 | // get user data & prepare voice account response | 243 | // get user data & prepare voice account response |
244 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); | 244 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); |
245 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); | 245 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); |
246 | 246 | ||
247 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); | 247 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); |
248 | if (null == userInfo) throw new Exception("cannot get user details"); | 248 | if (null == userInfo) throw new Exception("cannot get user details"); |
249 | 249 | ||
250 | // we generate a nonce everytime | 250 | // we generate a nonce everytime |
251 | string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); | 251 | string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); |
252 | LLSDVoiceAccountResponse voiceAccountResponse = | 252 | LLSDVoiceAccountResponse voiceAccountResponse = |
253 | new LLSDVoiceAccountResponse(voiceUser, voicePassword); | 253 | new LLSDVoiceAccountResponse(voiceUser, voicePassword); |
254 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); | 254 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); |
255 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); | 255 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); |
256 | 256 | ||
257 | 257 | ||
258 | // update user account on asterisk frontend | 258 | // update user account on asterisk frontend |
259 | Hashtable requestData = new Hashtable(); | 259 | Hashtable requestData = new Hashtable(); |
260 | requestData["admin_password"] = m_asterisk_password; | 260 | requestData["admin_password"] = m_asterisk_password; |
261 | requestData["username"] = voiceUser; | 261 | requestData["username"] = voiceUser; |
262 | if (!String.IsNullOrEmpty(m_sipDomain)) | 262 | if (!String.IsNullOrEmpty(m_sipDomain)) |
263 | { | 263 | { |
264 | requestData["username"] += String.Format("@{0}", m_sipDomain); | 264 | requestData["username"] += String.Format("@{0}", m_sipDomain); |
265 | } | 265 | } |
266 | requestData["password"] = voicePassword; | 266 | requestData["password"] = voicePassword; |
267 | 267 | ||
268 | ArrayList SendParams = new ArrayList(); | 268 | ArrayList SendParams = new ArrayList(); |
269 | SendParams.Add(requestData); | 269 | SendParams.Add(requestData); |
270 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); | 270 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); |
271 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); | 271 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); |
272 | Hashtable responseData = (Hashtable) updateAccountResponse.Value; | 272 | Hashtable responseData = (Hashtable) updateAccountResponse.Value; |
273 | 273 | ||
274 | if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); | 274 | if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); |
275 | 275 | ||
276 | bool success = Convert.ToBoolean((string) responseData["success"]); | 276 | bool success = Convert.ToBoolean((string) responseData["success"]); |
277 | if (!success) throw new Exception("account_update failed"); | 277 | if (!success) throw new Exception("account_update failed"); |
278 | 278 | ||
279 | return r; | 279 | return r; |
280 | } | 280 | } |
281 | catch (Exception e) | 281 | catch (Exception e) |
282 | { | 282 | { |
283 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); | 283 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); |
284 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); | 284 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); |
285 | 285 | ||
286 | return "<llsd>undef</llsd>"; | 286 | return "<llsd>undef</llsd>"; |
287 | } | 287 | } |
288 | } | 288 | } |
289 | } | 289 | } |
290 | } \ No newline at end of file | 290 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs index 8d9ba6f..1527f1e 100644 --- a/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs | |||
@@ -1,200 +1,200 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications.Cache; | 35 | using OpenSim.Framework.Communications.Cache; |
36 | using OpenSim.Framework.Servers; | 36 | using OpenSim.Framework.Servers; |
37 | using OpenSim.Region.Capabilities; | 37 | using OpenSim.Region.Capabilities; |
38 | using OpenSim.Region.Environment.Interfaces; | 38 | using OpenSim.Region.Environment.Interfaces; |
39 | using OpenSim.Region.Environment.Scenes; | 39 | using OpenSim.Region.Environment.Scenes; |
40 | using Caps=OpenSim.Region.Capabilities.Caps; | 40 | using Caps=OpenSim.Region.Capabilities.Caps; |
41 | 41 | ||
42 | namespace OpenSim.Region.Environment.Modules.Avatar.Voice.SIPVoice | 42 | namespace OpenSim.Region.Environment.Modules.Avatar.Voice.SIPVoice |
43 | { | 43 | { |
44 | public class SIPVoiceModule : IRegionModule | 44 | public class SIPVoiceModule : IRegionModule |
45 | { | 45 | { |
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; | 49 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; |
50 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; | 50 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; |
51 | private IConfig m_config; | 51 | private IConfig m_config; |
52 | private Scene m_scene; | 52 | private Scene m_scene; |
53 | private string m_sipDomain; | 53 | private string m_sipDomain; |
54 | 54 | ||
55 | #region IRegionModule Members | 55 | #region IRegionModule Members |
56 | 56 | ||
57 | public void Initialise(Scene scene, IConfigSource config) | 57 | public void Initialise(Scene scene, IConfigSource config) |
58 | { | 58 | { |
59 | m_scene = scene; | 59 | m_scene = scene; |
60 | m_config = config.Configs["Voice"]; | 60 | m_config = config.Configs["Voice"]; |
61 | 61 | ||
62 | if (null == m_config || !m_config.GetBoolean("enabled", false)) | 62 | if (null == m_config || !m_config.GetBoolean("enabled", false)) |
63 | { | 63 | { |
64 | m_log.Info("[VOICE] plugin disabled"); | 64 | m_log.Info("[VOICE] plugin disabled"); |
65 | return; | 65 | return; |
66 | } | 66 | } |
67 | m_log.Info("[VOICE] plugin enabled"); | 67 | m_log.Info("[VOICE] plugin enabled"); |
68 | 68 | ||
69 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); | 69 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); |
70 | if (String.IsNullOrEmpty(m_sipDomain)) | 70 | if (String.IsNullOrEmpty(m_sipDomain)) |
71 | { | 71 | { |
72 | m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); | 72 | m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); |
73 | m_log.Info("[VOICE] plugin disabled"); | 73 | m_log.Info("[VOICE] plugin disabled"); |
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); | 76 | m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); |
77 | 77 | ||
78 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | 78 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; |
79 | } | 79 | } |
80 | 80 | ||
81 | public void PostInitialise() | 81 | public void PostInitialise() |
82 | { | 82 | { |
83 | } | 83 | } |
84 | 84 | ||
85 | public void Close() | 85 | public void Close() |
86 | { | 86 | { |
87 | } | 87 | } |
88 | 88 | ||
89 | public string Name | 89 | public string Name |
90 | { | 90 | { |
91 | get { return "VoiceModule"; } | 91 | get { return "VoiceModule"; } |
92 | } | 92 | } |
93 | 93 | ||
94 | public bool IsSharedModule | 94 | public bool IsSharedModule |
95 | { | 95 | { |
96 | get { return false; } | 96 | get { return false; } |
97 | } | 97 | } |
98 | 98 | ||
99 | #endregion | 99 | #endregion |
100 | 100 | ||
101 | public void OnRegisterCaps(LLUUID agentID, Caps caps) | 101 | public void OnRegisterCaps(LLUUID agentID, Caps caps) |
102 | { | 102 | { |
103 | m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 103 | m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); |
104 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 104 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
105 | caps.RegisterHandler("ParcelVoiceInfoRequest", | 105 | caps.RegisterHandler("ParcelVoiceInfoRequest", |
106 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, | 106 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, |
107 | delegate(string request, string path, string param) | 107 | delegate(string request, string path, string param) |
108 | { | 108 | { |
109 | return ParcelVoiceInfoRequest(request, path, param, | 109 | return ParcelVoiceInfoRequest(request, path, param, |
110 | agentID, caps); | 110 | agentID, caps); |
111 | })); | 111 | })); |
112 | caps.RegisterHandler("ProvisionVoiceAccountRequest", | 112 | caps.RegisterHandler("ProvisionVoiceAccountRequest", |
113 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, | 113 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, |
114 | delegate(string request, string path, string param) | 114 | delegate(string request, string path, string param) |
115 | { | 115 | { |
116 | return ProvisionVoiceAccountRequest(request, path, param, | 116 | return ProvisionVoiceAccountRequest(request, path, param, |
117 | agentID, caps); | 117 | agentID, caps); |
118 | })); | 118 | })); |
119 | } | 119 | } |
120 | 120 | ||
121 | /// <summary> | 121 | /// <summary> |
122 | /// Callback for a client request for ParcelVoiceInfo | 122 | /// Callback for a client request for ParcelVoiceInfo |
123 | /// </summary> | 123 | /// </summary> |
124 | /// <param name="request"></param> | 124 | /// <param name="request"></param> |
125 | /// <param name="path"></param> | 125 | /// <param name="path"></param> |
126 | /// <param name="param"></param> | 126 | /// <param name="param"></param> |
127 | /// <param name="agentID"></param> | 127 | /// <param name="agentID"></param> |
128 | /// <param name="caps"></param> | 128 | /// <param name="caps"></param> |
129 | /// <returns></returns> | 129 | /// <returns></returns> |
130 | public string ParcelVoiceInfoRequest(string request, string path, string param, | 130 | public string ParcelVoiceInfoRequest(string request, string path, string param, |
131 | LLUUID agentID, Caps caps) | 131 | LLUUID agentID, Caps caps) |
132 | { | 132 | { |
133 | try | 133 | try |
134 | { | 134 | { |
135 | m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); | 135 | m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); |
136 | 136 | ||
137 | // FIXME: get the creds from region file or from config | 137 | // FIXME: get the creds from region file or from config |
138 | Hashtable creds = new Hashtable(); | 138 | Hashtable creds = new Hashtable(); |
139 | 139 | ||
140 | creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain); | 140 | creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain); |
141 | 141 | ||
142 | string regionName = m_scene.RegionInfo.RegionName; | 142 | string regionName = m_scene.RegionInfo.RegionName; |
143 | ScenePresence avatar = m_scene.GetScenePresence(agentID); | 143 | ScenePresence avatar = m_scene.GetScenePresence(agentID); |
144 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); | 144 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); |
145 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 145 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
146 | 146 | ||
147 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = | 147 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = |
148 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); | 148 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); |
149 | 149 | ||
150 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); | 150 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); |
151 | m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); | 151 | m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); |
152 | 152 | ||
153 | return r; | 153 | return r; |
154 | } | 154 | } |
155 | catch (Exception e) | 155 | catch (Exception e) |
156 | { | 156 | { |
157 | m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); | 157 | m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); |
158 | } | 158 | } |
159 | 159 | ||
160 | return null; | 160 | return null; |
161 | } | 161 | } |
162 | 162 | ||
163 | /// <summary> | 163 | /// <summary> |
164 | /// Callback for a client request for Voice Account Details | 164 | /// Callback for a client request for Voice Account Details |
165 | /// </summary> | 165 | /// </summary> |
166 | /// <param name="request"></param> | 166 | /// <param name="request"></param> |
167 | /// <param name="path"></param> | 167 | /// <param name="path"></param> |
168 | /// <param name="param"></param> | 168 | /// <param name="param"></param> |
169 | /// <param name="agentID"></param> | 169 | /// <param name="agentID"></param> |
170 | /// <param name="caps"></param> | 170 | /// <param name="caps"></param> |
171 | /// <returns></returns> | 171 | /// <returns></returns> |
172 | public string ProvisionVoiceAccountRequest(string request, string path, string param, | 172 | public string ProvisionVoiceAccountRequest(string request, string path, string param, |
173 | LLUUID agentID, Caps caps) | 173 | LLUUID agentID, Caps caps) |
174 | { | 174 | { |
175 | try | 175 | try |
176 | { | 176 | { |
177 | m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | 177 | m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", |
178 | request, path, param); | 178 | request, path, param); |
179 | 179 | ||
180 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); | 180 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); |
181 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); | 181 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); |
182 | 182 | ||
183 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); | 183 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); |
184 | if (null == userInfo) throw new Exception("cannot get user details"); | 184 | if (null == userInfo) throw new Exception("cannot get user details"); |
185 | 185 | ||
186 | LLSDVoiceAccountResponse voiceAccountResponse = | 186 | LLSDVoiceAccountResponse voiceAccountResponse = |
187 | new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); | 187 | new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); |
188 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); | 188 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); |
189 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); | 189 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); |
190 | return r; | 190 | return r; |
191 | } | 191 | } |
192 | catch (Exception e) | 192 | catch (Exception e) |
193 | { | 193 | { |
194 | m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); | 194 | m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); |
195 | } | 195 | } |
196 | 196 | ||
197 | return null; | 197 | return null; |
198 | } | 198 | } |
199 | } | 199 | } |
200 | } \ No newline at end of file | 200 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Framework/Commander.cs b/OpenSim/Region/Environment/Modules/Framework/Commander.cs index 6cf8298..4430c10 100644 --- a/OpenSim/Region/Environment/Modules/Framework/Commander.cs +++ b/OpenSim/Region/Environment/Modules/Framework/Commander.cs | |||
@@ -1,308 +1,308 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Text; | 31 | using System.Text; |
32 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.Modules.Framework | 36 | namespace OpenSim.Region.Environment.Modules.Framework |
37 | { | 37 | { |
38 | /// <summary> | 38 | /// <summary> |
39 | /// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s. | 39 | /// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s. |
40 | /// Used for console commands and script API generation | 40 | /// Used for console commands and script API generation |
41 | /// </summary> | 41 | /// </summary> |
42 | public class Command : ICommand | 42 | public class Command : ICommand |
43 | { | 43 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | private List<CommandArgument> m_args = new List<CommandArgument>(); | 45 | private List<CommandArgument> m_args = new List<CommandArgument>(); |
46 | 46 | ||
47 | private Action<object[]> m_command; | 47 | private Action<object[]> m_command; |
48 | private string m_help; | 48 | private string m_help; |
49 | private string m_name; | 49 | private string m_name; |
50 | 50 | ||
51 | public Command(string name, Action<Object[]> command, string help) | 51 | public Command(string name, Action<Object[]> command, string help) |
52 | { | 52 | { |
53 | m_name = name; | 53 | m_name = name; |
54 | m_command = command; | 54 | m_command = command; |
55 | m_help = help; | 55 | m_help = help; |
56 | } | 56 | } |
57 | 57 | ||
58 | #region ICommand Members | 58 | #region ICommand Members |
59 | 59 | ||
60 | public void AddArgument(string name, string helptext, string type) | 60 | public void AddArgument(string name, string helptext, string type) |
61 | { | 61 | { |
62 | m_args.Add(new CommandArgument(name, helptext, type)); | 62 | m_args.Add(new CommandArgument(name, helptext, type)); |
63 | } | 63 | } |
64 | 64 | ||
65 | public string Name | 65 | public string Name |
66 | { | 66 | { |
67 | get { return m_name; } | 67 | get { return m_name; } |
68 | } | 68 | } |
69 | 69 | ||
70 | public string Help | 70 | public string Help |
71 | { | 71 | { |
72 | get { return m_help; } | 72 | get { return m_help; } |
73 | } | 73 | } |
74 | 74 | ||
75 | public Dictionary<string, string> Arguments | 75 | public Dictionary<string, string> Arguments |
76 | { | 76 | { |
77 | get | 77 | get |
78 | { | 78 | { |
79 | Dictionary<string, string> tmp = new Dictionary<string, string>(); | 79 | Dictionary<string, string> tmp = new Dictionary<string, string>(); |
80 | foreach (CommandArgument arg in m_args) | 80 | foreach (CommandArgument arg in m_args) |
81 | { | 81 | { |
82 | tmp.Add(arg.Name, arg.ArgumentType); | 82 | tmp.Add(arg.Name, arg.ArgumentType); |
83 | } | 83 | } |
84 | return tmp; | 84 | return tmp; |
85 | } | 85 | } |
86 | } | 86 | } |
87 | 87 | ||
88 | public void ShowConsoleHelp() | 88 | public void ShowConsoleHelp() |
89 | { | 89 | { |
90 | m_log.Info("== " + Name + " =="); | 90 | m_log.Info("== " + Name + " =="); |
91 | m_log.Info(m_help); | 91 | m_log.Info(m_help); |
92 | m_log.Info("= Parameters ="); | 92 | m_log.Info("= Parameters ="); |
93 | foreach (CommandArgument arg in m_args) | 93 | foreach (CommandArgument arg in m_args) |
94 | { | 94 | { |
95 | m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")"); | 95 | m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")"); |
96 | m_log.Info("\t" + arg.HelpText); | 96 | m_log.Info("\t" + arg.HelpText); |
97 | } | 97 | } |
98 | } | 98 | } |
99 | 99 | ||
100 | public void Run(Object[] args) | 100 | public void Run(Object[] args) |
101 | { | 101 | { |
102 | Object[] cleanArgs = new Object[m_args.Count]; | 102 | Object[] cleanArgs = new Object[m_args.Count]; |
103 | 103 | ||
104 | if (args.Length < cleanArgs.Length) | 104 | if (args.Length < cleanArgs.Length) |
105 | { | 105 | { |
106 | m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)"); | 106 | m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)"); |
107 | ShowConsoleHelp(); | 107 | ShowConsoleHelp(); |
108 | return; | 108 | return; |
109 | } | 109 | } |
110 | if (args.Length > cleanArgs.Length) | 110 | if (args.Length > cleanArgs.Length) |
111 | { | 111 | { |
112 | m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help."); | 112 | m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help."); |
113 | return; | 113 | return; |
114 | } | 114 | } |
115 | 115 | ||
116 | int i = 0; | 116 | int i = 0; |
117 | foreach (Object arg in args) | 117 | foreach (Object arg in args) |
118 | { | 118 | { |
119 | if (string.IsNullOrEmpty(arg.ToString())) | 119 | if (string.IsNullOrEmpty(arg.ToString())) |
120 | { | 120 | { |
121 | m_log.Error("Empty arguments are not allowed"); | 121 | m_log.Error("Empty arguments are not allowed"); |
122 | return; | 122 | return; |
123 | } | 123 | } |
124 | try | 124 | try |
125 | { | 125 | { |
126 | switch (m_args[i].ArgumentType) | 126 | switch (m_args[i].ArgumentType) |
127 | { | 127 | { |
128 | case "String": | 128 | case "String": |
129 | m_args[i].ArgumentValue = arg.ToString(); | 129 | m_args[i].ArgumentValue = arg.ToString(); |
130 | break; | 130 | break; |
131 | case "Integer": | 131 | case "Integer": |
132 | m_args[i].ArgumentValue = Int32.Parse(arg.ToString()); | 132 | m_args[i].ArgumentValue = Int32.Parse(arg.ToString()); |
133 | break; | 133 | break; |
134 | case "Double": | 134 | case "Double": |
135 | m_args[i].ArgumentValue = Double.Parse(arg.ToString()); | 135 | m_args[i].ArgumentValue = Double.Parse(arg.ToString()); |
136 | break; | 136 | break; |
137 | case "Boolean": | 137 | case "Boolean": |
138 | m_args[i].ArgumentValue = Boolean.Parse(arg.ToString()); | 138 | m_args[i].ArgumentValue = Boolean.Parse(arg.ToString()); |
139 | break; | 139 | break; |
140 | default: | 140 | default: |
141 | m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name); | 141 | m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name); |
142 | break; | 142 | break; |
143 | } | 143 | } |
144 | } | 144 | } |
145 | catch (FormatException) | 145 | catch (FormatException) |
146 | { | 146 | { |
147 | m_log.Error("Argument number " + (i + 1) + | 147 | m_log.Error("Argument number " + (i + 1) + |
148 | " (" + m_args[i].Name + ") must be a valid " + | 148 | " (" + m_args[i].Name + ") must be a valid " + |
149 | m_args[i].ArgumentType.ToLower() + "."); | 149 | m_args[i].ArgumentType.ToLower() + "."); |
150 | } | 150 | } |
151 | cleanArgs[i] = m_args[i].ArgumentValue; | 151 | cleanArgs[i] = m_args[i].ArgumentValue; |
152 | 152 | ||
153 | i++; | 153 | i++; |
154 | } | 154 | } |
155 | 155 | ||
156 | m_command.Invoke(cleanArgs); | 156 | m_command.Invoke(cleanArgs); |
157 | } | 157 | } |
158 | 158 | ||
159 | #endregion | 159 | #endregion |
160 | } | 160 | } |
161 | 161 | ||
162 | /// <summary> | 162 | /// <summary> |
163 | /// A single command argument, contains name, type and at runtime, value. | 163 | /// A single command argument, contains name, type and at runtime, value. |
164 | /// </summary> | 164 | /// </summary> |
165 | public class CommandArgument | 165 | public class CommandArgument |
166 | { | 166 | { |
167 | private string m_help; | 167 | private string m_help; |
168 | private string m_name; | 168 | private string m_name; |
169 | private string m_type; | 169 | private string m_type; |
170 | private Object m_val; | 170 | private Object m_val; |
171 | 171 | ||
172 | public CommandArgument(string name, string help, string type) | 172 | public CommandArgument(string name, string help, string type) |
173 | { | 173 | { |
174 | m_name = name; | 174 | m_name = name; |
175 | m_help = help; | 175 | m_help = help; |
176 | m_type = type; | 176 | m_type = type; |
177 | } | 177 | } |
178 | 178 | ||
179 | public string Name | 179 | public string Name |
180 | { | 180 | { |
181 | get { return m_name; } | 181 | get { return m_name; } |
182 | } | 182 | } |
183 | 183 | ||
184 | public string HelpText | 184 | public string HelpText |
185 | { | 185 | { |
186 | get { return m_help; } | 186 | get { return m_help; } |
187 | } | 187 | } |
188 | 188 | ||
189 | public string ArgumentType | 189 | public string ArgumentType |
190 | { | 190 | { |
191 | get { return m_type; } | 191 | get { return m_type; } |
192 | } | 192 | } |
193 | 193 | ||
194 | public Object ArgumentValue | 194 | public Object ArgumentValue |
195 | { | 195 | { |
196 | get { return m_val; } | 196 | get { return m_val; } |
197 | set { m_val = value; } | 197 | set { m_val = value; } |
198 | } | 198 | } |
199 | } | 199 | } |
200 | 200 | ||
201 | /// <summary> | 201 | /// <summary> |
202 | /// A class to enable modules to register console and script commands, which enforces typing and valid input. | 202 | /// A class to enable modules to register console and script commands, which enforces typing and valid input. |
203 | /// </summary> | 203 | /// </summary> |
204 | public class Commander : ICommander | 204 | public class Commander : ICommander |
205 | { | 205 | { |
206 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 206 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
207 | private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>(); | 207 | private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>(); |
208 | private string m_name; | 208 | private string m_name; |
209 | 209 | ||
210 | public Commander(string name) | 210 | public Commander(string name) |
211 | { | 211 | { |
212 | m_name = name; | 212 | m_name = name; |
213 | } | 213 | } |
214 | 214 | ||
215 | #region ICommander Members | 215 | #region ICommander Members |
216 | 216 | ||
217 | public void RegisterCommand(string commandName, ICommand command) | 217 | public void RegisterCommand(string commandName, ICommand command) |
218 | { | 218 | { |
219 | m_commands[commandName] = command; | 219 | m_commands[commandName] = command; |
220 | } | 220 | } |
221 | 221 | ||
222 | /// <summary> | 222 | /// <summary> |
223 | /// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands | 223 | /// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands |
224 | /// </summary> | 224 | /// </summary> |
225 | /// <returns>Returns C# source code to create a binding</returns> | 225 | /// <returns>Returns C# source code to create a binding</returns> |
226 | public string GenerateRuntimeAPI() | 226 | public string GenerateRuntimeAPI() |
227 | { | 227 | { |
228 | string classSrc = "\n\tpublic class " + m_name + " {\n"; | 228 | string classSrc = "\n\tpublic class " + m_name + " {\n"; |
229 | foreach (ICommand com in m_commands.Values) | 229 | foreach (ICommand com in m_commands.Values) |
230 | { | 230 | { |
231 | classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( "; | 231 | classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( "; |
232 | foreach (KeyValuePair<string, string> arg in com.Arguments) | 232 | foreach (KeyValuePair<string, string> arg in com.Arguments) |
233 | { | 233 | { |
234 | classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ","; | 234 | classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ","; |
235 | } | 235 | } |
236 | classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma | 236 | classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma |
237 | classSrc += " )\n\t{\n"; | 237 | classSrc += " )\n\t{\n"; |
238 | classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n"; | 238 | classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n"; |
239 | int i = 0; | 239 | int i = 0; |
240 | foreach (KeyValuePair<string, string> arg in com.Arguments) | 240 | foreach (KeyValuePair<string, string> arg in com.Arguments) |
241 | { | 241 | { |
242 | classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n"; | 242 | classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n"; |
243 | i++; | 243 | i++; |
244 | } | 244 | } |
245 | classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n"; | 245 | classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n"; |
246 | classSrc += "\t}\n"; | 246 | classSrc += "\t}\n"; |
247 | } | 247 | } |
248 | classSrc += "}\n"; | 248 | classSrc += "}\n"; |
249 | 249 | ||
250 | return classSrc; | 250 | return classSrc; |
251 | } | 251 | } |
252 | 252 | ||
253 | /// <summary> | 253 | /// <summary> |
254 | /// Runs a specified function with attached arguments | 254 | /// Runs a specified function with attached arguments |
255 | /// *** <b>DO NOT CALL DIRECTLY.</b> *** | 255 | /// *** <b>DO NOT CALL DIRECTLY.</b> *** |
256 | /// Call ProcessConsoleCommand instead if handling human input. | 256 | /// Call ProcessConsoleCommand instead if handling human input. |
257 | /// </summary> | 257 | /// </summary> |
258 | /// <param name="function">The function name to call</param> | 258 | /// <param name="function">The function name to call</param> |
259 | /// <param name="args">The function parameters</param> | 259 | /// <param name="args">The function parameters</param> |
260 | public void Run(string function, object[] args) | 260 | public void Run(string function, object[] args) |
261 | { | 261 | { |
262 | m_commands[function].Run(args); | 262 | m_commands[function].Run(args); |
263 | } | 263 | } |
264 | 264 | ||
265 | public void ProcessConsoleCommand(string function, string[] args) | 265 | public void ProcessConsoleCommand(string function, string[] args) |
266 | { | 266 | { |
267 | if (m_commands.ContainsKey(function)) | 267 | if (m_commands.ContainsKey(function)) |
268 | { | 268 | { |
269 | if (args.Length > 0 && args[0] == "help") | 269 | if (args.Length > 0 && args[0] == "help") |
270 | { | 270 | { |
271 | m_commands[function].ShowConsoleHelp(); | 271 | m_commands[function].ShowConsoleHelp(); |
272 | } | 272 | } |
273 | else | 273 | else |
274 | { | 274 | { |
275 | m_commands[function].Run(args); | 275 | m_commands[function].Run(args); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | else | 278 | else |
279 | { | 279 | { |
280 | if (function != "help") | 280 | if (function != "help") |
281 | m_log.Error("Invalid command - No such command exists"); | 281 | m_log.Error("Invalid command - No such command exists"); |
282 | if (function == "api") | 282 | if (function == "api") |
283 | m_log.Info(GenerateRuntimeAPI()); | 283 | m_log.Info(GenerateRuntimeAPI()); |
284 | ShowConsoleHelp(); | 284 | ShowConsoleHelp(); |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | #endregion | 288 | #endregion |
289 | 289 | ||
290 | private void ShowConsoleHelp() | 290 | private void ShowConsoleHelp() |
291 | { | 291 | { |
292 | m_log.Info("===" + m_name + "==="); | 292 | m_log.Info("===" + m_name + "==="); |
293 | foreach (ICommand com in m_commands.Values) | 293 | foreach (ICommand com in m_commands.Values) |
294 | { | 294 | { |
295 | m_log.Info("* " + com.Name + " - " + com.Help); | 295 | m_log.Info("* " + com.Name + " - " + com.Help); |
296 | } | 296 | } |
297 | } | 297 | } |
298 | 298 | ||
299 | private string EscapeRuntimeAPICommand(string command) | 299 | private string EscapeRuntimeAPICommand(string command) |
300 | { | 300 | { |
301 | command = command.Replace('-', '_'); | 301 | command = command.Replace('-', '_'); |
302 | StringBuilder tmp = new StringBuilder(command); | 302 | StringBuilder tmp = new StringBuilder(command); |
303 | tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0]; | 303 | tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0]; |
304 | 304 | ||
305 | return tmp.ToString(); | 305 | return tmp.ToString(); |
306 | } | 306 | } |
307 | } | 307 | } |
308 | } \ No newline at end of file | 308 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs b/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs index cf87021..7b5c981 100644 --- a/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs +++ b/OpenSim/Region/Environment/Modules/Framework/CommanderTestModule.cs | |||
@@ -1,88 +1,88 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using Nini.Config; | 29 | using Nini.Config; |
30 | using OpenSim.Region.Environment.Interfaces; | 30 | using OpenSim.Region.Environment.Interfaces; |
31 | using OpenSim.Region.Environment.Scenes; | 31 | using OpenSim.Region.Environment.Scenes; |
32 | 32 | ||
33 | namespace OpenSim.Region.Environment.Modules.Framework | 33 | namespace OpenSim.Region.Environment.Modules.Framework |
34 | { | 34 | { |
35 | public class CommanderTestModule : IRegionModule, ICommandableModule | 35 | public class CommanderTestModule : IRegionModule, ICommandableModule |
36 | { | 36 | { |
37 | private Commander m_commander = new Commander("CommanderTest"); | 37 | private Commander m_commander = new Commander("CommanderTest"); |
38 | private Scene m_scene; | 38 | private Scene m_scene; |
39 | 39 | ||
40 | #region ICommandableModule Members | 40 | #region ICommandableModule Members |
41 | 41 | ||
42 | public ICommander CommandInterface | 42 | public ICommander CommandInterface |
43 | { | 43 | { |
44 | get { throw new NotImplementedException(); } | 44 | get { throw new NotImplementedException(); } |
45 | } | 45 | } |
46 | 46 | ||
47 | #endregion | 47 | #endregion |
48 | 48 | ||
49 | #region IRegionModule Members | 49 | #region IRegionModule Members |
50 | 50 | ||
51 | public void Initialise(Scene scene, IConfigSource source) | 51 | public void Initialise(Scene scene, IConfigSource source) |
52 | { | 52 | { |
53 | m_scene = scene; | 53 | m_scene = scene; |
54 | } | 54 | } |
55 | 55 | ||
56 | public void PostInitialise() | 56 | public void PostInitialise() |
57 | { | 57 | { |
58 | Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string"); | 58 | Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string"); |
59 | testCommand.AddArgument("world", "Write world here", "string"); | 59 | testCommand.AddArgument("world", "Write world here", "string"); |
60 | 60 | ||
61 | m_commander.RegisterCommand("hello", testCommand); | 61 | m_commander.RegisterCommand("hello", testCommand); |
62 | 62 | ||
63 | // Register me | 63 | // Register me |
64 | m_scene.RegisterModuleCommander("commandertest", m_commander); | 64 | m_scene.RegisterModuleCommander("commandertest", m_commander); |
65 | } | 65 | } |
66 | 66 | ||
67 | public void Close() | 67 | public void Close() |
68 | { | 68 | { |
69 | } | 69 | } |
70 | 70 | ||
71 | public string Name | 71 | public string Name |
72 | { | 72 | { |
73 | get { return "CommanderTestModule"; } | 73 | get { return "CommanderTestModule"; } |
74 | } | 74 | } |
75 | 75 | ||
76 | public bool IsSharedModule | 76 | public bool IsSharedModule |
77 | { | 77 | { |
78 | get { return false; } | 78 | get { return false; } |
79 | } | 79 | } |
80 | 80 | ||
81 | #endregion | 81 | #endregion |
82 | 82 | ||
83 | private void InterfaceHelloWorld(Object[] args) | 83 | private void InterfaceHelloWorld(Object[] args) |
84 | { | 84 | { |
85 | Console.WriteLine("Hello World"); | 85 | Console.WriteLine("Hello World"); |
86 | } | 86 | } |
87 | } | 87 | } |
88 | } \ No newline at end of file | 88 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Grid/Interregion/IInterregionModule.cs b/OpenSim/Region/Environment/Modules/Grid/Interregion/IInterregionModule.cs index ac4062b..95d22f0 100644 --- a/OpenSim/Region/Environment/Modules/Grid/Interregion/IInterregionModule.cs +++ b/OpenSim/Region/Environment/Modules/Grid/Interregion/IInterregionModule.cs | |||
@@ -1,16 +1,16 @@ | |||
1 | using OpenSim.Framework; | 1 | using OpenSim.Framework; |
2 | using OpenSim.Region.Environment.Modules.Communications.Interregion; | 2 | using OpenSim.Region.Environment.Modules.Communications.Interregion; |
3 | using OpenSim.Region.Environment.Scenes; | 3 | using OpenSim.Region.Environment.Scenes; |
4 | 4 | ||
5 | namespace OpenSim.Region.Environment.Modules.Grid.Interregion | 5 | namespace OpenSim.Region.Environment.Modules.Grid.Interregion |
6 | { | 6 | { |
7 | public interface IInterregionModule | 7 | public interface IInterregionModule |
8 | { | 8 | { |
9 | void RegisterMethod<T>(T e); | 9 | void RegisterMethod<T>(T e); |
10 | bool HasInterface<T>(Location loc); | 10 | bool HasInterface<T>(Location loc); |
11 | T RequestInterface<T>(Location loc); | 11 | T RequestInterface<T>(Location loc); |
12 | T[] RequestInterface<T>(); | 12 | T[] RequestInterface<T>(); |
13 | Location GetLocationByDirection(Scene scene, InterregionModule.Direction dir); | 13 | Location GetLocationByDirection(Scene scene, InterregionModule.Direction dir); |
14 | void internal_CreateRemotingObjects(); | 14 | void internal_CreateRemotingObjects(); |
15 | } | 15 | } |
16 | } \ No newline at end of file | 16 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Grid/Interregion/InterregionModule.cs b/OpenSim/Region/Environment/Modules/Grid/Interregion/InterregionModule.cs index 8307e50..651ed60 100644 --- a/OpenSim/Region/Environment/Modules/Grid/Interregion/InterregionModule.cs +++ b/OpenSim/Region/Environment/Modules/Grid/Interregion/InterregionModule.cs | |||
@@ -1,180 +1,180 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using System.Runtime.Remoting; | 3 | using System.Runtime.Remoting; |
4 | using System.Runtime.Remoting.Channels; | 4 | using System.Runtime.Remoting.Channels; |
5 | using System.Runtime.Remoting.Channels.Tcp; | 5 | using System.Runtime.Remoting.Channels.Tcp; |
6 | using Nini.Config; | 6 | using Nini.Config; |
7 | using OpenSim.Framework; | 7 | using OpenSim.Framework; |
8 | using OpenSim.Region.Environment.Interfaces; | 8 | using OpenSim.Region.Environment.Interfaces; |
9 | using OpenSim.Region.Environment.Modules.Grid.Interregion; | 9 | using OpenSim.Region.Environment.Modules.Grid.Interregion; |
10 | using OpenSim.Region.Environment.Scenes; | 10 | using OpenSim.Region.Environment.Scenes; |
11 | 11 | ||
12 | namespace OpenSim.Region.Environment.Modules.Communications.Interregion | 12 | namespace OpenSim.Region.Environment.Modules.Communications.Interregion |
13 | { | 13 | { |
14 | public class InterregionModule : IInterregionModule, IRegionModule | 14 | public class InterregionModule : IInterregionModule, IRegionModule |
15 | { | 15 | { |
16 | #region Direction enum | 16 | #region Direction enum |
17 | 17 | ||
18 | public enum Direction | 18 | public enum Direction |
19 | { | 19 | { |
20 | North, | 20 | North, |
21 | NorthEast, | 21 | NorthEast, |
22 | East, | 22 | East, |
23 | SouthEast, | 23 | SouthEast, |
24 | South, | 24 | South, |
25 | SouthWest, | 25 | SouthWest, |
26 | West, | 26 | West, |
27 | NorthWest | 27 | NorthWest |
28 | } | 28 | } |
29 | 29 | ||
30 | #endregion | 30 | #endregion |
31 | 31 | ||
32 | private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>(); | 32 | private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>(); |
33 | private readonly List<Location> m_myLocations = new List<Location>(); | 33 | private readonly List<Location> m_myLocations = new List<Location>(); |
34 | 34 | ||
35 | private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>(); | 35 | private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>(); |
36 | private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>(); | 36 | private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>(); |
37 | private IConfigSource m_config; | 37 | private IConfigSource m_config; |
38 | private bool m_enabled = false; | 38 | private bool m_enabled = false; |
39 | 39 | ||
40 | private Object m_lockObject = new object(); | 40 | private Object m_lockObject = new object(); |
41 | private RemotingObject m_myRemote; | 41 | private RemotingObject m_myRemote; |
42 | private TcpChannel m_tcpChannel; | 42 | private TcpChannel m_tcpChannel; |
43 | private int m_tcpPort = 10101; | 43 | private int m_tcpPort = 10101; |
44 | 44 | ||
45 | #region IInterregionModule Members | 45 | #region IInterregionModule Members |
46 | 46 | ||
47 | public void internal_CreateRemotingObjects() | 47 | public void internal_CreateRemotingObjects() |
48 | { | 48 | { |
49 | lock (m_lockObject) | 49 | lock (m_lockObject) |
50 | { | 50 | { |
51 | if (m_tcpChannel == null) | 51 | if (m_tcpChannel == null) |
52 | { | 52 | { |
53 | m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray()); | 53 | m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray()); |
54 | m_tcpChannel = new TcpChannel(m_tcpPort); | 54 | m_tcpChannel = new TcpChannel(m_tcpPort); |
55 | 55 | ||
56 | ChannelServices.RegisterChannel(m_tcpChannel, false); | 56 | ChannelServices.RegisterChannel(m_tcpChannel, false); |
57 | RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject)); | 57 | RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject)); |
58 | } | 58 | } |
59 | } | 59 | } |
60 | } | 60 | } |
61 | 61 | ||
62 | public void RegisterMethod<T>(T e) | 62 | public void RegisterMethod<T>(T e) |
63 | { | 63 | { |
64 | m_interfaces[typeof (T)] = e; | 64 | m_interfaces[typeof (T)] = e; |
65 | } | 65 | } |
66 | 66 | ||
67 | public bool HasInterface<T>(Location loc) | 67 | public bool HasInterface<T>(Location loc) |
68 | { | 68 | { |
69 | foreach (string val in m_neighbourInterfaces[loc]) | 69 | foreach (string val in m_neighbourInterfaces[loc]) |
70 | { | 70 | { |
71 | if (val == typeof (T).FullName) | 71 | if (val == typeof (T).FullName) |
72 | { | 72 | { |
73 | return true; | 73 | return true; |
74 | } | 74 | } |
75 | } | 75 | } |
76 | return false; | 76 | return false; |
77 | } | 77 | } |
78 | 78 | ||
79 | public T RequestInterface<T>(Location loc) | 79 | public T RequestInterface<T>(Location loc) |
80 | { | 80 | { |
81 | if (m_neighbourRemote.ContainsKey(loc)) | 81 | if (m_neighbourRemote.ContainsKey(loc)) |
82 | { | 82 | { |
83 | return m_neighbourRemote[loc].RequestInterface<T>(); | 83 | return m_neighbourRemote[loc].RequestInterface<T>(); |
84 | } | 84 | } |
85 | else | 85 | else |
86 | { | 86 | { |
87 | throw new IndexOutOfRangeException("No neighbour availible at that location"); | 87 | throw new IndexOutOfRangeException("No neighbour availible at that location"); |
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | public T[] RequestInterface<T>() | 91 | public T[] RequestInterface<T>() |
92 | { | 92 | { |
93 | List<T> m_t = new List<T>(); | 93 | List<T> m_t = new List<T>(); |
94 | foreach (RemotingObject remote in m_neighbourRemote.Values) | 94 | foreach (RemotingObject remote in m_neighbourRemote.Values) |
95 | { | 95 | { |
96 | try | 96 | try |
97 | { | 97 | { |
98 | m_t.Add(remote.RequestInterface<T>()); | 98 | m_t.Add(remote.RequestInterface<T>()); |
99 | } | 99 | } |
100 | catch (NotSupportedException) | 100 | catch (NotSupportedException) |
101 | { | 101 | { |
102 | } | 102 | } |
103 | } | 103 | } |
104 | return m_t.ToArray(); | 104 | return m_t.ToArray(); |
105 | } | 105 | } |
106 | 106 | ||
107 | public Location GetLocationByDirection(Scene scene, Direction dir) | 107 | public Location GetLocationByDirection(Scene scene, Direction dir) |
108 | { | 108 | { |
109 | return new Location(0, 0); | 109 | return new Location(0, 0); |
110 | } | 110 | } |
111 | 111 | ||
112 | #endregion | 112 | #endregion |
113 | 113 | ||
114 | //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated. | 114 | //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated. |
115 | 115 | ||
116 | #region IRegionModule Members | 116 | #region IRegionModule Members |
117 | 117 | ||
118 | public void Initialise(Scene scene, IConfigSource source) | 118 | public void Initialise(Scene scene, IConfigSource source) |
119 | { | 119 | { |
120 | if (m_enabled) | 120 | if (m_enabled) |
121 | { | 121 | { |
122 | m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX, | 122 | m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX, |
123 | (int) scene.RegionInfo.RegionLocY)); | 123 | (int) scene.RegionInfo.RegionLocY)); |
124 | m_config = source; | 124 | m_config = source; |
125 | 125 | ||
126 | scene.RegisterModuleInterface<IInterregionModule>(this); | 126 | scene.RegisterModuleInterface<IInterregionModule>(this); |
127 | } | 127 | } |
128 | } | 128 | } |
129 | 129 | ||
130 | //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated. | 130 | //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated. |
131 | public void PostInitialise() | 131 | public void PostInitialise() |
132 | { | 132 | { |
133 | if (m_enabled) | 133 | if (m_enabled) |
134 | { | 134 | { |
135 | try | 135 | try |
136 | { | 136 | { |
137 | m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort); | 137 | m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort); |
138 | } | 138 | } |
139 | catch | 139 | catch |
140 | { | 140 | { |
141 | } | 141 | } |
142 | 142 | ||
143 | internal_CreateRemotingObjects(); | 143 | internal_CreateRemotingObjects(); |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | public void Close() | 147 | public void Close() |
148 | { | 148 | { |
149 | ChannelServices.UnregisterChannel(m_tcpChannel); | 149 | ChannelServices.UnregisterChannel(m_tcpChannel); |
150 | } | 150 | } |
151 | 151 | ||
152 | public string Name | 152 | public string Name |
153 | { | 153 | { |
154 | get { return "InterregionModule"; } | 154 | get { return "InterregionModule"; } |
155 | } | 155 | } |
156 | 156 | ||
157 | public bool IsSharedModule | 157 | public bool IsSharedModule |
158 | { | 158 | { |
159 | get { return true; } | 159 | get { return true; } |
160 | } | 160 | } |
161 | 161 | ||
162 | #endregion | 162 | #endregion |
163 | 163 | ||
164 | public void RegisterRemoteRegion(string uri) | 164 | public void RegisterRemoteRegion(string uri) |
165 | { | 165 | { |
166 | RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri)); | 166 | RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri)); |
167 | } | 167 | } |
168 | 168 | ||
169 | private void RegisterRemotingInterface(RemotingObject remote) | 169 | private void RegisterRemotingInterface(RemotingObject remote) |
170 | { | 170 | { |
171 | Location[] locs = remote.GetLocations(); | 171 | Location[] locs = remote.GetLocations(); |
172 | string[] interfaces = remote.GetInterfaces(); | 172 | string[] interfaces = remote.GetInterfaces(); |
173 | foreach (Location loc in locs) | 173 | foreach (Location loc in locs) |
174 | { | 174 | { |
175 | m_neighbourInterfaces[loc] = interfaces; | 175 | m_neighbourInterfaces[loc] = interfaces; |
176 | m_neighbourRemote[loc] = remote; | 176 | m_neighbourRemote[loc] = remote; |
177 | } | 177 | } |
178 | } | 178 | } |
179 | } | 179 | } |
180 | } \ No newline at end of file | 180 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Grid/Interregion/RemotingObject.cs b/OpenSim/Region/Environment/Modules/Grid/Interregion/RemotingObject.cs index 2c72bb9..453a2b7 100644 --- a/OpenSim/Region/Environment/Modules/Grid/Interregion/RemotingObject.cs +++ b/OpenSim/Region/Environment/Modules/Grid/Interregion/RemotingObject.cs | |||
@@ -1,50 +1,50 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using OpenSim.Framework; | 3 | using OpenSim.Framework; |
4 | 4 | ||
5 | namespace OpenSim.Region.Environment.Modules.Grid.Interregion | 5 | namespace OpenSim.Region.Environment.Modules.Grid.Interregion |
6 | { | 6 | { |
7 | public class RemotingObject : MarshalByRefObject | 7 | public class RemotingObject : MarshalByRefObject |
8 | { | 8 | { |
9 | private readonly Location[] m_coords; | 9 | private readonly Location[] m_coords; |
10 | private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>(); | 10 | private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>(); |
11 | 11 | ||
12 | public RemotingObject(Dictionary<Type, Object> myInterfaces, Location[] coords) | 12 | public RemotingObject(Dictionary<Type, Object> myInterfaces, Location[] coords) |
13 | { | 13 | { |
14 | m_interfaces = myInterfaces; | 14 | m_interfaces = myInterfaces; |
15 | m_coords = coords; | 15 | m_coords = coords; |
16 | } | 16 | } |
17 | 17 | ||
18 | public Location[] GetLocations() | 18 | public Location[] GetLocations() |
19 | { | 19 | { |
20 | return (Location[]) m_coords.Clone(); | 20 | return (Location[]) m_coords.Clone(); |
21 | } | 21 | } |
22 | 22 | ||
23 | public string[] GetInterfaces() | 23 | public string[] GetInterfaces() |
24 | { | 24 | { |
25 | string[] interfaces = new string[m_interfaces.Count]; | 25 | string[] interfaces = new string[m_interfaces.Count]; |
26 | int i = 0; | 26 | int i = 0; |
27 | 27 | ||
28 | foreach (KeyValuePair<Type, object> pair in m_interfaces) | 28 | foreach (KeyValuePair<Type, object> pair in m_interfaces) |
29 | { | 29 | { |
30 | interfaces[i++] = pair.Key.FullName; | 30 | interfaces[i++] = pair.Key.FullName; |
31 | } | 31 | } |
32 | 32 | ||
33 | return interfaces; | 33 | return interfaces; |
34 | } | 34 | } |
35 | 35 | ||
36 | /// <summary> | 36 | /// <summary> |
37 | /// Returns a registered interface availible to neighbouring regions. | 37 | /// Returns a registered interface availible to neighbouring regions. |
38 | /// </summary> | 38 | /// </summary> |
39 | /// <typeparam name="T">The type of interface you wish to request</typeparam> | 39 | /// <typeparam name="T">The type of interface you wish to request</typeparam> |
40 | /// <returns>A MarshalByRefObject inherited from this region inheriting the interface requested.</returns> | 40 | /// <returns>A MarshalByRefObject inherited from this region inheriting the interface requested.</returns> |
41 | /// <remarks>All registered interfaces <b>MUST</b> inherit from MarshalByRefObject and use only serialisable types.</remarks> | 41 | /// <remarks>All registered interfaces <b>MUST</b> inherit from MarshalByRefObject and use only serialisable types.</remarks> |
42 | public T RequestInterface<T>() | 42 | public T RequestInterface<T>() |
43 | { | 43 | { |
44 | if (m_interfaces.ContainsKey(typeof (T))) | 44 | if (m_interfaces.ContainsKey(typeof (T))) |
45 | return (T) m_interfaces[typeof (T)]; | 45 | return (T) m_interfaces[typeof (T)]; |
46 | 46 | ||
47 | throw new NotSupportedException("No such interface registered."); | 47 | throw new NotSupportedException("No such interface registered."); |
48 | } | 48 | } |
49 | } | 49 | } |
50 | } \ No newline at end of file | 50 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs index 68ca5e9..c0e3d3b 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs | |||
@@ -1,283 +1,283 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Drawing; | 30 | using System.Drawing; |
31 | using System.Drawing.Imaging; | 31 | using System.Drawing.Imaging; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenJPEGNet; | 34 | using OpenJPEGNet; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
37 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
38 | 38 | ||
39 | namespace OpenSim.Region.Environment.Modules.Scripting.DynamicTexture | 39 | namespace OpenSim.Region.Environment.Modules.Scripting.DynamicTexture |
40 | { | 40 | { |
41 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager | 41 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager |
42 | { | 42 | { |
43 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); | 43 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); |
44 | 44 | ||
45 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = | 45 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = |
46 | new Dictionary<string, IDynamicTextureRender>(); | 46 | new Dictionary<string, IDynamicTextureRender>(); |
47 | 47 | ||
48 | private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>(); | 48 | private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>(); |
49 | 49 | ||
50 | #region IDynamicTextureManager Members | 50 | #region IDynamicTextureManager Members |
51 | 51 | ||
52 | public void RegisterRender(string handleType, IDynamicTextureRender render) | 52 | public void RegisterRender(string handleType, IDynamicTextureRender render) |
53 | { | 53 | { |
54 | if (!RenderPlugins.ContainsKey(handleType)) | 54 | if (!RenderPlugins.ContainsKey(handleType)) |
55 | { | 55 | { |
56 | RenderPlugins.Add(handleType, render); | 56 | RenderPlugins.Add(handleType, render); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | public void ReturnData(LLUUID id, byte[] data) | 60 | public void ReturnData(LLUUID id, byte[] data) |
61 | { | 61 | { |
62 | if (Updaters.ContainsKey(id)) | 62 | if (Updaters.ContainsKey(id)) |
63 | { | 63 | { |
64 | DynamicTextureUpdater updater = Updaters[id]; | 64 | DynamicTextureUpdater updater = Updaters[id]; |
65 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) | 65 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) |
66 | { | 66 | { |
67 | Scene scene = RegisteredScenes[updater.SimUUID]; | 67 | Scene scene = RegisteredScenes[updater.SimUUID]; |
68 | updater.DataReceived(data, scene); | 68 | updater.DataReceived(data, scene); |
69 | } | 69 | } |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | 73 | ||
74 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, | 74 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, |
75 | string extraParams, int updateTimer) | 75 | string extraParams, int updateTimer) |
76 | { | 76 | { |
77 | return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); | 77 | return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); |
78 | } | 78 | } |
79 | 79 | ||
80 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, | 80 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, |
81 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) | 81 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) |
82 | { | 82 | { |
83 | if (RenderPlugins.ContainsKey(contentType)) | 83 | if (RenderPlugins.ContainsKey(contentType)) |
84 | { | 84 | { |
85 | //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType); | 85 | //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType); |
86 | 86 | ||
87 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | 87 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); |
88 | updater.SimUUID = simID; | 88 | updater.SimUUID = simID; |
89 | updater.PrimID = primID; | 89 | updater.PrimID = primID; |
90 | updater.ContentType = contentType; | 90 | updater.ContentType = contentType; |
91 | updater.Url = url; | 91 | updater.Url = url; |
92 | updater.UpdateTimer = updateTimer; | 92 | updater.UpdateTimer = updateTimer; |
93 | updater.UpdaterID = LLUUID.Random(); | 93 | updater.UpdaterID = LLUUID.Random(); |
94 | updater.Params = extraParams; | 94 | updater.Params = extraParams; |
95 | updater.BlendWithOldTexture = SetBlending; | 95 | updater.BlendWithOldTexture = SetBlending; |
96 | updater.FrontAlpha = AlphaValue; | 96 | updater.FrontAlpha = AlphaValue; |
97 | 97 | ||
98 | if (!Updaters.ContainsKey(updater.UpdaterID)) | 98 | if (!Updaters.ContainsKey(updater.UpdaterID)) |
99 | { | 99 | { |
100 | Updaters.Add(updater.UpdaterID, updater); | 100 | Updaters.Add(updater.UpdaterID, updater); |
101 | } | 101 | } |
102 | 102 | ||
103 | RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); | 103 | RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); |
104 | return updater.UpdaterID; | 104 | return updater.UpdaterID; |
105 | } | 105 | } |
106 | return LLUUID.Zero; | 106 | return LLUUID.Zero; |
107 | } | 107 | } |
108 | 108 | ||
109 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, | 109 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, |
110 | string extraParams, int updateTimer) | 110 | string extraParams, int updateTimer) |
111 | { | 111 | { |
112 | return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); | 112 | return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); |
113 | } | 113 | } |
114 | 114 | ||
115 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, | 115 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, |
116 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) | 116 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) |
117 | { | 117 | { |
118 | if (RenderPlugins.ContainsKey(contentType)) | 118 | if (RenderPlugins.ContainsKey(contentType)) |
119 | { | 119 | { |
120 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | 120 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); |
121 | updater.SimUUID = simID; | 121 | updater.SimUUID = simID; |
122 | updater.PrimID = primID; | 122 | updater.PrimID = primID; |
123 | updater.ContentType = contentType; | 123 | updater.ContentType = contentType; |
124 | updater.BodyData = data; | 124 | updater.BodyData = data; |
125 | updater.UpdateTimer = updateTimer; | 125 | updater.UpdateTimer = updateTimer; |
126 | updater.UpdaterID = LLUUID.Random(); | 126 | updater.UpdaterID = LLUUID.Random(); |
127 | updater.Params = extraParams; | 127 | updater.Params = extraParams; |
128 | updater.BlendWithOldTexture = SetBlending; | 128 | updater.BlendWithOldTexture = SetBlending; |
129 | updater.FrontAlpha = AlphaValue; | 129 | updater.FrontAlpha = AlphaValue; |
130 | 130 | ||
131 | if (!Updaters.ContainsKey(updater.UpdaterID)) | 131 | if (!Updaters.ContainsKey(updater.UpdaterID)) |
132 | { | 132 | { |
133 | Updaters.Add(updater.UpdaterID, updater); | 133 | Updaters.Add(updater.UpdaterID, updater); |
134 | } | 134 | } |
135 | 135 | ||
136 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); | 136 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); |
137 | return updater.UpdaterID; | 137 | return updater.UpdaterID; |
138 | } | 138 | } |
139 | return LLUUID.Zero; | 139 | return LLUUID.Zero; |
140 | } | 140 | } |
141 | 141 | ||
142 | #endregion | 142 | #endregion |
143 | 143 | ||
144 | #region IRegionModule Members | 144 | #region IRegionModule Members |
145 | 145 | ||
146 | public void Initialise(Scene scene, IConfigSource config) | 146 | public void Initialise(Scene scene, IConfigSource config) |
147 | { | 147 | { |
148 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | 148 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) |
149 | { | 149 | { |
150 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); | 150 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); |
151 | scene.RegisterModuleInterface<IDynamicTextureManager>(this); | 151 | scene.RegisterModuleInterface<IDynamicTextureManager>(this); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | public void PostInitialise() | 155 | public void PostInitialise() |
156 | { | 156 | { |
157 | } | 157 | } |
158 | 158 | ||
159 | public void Close() | 159 | public void Close() |
160 | { | 160 | { |
161 | } | 161 | } |
162 | 162 | ||
163 | public string Name | 163 | public string Name |
164 | { | 164 | { |
165 | get { return "DynamicTextureModule"; } | 165 | get { return "DynamicTextureModule"; } |
166 | } | 166 | } |
167 | 167 | ||
168 | public bool IsSharedModule | 168 | public bool IsSharedModule |
169 | { | 169 | { |
170 | get { return true; } | 170 | get { return true; } |
171 | } | 171 | } |
172 | 172 | ||
173 | #endregion | 173 | #endregion |
174 | 174 | ||
175 | #region Nested type: DynamicTextureUpdater | 175 | #region Nested type: DynamicTextureUpdater |
176 | 176 | ||
177 | public class DynamicTextureUpdater | 177 | public class DynamicTextureUpdater |
178 | { | 178 | { |
179 | public bool BlendWithOldTexture = false; | 179 | public bool BlendWithOldTexture = false; |
180 | public string BodyData; | 180 | public string BodyData; |
181 | public string ContentType; | 181 | public string ContentType; |
182 | public byte FrontAlpha = 255; | 182 | public byte FrontAlpha = 255; |
183 | public LLUUID LastAssetID; | 183 | public LLUUID LastAssetID; |
184 | public string Params; | 184 | public string Params; |
185 | public LLUUID PrimID; | 185 | public LLUUID PrimID; |
186 | public bool SetNewFrontAlpha = false; | 186 | public bool SetNewFrontAlpha = false; |
187 | public LLUUID SimUUID; | 187 | public LLUUID SimUUID; |
188 | public LLUUID UpdaterID; | 188 | public LLUUID UpdaterID; |
189 | public int UpdateTimer; | 189 | public int UpdateTimer; |
190 | public string Url; | 190 | public string Url; |
191 | 191 | ||
192 | public DynamicTextureUpdater() | 192 | public DynamicTextureUpdater() |
193 | { | 193 | { |
194 | LastAssetID = LLUUID.Zero; | 194 | LastAssetID = LLUUID.Zero; |
195 | UpdateTimer = 0; | 195 | UpdateTimer = 0; |
196 | BodyData = null; | 196 | BodyData = null; |
197 | } | 197 | } |
198 | 198 | ||
199 | public void DataReceived(byte[] data, Scene scene) | 199 | public void DataReceived(byte[] data, Scene scene) |
200 | { | 200 | { |
201 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); | 201 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); |
202 | byte[] assetData; | 202 | byte[] assetData; |
203 | AssetBase oldAsset = null; | 203 | AssetBase oldAsset = null; |
204 | if (BlendWithOldTexture) | 204 | if (BlendWithOldTexture) |
205 | { | 205 | { |
206 | LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; | 206 | LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; |
207 | oldAsset = scene.AssetCache.GetAsset(lastTextureID, true); | 207 | oldAsset = scene.AssetCache.GetAsset(lastTextureID, true); |
208 | if (oldAsset != null) | 208 | if (oldAsset != null) |
209 | { | 209 | { |
210 | assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); | 210 | assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); |
211 | } | 211 | } |
212 | else | 212 | else |
213 | { | 213 | { |
214 | assetData = new byte[data.Length]; | 214 | assetData = new byte[data.Length]; |
215 | Array.Copy(data, assetData, data.Length); | 215 | Array.Copy(data, assetData, data.Length); |
216 | } | 216 | } |
217 | } | 217 | } |
218 | else | 218 | else |
219 | { | 219 | { |
220 | assetData = new byte[data.Length]; | 220 | assetData = new byte[data.Length]; |
221 | Array.Copy(data, assetData, data.Length); | 221 | Array.Copy(data, assetData, data.Length); |
222 | } | 222 | } |
223 | 223 | ||
224 | //TODO delete the last asset(data), if it was a dynamic texture | 224 | //TODO delete the last asset(data), if it was a dynamic texture |
225 | AssetBase asset = new AssetBase(); | 225 | AssetBase asset = new AssetBase(); |
226 | asset.FullID = LLUUID.Random(); | 226 | asset.FullID = LLUUID.Random(); |
227 | asset.Data = assetData; | 227 | asset.Data = assetData; |
228 | asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); | 228 | asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); |
229 | asset.Type = 0; | 229 | asset.Type = 0; |
230 | asset.Description = "dynamic image"; | 230 | asset.Description = "dynamic image"; |
231 | asset.Local = false; | 231 | asset.Local = false; |
232 | asset.Temporary = true; | 232 | asset.Temporary = true; |
233 | scene.AssetCache.AddAsset(asset); | 233 | scene.AssetCache.AddAsset(asset); |
234 | 234 | ||
235 | LastAssetID = asset.FullID; | 235 | LastAssetID = asset.FullID; |
236 | 236 | ||
237 | 237 | ||
238 | part.Shape.Textures = new LLObject.TextureEntry(asset.FullID); | 238 | part.Shape.Textures = new LLObject.TextureEntry(asset.FullID); |
239 | part.ScheduleFullUpdate(); | 239 | part.ScheduleFullUpdate(); |
240 | } | 240 | } |
241 | 241 | ||
242 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) | 242 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) |
243 | { | 243 | { |
244 | Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage)); | 244 | Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage)); |
245 | Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage)); | 245 | Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage)); |
246 | if (setNewAlpha) | 246 | if (setNewAlpha) |
247 | { | 247 | { |
248 | SetAlpha(ref image1, newAlpha); | 248 | SetAlpha(ref image1, newAlpha); |
249 | } | 249 | } |
250 | Bitmap joint = MergeBitMaps(image1, image2); | 250 | Bitmap joint = MergeBitMaps(image1, image2); |
251 | 251 | ||
252 | return OpenJPEG.EncodeFromImage(joint, true); | 252 | return OpenJPEG.EncodeFromImage(joint, true); |
253 | } | 253 | } |
254 | 254 | ||
255 | public Bitmap MergeBitMaps(Bitmap front, Bitmap back) | 255 | public Bitmap MergeBitMaps(Bitmap front, Bitmap back) |
256 | { | 256 | { |
257 | Bitmap joint; | 257 | Bitmap joint; |
258 | Graphics jG; | 258 | Graphics jG; |
259 | 259 | ||
260 | joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb); | 260 | joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb); |
261 | jG = Graphics.FromImage(joint); | 261 | jG = Graphics.FromImage(joint); |
262 | 262 | ||
263 | jG.DrawImage(back, 0, 0, back.Width, back.Height); | 263 | jG.DrawImage(back, 0, 0, back.Width, back.Height); |
264 | jG.DrawImage(front, 0, 0, back.Width, back.Height); | 264 | jG.DrawImage(front, 0, 0, back.Width, back.Height); |
265 | 265 | ||
266 | return joint; | 266 | return joint; |
267 | } | 267 | } |
268 | 268 | ||
269 | private void SetAlpha(ref Bitmap b, byte alpha) | 269 | private void SetAlpha(ref Bitmap b, byte alpha) |
270 | { | 270 | { |
271 | for (int w = 0; w < b.Width; w++) | 271 | for (int w = 0; w < b.Width; w++) |
272 | { | 272 | { |
273 | for (int h = 0; h < b.Height; h++) | 273 | for (int h = 0; h < b.Height; h++) |
274 | { | 274 | { |
275 | b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h))); | 275 | b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h))); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | } | 278 | } |
279 | } | 279 | } |
280 | 280 | ||
281 | #endregion | 281 | #endregion |
282 | } | 282 | } |
283 | } \ No newline at end of file | 283 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 184e026..e1339a3 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -1,364 +1,364 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Threading; | 33 | using System.Threading; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | 39 | ||
40 | /***************************************************** | 40 | /***************************************************** |
41 | * | 41 | * |
42 | * ScriptsHttpRequests | 42 | * ScriptsHttpRequests |
43 | * | 43 | * |
44 | * Implements the llHttpRequest and http_response | 44 | * Implements the llHttpRequest and http_response |
45 | * callback. | 45 | * callback. |
46 | * | 46 | * |
47 | * Some stuff was already in LSLLongCmdHandler, and then | 47 | * Some stuff was already in LSLLongCmdHandler, and then |
48 | * there was this file with a stub class in it. So, | 48 | * there was this file with a stub class in it. So, |
49 | * I am moving some of the objects and functions out of | 49 | * I am moving some of the objects and functions out of |
50 | * LSLLongCmdHandler, such as the HttpRequestClass, the | 50 | * LSLLongCmdHandler, such as the HttpRequestClass, the |
51 | * start and stop methods, and setting up pending and | 51 | * start and stop methods, and setting up pending and |
52 | * completed queues. These are processed in the | 52 | * completed queues. These are processed in the |
53 | * LSLLongCmdHandler polling loop. Similiar to the | 53 | * LSLLongCmdHandler polling loop. Similiar to the |
54 | * XMLRPCModule, since that seems to work. | 54 | * XMLRPCModule, since that seems to work. |
55 | * | 55 | * |
56 | * //TODO | 56 | * //TODO |
57 | * | 57 | * |
58 | * This probably needs some throttling mechanism but | 58 | * This probably needs some throttling mechanism but |
59 | * its wide open right now. This applies to both | 59 | * its wide open right now. This applies to both |
60 | * number of requests and data volume. | 60 | * number of requests and data volume. |
61 | * | 61 | * |
62 | * Linden puts all kinds of header fields in the requests. | 62 | * Linden puts all kinds of header fields in the requests. |
63 | * Not doing any of that: | 63 | * Not doing any of that: |
64 | * User-Agent | 64 | * User-Agent |
65 | * X-SecondLife-Shard | 65 | * X-SecondLife-Shard |
66 | * X-SecondLife-Object-Name | 66 | * X-SecondLife-Object-Name |
67 | * X-SecondLife-Object-Key | 67 | * X-SecondLife-Object-Key |
68 | * X-SecondLife-Region | 68 | * X-SecondLife-Region |
69 | * X-SecondLife-Local-Position | 69 | * X-SecondLife-Local-Position |
70 | * X-SecondLife-Local-Velocity | 70 | * X-SecondLife-Local-Velocity |
71 | * X-SecondLife-Local-Rotation | 71 | * X-SecondLife-Local-Rotation |
72 | * X-SecondLife-Owner-Name | 72 | * X-SecondLife-Owner-Name |
73 | * X-SecondLife-Owner-Key | 73 | * X-SecondLife-Owner-Key |
74 | * | 74 | * |
75 | * HTTPS support | 75 | * HTTPS support |
76 | * | 76 | * |
77 | * Configurable timeout? | 77 | * Configurable timeout? |
78 | * Configurable max repsonse size? | 78 | * Configurable max repsonse size? |
79 | * Configurable | 79 | * Configurable |
80 | * | 80 | * |
81 | * **************************************************/ | 81 | * **************************************************/ |
82 | 82 | ||
83 | namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest | 83 | namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest |
84 | { | 84 | { |
85 | public class HttpRequestModule : IRegionModule, IHttpRequests | 85 | public class HttpRequestModule : IRegionModule, IHttpRequests |
86 | { | 86 | { |
87 | private object HttpListLock = new object(); | 87 | private object HttpListLock = new object(); |
88 | private int httpTimeout = 30000; | 88 | private int httpTimeout = 30000; |
89 | private string m_name = "HttpScriptRequests"; | 89 | private string m_name = "HttpScriptRequests"; |
90 | 90 | ||
91 | // <request id, HttpRequestClass> | 91 | // <request id, HttpRequestClass> |
92 | private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests; | 92 | private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests; |
93 | private Scene m_scene; | 93 | private Scene m_scene; |
94 | private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); | 94 | private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); |
95 | 95 | ||
96 | public HttpRequestModule() | 96 | public HttpRequestModule() |
97 | { | 97 | { |
98 | } | 98 | } |
99 | 99 | ||
100 | #region IHttpRequests Members | 100 | #region IHttpRequests Members |
101 | 101 | ||
102 | public LLUUID MakeHttpRequest(string url, string parameters, string body) | 102 | public LLUUID MakeHttpRequest(string url, string parameters, string body) |
103 | { | 103 | { |
104 | return LLUUID.Zero; | 104 | return LLUUID.Zero; |
105 | } | 105 | } |
106 | 106 | ||
107 | public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body) | 107 | public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body) |
108 | { | 108 | { |
109 | LLUUID reqID = LLUUID.Random(); | 109 | LLUUID reqID = LLUUID.Random(); |
110 | HttpRequestClass htc = new HttpRequestClass(); | 110 | HttpRequestClass htc = new HttpRequestClass(); |
111 | 111 | ||
112 | // Partial implementation: support for parameter flags needed | 112 | // Partial implementation: support for parameter flags needed |
113 | // see http://wiki.secondlife.com/wiki/LlHTTPRequest | 113 | // see http://wiki.secondlife.com/wiki/LlHTTPRequest |
114 | // | 114 | // |
115 | // Parameters are expected in {key, value, ... , key, value} | 115 | // Parameters are expected in {key, value, ... , key, value} |
116 | if (parameters != null) | 116 | if (parameters != null) |
117 | { | 117 | { |
118 | string[] parms = parameters.ToArray(); | 118 | string[] parms = parameters.ToArray(); |
119 | for (int i = 0; i < parms.Length / 2; i += 2) | 119 | for (int i = 0; i < parms.Length / 2; i += 2) |
120 | { | 120 | { |
121 | switch (Int32.Parse(parms[i])) | 121 | switch (Int32.Parse(parms[i])) |
122 | { | 122 | { |
123 | case HttpRequestClass.HTTP_METHOD: | 123 | case HttpRequestClass.HTTP_METHOD: |
124 | 124 | ||
125 | htc.httpMethod = parms[i + 1]; | 125 | htc.httpMethod = parms[i + 1]; |
126 | break; | 126 | break; |
127 | 127 | ||
128 | case HttpRequestClass.HTTP_MIMETYPE: | 128 | case HttpRequestClass.HTTP_MIMETYPE: |
129 | 129 | ||
130 | htc.httpMIMEType = parms[i + 1]; | 130 | htc.httpMIMEType = parms[i + 1]; |
131 | break; | 131 | break; |
132 | 132 | ||
133 | case HttpRequestClass.HTTP_BODY_MAXLENGTH: | 133 | case HttpRequestClass.HTTP_BODY_MAXLENGTH: |
134 | 134 | ||
135 | // TODO implement me | 135 | // TODO implement me |
136 | break; | 136 | break; |
137 | 137 | ||
138 | case HttpRequestClass.HTTP_VERIFY_CERT: | 138 | case HttpRequestClass.HTTP_VERIFY_CERT: |
139 | 139 | ||
140 | // TODO implement me | 140 | // TODO implement me |
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
146 | htc.localID = localID; | 146 | htc.localID = localID; |
147 | htc.itemID = itemID; | 147 | htc.itemID = itemID; |
148 | htc.url = url; | 148 | htc.url = url; |
149 | htc.reqID = reqID; | 149 | htc.reqID = reqID; |
150 | htc.httpTimeout = httpTimeout; | 150 | htc.httpTimeout = httpTimeout; |
151 | htc.outbound_body = body; | 151 | htc.outbound_body = body; |
152 | 152 | ||
153 | lock (HttpListLock) | 153 | lock (HttpListLock) |
154 | { | 154 | { |
155 | m_pendingRequests.Add(reqID, htc); | 155 | m_pendingRequests.Add(reqID, htc); |
156 | } | 156 | } |
157 | 157 | ||
158 | htc.process(); | 158 | htc.process(); |
159 | 159 | ||
160 | return reqID; | 160 | return reqID; |
161 | } | 161 | } |
162 | 162 | ||
163 | public void StopHttpRequest(uint m_localID, LLUUID m_itemID) | 163 | public void StopHttpRequest(uint m_localID, LLUUID m_itemID) |
164 | { | 164 | { |
165 | if (m_pendingRequests != null) | 165 | if (m_pendingRequests != null) |
166 | { | 166 | { |
167 | lock (HttpListLock) | 167 | lock (HttpListLock) |
168 | { | 168 | { |
169 | HttpRequestClass tmpReq; | 169 | HttpRequestClass tmpReq; |
170 | if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) | 170 | if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) |
171 | { | 171 | { |
172 | tmpReq.Stop(); | 172 | tmpReq.Stop(); |
173 | m_pendingRequests.Remove(m_itemID); | 173 | m_pendingRequests.Remove(m_itemID); |
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
179 | /* | 179 | /* |
180 | * TODO | 180 | * TODO |
181 | * Not sure how important ordering is is here - the next first | 181 | * Not sure how important ordering is is here - the next first |
182 | * one completed in the list is returned, based soley on its list | 182 | * one completed in the list is returned, based soley on its list |
183 | * position, not the order in which the request was started or | 183 | * position, not the order in which the request was started or |
184 | * finsihed. I thought about setting up a queue for this, but | 184 | * finsihed. I thought about setting up a queue for this, but |
185 | * it will need some refactoring and this works 'enough' right now | 185 | * it will need some refactoring and this works 'enough' right now |
186 | */ | 186 | */ |
187 | 187 | ||
188 | public HttpRequestClass GetNextCompletedRequest() | 188 | public HttpRequestClass GetNextCompletedRequest() |
189 | { | 189 | { |
190 | lock (HttpListLock) | 190 | lock (HttpListLock) |
191 | { | 191 | { |
192 | foreach (LLUUID luid in m_pendingRequests.Keys) | 192 | foreach (LLUUID luid in m_pendingRequests.Keys) |
193 | { | 193 | { |
194 | HttpRequestClass tmpReq; | 194 | HttpRequestClass tmpReq; |
195 | 195 | ||
196 | if (m_pendingRequests.TryGetValue(luid, out tmpReq)) | 196 | if (m_pendingRequests.TryGetValue(luid, out tmpReq)) |
197 | { | 197 | { |
198 | if (tmpReq.finished) | 198 | if (tmpReq.finished) |
199 | { | 199 | { |
200 | return tmpReq; | 200 | return tmpReq; |
201 | } | 201 | } |
202 | } | 202 | } |
203 | } | 203 | } |
204 | } | 204 | } |
205 | return null; | 205 | return null; |
206 | } | 206 | } |
207 | 207 | ||
208 | public void RemoveCompletedRequest(LLUUID id) | 208 | public void RemoveCompletedRequest(LLUUID id) |
209 | { | 209 | { |
210 | lock (HttpListLock) | 210 | lock (HttpListLock) |
211 | { | 211 | { |
212 | HttpRequestClass tmpReq; | 212 | HttpRequestClass tmpReq; |
213 | if (m_pendingRequests.TryGetValue(id, out tmpReq)) | 213 | if (m_pendingRequests.TryGetValue(id, out tmpReq)) |
214 | { | 214 | { |
215 | tmpReq.Stop(); | 215 | tmpReq.Stop(); |
216 | tmpReq = null; | 216 | tmpReq = null; |
217 | m_pendingRequests.Remove(id); | 217 | m_pendingRequests.Remove(id); |
218 | } | 218 | } |
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | #endregion | 222 | #endregion |
223 | 223 | ||
224 | #region IRegionModule Members | 224 | #region IRegionModule Members |
225 | 225 | ||
226 | public void Initialise(Scene scene, IConfigSource config) | 226 | public void Initialise(Scene scene, IConfigSource config) |
227 | { | 227 | { |
228 | m_scene = scene; | 228 | m_scene = scene; |
229 | 229 | ||
230 | m_scene.RegisterModuleInterface<IHttpRequests>(this); | 230 | m_scene.RegisterModuleInterface<IHttpRequests>(this); |
231 | 231 | ||
232 | m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>(); | 232 | m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>(); |
233 | } | 233 | } |
234 | 234 | ||
235 | public void PostInitialise() | 235 | public void PostInitialise() |
236 | { | 236 | { |
237 | } | 237 | } |
238 | 238 | ||
239 | public void Close() | 239 | public void Close() |
240 | { | 240 | { |
241 | } | 241 | } |
242 | 242 | ||
243 | public string Name | 243 | public string Name |
244 | { | 244 | { |
245 | get { return m_name; } | 245 | get { return m_name; } |
246 | } | 246 | } |
247 | 247 | ||
248 | public bool IsSharedModule | 248 | public bool IsSharedModule |
249 | { | 249 | { |
250 | get { return true; } | 250 | get { return true; } |
251 | } | 251 | } |
252 | 252 | ||
253 | #endregion | 253 | #endregion |
254 | } | 254 | } |
255 | 255 | ||
256 | public class HttpRequestClass | 256 | public class HttpRequestClass |
257 | { | 257 | { |
258 | // Constants for parameters | 258 | // Constants for parameters |
259 | public const int HTTP_BODY_MAXLENGTH = 2; | 259 | public const int HTTP_BODY_MAXLENGTH = 2; |
260 | public const int HTTP_METHOD = 0; | 260 | public const int HTTP_METHOD = 0; |
261 | public const int HTTP_MIMETYPE = 1; | 261 | public const int HTTP_MIMETYPE = 1; |
262 | public const int HTTP_VERIFY_CERT = 3; | 262 | public const int HTTP_VERIFY_CERT = 3; |
263 | public bool finished; | 263 | public bool finished; |
264 | public int httpBodyMaxLen = 2048; // not implemented | 264 | public int httpBodyMaxLen = 2048; // not implemented |
265 | 265 | ||
266 | // Parameter members and default values | 266 | // Parameter members and default values |
267 | public string httpMethod = "GET"; | 267 | public string httpMethod = "GET"; |
268 | public string httpMIMEType = "text/plain;charset=utf-8"; | 268 | public string httpMIMEType = "text/plain;charset=utf-8"; |
269 | private Thread httpThread; | 269 | private Thread httpThread; |
270 | public int httpTimeout; | 270 | public int httpTimeout; |
271 | public bool httpVerifyCert = true; // not implemented | 271 | public bool httpVerifyCert = true; // not implemented |
272 | 272 | ||
273 | // Request info | 273 | // Request info |
274 | public LLUUID itemID; | 274 | public LLUUID itemID; |
275 | public uint localID; | 275 | public uint localID; |
276 | public DateTime next; | 276 | public DateTime next; |
277 | public string outbound_body; | 277 | public string outbound_body; |
278 | public LLUUID reqID; | 278 | public LLUUID reqID; |
279 | public HttpWebRequest request; | 279 | public HttpWebRequest request; |
280 | public string response_body; | 280 | public string response_body; |
281 | public List<string> response_metadata; | 281 | public List<string> response_metadata; |
282 | public int status; | 282 | public int status; |
283 | public string url; | 283 | public string url; |
284 | 284 | ||
285 | public void process() | 285 | public void process() |
286 | { | 286 | { |
287 | httpThread = new Thread(SendRequest); | 287 | httpThread = new Thread(SendRequest); |
288 | httpThread.Name = "HttpRequestThread"; | 288 | httpThread.Name = "HttpRequestThread"; |
289 | httpThread.Priority = ThreadPriority.BelowNormal; | 289 | httpThread.Priority = ThreadPriority.BelowNormal; |
290 | httpThread.IsBackground = true; | 290 | httpThread.IsBackground = true; |
291 | finished = false; | 291 | finished = false; |
292 | httpThread.Start(); | 292 | httpThread.Start(); |
293 | ThreadTracker.Add(httpThread); | 293 | ThreadTracker.Add(httpThread); |
294 | } | 294 | } |
295 | 295 | ||
296 | /* | 296 | /* |
297 | * TODO: More work on the response codes. Right now | 297 | * TODO: More work on the response codes. Right now |
298 | * returning 200 for success or 499 for exception | 298 | * returning 200 for success or 499 for exception |
299 | */ | 299 | */ |
300 | 300 | ||
301 | public void SendRequest() | 301 | public void SendRequest() |
302 | { | 302 | { |
303 | HttpWebResponse response = null; | 303 | HttpWebResponse response = null; |
304 | StringBuilder sb = new StringBuilder(); | 304 | StringBuilder sb = new StringBuilder(); |
305 | byte[] buf = new byte[8192]; | 305 | byte[] buf = new byte[8192]; |
306 | string tempString = null; | 306 | string tempString = null; |
307 | int count = 0; | 307 | int count = 0; |
308 | 308 | ||
309 | try | 309 | try |
310 | { | 310 | { |
311 | request = (HttpWebRequest) | 311 | request = (HttpWebRequest) |
312 | WebRequest.Create(url); | 312 | WebRequest.Create(url); |
313 | request.Method = httpMethod; | 313 | request.Method = httpMethod; |
314 | request.ContentType = httpMIMEType; | 314 | request.ContentType = httpMIMEType; |
315 | 315 | ||
316 | request.Timeout = httpTimeout; | 316 | request.Timeout = httpTimeout; |
317 | // execute the request | 317 | // execute the request |
318 | response = (HttpWebResponse) | 318 | response = (HttpWebResponse) |
319 | request.GetResponse(); | 319 | request.GetResponse(); |
320 | 320 | ||
321 | Stream resStream = response.GetResponseStream(); | 321 | Stream resStream = response.GetResponseStream(); |
322 | 322 | ||
323 | do | 323 | do |
324 | { | 324 | { |
325 | // fill the buffer with data | 325 | // fill the buffer with data |
326 | count = resStream.Read(buf, 0, buf.Length); | 326 | count = resStream.Read(buf, 0, buf.Length); |
327 | 327 | ||
328 | // make sure we read some data | 328 | // make sure we read some data |
329 | if (count != 0) | 329 | if (count != 0) |
330 | { | 330 | { |
331 | // translate from bytes to ASCII text | 331 | // translate from bytes to ASCII text |
332 | tempString = Encoding.UTF8.GetString(buf, 0, count); | 332 | tempString = Encoding.UTF8.GetString(buf, 0, count); |
333 | 333 | ||
334 | // continue building the string | 334 | // continue building the string |
335 | sb.Append(tempString); | 335 | sb.Append(tempString); |
336 | } | 336 | } |
337 | } while (count > 0); // any more data to read? | 337 | } while (count > 0); // any more data to read? |
338 | 338 | ||
339 | response_body = sb.ToString(); | 339 | response_body = sb.ToString(); |
340 | } | 340 | } |
341 | catch (Exception e) | 341 | catch (Exception e) |
342 | { | 342 | { |
343 | status = 499; | 343 | status = 499; |
344 | response_body = e.Message; | 344 | response_body = e.Message; |
345 | finished = true; | 345 | finished = true; |
346 | return; | 346 | return; |
347 | } | 347 | } |
348 | 348 | ||
349 | status = 200; | 349 | status = 200; |
350 | finished = true; | 350 | finished = true; |
351 | } | 351 | } |
352 | 352 | ||
353 | public void Stop() | 353 | public void Stop() |
354 | { | 354 | { |
355 | try | 355 | try |
356 | { | 356 | { |
357 | httpThread.Abort(); | 357 | httpThread.Abort(); |
358 | } | 358 | } |
359 | catch (Exception) | 359 | catch (Exception) |
360 | { | 360 | { |
361 | } | 361 | } |
362 | } | 362 | } |
363 | } | 363 | } |
364 | } \ No newline at end of file | 364 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs index a0408cd..c828ef0 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs | |||
@@ -1,191 +1,191 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net; | 31 | using System.Net; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenJPEGNet; | 34 | using OpenJPEGNet; |
35 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
36 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL | 38 | namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL |
39 | { | 39 | { |
40 | public class LoadImageURLModule : IRegionModule, IDynamicTextureRender | 40 | public class LoadImageURLModule : IRegionModule, IDynamicTextureRender |
41 | { | 41 | { |
42 | private string m_name = "LoadImageURL"; | 42 | private string m_name = "LoadImageURL"; |
43 | private Scene m_scene; | 43 | private Scene m_scene; |
44 | private IDynamicTextureManager m_textureManager; | 44 | private IDynamicTextureManager m_textureManager; |
45 | 45 | ||
46 | #region IDynamicTextureRender Members | 46 | #region IDynamicTextureRender Members |
47 | 47 | ||
48 | public string GetName() | 48 | public string GetName() |
49 | { | 49 | { |
50 | return m_name; | 50 | return m_name; |
51 | } | 51 | } |
52 | 52 | ||
53 | public string GetContentType() | 53 | public string GetContentType() |
54 | { | 54 | { |
55 | return ("image"); | 55 | return ("image"); |
56 | } | 56 | } |
57 | 57 | ||
58 | public bool SupportsAsynchronous() | 58 | public bool SupportsAsynchronous() |
59 | { | 59 | { |
60 | return true; | 60 | return true; |
61 | } | 61 | } |
62 | 62 | ||
63 | public byte[] ConvertUrl(string url, string extraParams) | 63 | public byte[] ConvertUrl(string url, string extraParams) |
64 | { | 64 | { |
65 | return null; | 65 | return null; |
66 | } | 66 | } |
67 | 67 | ||
68 | public byte[] ConvertStream(Stream data, string extraParams) | 68 | public byte[] ConvertStream(Stream data, string extraParams) |
69 | { | 69 | { |
70 | return null; | 70 | return null; |
71 | } | 71 | } |
72 | 72 | ||
73 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) | 73 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) |
74 | { | 74 | { |
75 | MakeHttpRequest(url, id); | 75 | MakeHttpRequest(url, id); |
76 | return true; | 76 | return true; |
77 | } | 77 | } |
78 | 78 | ||
79 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) | 79 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) |
80 | { | 80 | { |
81 | return false; | 81 | return false; |
82 | } | 82 | } |
83 | 83 | ||
84 | #endregion | 84 | #endregion |
85 | 85 | ||
86 | #region IRegionModule Members | 86 | #region IRegionModule Members |
87 | 87 | ||
88 | public void Initialise(Scene scene, IConfigSource config) | 88 | public void Initialise(Scene scene, IConfigSource config) |
89 | { | 89 | { |
90 | if (m_scene == null) | 90 | if (m_scene == null) |
91 | { | 91 | { |
92 | m_scene = scene; | 92 | m_scene = scene; |
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | public void PostInitialise() | 96 | public void PostInitialise() |
97 | { | 97 | { |
98 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); | 98 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); |
99 | if (m_textureManager != null) | 99 | if (m_textureManager != null) |
100 | { | 100 | { |
101 | m_textureManager.RegisterRender(GetContentType(), this); | 101 | m_textureManager.RegisterRender(GetContentType(), this); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void Close() | 105 | public void Close() |
106 | { | 106 | { |
107 | } | 107 | } |
108 | 108 | ||
109 | public string Name | 109 | public string Name |
110 | { | 110 | { |
111 | get { return m_name; } | 111 | get { return m_name; } |
112 | } | 112 | } |
113 | 113 | ||
114 | public bool IsSharedModule | 114 | public bool IsSharedModule |
115 | { | 115 | { |
116 | get { return true; } | 116 | get { return true; } |
117 | } | 117 | } |
118 | 118 | ||
119 | #endregion | 119 | #endregion |
120 | 120 | ||
121 | private void MakeHttpRequest(string url, LLUUID requestID) | 121 | private void MakeHttpRequest(string url, LLUUID requestID) |
122 | { | 122 | { |
123 | WebRequest request = HttpWebRequest.Create(url); | 123 | WebRequest request = HttpWebRequest.Create(url); |
124 | RequestState state = new RequestState((HttpWebRequest) request, requestID); | 124 | RequestState state = new RequestState((HttpWebRequest) request, requestID); |
125 | IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); | 125 | IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); |
126 | 126 | ||
127 | TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); | 127 | TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); |
128 | state.TimeOfRequest = (int) t.TotalSeconds; | 128 | state.TimeOfRequest = (int) t.TotalSeconds; |
129 | } | 129 | } |
130 | 130 | ||
131 | private void HttpRequestReturn(IAsyncResult result) | 131 | private void HttpRequestReturn(IAsyncResult result) |
132 | { | 132 | { |
133 | RequestState state = (RequestState) result.AsyncState; | 133 | RequestState state = (RequestState) result.AsyncState; |
134 | WebRequest request = (WebRequest) state.Request; | 134 | WebRequest request = (WebRequest) state.Request; |
135 | HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result); | 135 | HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result); |
136 | if (response.StatusCode == HttpStatusCode.OK) | 136 | if (response.StatusCode == HttpStatusCode.OK) |
137 | { | 137 | { |
138 | Bitmap image = new Bitmap(response.GetResponseStream()); | 138 | Bitmap image = new Bitmap(response.GetResponseStream()); |
139 | Size newsize; | 139 | Size newsize; |
140 | 140 | ||
141 | // TODO: make this a bit less hard coded | 141 | // TODO: make this a bit less hard coded |
142 | if ((image.Height < 64) && (image.Width < 64)) | 142 | if ((image.Height < 64) && (image.Width < 64)) |
143 | { | 143 | { |
144 | newsize = new Size(32, 32); | 144 | newsize = new Size(32, 32); |
145 | } | 145 | } |
146 | else if ((image.Height < 128) && (image.Width < 128)) | 146 | else if ((image.Height < 128) && (image.Width < 128)) |
147 | { | 147 | { |
148 | newsize = new Size(64, 64); | 148 | newsize = new Size(64, 64); |
149 | } | 149 | } |
150 | else if ((image.Height < 256) && (image.Width < 256)) | 150 | else if ((image.Height < 256) && (image.Width < 256)) |
151 | { | 151 | { |
152 | newsize = new Size(128, 128); | 152 | newsize = new Size(128, 128); |
153 | } | 153 | } |
154 | else if ((image.Height < 512 && image.Width < 512)) | 154 | else if ((image.Height < 512 && image.Width < 512)) |
155 | { | 155 | { |
156 | newsize = new Size(256, 256); | 156 | newsize = new Size(256, 256); |
157 | } | 157 | } |
158 | else if ((image.Height < 1024 && image.Width < 1024)) | 158 | else if ((image.Height < 1024 && image.Width < 1024)) |
159 | { | 159 | { |
160 | newsize = new Size(512, 512); | 160 | newsize = new Size(512, 512); |
161 | } | 161 | } |
162 | else | 162 | else |
163 | { | 163 | { |
164 | newsize = new Size(1024, 1024); | 164 | newsize = new Size(1024, 1024); |
165 | } | 165 | } |
166 | 166 | ||
167 | Bitmap resize = new Bitmap(image, newsize); | 167 | Bitmap resize = new Bitmap(image, newsize); |
168 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); | 168 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); |
169 | 169 | ||
170 | m_textureManager.ReturnData(state.RequestID, imageJ2000); | 170 | m_textureManager.ReturnData(state.RequestID, imageJ2000); |
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | #region Nested type: RequestState | 174 | #region Nested type: RequestState |
175 | 175 | ||
176 | public class RequestState | 176 | public class RequestState |
177 | { | 177 | { |
178 | public HttpWebRequest Request = null; | 178 | public HttpWebRequest Request = null; |
179 | public LLUUID RequestID = LLUUID.Zero; | 179 | public LLUUID RequestID = LLUUID.Zero; |
180 | public int TimeOfRequest = 0; | 180 | public int TimeOfRequest = 0; |
181 | 181 | ||
182 | public RequestState(HttpWebRequest request, LLUUID requestID) | 182 | public RequestState(HttpWebRequest request, LLUUID requestID) |
183 | { | 183 | { |
184 | Request = request; | 184 | Request = request; |
185 | RequestID = requestID; | 185 | RequestID = requestID; |
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | #endregion | 189 | #endregion |
190 | } | 190 | } |
191 | } \ No newline at end of file | 191 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs index 386c2b5..626c60f 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs | |||
@@ -1,369 +1,369 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using System.Drawing.Imaging; | 30 | using System.Drawing.Imaging; |
31 | using System.Globalization; | 31 | using System.Globalization; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Net; | 33 | using System.Net; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenJPEGNet; | 36 | using OpenJPEGNet; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | using Image=System.Drawing.Image; | 39 | using Image=System.Drawing.Image; |
40 | 40 | ||
41 | //using Cairo; | 41 | //using Cairo; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender | 43 | namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender |
44 | { | 44 | { |
45 | public class VectorRenderModule : IRegionModule, IDynamicTextureRender | 45 | public class VectorRenderModule : IRegionModule, IDynamicTextureRender |
46 | { | 46 | { |
47 | private string m_name = "VectorRenderModule"; | 47 | private string m_name = "VectorRenderModule"; |
48 | private Scene m_scene; | 48 | private Scene m_scene; |
49 | private IDynamicTextureManager m_textureManager; | 49 | private IDynamicTextureManager m_textureManager; |
50 | 50 | ||
51 | public VectorRenderModule() | 51 | public VectorRenderModule() |
52 | { | 52 | { |
53 | } | 53 | } |
54 | 54 | ||
55 | #region IDynamicTextureRender Members | 55 | #region IDynamicTextureRender Members |
56 | 56 | ||
57 | public string GetContentType() | 57 | public string GetContentType() |
58 | { | 58 | { |
59 | return ("vector"); | 59 | return ("vector"); |
60 | } | 60 | } |
61 | 61 | ||
62 | public string GetName() | 62 | public string GetName() |
63 | { | 63 | { |
64 | return m_name; | 64 | return m_name; |
65 | } | 65 | } |
66 | 66 | ||
67 | public bool SupportsAsynchronous() | 67 | public bool SupportsAsynchronous() |
68 | { | 68 | { |
69 | return true; | 69 | return true; |
70 | } | 70 | } |
71 | 71 | ||
72 | public byte[] ConvertUrl(string url, string extraParams) | 72 | public byte[] ConvertUrl(string url, string extraParams) |
73 | { | 73 | { |
74 | return null; | 74 | return null; |
75 | } | 75 | } |
76 | 76 | ||
77 | public byte[] ConvertStream(Stream data, string extraParams) | 77 | public byte[] ConvertStream(Stream data, string extraParams) |
78 | { | 78 | { |
79 | return null; | 79 | return null; |
80 | } | 80 | } |
81 | 81 | ||
82 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) | 82 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) |
83 | { | 83 | { |
84 | return false; | 84 | return false; |
85 | } | 85 | } |
86 | 86 | ||
87 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) | 87 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) |
88 | { | 88 | { |
89 | Draw(bodyData, id, extraParams); | 89 | Draw(bodyData, id, extraParams); |
90 | return true; | 90 | return true; |
91 | } | 91 | } |
92 | 92 | ||
93 | #endregion | 93 | #endregion |
94 | 94 | ||
95 | #region IRegionModule Members | 95 | #region IRegionModule Members |
96 | 96 | ||
97 | public void Initialise(Scene scene, IConfigSource config) | 97 | public void Initialise(Scene scene, IConfigSource config) |
98 | { | 98 | { |
99 | if (m_scene == null) | 99 | if (m_scene == null) |
100 | { | 100 | { |
101 | m_scene = scene; | 101 | m_scene = scene; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void PostInitialise() | 105 | public void PostInitialise() |
106 | { | 106 | { |
107 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); | 107 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); |
108 | if (m_textureManager != null) | 108 | if (m_textureManager != null) |
109 | { | 109 | { |
110 | m_textureManager.RegisterRender(GetContentType(), this); | 110 | m_textureManager.RegisterRender(GetContentType(), this); |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | public void Close() | 114 | public void Close() |
115 | { | 115 | { |
116 | } | 116 | } |
117 | 117 | ||
118 | public string Name | 118 | public string Name |
119 | { | 119 | { |
120 | get { return m_name; } | 120 | get { return m_name; } |
121 | } | 121 | } |
122 | 122 | ||
123 | public bool IsSharedModule | 123 | public bool IsSharedModule |
124 | { | 124 | { |
125 | get { return true; } | 125 | get { return true; } |
126 | } | 126 | } |
127 | 127 | ||
128 | #endregion | 128 | #endregion |
129 | 129 | ||
130 | private void Draw(string data, LLUUID id, string extraParams) | 130 | private void Draw(string data, LLUUID id, string extraParams) |
131 | { | 131 | { |
132 | // TODO: this is a brutal hack. extraParams should actually be parsed reasonably. | 132 | // TODO: this is a brutal hack. extraParams should actually be parsed reasonably. |
133 | int size = 256; | 133 | int size = 256; |
134 | try | 134 | try |
135 | { | 135 | { |
136 | size = Convert.ToInt32(extraParams); | 136 | size = Convert.ToInt32(extraParams); |
137 | } | 137 | } |
138 | catch (Exception e) | 138 | catch (Exception e) |
139 | { | 139 | { |
140 | //Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used | 140 | //Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used |
141 | Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString()); | 141 | Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString()); |
142 | } | 142 | } |
143 | 143 | ||
144 | if ((size < 128) || (size > 1024)) | 144 | if ((size < 128) || (size > 1024)) |
145 | size = 256; | 145 | size = 256; |
146 | 146 | ||
147 | Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb); | 147 | Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb); |
148 | 148 | ||
149 | Graphics graph = Graphics.FromImage(bitmap); | 149 | Graphics graph = Graphics.FromImage(bitmap); |
150 | 150 | ||
151 | extraParams = extraParams.ToLower(); | 151 | extraParams = extraParams.ToLower(); |
152 | int alpha = 255; | 152 | int alpha = 255; |
153 | if (extraParams == "setalpha") | 153 | if (extraParams == "setalpha") |
154 | { | 154 | { |
155 | alpha = 0; | 155 | alpha = 0; |
156 | } | 156 | } |
157 | else | 157 | else |
158 | { | 158 | { |
159 | graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size); | 159 | graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size); |
160 | } | 160 | } |
161 | 161 | ||
162 | for (int w = 0; w < bitmap.Width; w++) | 162 | for (int w = 0; w < bitmap.Width; w++) |
163 | { | 163 | { |
164 | for (int h = 0; h < bitmap.Height; h++) | 164 | for (int h = 0; h < bitmap.Height; h++) |
165 | { | 165 | { |
166 | bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); | 166 | bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); |
167 | } | 167 | } |
168 | } | 168 | } |
169 | 169 | ||
170 | 170 | ||
171 | GDIDraw(data, graph); | 171 | GDIDraw(data, graph); |
172 | 172 | ||
173 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); | 173 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); |
174 | m_textureManager.ReturnData(id, imageJ2000); | 174 | m_textureManager.ReturnData(id, imageJ2000); |
175 | } | 175 | } |
176 | 176 | ||
177 | /* | 177 | /* |
178 | private void CairoDraw(string data, System.Drawing.Graphics graph) | 178 | private void CairoDraw(string data, System.Drawing.Graphics graph) |
179 | { | 179 | { |
180 | using (Win32Surface draw = new Win32Surface(graph.GetHdc())) | 180 | using (Win32Surface draw = new Win32Surface(graph.GetHdc())) |
181 | { | 181 | { |
182 | Context contex = new Context(draw); | 182 | Context contex = new Context(draw); |
183 | 183 | ||
184 | contex.Antialias = Antialias.None; //fastest method but low quality | 184 | contex.Antialias = Antialias.None; //fastest method but low quality |
185 | contex.LineWidth = 7; | 185 | contex.LineWidth = 7; |
186 | char[] lineDelimiter = { ';' }; | 186 | char[] lineDelimiter = { ';' }; |
187 | char[] partsDelimiter = { ',' }; | 187 | char[] partsDelimiter = { ',' }; |
188 | string[] lines = data.Split(lineDelimiter); | 188 | string[] lines = data.Split(lineDelimiter); |
189 | 189 | ||
190 | foreach (string line in lines) | 190 | foreach (string line in lines) |
191 | { | 191 | { |
192 | string nextLine = line.Trim(); | 192 | string nextLine = line.Trim(); |
193 | 193 | ||
194 | if (nextLine.StartsWith("MoveTO")) | 194 | if (nextLine.StartsWith("MoveTO")) |
195 | { | 195 | { |
196 | float x = 0; | 196 | float x = 0; |
197 | float y = 0; | 197 | float y = 0; |
198 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); | 198 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); |
199 | contex.MoveTo(x, y); | 199 | contex.MoveTo(x, y); |
200 | } | 200 | } |
201 | else if (nextLine.StartsWith("LineTo")) | 201 | else if (nextLine.StartsWith("LineTo")) |
202 | { | 202 | { |
203 | float x = 0; | 203 | float x = 0; |
204 | float y = 0; | 204 | float y = 0; |
205 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); | 205 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); |
206 | contex.LineTo(x, y); | 206 | contex.LineTo(x, y); |
207 | contex.Stroke(); | 207 | contex.Stroke(); |
208 | } | 208 | } |
209 | } | 209 | } |
210 | } | 210 | } |
211 | graph.ReleaseHdc(); | 211 | graph.ReleaseHdc(); |
212 | } | 212 | } |
213 | */ | 213 | */ |
214 | 214 | ||
215 | private void GDIDraw(string data, Graphics graph) | 215 | private void GDIDraw(string data, Graphics graph) |
216 | { | 216 | { |
217 | Point startPoint = new Point(0, 0); | 217 | Point startPoint = new Point(0, 0); |
218 | Point endPoint = new Point(0, 0); | 218 | Point endPoint = new Point(0, 0); |
219 | Pen drawPen = new Pen(Color.Black, 7); | 219 | Pen drawPen = new Pen(Color.Black, 7); |
220 | Font myFont = new Font("Times New Roman", 14); | 220 | Font myFont = new Font("Times New Roman", 14); |
221 | SolidBrush myBrush = new SolidBrush(Color.Black); | 221 | SolidBrush myBrush = new SolidBrush(Color.Black); |
222 | char[] lineDelimiter = {';'}; | 222 | char[] lineDelimiter = {';'}; |
223 | char[] partsDelimiter = {','}; | 223 | char[] partsDelimiter = {','}; |
224 | string[] lines = data.Split(lineDelimiter); | 224 | string[] lines = data.Split(lineDelimiter); |
225 | 225 | ||
226 | foreach (string line in lines) | 226 | foreach (string line in lines) |
227 | { | 227 | { |
228 | string nextLine = line.Trim(); | 228 | string nextLine = line.Trim(); |
229 | //replace with switch, or even better, do some proper parsing | 229 | //replace with switch, or even better, do some proper parsing |
230 | if (nextLine.StartsWith("MoveTo")) | 230 | if (nextLine.StartsWith("MoveTo")) |
231 | { | 231 | { |
232 | float x = 0; | 232 | float x = 0; |
233 | float y = 0; | 233 | float y = 0; |
234 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); | 234 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); |
235 | startPoint.X = (int) x; | 235 | startPoint.X = (int) x; |
236 | startPoint.Y = (int) y; | 236 | startPoint.Y = (int) y; |
237 | } | 237 | } |
238 | else if (nextLine.StartsWith("LineTo")) | 238 | else if (nextLine.StartsWith("LineTo")) |
239 | { | 239 | { |
240 | float x = 0; | 240 | float x = 0; |
241 | float y = 0; | 241 | float y = 0; |
242 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); | 242 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); |
243 | endPoint.X = (int) x; | 243 | endPoint.X = (int) x; |
244 | endPoint.Y = (int) y; | 244 | endPoint.Y = (int) y; |
245 | graph.DrawLine(drawPen, startPoint, endPoint); | 245 | graph.DrawLine(drawPen, startPoint, endPoint); |
246 | startPoint.X = endPoint.X; | 246 | startPoint.X = endPoint.X; |
247 | startPoint.Y = endPoint.Y; | 247 | startPoint.Y = endPoint.Y; |
248 | } | 248 | } |
249 | else if (nextLine.StartsWith("Text")) | 249 | else if (nextLine.StartsWith("Text")) |
250 | { | 250 | { |
251 | nextLine = nextLine.Remove(0, 4); | 251 | nextLine = nextLine.Remove(0, 4); |
252 | nextLine = nextLine.Trim(); | 252 | nextLine = nextLine.Trim(); |
253 | graph.DrawString(nextLine, myFont, myBrush, startPoint); | 253 | graph.DrawString(nextLine, myFont, myBrush, startPoint); |
254 | } | 254 | } |
255 | else if (nextLine.StartsWith("Image")) | 255 | else if (nextLine.StartsWith("Image")) |
256 | { | 256 | { |
257 | float x = 0; | 257 | float x = 0; |
258 | float y = 0; | 258 | float y = 0; |
259 | GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); | 259 | GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); |
260 | endPoint.X = (int) x; | 260 | endPoint.X = (int) x; |
261 | endPoint.Y = (int) y; | 261 | endPoint.Y = (int) y; |
262 | Image image = ImageHttpRequest(nextLine); | 262 | Image image = ImageHttpRequest(nextLine); |
263 | graph.DrawImage(image, (float) startPoint.X, (float) startPoint.Y, x, y); | 263 | graph.DrawImage(image, (float) startPoint.X, (float) startPoint.Y, x, y); |
264 | startPoint.X += endPoint.X; | 264 | startPoint.X += endPoint.X; |
265 | startPoint.Y += endPoint.Y; | 265 | startPoint.Y += endPoint.Y; |
266 | } | 266 | } |
267 | else if (nextLine.StartsWith("Rectangle")) | 267 | else if (nextLine.StartsWith("Rectangle")) |
268 | { | 268 | { |
269 | float x = 0; | 269 | float x = 0; |
270 | float y = 0; | 270 | float y = 0; |
271 | GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y); | 271 | GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y); |
272 | endPoint.X = (int) x; | 272 | endPoint.X = (int) x; |
273 | endPoint.Y = (int) y; | 273 | endPoint.Y = (int) y; |
274 | graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); | 274 | graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); |
275 | startPoint.X += endPoint.X; | 275 | startPoint.X += endPoint.X; |
276 | startPoint.Y += endPoint.Y; | 276 | startPoint.Y += endPoint.Y; |
277 | } | 277 | } |
278 | else if (nextLine.StartsWith("FillRectangle")) | 278 | else if (nextLine.StartsWith("FillRectangle")) |
279 | { | 279 | { |
280 | float x = 0; | 280 | float x = 0; |
281 | float y = 0; | 281 | float y = 0; |
282 | GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y); | 282 | GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y); |
283 | endPoint.X = (int) x; | 283 | endPoint.X = (int) x; |
284 | endPoint.Y = (int) y; | 284 | endPoint.Y = (int) y; |
285 | graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); | 285 | graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); |
286 | startPoint.X += endPoint.X; | 286 | startPoint.X += endPoint.X; |
287 | startPoint.Y += endPoint.Y; | 287 | startPoint.Y += endPoint.Y; |
288 | } | 288 | } |
289 | else if (nextLine.StartsWith("Ellipse")) | 289 | else if (nextLine.StartsWith("Ellipse")) |
290 | { | 290 | { |
291 | float x = 0; | 291 | float x = 0; |
292 | float y = 0; | 292 | float y = 0; |
293 | GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y); | 293 | GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y); |
294 | endPoint.X = (int) x; | 294 | endPoint.X = (int) x; |
295 | endPoint.Y = (int) y; | 295 | endPoint.Y = (int) y; |
296 | graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); | 296 | graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); |
297 | startPoint.X += endPoint.X; | 297 | startPoint.X += endPoint.X; |
298 | startPoint.Y += endPoint.Y; | 298 | startPoint.Y += endPoint.Y; |
299 | } | 299 | } |
300 | else if (nextLine.StartsWith("FontSize")) | 300 | else if (nextLine.StartsWith("FontSize")) |
301 | { | 301 | { |
302 | nextLine = nextLine.Remove(0, 8); | 302 | nextLine = nextLine.Remove(0, 8); |
303 | nextLine = nextLine.Trim(); | 303 | nextLine = nextLine.Trim(); |
304 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); | 304 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); |
305 | myFont = new Font("Times New Roman", size); | 305 | myFont = new Font("Times New Roman", size); |
306 | } | 306 | } |
307 | else if (nextLine.StartsWith("PenSize")) | 307 | else if (nextLine.StartsWith("PenSize")) |
308 | { | 308 | { |
309 | nextLine = nextLine.Remove(0, 8); | 309 | nextLine = nextLine.Remove(0, 8); |
310 | nextLine = nextLine.Trim(); | 310 | nextLine = nextLine.Trim(); |
311 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); | 311 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); |
312 | drawPen.Width = size; | 312 | drawPen.Width = size; |
313 | } | 313 | } |
314 | else if (nextLine.StartsWith("PenColour")) | 314 | else if (nextLine.StartsWith("PenColour")) |
315 | { | 315 | { |
316 | nextLine = nextLine.Remove(0, 9); | 316 | nextLine = nextLine.Remove(0, 9); |
317 | nextLine = nextLine.Trim(); | 317 | nextLine = nextLine.Trim(); |
318 | 318 | ||
319 | Color newColour = Color.FromName(nextLine); | 319 | Color newColour = Color.FromName(nextLine); |
320 | 320 | ||
321 | myBrush.Color = newColour; | 321 | myBrush.Color = newColour; |
322 | drawPen.Color = newColour; | 322 | drawPen.Color = newColour; |
323 | } | 323 | } |
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
327 | private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) | 327 | private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) |
328 | { | 328 | { |
329 | line = line.Remove(0, startLength); | 329 | line = line.Remove(0, startLength); |
330 | string[] parts = line.Split(partsDelimiter); | 330 | string[] parts = line.Split(partsDelimiter); |
331 | if (parts.Length == 2) | 331 | if (parts.Length == 2) |
332 | { | 332 | { |
333 | string xVal = parts[0].Trim(); | 333 | string xVal = parts[0].Trim(); |
334 | string yVal = parts[1].Trim(); | 334 | string yVal = parts[1].Trim(); |
335 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); | 335 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); |
336 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); | 336 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); |
337 | } | 337 | } |
338 | else if (parts.Length > 2) | 338 | else if (parts.Length > 2) |
339 | { | 339 | { |
340 | string xVal = parts[0].Trim(); | 340 | string xVal = parts[0].Trim(); |
341 | string yVal = parts[1].Trim(); | 341 | string yVal = parts[1].Trim(); |
342 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); | 342 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); |
343 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); | 343 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); |
344 | 344 | ||
345 | line = ""; | 345 | line = ""; |
346 | for (int i = 2; i < parts.Length; i++) | 346 | for (int i = 2; i < parts.Length; i++) |
347 | { | 347 | { |
348 | line = line + parts[i].Trim(); | 348 | line = line + parts[i].Trim(); |
349 | line = line + " "; | 349 | line = line + " "; |
350 | } | 350 | } |
351 | } | 351 | } |
352 | } | 352 | } |
353 | 353 | ||
354 | private Bitmap ImageHttpRequest(string url) | 354 | private Bitmap ImageHttpRequest(string url) |
355 | { | 355 | { |
356 | WebRequest request = HttpWebRequest.Create(url); | 356 | WebRequest request = HttpWebRequest.Create(url); |
357 | //Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. | 357 | //Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. |
358 | //Ckrinke Stream str = null; | 358 | //Ckrinke Stream str = null; |
359 | HttpWebResponse response = (HttpWebResponse) (request).GetResponse(); | 359 | HttpWebResponse response = (HttpWebResponse) (request).GetResponse(); |
360 | if (response.StatusCode == HttpStatusCode.OK) | 360 | if (response.StatusCode == HttpStatusCode.OK) |
361 | { | 361 | { |
362 | Bitmap image = new Bitmap(response.GetResponseStream()); | 362 | Bitmap image = new Bitmap(response.GetResponseStream()); |
363 | return image; | 363 | return image; |
364 | } | 364 | } |
365 | 365 | ||
366 | return null; | 366 | return null; |
367 | } | 367 | } |
368 | } | 368 | } |
369 | } \ No newline at end of file | 369 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs index ff3b31e..e79b2bd 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs | |||
@@ -1,585 +1,585 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | /***************************************************** | 36 | /***************************************************** |
37 | * | 37 | * |
38 | * WorldCommModule | 38 | * WorldCommModule |
39 | * | 39 | * |
40 | * | 40 | * |
41 | * Holding place for world comms - basically llListen | 41 | * Holding place for world comms - basically llListen |
42 | * function implementation. | 42 | * function implementation. |
43 | * | 43 | * |
44 | * lLListen(integer channel, string name, key id, string msg) | 44 | * lLListen(integer channel, string name, key id, string msg) |
45 | * The name, id, and msg arguments specify the filtering | 45 | * The name, id, and msg arguments specify the filtering |
46 | * criteria. You can pass the empty string | 46 | * criteria. You can pass the empty string |
47 | * (or NULL_KEY for id) for these to set a completely | 47 | * (or NULL_KEY for id) for these to set a completely |
48 | * open filter; this causes the listen() event handler to be | 48 | * open filter; this causes the listen() event handler to be |
49 | * invoked for all chat on the channel. To listen only | 49 | * invoked for all chat on the channel. To listen only |
50 | * for chat spoken by a specific object or avatar, | 50 | * for chat spoken by a specific object or avatar, |
51 | * specify the name and/or id arguments. To listen | 51 | * specify the name and/or id arguments. To listen |
52 | * only for a specific command, specify the | 52 | * only for a specific command, specify the |
53 | * (case-sensitive) msg argument. If msg is not empty, | 53 | * (case-sensitive) msg argument. If msg is not empty, |
54 | * listener will only hear strings which are exactly equal | 54 | * listener will only hear strings which are exactly equal |
55 | * to msg. You can also use all the arguments to establish | 55 | * to msg. You can also use all the arguments to establish |
56 | * the most restrictive filtering criteria. | 56 | * the most restrictive filtering criteria. |
57 | * | 57 | * |
58 | * It might be useful for each listener to maintain a message | 58 | * It might be useful for each listener to maintain a message |
59 | * digest, with a list of recent messages by UUID. This can | 59 | * digest, with a list of recent messages by UUID. This can |
60 | * be used to prevent in-world repeater loops. However, the | 60 | * be used to prevent in-world repeater loops. However, the |
61 | * linden functions do not have this capability, so for now | 61 | * linden functions do not have this capability, so for now |
62 | * thats the way it works. | 62 | * thats the way it works. |
63 | * | 63 | * |
64 | * **************************************************/ | 64 | * **************************************************/ |
65 | 65 | ||
66 | namespace OpenSim.Region.Environment.Modules.Scripting.WorldComm | 66 | namespace OpenSim.Region.Environment.Modules.Scripting.WorldComm |
67 | { | 67 | { |
68 | public class WorldCommModule : IRegionModule, IWorldComm | 68 | public class WorldCommModule : IRegionModule, IWorldComm |
69 | { | 69 | { |
70 | private object CommListLock = new object(); | 70 | private object CommListLock = new object(); |
71 | private object ListLock = new object(); | 71 | private object ListLock = new object(); |
72 | private ListenerManager m_listenerManager; | 72 | private ListenerManager m_listenerManager; |
73 | private string m_name = "WorldCommModule"; | 73 | private string m_name = "WorldCommModule"; |
74 | private Queue m_pending; | 74 | private Queue m_pending; |
75 | private Queue m_pendingQ; | 75 | private Queue m_pendingQ; |
76 | private Scene m_scene; | 76 | private Scene m_scene; |
77 | 77 | ||
78 | public WorldCommModule() | 78 | public WorldCommModule() |
79 | { | 79 | { |
80 | } | 80 | } |
81 | 81 | ||
82 | #region IRegionModule Members | 82 | #region IRegionModule Members |
83 | 83 | ||
84 | public void Initialise(Scene scene, IConfigSource config) | 84 | public void Initialise(Scene scene, IConfigSource config) |
85 | { | 85 | { |
86 | m_scene = scene; | 86 | m_scene = scene; |
87 | m_scene.RegisterModuleInterface<IWorldComm>(this); | 87 | m_scene.RegisterModuleInterface<IWorldComm>(this); |
88 | m_listenerManager = new ListenerManager(); | 88 | m_listenerManager = new ListenerManager(); |
89 | m_scene.EventManager.OnNewClient += NewClient; | 89 | m_scene.EventManager.OnNewClient += NewClient; |
90 | m_pendingQ = new Queue(); | 90 | m_pendingQ = new Queue(); |
91 | m_pending = Queue.Synchronized(m_pendingQ); | 91 | m_pending = Queue.Synchronized(m_pendingQ); |
92 | } | 92 | } |
93 | 93 | ||
94 | public void PostInitialise() | 94 | public void PostInitialise() |
95 | { | 95 | { |
96 | } | 96 | } |
97 | 97 | ||
98 | public void Close() | 98 | public void Close() |
99 | { | 99 | { |
100 | } | 100 | } |
101 | 101 | ||
102 | public string Name | 102 | public string Name |
103 | { | 103 | { |
104 | get { return m_name; } | 104 | get { return m_name; } |
105 | } | 105 | } |
106 | 106 | ||
107 | public bool IsSharedModule | 107 | public bool IsSharedModule |
108 | { | 108 | { |
109 | get { return false; } | 109 | get { return false; } |
110 | } | 110 | } |
111 | 111 | ||
112 | #endregion | 112 | #endregion |
113 | 113 | ||
114 | #region IWorldComm Members | 114 | #region IWorldComm Members |
115 | 115 | ||
116 | public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) | 116 | public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) |
117 | { | 117 | { |
118 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); | 118 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); |
119 | } | 119 | } |
120 | 120 | ||
121 | public void ListenControl(int handle, int active) | 121 | public void ListenControl(int handle, int active) |
122 | { | 122 | { |
123 | if (m_listenerManager != null) | 123 | if (m_listenerManager != null) |
124 | { | 124 | { |
125 | if (active == 1) | 125 | if (active == 1) |
126 | m_listenerManager.Activate(handle); | 126 | m_listenerManager.Activate(handle); |
127 | else if (active == 0) | 127 | else if (active == 0) |
128 | m_listenerManager.Dectivate(handle); | 128 | m_listenerManager.Dectivate(handle); |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | public void ListenRemove(int handle) | 132 | public void ListenRemove(int handle) |
133 | { | 133 | { |
134 | if (m_listenerManager != null) | 134 | if (m_listenerManager != null) |
135 | { | 135 | { |
136 | m_listenerManager.Remove(handle); | 136 | m_listenerManager.Remove(handle); |
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | public void DeleteListener(LLUUID itemID) | 140 | public void DeleteListener(LLUUID itemID) |
141 | { | 141 | { |
142 | if (m_listenerManager != null) | 142 | if (m_listenerManager != null) |
143 | { | 143 | { |
144 | m_listenerManager.DeleteListener(itemID); | 144 | m_listenerManager.DeleteListener(itemID); |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
148 | // This method scans nearby objects and determines if they are listeners, | 148 | // This method scans nearby objects and determines if they are listeners, |
149 | // and if so if this message fits the filter. If it does, then | 149 | // and if so if this message fits the filter. If it does, then |
150 | // enqueue the message for delivery to the objects listen event handler. | 150 | // enqueue the message for delivery to the objects listen event handler. |
151 | // Objects that do an llSay have their messages delivered here, and for | 151 | // Objects that do an llSay have their messages delivered here, and for |
152 | // nearby avatars, the SimChat function is used. | 152 | // nearby avatars, the SimChat function is used. |
153 | public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) | 153 | public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) |
154 | { | 154 | { |
155 | SceneObjectPart source = null; | 155 | SceneObjectPart source = null; |
156 | ScenePresence avatar = null; | 156 | ScenePresence avatar = null; |
157 | 157 | ||
158 | source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); | 158 | source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); |
159 | if (source == null) | 159 | if (source == null) |
160 | { | 160 | { |
161 | avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); | 161 | avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); |
162 | } | 162 | } |
163 | if ((avatar != null) || (source != null)) | 163 | if ((avatar != null) || (source != null)) |
164 | { | 164 | { |
165 | // Loop through the objects in the scene | 165 | // Loop through the objects in the scene |
166 | // If they are in proximity, then if they are | 166 | // If they are in proximity, then if they are |
167 | // listeners, if so add them to the pending queue | 167 | // listeners, if so add them to the pending queue |
168 | 168 | ||
169 | foreach (ListenerInfo li in m_listenerManager.GetListeners()) | 169 | foreach (ListenerInfo li in m_listenerManager.GetListeners()) |
170 | { | 170 | { |
171 | EntityBase sPart; | 171 | EntityBase sPart; |
172 | 172 | ||
173 | m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); | 173 | m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); |
174 | 174 | ||
175 | if (sPart != null) | 175 | if (sPart != null) |
176 | { | 176 | { |
177 | double dis = 0; | 177 | double dis = 0; |
178 | 178 | ||
179 | if (source != null) | 179 | if (source != null) |
180 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); | 180 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); |
181 | else | 181 | else |
182 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); | 182 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); |
183 | 183 | ||
184 | switch (type) | 184 | switch (type) |
185 | { | 185 | { |
186 | case ChatTypeEnum.Whisper: | 186 | case ChatTypeEnum.Whisper: |
187 | 187 | ||
188 | if ((dis < 10) && (dis > -10)) | 188 | if ((dis < 10) && (dis > -10)) |
189 | { | 189 | { |
190 | if (li.GetChannel() == channel) | 190 | if (li.GetChannel() == channel) |
191 | { | 191 | { |
192 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 192 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
193 | sourceItemID, sPart.UUID, channel, name, msg | 193 | sourceItemID, sPart.UUID, channel, name, msg |
194 | ); | 194 | ); |
195 | if (isListener != null) | 195 | if (isListener != null) |
196 | { | 196 | { |
197 | lock (m_pending.SyncRoot) | 197 | lock (m_pending.SyncRoot) |
198 | { | 198 | { |
199 | m_pending.Enqueue(isListener); | 199 | m_pending.Enqueue(isListener); |
200 | } | 200 | } |
201 | } | 201 | } |
202 | } | 202 | } |
203 | } | 203 | } |
204 | break; | 204 | break; |
205 | 205 | ||
206 | case ChatTypeEnum.Say: | 206 | case ChatTypeEnum.Say: |
207 | 207 | ||
208 | if ((dis < 30) && (dis > -30)) | 208 | if ((dis < 30) && (dis > -30)) |
209 | { | 209 | { |
210 | if (li.GetChannel() == channel) | 210 | if (li.GetChannel() == channel) |
211 | { | 211 | { |
212 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 212 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
213 | sourceItemID, sPart.UUID, channel, name, msg | 213 | sourceItemID, sPart.UUID, channel, name, msg |
214 | ); | 214 | ); |
215 | if (isListener != null) | 215 | if (isListener != null) |
216 | { | 216 | { |
217 | lock (m_pending.SyncRoot) | 217 | lock (m_pending.SyncRoot) |
218 | { | 218 | { |
219 | m_pending.Enqueue(isListener); | 219 | m_pending.Enqueue(isListener); |
220 | } | 220 | } |
221 | } | 221 | } |
222 | } | 222 | } |
223 | } | 223 | } |
224 | break; | 224 | break; |
225 | 225 | ||
226 | case ChatTypeEnum.Shout: | 226 | case ChatTypeEnum.Shout: |
227 | if ((dis < 100) && (dis > -100)) | 227 | if ((dis < 100) && (dis > -100)) |
228 | { | 228 | { |
229 | if (li.GetChannel() == channel) | 229 | if (li.GetChannel() == channel) |
230 | { | 230 | { |
231 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 231 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
232 | sourceItemID, sPart.UUID, channel, name, msg | 232 | sourceItemID, sPart.UUID, channel, name, msg |
233 | ); | 233 | ); |
234 | if (isListener != null) | 234 | if (isListener != null) |
235 | { | 235 | { |
236 | lock (m_pending.SyncRoot) | 236 | lock (m_pending.SyncRoot) |
237 | { | 237 | { |
238 | m_pending.Enqueue(isListener); | 238 | m_pending.Enqueue(isListener); |
239 | } | 239 | } |
240 | } | 240 | } |
241 | } | 241 | } |
242 | } | 242 | } |
243 | break; | 243 | break; |
244 | 244 | ||
245 | case ChatTypeEnum.Broadcast: | 245 | case ChatTypeEnum.Broadcast: |
246 | // Dont process if this message is from itself! | 246 | // Dont process if this message is from itself! |
247 | if (li.GetHostID().ToString().Equals(sourceItemID) || | 247 | if (li.GetHostID().ToString().Equals(sourceItemID) || |
248 | sPart.UUID.ToString().Equals(sourceItemID)) | 248 | sPart.UUID.ToString().Equals(sourceItemID)) |
249 | continue; | 249 | continue; |
250 | 250 | ||
251 | if (li.GetChannel() == channel) | 251 | if (li.GetChannel() == channel) |
252 | { | 252 | { |
253 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 253 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
254 | sourceItemID, sPart.UUID, channel, name, msg | 254 | sourceItemID, sPart.UUID, channel, name, msg |
255 | ); | 255 | ); |
256 | if (isListener != null) | 256 | if (isListener != null) |
257 | { | 257 | { |
258 | lock (m_pending.SyncRoot) | 258 | lock (m_pending.SyncRoot) |
259 | { | 259 | { |
260 | m_pending.Enqueue(isListener); | 260 | m_pending.Enqueue(isListener); |
261 | } | 261 | } |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | break; | 265 | break; |
266 | } | 266 | } |
267 | } | 267 | } |
268 | } | 268 | } |
269 | } | 269 | } |
270 | } | 270 | } |
271 | 271 | ||
272 | public bool HasMessages() | 272 | public bool HasMessages() |
273 | { | 273 | { |
274 | if (m_pending != null) | 274 | if (m_pending != null) |
275 | return (m_pending.Count > 0); | 275 | return (m_pending.Count > 0); |
276 | else | 276 | else |
277 | return false; | 277 | return false; |
278 | } | 278 | } |
279 | 279 | ||
280 | public ListenerInfo GetNextMessage() | 280 | public ListenerInfo GetNextMessage() |
281 | { | 281 | { |
282 | ListenerInfo li = null; | 282 | ListenerInfo li = null; |
283 | 283 | ||
284 | lock (m_pending.SyncRoot) | 284 | lock (m_pending.SyncRoot) |
285 | { | 285 | { |
286 | li = (ListenerInfo) m_pending.Dequeue(); | 286 | li = (ListenerInfo) m_pending.Dequeue(); |
287 | } | 287 | } |
288 | 288 | ||
289 | return li; | 289 | return li; |
290 | } | 290 | } |
291 | 291 | ||
292 | public uint PeekNextMessageLocalID() | 292 | public uint PeekNextMessageLocalID() |
293 | { | 293 | { |
294 | return ((ListenerInfo) m_pending.Peek()).GetLocalID(); | 294 | return ((ListenerInfo) m_pending.Peek()).GetLocalID(); |
295 | } | 295 | } |
296 | 296 | ||
297 | public LLUUID PeekNextMessageItemID() | 297 | public LLUUID PeekNextMessageItemID() |
298 | { | 298 | { |
299 | return ((ListenerInfo) m_pending.Peek()).GetItemID(); | 299 | return ((ListenerInfo) m_pending.Peek()).GetItemID(); |
300 | } | 300 | } |
301 | 301 | ||
302 | #endregion | 302 | #endregion |
303 | 303 | ||
304 | public void NewClient(IClientAPI client) | 304 | public void NewClient(IClientAPI client) |
305 | { | 305 | { |
306 | client.OnChatFromViewer += DeliverClientMessage; | 306 | client.OnChatFromViewer += DeliverClientMessage; |
307 | } | 307 | } |
308 | 308 | ||
309 | /******************************************************************** | 309 | /******************************************************************** |
310 | * | 310 | * |
311 | * Listener Stuff | 311 | * Listener Stuff |
312 | * | 312 | * |
313 | * *****************************************************************/ | 313 | * *****************************************************************/ |
314 | 314 | ||
315 | private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) | 315 | private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) |
316 | { | 316 | { |
317 | DeliverMessage(e.Sender.AgentId.ToString(), | 317 | DeliverMessage(e.Sender.AgentId.ToString(), |
318 | e.Type, e.Channel, | 318 | e.Type, e.Channel, |
319 | e.Sender.FirstName + " " + e.Sender.LastName, | 319 | e.Sender.FirstName + " " + e.Sender.LastName, |
320 | e.Message); | 320 | e.Message); |
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
324 | public class ListenerManager | 324 | public class ListenerManager |
325 | { | 325 | { |
326 | //private Dictionary<int, ListenerInfo> m_listeners; | 326 | //private Dictionary<int, ListenerInfo> m_listeners; |
327 | private object ListenersLock = new object(); | 327 | private object ListenersLock = new object(); |
328 | private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); | 328 | private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); |
329 | private int m_MaxListeners = 100; | 329 | private int m_MaxListeners = 100; |
330 | 330 | ||
331 | public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) | 331 | public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) |
332 | { | 332 | { |
333 | if (m_listeners.Count < m_MaxListeners) | 333 | if (m_listeners.Count < m_MaxListeners) |
334 | { | 334 | { |
335 | ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); | 335 | ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); |
336 | 336 | ||
337 | if (isListener == null) | 337 | if (isListener == null) |
338 | { | 338 | { |
339 | int newHandle = GetNewHandle(); | 339 | int newHandle = GetNewHandle(); |
340 | 340 | ||
341 | if (newHandle > -1) | 341 | if (newHandle > -1) |
342 | { | 342 | { |
343 | ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); | 343 | ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); |
344 | 344 | ||
345 | lock (m_listeners.SyncRoot) | 345 | lock (m_listeners.SyncRoot) |
346 | { | 346 | { |
347 | m_listeners.Add(newHandle, li); | 347 | m_listeners.Add(newHandle, li); |
348 | } | 348 | } |
349 | 349 | ||
350 | return newHandle; | 350 | return newHandle; |
351 | } | 351 | } |
352 | } | 352 | } |
353 | } | 353 | } |
354 | 354 | ||
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | 357 | ||
358 | public void Remove(int handle) | 358 | public void Remove(int handle) |
359 | { | 359 | { |
360 | lock (m_listeners.SyncRoot) | 360 | lock (m_listeners.SyncRoot) |
361 | { | 361 | { |
362 | m_listeners.Remove(handle); | 362 | m_listeners.Remove(handle); |
363 | } | 363 | } |
364 | } | 364 | } |
365 | 365 | ||
366 | public void DeleteListener(LLUUID itemID) | 366 | public void DeleteListener(LLUUID itemID) |
367 | { | 367 | { |
368 | ArrayList removedListeners = new ArrayList(); | 368 | ArrayList removedListeners = new ArrayList(); |
369 | 369 | ||
370 | lock (m_listeners.SyncRoot) | 370 | lock (m_listeners.SyncRoot) |
371 | { | 371 | { |
372 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); | 372 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); |
373 | while (en.MoveNext()) | 373 | while (en.MoveNext()) |
374 | { | 374 | { |
375 | ListenerInfo li = (ListenerInfo) en.Value; | 375 | ListenerInfo li = (ListenerInfo) en.Value; |
376 | if (li.GetItemID().Equals(itemID)) | 376 | if (li.GetItemID().Equals(itemID)) |
377 | { | 377 | { |
378 | removedListeners.Add(li.GetHandle()); | 378 | removedListeners.Add(li.GetHandle()); |
379 | } | 379 | } |
380 | } | 380 | } |
381 | foreach (int handle in removedListeners) | 381 | foreach (int handle in removedListeners) |
382 | { | 382 | { |
383 | m_listeners.Remove(handle); | 383 | m_listeners.Remove(handle); |
384 | } | 384 | } |
385 | } | 385 | } |
386 | } | 386 | } |
387 | 387 | ||
388 | private int GetNewHandle() | 388 | private int GetNewHandle() |
389 | { | 389 | { |
390 | for (int i = 0; i < int.MaxValue - 1; i++) | 390 | for (int i = 0; i < int.MaxValue - 1; i++) |
391 | { | 391 | { |
392 | if (!m_listeners.ContainsKey(i)) | 392 | if (!m_listeners.ContainsKey(i)) |
393 | return i; | 393 | return i; |
394 | } | 394 | } |
395 | 395 | ||
396 | return -1; | 396 | return -1; |
397 | } | 397 | } |
398 | 398 | ||
399 | public bool IsListener(LLUUID hostID) | 399 | public bool IsListener(LLUUID hostID) |
400 | { | 400 | { |
401 | foreach (ListenerInfo li in m_listeners.Values) | 401 | foreach (ListenerInfo li in m_listeners.Values) |
402 | { | 402 | { |
403 | if (li.GetHostID().Equals(hostID)) | 403 | if (li.GetHostID().Equals(hostID)) |
404 | return true; | 404 | return true; |
405 | } | 405 | } |
406 | 406 | ||
407 | return false; | 407 | return false; |
408 | } | 408 | } |
409 | 409 | ||
410 | public void Activate(int handle) | 410 | public void Activate(int handle) |
411 | { | 411 | { |
412 | if (m_listeners.ContainsKey(handle)) | 412 | if (m_listeners.ContainsKey(handle)) |
413 | { | 413 | { |
414 | lock (m_listeners.SyncRoot) | 414 | lock (m_listeners.SyncRoot) |
415 | { | 415 | { |
416 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; | 416 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; |
417 | li.Activate(); | 417 | li.Activate(); |
418 | } | 418 | } |
419 | } | 419 | } |
420 | } | 420 | } |
421 | 421 | ||
422 | public void Dectivate(int handle) | 422 | public void Dectivate(int handle) |
423 | { | 423 | { |
424 | if (m_listeners.ContainsKey(handle)) | 424 | if (m_listeners.ContainsKey(handle)) |
425 | { | 425 | { |
426 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; | 426 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; |
427 | li.Deactivate(); | 427 | li.Deactivate(); |
428 | } | 428 | } |
429 | } | 429 | } |
430 | 430 | ||
431 | // Theres probably a more clever and efficient way to | 431 | // Theres probably a more clever and efficient way to |
432 | // do this, maybe with regex. | 432 | // do this, maybe with regex. |
433 | public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, | 433 | public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, |
434 | string msg) | 434 | string msg) |
435 | { | 435 | { |
436 | bool isMatch = true; | 436 | bool isMatch = true; |
437 | lock (m_listeners.SyncRoot) | 437 | lock (m_listeners.SyncRoot) |
438 | { | 438 | { |
439 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); | 439 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); |
440 | while (en.MoveNext()) | 440 | while (en.MoveNext()) |
441 | { | 441 | { |
442 | ListenerInfo li = (ListenerInfo) en.Value; | 442 | ListenerInfo li = (ListenerInfo) en.Value; |
443 | 443 | ||
444 | if (li.IsActive()) | 444 | if (li.IsActive()) |
445 | { | 445 | { |
446 | if (li.GetHostID().Equals(listenerKey)) | 446 | if (li.GetHostID().Equals(listenerKey)) |
447 | { | 447 | { |
448 | if (channel == li.GetChannel()) | 448 | if (channel == li.GetChannel()) |
449 | { | 449 | { |
450 | if ((li.GetID().ToString().Length > 0) && | 450 | if ((li.GetID().ToString().Length > 0) && |
451 | (!li.GetID().Equals(LLUUID.Zero))) | 451 | (!li.GetID().Equals(LLUUID.Zero))) |
452 | { | 452 | { |
453 | if (!li.GetID().ToString().Equals(sourceItemID)) | 453 | if (!li.GetID().ToString().Equals(sourceItemID)) |
454 | { | 454 | { |
455 | isMatch = false; | 455 | isMatch = false; |
456 | } | 456 | } |
457 | } | 457 | } |
458 | if (isMatch && (li.GetName().Length > 0)) | 458 | if (isMatch && (li.GetName().Length > 0)) |
459 | { | 459 | { |
460 | if (li.GetName().Equals(name)) | 460 | if (li.GetName().Equals(name)) |
461 | { | 461 | { |
462 | isMatch = false; | 462 | isMatch = false; |
463 | } | 463 | } |
464 | } | 464 | } |
465 | if (isMatch) | 465 | if (isMatch) |
466 | { | 466 | { |
467 | return new ListenerInfo( | 467 | return new ListenerInfo( |
468 | li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), | 468 | li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), |
469 | li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) | 469 | li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) |
470 | ); | 470 | ); |
471 | } | 471 | } |
472 | } | 472 | } |
473 | } | 473 | } |
474 | } | 474 | } |
475 | } | 475 | } |
476 | } | 476 | } |
477 | return null; | 477 | return null; |
478 | } | 478 | } |
479 | 479 | ||
480 | public ICollection GetListeners() | 480 | public ICollection GetListeners() |
481 | { | 481 | { |
482 | return m_listeners.Values; | 482 | return m_listeners.Values; |
483 | } | 483 | } |
484 | } | 484 | } |
485 | 485 | ||
486 | public class ListenerInfo | 486 | public class ListenerInfo |
487 | { | 487 | { |
488 | private bool m_active; // Listener is active or not | 488 | private bool m_active; // Listener is active or not |
489 | private int m_channel; // Channel | 489 | private int m_channel; // Channel |
490 | private int m_handle; // Assigned handle of this listener | 490 | private int m_handle; // Assigned handle of this listener |
491 | private LLUUID m_hostID; // ID of the host/scene part | 491 | private LLUUID m_hostID; // ID of the host/scene part |
492 | private LLUUID m_id; // ID to filter messages from | 492 | private LLUUID m_id; // ID to filter messages from |
493 | private LLUUID m_itemID; // ID of the host script engine | 493 | private LLUUID m_itemID; // ID of the host script engine |
494 | private uint m_localID; // Local ID from script engine | 494 | private uint m_localID; // Local ID from script engine |
495 | private string m_message; // The message | 495 | private string m_message; // The message |
496 | private string m_name; // Object name to filter messages from | 496 | private string m_name; // Object name to filter messages from |
497 | private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message | 497 | private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message |
498 | 498 | ||
499 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) | 499 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) |
500 | { | 500 | { |
501 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); | 501 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); |
502 | } | 502 | } |
503 | 503 | ||
504 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, | 504 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, |
505 | string message, LLUUID sourceItemID) | 505 | string message, LLUUID sourceItemID) |
506 | { | 506 | { |
507 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); | 507 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); |
508 | m_sourceItemID = sourceItemID; | 508 | m_sourceItemID = sourceItemID; |
509 | } | 509 | } |
510 | 510 | ||
511 | private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, | 511 | private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, |
512 | LLUUID id, string message) | 512 | LLUUID id, string message) |
513 | { | 513 | { |
514 | m_handle = handle; | 514 | m_handle = handle; |
515 | m_channel = channel; | 515 | m_channel = channel; |
516 | m_itemID = ItemID; | 516 | m_itemID = ItemID; |
517 | m_hostID = hostID; | 517 | m_hostID = hostID; |
518 | m_name = name; | 518 | m_name = name; |
519 | m_id = id; | 519 | m_id = id; |
520 | m_message = message; | 520 | m_message = message; |
521 | m_active = true; | 521 | m_active = true; |
522 | m_localID = localID; | 522 | m_localID = localID; |
523 | } | 523 | } |
524 | 524 | ||
525 | public LLUUID GetItemID() | 525 | public LLUUID GetItemID() |
526 | { | 526 | { |
527 | return m_itemID; | 527 | return m_itemID; |
528 | } | 528 | } |
529 | 529 | ||
530 | public LLUUID GetHostID() | 530 | public LLUUID GetHostID() |
531 | { | 531 | { |
532 | return m_hostID; | 532 | return m_hostID; |
533 | } | 533 | } |
534 | 534 | ||
535 | public LLUUID GetSourceItemID() | 535 | public LLUUID GetSourceItemID() |
536 | { | 536 | { |
537 | return m_sourceItemID; | 537 | return m_sourceItemID; |
538 | } | 538 | } |
539 | 539 | ||
540 | public int GetChannel() | 540 | public int GetChannel() |
541 | { | 541 | { |
542 | return m_channel; | 542 | return m_channel; |
543 | } | 543 | } |
544 | 544 | ||
545 | public uint GetLocalID() | 545 | public uint GetLocalID() |
546 | { | 546 | { |
547 | return m_localID; | 547 | return m_localID; |
548 | } | 548 | } |
549 | 549 | ||
550 | public int GetHandle() | 550 | public int GetHandle() |
551 | { | 551 | { |
552 | return m_handle; | 552 | return m_handle; |
553 | } | 553 | } |
554 | 554 | ||
555 | public string GetMessage() | 555 | public string GetMessage() |
556 | { | 556 | { |
557 | return m_message; | 557 | return m_message; |
558 | } | 558 | } |
559 | 559 | ||
560 | public string GetName() | 560 | public string GetName() |
561 | { | 561 | { |
562 | return m_name; | 562 | return m_name; |
563 | } | 563 | } |
564 | 564 | ||
565 | public bool IsActive() | 565 | public bool IsActive() |
566 | { | 566 | { |
567 | return m_active; | 567 | return m_active; |
568 | } | 568 | } |
569 | 569 | ||
570 | public void Deactivate() | 570 | public void Deactivate() |
571 | { | 571 | { |
572 | m_active = false; | 572 | m_active = false; |
573 | } | 573 | } |
574 | 574 | ||
575 | public void Activate() | 575 | public void Activate() |
576 | { | 576 | { |
577 | m_active = true; | 577 | m_active = true; |
578 | } | 578 | } |
579 | 579 | ||
580 | public LLUUID GetID() | 580 | public LLUUID GetID() |
581 | { | 581 | { |
582 | return m_id; | 582 | return m_id; |
583 | } | 583 | } |
584 | } | 584 | } |
585 | } \ No newline at end of file | 585 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs index 6ca8136..a039d42 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs | |||
@@ -1,672 +1,672 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Threading; | 33 | using System.Threading; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using log4net; | 35 | using log4net; |
36 | using Nini.Config; | 36 | using Nini.Config; |
37 | using Nwc.XmlRpc; | 37 | using Nwc.XmlRpc; |
38 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Framework.Servers; | 39 | using OpenSim.Framework.Servers; |
40 | using OpenSim.Region.Environment.Interfaces; | 40 | using OpenSim.Region.Environment.Interfaces; |
41 | using OpenSim.Region.Environment.Scenes; | 41 | using OpenSim.Region.Environment.Scenes; |
42 | 42 | ||
43 | /***************************************************** | 43 | /***************************************************** |
44 | * | 44 | * |
45 | * XMLRPCModule | 45 | * XMLRPCModule |
46 | * | 46 | * |
47 | * Module for accepting incoming communications from | 47 | * Module for accepting incoming communications from |
48 | * external XMLRPC client and calling a remote data | 48 | * external XMLRPC client and calling a remote data |
49 | * procedure for a registered data channel/prim. | 49 | * procedure for a registered data channel/prim. |
50 | * | 50 | * |
51 | * | 51 | * |
52 | * 1. On module load, open a listener port | 52 | * 1. On module load, open a listener port |
53 | * 2. Attach an XMLRPC handler | 53 | * 2. Attach an XMLRPC handler |
54 | * 3. When a request is received: | 54 | * 3. When a request is received: |
55 | * 3.1 Parse into components: channel key, int, string | 55 | * 3.1 Parse into components: channel key, int, string |
56 | * 3.2 Look up registered channel listeners | 56 | * 3.2 Look up registered channel listeners |
57 | * 3.3 Call the channel (prim) remote data method | 57 | * 3.3 Call the channel (prim) remote data method |
58 | * 3.4 Capture the response (llRemoteDataReply) | 58 | * 3.4 Capture the response (llRemoteDataReply) |
59 | * 3.5 Return response to client caller | 59 | * 3.5 Return response to client caller |
60 | * 3.6 If no response from llRemoteDataReply within | 60 | * 3.6 If no response from llRemoteDataReply within |
61 | * RemoteReplyScriptTimeout, generate script timeout fault | 61 | * RemoteReplyScriptTimeout, generate script timeout fault |
62 | * | 62 | * |
63 | * Prims in script must: | 63 | * Prims in script must: |
64 | * 1. Open a remote data channel | 64 | * 1. Open a remote data channel |
65 | * 1.1 Generate a channel ID | 65 | * 1.1 Generate a channel ID |
66 | * 1.2 Register primid,channelid pair with module | 66 | * 1.2 Register primid,channelid pair with module |
67 | * 2. Implement the remote data procedure handler | 67 | * 2. Implement the remote data procedure handler |
68 | * | 68 | * |
69 | * llOpenRemoteDataChannel | 69 | * llOpenRemoteDataChannel |
70 | * llRemoteDataReply | 70 | * llRemoteDataReply |
71 | * remote_data(integer type, key channel, key messageid, string sender, integer ival, string sval) | 71 | * remote_data(integer type, key channel, key messageid, string sender, integer ival, string sval) |
72 | * llCloseRemoteDataChannel | 72 | * llCloseRemoteDataChannel |
73 | * | 73 | * |
74 | * **************************************************/ | 74 | * **************************************************/ |
75 | 75 | ||
76 | namespace OpenSim.Region.Environment.Modules.Scripting.XMLRPC | 76 | namespace OpenSim.Region.Environment.Modules.Scripting.XMLRPC |
77 | { | 77 | { |
78 | public class XMLRPCModule : IRegionModule, IXMLRPC | 78 | public class XMLRPCModule : IRegionModule, IXMLRPC |
79 | { | 79 | { |
80 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 80 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
81 | 81 | ||
82 | private string m_name = "XMLRPCModule"; | 82 | private string m_name = "XMLRPCModule"; |
83 | 83 | ||
84 | // <channel id, RPCChannelInfo> | 84 | // <channel id, RPCChannelInfo> |
85 | private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; | 85 | private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; |
86 | private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses; | 86 | private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses; |
87 | private int m_remoteDataPort = 0; | 87 | private int m_remoteDataPort = 0; |
88 | 88 | ||
89 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending; | 89 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending; |
90 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses; | 90 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses; |
91 | private List<Scene> m_scenes = new List<Scene>(); | 91 | private List<Scene> m_scenes = new List<Scene>(); |
92 | private int RemoteReplyScriptTimeout = 9000; | 92 | private int RemoteReplyScriptTimeout = 9000; |
93 | private int RemoteReplyScriptWait = 300; | 93 | private int RemoteReplyScriptWait = 300; |
94 | private object XMLRPCListLock = new object(); | 94 | private object XMLRPCListLock = new object(); |
95 | 95 | ||
96 | #region IRegionModule Members | 96 | #region IRegionModule Members |
97 | 97 | ||
98 | public void Initialise(Scene scene, IConfigSource config) | 98 | public void Initialise(Scene scene, IConfigSource config) |
99 | { | 99 | { |
100 | try | 100 | try |
101 | { | 101 | { |
102 | m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort); | 102 | m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort); |
103 | } | 103 | } |
104 | catch (Exception) | 104 | catch (Exception) |
105 | { | 105 | { |
106 | } | 106 | } |
107 | 107 | ||
108 | if (!m_scenes.Contains(scene)) | 108 | if (!m_scenes.Contains(scene)) |
109 | { | 109 | { |
110 | m_scenes.Add(scene); | 110 | m_scenes.Add(scene); |
111 | 111 | ||
112 | scene.RegisterModuleInterface<IXMLRPC>(this); | 112 | scene.RegisterModuleInterface<IXMLRPC>(this); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | public void PostInitialise() | 116 | public void PostInitialise() |
117 | { | 117 | { |
118 | if (IsEnabled()) | 118 | if (IsEnabled()) |
119 | { | 119 | { |
120 | m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); | 120 | m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); |
121 | m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>(); | 121 | m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>(); |
122 | m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>(); | 122 | m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>(); |
123 | m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>(); | 123 | m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>(); |
124 | 124 | ||
125 | // Start http server | 125 | // Start http server |
126 | // Attach xmlrpc handlers | 126 | // Attach xmlrpc handlers |
127 | m_log.Info("[REMOTE_DATA]: " + | 127 | m_log.Info("[REMOTE_DATA]: " + |
128 | "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); | 128 | "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); |
129 | BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); | 129 | BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); |
130 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); | 130 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); |
131 | httpServer.Start(); | 131 | httpServer.Start(); |
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | public void Close() | 135 | public void Close() |
136 | { | 136 | { |
137 | } | 137 | } |
138 | 138 | ||
139 | public string Name | 139 | public string Name |
140 | { | 140 | { |
141 | get { return m_name; } | 141 | get { return m_name; } |
142 | } | 142 | } |
143 | 143 | ||
144 | public bool IsSharedModule | 144 | public bool IsSharedModule |
145 | { | 145 | { |
146 | get { return true; } | 146 | get { return true; } |
147 | } | 147 | } |
148 | 148 | ||
149 | #endregion | 149 | #endregion |
150 | 150 | ||
151 | #region IXMLRPC Members | 151 | #region IXMLRPC Members |
152 | 152 | ||
153 | public bool IsEnabled() | 153 | public bool IsEnabled() |
154 | { | 154 | { |
155 | return (m_remoteDataPort > 0); | 155 | return (m_remoteDataPort > 0); |
156 | } | 156 | } |
157 | 157 | ||
158 | /********************************************** | 158 | /********************************************** |
159 | * OpenXMLRPCChannel | 159 | * OpenXMLRPCChannel |
160 | * | 160 | * |
161 | * Generate a LLUUID channel key and add it and | 161 | * Generate a LLUUID channel key and add it and |
162 | * the prim id to dictionary <channelUUID, primUUID> | 162 | * the prim id to dictionary <channelUUID, primUUID> |
163 | * | 163 | * |
164 | * First check if there is a channel assigned for | 164 | * First check if there is a channel assigned for |
165 | * this itemID. If there is, then someone called | 165 | * this itemID. If there is, then someone called |
166 | * llOpenRemoteDataChannel twice. Just return the | 166 | * llOpenRemoteDataChannel twice. Just return the |
167 | * original channel. Other option is to delete the | 167 | * original channel. Other option is to delete the |
168 | * current channel and assign a new one. | 168 | * current channel and assign a new one. |
169 | * | 169 | * |
170 | * ********************************************/ | 170 | * ********************************************/ |
171 | 171 | ||
172 | public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID) | 172 | public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID) |
173 | { | 173 | { |
174 | LLUUID channel = new LLUUID(); | 174 | LLUUID channel = new LLUUID(); |
175 | 175 | ||
176 | //Is a dupe? | 176 | //Is a dupe? |
177 | foreach (RPCChannelInfo ci in m_openChannels.Values) | 177 | foreach (RPCChannelInfo ci in m_openChannels.Values) |
178 | { | 178 | { |
179 | if (ci.GetItemID().Equals(itemID)) | 179 | if (ci.GetItemID().Equals(itemID)) |
180 | { | 180 | { |
181 | // return the original channel ID for this item | 181 | // return the original channel ID for this item |
182 | channel = ci.GetChannelID(); | 182 | channel = ci.GetChannelID(); |
183 | break; | 183 | break; |
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | if (channel == LLUUID.Zero) | 187 | if (channel == LLUUID.Zero) |
188 | { | 188 | { |
189 | channel = LLUUID.Random(); | 189 | channel = LLUUID.Random(); |
190 | RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel); | 190 | RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel); |
191 | lock (XMLRPCListLock) | 191 | lock (XMLRPCListLock) |
192 | { | 192 | { |
193 | m_openChannels.Add(channel, rpcChanInfo); | 193 | m_openChannels.Add(channel, rpcChanInfo); |
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
197 | return channel; | 197 | return channel; |
198 | } | 198 | } |
199 | 199 | ||
200 | // Delete channels based on itemID | 200 | // Delete channels based on itemID |
201 | // for when a script is deleted | 201 | // for when a script is deleted |
202 | public void DeleteChannels(LLUUID itemID) | 202 | public void DeleteChannels(LLUUID itemID) |
203 | { | 203 | { |
204 | if (m_openChannels != null) | 204 | if (m_openChannels != null) |
205 | { | 205 | { |
206 | ArrayList tmp = new ArrayList(); | 206 | ArrayList tmp = new ArrayList(); |
207 | 207 | ||
208 | lock (XMLRPCListLock) | 208 | lock (XMLRPCListLock) |
209 | { | 209 | { |
210 | foreach (RPCChannelInfo li in m_openChannels.Values) | 210 | foreach (RPCChannelInfo li in m_openChannels.Values) |
211 | { | 211 | { |
212 | if (li.GetItemID().Equals(itemID)) | 212 | if (li.GetItemID().Equals(itemID)) |
213 | { | 213 | { |
214 | tmp.Add(itemID); | 214 | tmp.Add(itemID); |
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | IEnumerator tmpEnumerator = tmp.GetEnumerator(); | 218 | IEnumerator tmpEnumerator = tmp.GetEnumerator(); |
219 | while (tmpEnumerator.MoveNext()) | 219 | while (tmpEnumerator.MoveNext()) |
220 | m_openChannels.Remove((LLUUID) tmpEnumerator.Current); | 220 | m_openChannels.Remove((LLUUID) tmpEnumerator.Current); |
221 | } | 221 | } |
222 | } | 222 | } |
223 | } | 223 | } |
224 | 224 | ||
225 | /********************************************** | 225 | /********************************************** |
226 | * Remote Data Reply | 226 | * Remote Data Reply |
227 | * | 227 | * |
228 | * Response to RPC message | 228 | * Response to RPC message |
229 | * | 229 | * |
230 | *********************************************/ | 230 | *********************************************/ |
231 | 231 | ||
232 | public void RemoteDataReply(string channel, string message_id, string sdata, int idata) | 232 | public void RemoteDataReply(string channel, string message_id, string sdata, int idata) |
233 | { | 233 | { |
234 | RPCRequestInfo rpcInfo; | 234 | RPCRequestInfo rpcInfo; |
235 | LLUUID message_key = new LLUUID(message_id); | 235 | LLUUID message_key = new LLUUID(message_id); |
236 | 236 | ||
237 | if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo)) | 237 | if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo)) |
238 | { | 238 | { |
239 | rpcInfo.SetStrRetval(sdata); | 239 | rpcInfo.SetStrRetval(sdata); |
240 | rpcInfo.SetIntRetval(idata); | 240 | rpcInfo.SetIntRetval(idata); |
241 | rpcInfo.SetProcessed(true); | 241 | rpcInfo.SetProcessed(true); |
242 | m_rpcPendingResponses.Remove(message_key); | 242 | m_rpcPendingResponses.Remove(message_key); |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | /********************************************** | 246 | /********************************************** |
247 | * CloseXMLRPCChannel | 247 | * CloseXMLRPCChannel |
248 | * | 248 | * |
249 | * Remove channel from dictionary | 249 | * Remove channel from dictionary |
250 | * | 250 | * |
251 | *********************************************/ | 251 | *********************************************/ |
252 | 252 | ||
253 | public void CloseXMLRPCChannel(LLUUID channelKey) | 253 | public void CloseXMLRPCChannel(LLUUID channelKey) |
254 | { | 254 | { |
255 | if (m_openChannels.ContainsKey(channelKey)) | 255 | if (m_openChannels.ContainsKey(channelKey)) |
256 | m_openChannels.Remove(channelKey); | 256 | m_openChannels.Remove(channelKey); |
257 | } | 257 | } |
258 | 258 | ||
259 | 259 | ||
260 | public bool hasRequests() | 260 | public bool hasRequests() |
261 | { | 261 | { |
262 | lock (XMLRPCListLock) | 262 | lock (XMLRPCListLock) |
263 | { | 263 | { |
264 | if (m_rpcPending != null) | 264 | if (m_rpcPending != null) |
265 | return (m_rpcPending.Count > 0); | 265 | return (m_rpcPending.Count > 0); |
266 | else | 266 | else |
267 | return false; | 267 | return false; |
268 | } | 268 | } |
269 | } | 269 | } |
270 | 270 | ||
271 | public RPCRequestInfo GetNextCompletedRequest() | 271 | public RPCRequestInfo GetNextCompletedRequest() |
272 | { | 272 | { |
273 | if (m_rpcPending != null) | 273 | if (m_rpcPending != null) |
274 | { | 274 | { |
275 | lock (XMLRPCListLock) | 275 | lock (XMLRPCListLock) |
276 | { | 276 | { |
277 | foreach (LLUUID luid in m_rpcPending.Keys) | 277 | foreach (LLUUID luid in m_rpcPending.Keys) |
278 | { | 278 | { |
279 | RPCRequestInfo tmpReq; | 279 | RPCRequestInfo tmpReq; |
280 | 280 | ||
281 | if (m_rpcPending.TryGetValue(luid, out tmpReq)) | 281 | if (m_rpcPending.TryGetValue(luid, out tmpReq)) |
282 | { | 282 | { |
283 | if (!tmpReq.IsProcessed()) return tmpReq; | 283 | if (!tmpReq.IsProcessed()) return tmpReq; |
284 | } | 284 | } |
285 | } | 285 | } |
286 | } | 286 | } |
287 | } | 287 | } |
288 | return null; | 288 | return null; |
289 | } | 289 | } |
290 | 290 | ||
291 | public void RemoveCompletedRequest(LLUUID id) | 291 | public void RemoveCompletedRequest(LLUUID id) |
292 | { | 292 | { |
293 | lock (XMLRPCListLock) | 293 | lock (XMLRPCListLock) |
294 | { | 294 | { |
295 | RPCRequestInfo tmp; | 295 | RPCRequestInfo tmp; |
296 | if (m_rpcPending.TryGetValue(id, out tmp)) | 296 | if (m_rpcPending.TryGetValue(id, out tmp)) |
297 | { | 297 | { |
298 | m_rpcPending.Remove(id); | 298 | m_rpcPending.Remove(id); |
299 | m_rpcPendingResponses.Add(id, tmp); | 299 | m_rpcPendingResponses.Add(id, tmp); |
300 | } | 300 | } |
301 | else | 301 | else |
302 | { | 302 | { |
303 | Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST"); | 303 | Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST"); |
304 | } | 304 | } |
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
308 | public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) | 308 | public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) |
309 | { | 309 | { |
310 | SendRemoteDataRequest req = new SendRemoteDataRequest( | 310 | SendRemoteDataRequest req = new SendRemoteDataRequest( |
311 | localID, itemID, channel, dest, idata, sdata | 311 | localID, itemID, channel, dest, idata, sdata |
312 | ); | 312 | ); |
313 | m_pendingSRDResponses.Add(req.GetReqID(), req); | 313 | m_pendingSRDResponses.Add(req.GetReqID(), req); |
314 | return req.process(); | 314 | return req.process(); |
315 | } | 315 | } |
316 | 316 | ||
317 | public SendRemoteDataRequest GetNextCompletedSRDRequest() | 317 | public SendRemoteDataRequest GetNextCompletedSRDRequest() |
318 | { | 318 | { |
319 | if (m_pendingSRDResponses != null) | 319 | if (m_pendingSRDResponses != null) |
320 | { | 320 | { |
321 | lock (XMLRPCListLock) | 321 | lock (XMLRPCListLock) |
322 | { | 322 | { |
323 | foreach (LLUUID luid in m_pendingSRDResponses.Keys) | 323 | foreach (LLUUID luid in m_pendingSRDResponses.Keys) |
324 | { | 324 | { |
325 | SendRemoteDataRequest tmpReq; | 325 | SendRemoteDataRequest tmpReq; |
326 | 326 | ||
327 | if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq)) | 327 | if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq)) |
328 | { | 328 | { |
329 | if (tmpReq.finished) | 329 | if (tmpReq.finished) |
330 | return tmpReq; | 330 | return tmpReq; |
331 | } | 331 | } |
332 | } | 332 | } |
333 | } | 333 | } |
334 | } | 334 | } |
335 | return null; | 335 | return null; |
336 | } | 336 | } |
337 | 337 | ||
338 | public void RemoveCompletedSRDRequest(LLUUID id) | 338 | public void RemoveCompletedSRDRequest(LLUUID id) |
339 | { | 339 | { |
340 | lock (XMLRPCListLock) | 340 | lock (XMLRPCListLock) |
341 | { | 341 | { |
342 | SendRemoteDataRequest tmpReq; | 342 | SendRemoteDataRequest tmpReq; |
343 | if (m_pendingSRDResponses.TryGetValue(id, out tmpReq)) | 343 | if (m_pendingSRDResponses.TryGetValue(id, out tmpReq)) |
344 | { | 344 | { |
345 | m_pendingSRDResponses.Remove(id); | 345 | m_pendingSRDResponses.Remove(id); |
346 | } | 346 | } |
347 | } | 347 | } |
348 | } | 348 | } |
349 | 349 | ||
350 | public void CancelSRDRequests(LLUUID itemID) | 350 | public void CancelSRDRequests(LLUUID itemID) |
351 | { | 351 | { |
352 | if (m_pendingSRDResponses != null) | 352 | if (m_pendingSRDResponses != null) |
353 | { | 353 | { |
354 | lock (XMLRPCListLock) | 354 | lock (XMLRPCListLock) |
355 | { | 355 | { |
356 | foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values) | 356 | foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values) |
357 | { | 357 | { |
358 | if (li.m_itemID.Equals(itemID)) | 358 | if (li.m_itemID.Equals(itemID)) |
359 | m_pendingSRDResponses.Remove(li.GetReqID()); | 359 | m_pendingSRDResponses.Remove(li.GetReqID()); |
360 | } | 360 | } |
361 | } | 361 | } |
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
365 | #endregion | 365 | #endregion |
366 | 366 | ||
367 | public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request) | 367 | public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request) |
368 | { | 368 | { |
369 | XmlRpcResponse response = new XmlRpcResponse(); | 369 | XmlRpcResponse response = new XmlRpcResponse(); |
370 | 370 | ||
371 | Hashtable requestData = (Hashtable) request.Params[0]; | 371 | Hashtable requestData = (Hashtable) request.Params[0]; |
372 | bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && | 372 | bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && |
373 | requestData.Contains("StringValue")); | 373 | requestData.Contains("StringValue")); |
374 | 374 | ||
375 | if (GoodXML) | 375 | if (GoodXML) |
376 | { | 376 | { |
377 | LLUUID channel = new LLUUID((string) requestData["Channel"]); | 377 | LLUUID channel = new LLUUID((string) requestData["Channel"]); |
378 | RPCChannelInfo rpcChanInfo; | 378 | RPCChannelInfo rpcChanInfo; |
379 | if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) | 379 | if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) |
380 | { | 380 | { |
381 | string intVal = (string) requestData["IntValue"]; | 381 | string intVal = (string) requestData["IntValue"]; |
382 | string strVal = (string) requestData["StringValue"]; | 382 | string strVal = (string) requestData["StringValue"]; |
383 | 383 | ||
384 | RPCRequestInfo rpcInfo; | 384 | RPCRequestInfo rpcInfo; |
385 | 385 | ||
386 | lock (XMLRPCListLock) | 386 | lock (XMLRPCListLock) |
387 | { | 387 | { |
388 | rpcInfo = | 388 | rpcInfo = |
389 | new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, | 389 | new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, |
390 | intVal); | 390 | intVal); |
391 | m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo); | 391 | m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo); |
392 | } | 392 | } |
393 | 393 | ||
394 | int timeoutCtr = 0; | 394 | int timeoutCtr = 0; |
395 | 395 | ||
396 | while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout)) | 396 | while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout)) |
397 | { | 397 | { |
398 | Thread.Sleep(RemoteReplyScriptWait); | 398 | Thread.Sleep(RemoteReplyScriptWait); |
399 | timeoutCtr += RemoteReplyScriptWait; | 399 | timeoutCtr += RemoteReplyScriptWait; |
400 | } | 400 | } |
401 | if (rpcInfo.IsProcessed()) | 401 | if (rpcInfo.IsProcessed()) |
402 | { | 402 | { |
403 | Hashtable param = new Hashtable(); | 403 | Hashtable param = new Hashtable(); |
404 | param["StringValue"] = rpcInfo.GetStrRetval(); | 404 | param["StringValue"] = rpcInfo.GetStrRetval(); |
405 | param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval()); | 405 | param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval()); |
406 | 406 | ||
407 | ArrayList parameters = new ArrayList(); | 407 | ArrayList parameters = new ArrayList(); |
408 | parameters.Add(param); | 408 | parameters.Add(param); |
409 | 409 | ||
410 | response.Value = parameters; | 410 | response.Value = parameters; |
411 | rpcInfo = null; | 411 | rpcInfo = null; |
412 | } | 412 | } |
413 | else | 413 | else |
414 | { | 414 | { |
415 | response.SetFault(-1, "Script timeout"); | 415 | response.SetFault(-1, "Script timeout"); |
416 | rpcInfo = null; | 416 | rpcInfo = null; |
417 | } | 417 | } |
418 | } | 418 | } |
419 | else | 419 | else |
420 | { | 420 | { |
421 | response.SetFault(-1, "Invalid channel"); | 421 | response.SetFault(-1, "Invalid channel"); |
422 | } | 422 | } |
423 | } | 423 | } |
424 | 424 | ||
425 | return response; | 425 | return response; |
426 | } | 426 | } |
427 | } | 427 | } |
428 | 428 | ||
429 | public class RPCRequestInfo | 429 | public class RPCRequestInfo |
430 | { | 430 | { |
431 | private LLUUID m_ChannelKey; | 431 | private LLUUID m_ChannelKey; |
432 | private string m_IntVal; | 432 | private string m_IntVal; |
433 | private LLUUID m_ItemID; | 433 | private LLUUID m_ItemID; |
434 | private uint m_localID; | 434 | private uint m_localID; |
435 | private LLUUID m_MessageID; | 435 | private LLUUID m_MessageID; |
436 | private bool m_processed; | 436 | private bool m_processed; |
437 | private int m_respInt; | 437 | private int m_respInt; |
438 | private string m_respStr; | 438 | private string m_respStr; |
439 | private string m_StrVal; | 439 | private string m_StrVal; |
440 | 440 | ||
441 | public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal) | 441 | public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal) |
442 | { | 442 | { |
443 | m_localID = localID; | 443 | m_localID = localID; |
444 | m_StrVal = strVal; | 444 | m_StrVal = strVal; |
445 | m_IntVal = intVal; | 445 | m_IntVal = intVal; |
446 | m_ItemID = itemID; | 446 | m_ItemID = itemID; |
447 | m_ChannelKey = channelKey; | 447 | m_ChannelKey = channelKey; |
448 | m_MessageID = LLUUID.Random(); | 448 | m_MessageID = LLUUID.Random(); |
449 | m_processed = false; | 449 | m_processed = false; |
450 | m_respStr = String.Empty; | 450 | m_respStr = String.Empty; |
451 | m_respInt = 0; | 451 | m_respInt = 0; |
452 | } | 452 | } |
453 | 453 | ||
454 | public bool IsProcessed() | 454 | public bool IsProcessed() |
455 | { | 455 | { |
456 | return m_processed; | 456 | return m_processed; |
457 | } | 457 | } |
458 | 458 | ||
459 | public LLUUID GetChannelKey() | 459 | public LLUUID GetChannelKey() |
460 | { | 460 | { |
461 | return m_ChannelKey; | 461 | return m_ChannelKey; |
462 | } | 462 | } |
463 | 463 | ||
464 | public void SetProcessed(bool processed) | 464 | public void SetProcessed(bool processed) |
465 | { | 465 | { |
466 | m_processed = processed; | 466 | m_processed = processed; |
467 | } | 467 | } |
468 | 468 | ||
469 | public void SetStrRetval(string resp) | 469 | public void SetStrRetval(string resp) |
470 | { | 470 | { |
471 | m_respStr = resp; | 471 | m_respStr = resp; |
472 | } | 472 | } |
473 | 473 | ||
474 | public string GetStrRetval() | 474 | public string GetStrRetval() |
475 | { | 475 | { |
476 | return m_respStr; | 476 | return m_respStr; |
477 | } | 477 | } |
478 | 478 | ||
479 | public void SetIntRetval(int resp) | 479 | public void SetIntRetval(int resp) |
480 | { | 480 | { |
481 | m_respInt = resp; | 481 | m_respInt = resp; |
482 | } | 482 | } |
483 | 483 | ||
484 | public int GetIntRetval() | 484 | public int GetIntRetval() |
485 | { | 485 | { |
486 | return m_respInt; | 486 | return m_respInt; |
487 | } | 487 | } |
488 | 488 | ||
489 | public uint GetLocalID() | 489 | public uint GetLocalID() |
490 | { | 490 | { |
491 | return m_localID; | 491 | return m_localID; |
492 | } | 492 | } |
493 | 493 | ||
494 | public LLUUID GetItemID() | 494 | public LLUUID GetItemID() |
495 | { | 495 | { |
496 | return m_ItemID; | 496 | return m_ItemID; |
497 | } | 497 | } |
498 | 498 | ||
499 | public string GetStrVal() | 499 | public string GetStrVal() |
500 | { | 500 | { |
501 | return m_StrVal; | 501 | return m_StrVal; |
502 | } | 502 | } |
503 | 503 | ||
504 | public int GetIntValue() | 504 | public int GetIntValue() |
505 | { | 505 | { |
506 | return int.Parse(m_IntVal); | 506 | return int.Parse(m_IntVal); |
507 | } | 507 | } |
508 | 508 | ||
509 | public LLUUID GetMessageID() | 509 | public LLUUID GetMessageID() |
510 | { | 510 | { |
511 | return m_MessageID; | 511 | return m_MessageID; |
512 | } | 512 | } |
513 | } | 513 | } |
514 | 514 | ||
515 | public class RPCChannelInfo | 515 | public class RPCChannelInfo |
516 | { | 516 | { |
517 | private LLUUID m_ChannelKey; | 517 | private LLUUID m_ChannelKey; |
518 | private LLUUID m_itemID; | 518 | private LLUUID m_itemID; |
519 | private uint m_localID; | 519 | private uint m_localID; |
520 | 520 | ||
521 | public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID) | 521 | public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID) |
522 | { | 522 | { |
523 | m_ChannelKey = channelID; | 523 | m_ChannelKey = channelID; |
524 | m_localID = localID; | 524 | m_localID = localID; |
525 | m_itemID = itemID; | 525 | m_itemID = itemID; |
526 | } | 526 | } |
527 | 527 | ||
528 | public LLUUID GetItemID() | 528 | public LLUUID GetItemID() |
529 | { | 529 | { |
530 | return m_itemID; | 530 | return m_itemID; |
531 | } | 531 | } |
532 | 532 | ||
533 | public LLUUID GetChannelID() | 533 | public LLUUID GetChannelID() |
534 | { | 534 | { |
535 | return m_ChannelKey; | 535 | return m_ChannelKey; |
536 | } | 536 | } |
537 | 537 | ||
538 | public uint GetLocalID() | 538 | public uint GetLocalID() |
539 | { | 539 | { |
540 | return m_localID; | 540 | return m_localID; |
541 | } | 541 | } |
542 | } | 542 | } |
543 | 543 | ||
544 | public class SendRemoteDataRequest | 544 | public class SendRemoteDataRequest |
545 | { | 545 | { |
546 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 546 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
547 | public string channel; | 547 | public string channel; |
548 | public string destURL; | 548 | public string destURL; |
549 | public bool finished; | 549 | public bool finished; |
550 | private Thread httpThread; | 550 | private Thread httpThread; |
551 | public int idata; | 551 | public int idata; |
552 | public LLUUID m_itemID; | 552 | public LLUUID m_itemID; |
553 | public uint m_localID; | 553 | public uint m_localID; |
554 | public LLUUID reqID; | 554 | public LLUUID reqID; |
555 | public XmlRpcRequest request; | 555 | public XmlRpcRequest request; |
556 | public int response_idata; | 556 | public int response_idata; |
557 | public string response_sdata; | 557 | public string response_sdata; |
558 | public string sdata; | 558 | public string sdata; |
559 | 559 | ||
560 | public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) | 560 | public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) |
561 | { | 561 | { |
562 | this.channel = channel; | 562 | this.channel = channel; |
563 | destURL = dest; | 563 | destURL = dest; |
564 | this.idata = idata; | 564 | this.idata = idata; |
565 | this.sdata = sdata; | 565 | this.sdata = sdata; |
566 | m_itemID = itemID; | 566 | m_itemID = itemID; |
567 | m_localID = localID; | 567 | m_localID = localID; |
568 | 568 | ||
569 | reqID = LLUUID.Random(); | 569 | reqID = LLUUID.Random(); |
570 | } | 570 | } |
571 | 571 | ||
572 | public LLUUID process() | 572 | public LLUUID process() |
573 | { | 573 | { |
574 | httpThread = new Thread(SendRequest); | 574 | httpThread = new Thread(SendRequest); |
575 | httpThread.Name = "HttpRequestThread"; | 575 | httpThread.Name = "HttpRequestThread"; |
576 | httpThread.Priority = ThreadPriority.BelowNormal; | 576 | httpThread.Priority = ThreadPriority.BelowNormal; |
577 | httpThread.IsBackground = true; | 577 | httpThread.IsBackground = true; |
578 | finished = false; | 578 | finished = false; |
579 | httpThread.Start(); | 579 | httpThread.Start(); |
580 | ThreadTracker.Add(httpThread); | 580 | ThreadTracker.Add(httpThread); |
581 | 581 | ||
582 | return reqID; | 582 | return reqID; |
583 | } | 583 | } |
584 | 584 | ||
585 | /* | 585 | /* |
586 | * TODO: More work on the response codes. Right now | 586 | * TODO: More work on the response codes. Right now |
587 | * returning 200 for success or 499 for exception | 587 | * returning 200 for success or 499 for exception |
588 | */ | 588 | */ |
589 | 589 | ||
590 | public void SendRequest() | 590 | public void SendRequest() |
591 | { | 591 | { |
592 | Hashtable param = new Hashtable(); | 592 | Hashtable param = new Hashtable(); |
593 | 593 | ||
594 | // Check if channel is an LLUUID | 594 | // Check if channel is an LLUUID |
595 | // if not, use as method name | 595 | // if not, use as method name |
596 | LLUUID parseUID; | 596 | LLUUID parseUID; |
597 | string mName = "llRemoteData"; | 597 | string mName = "llRemoteData"; |
598 | if ((channel != null) && (channel != "")) | 598 | if ((channel != null) && (channel != "")) |
599 | if (!LLUUID.TryParse(channel, out parseUID)) | 599 | if (!LLUUID.TryParse(channel, out parseUID)) |
600 | mName = channel; | 600 | mName = channel; |
601 | else | 601 | else |
602 | param["Channel"] = channel; | 602 | param["Channel"] = channel; |
603 | 603 | ||
604 | param["StringValue"] = sdata; | 604 | param["StringValue"] = sdata; |
605 | param["IntValue"] = Convert.ToString(idata); | 605 | param["IntValue"] = Convert.ToString(idata); |
606 | 606 | ||
607 | ArrayList parameters = new ArrayList(); | 607 | ArrayList parameters = new ArrayList(); |
608 | parameters.Add(param); | 608 | parameters.Add(param); |
609 | XmlRpcRequest req = new XmlRpcRequest(mName, parameters); | 609 | XmlRpcRequest req = new XmlRpcRequest(mName, parameters); |
610 | try | 610 | try |
611 | { | 611 | { |
612 | XmlRpcResponse resp = req.Send(destURL, 30000); | 612 | XmlRpcResponse resp = req.Send(destURL, 30000); |
613 | if (resp != null) | 613 | if (resp != null) |
614 | { | 614 | { |
615 | Hashtable respParms; | 615 | Hashtable respParms; |
616 | if (resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) | 616 | if (resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) |
617 | { | 617 | { |
618 | respParms = (Hashtable) resp.Value; | 618 | respParms = (Hashtable) resp.Value; |
619 | } | 619 | } |
620 | else | 620 | else |
621 | { | 621 | { |
622 | ArrayList respData = (ArrayList) resp.Value; | 622 | ArrayList respData = (ArrayList) resp.Value; |
623 | respParms = (Hashtable) respData[0]; | 623 | respParms = (Hashtable) respData[0]; |
624 | } | 624 | } |
625 | if (respParms != null) | 625 | if (respParms != null) |
626 | { | 626 | { |
627 | if (respParms.Contains("StringValue")) | 627 | if (respParms.Contains("StringValue")) |
628 | { | 628 | { |
629 | sdata = (string) respParms["StringValue"]; | 629 | sdata = (string) respParms["StringValue"]; |
630 | } | 630 | } |
631 | if (respParms.Contains("IntValue")) | 631 | if (respParms.Contains("IntValue")) |
632 | { | 632 | { |
633 | idata = Convert.ToInt32((string) respParms["IntValue"]); | 633 | idata = Convert.ToInt32((string) respParms["IntValue"]); |
634 | } | 634 | } |
635 | if (respParms.Contains("faultString")) | 635 | if (respParms.Contains("faultString")) |
636 | { | 636 | { |
637 | sdata = (string) respParms["faultString"]; | 637 | sdata = (string) respParms["faultString"]; |
638 | } | 638 | } |
639 | if (respParms.Contains("faultCode")) | 639 | if (respParms.Contains("faultCode")) |
640 | { | 640 | { |
641 | idata = Convert.ToInt32(respParms["faultCode"]); | 641 | idata = Convert.ToInt32(respParms["faultCode"]); |
642 | } | 642 | } |
643 | } | 643 | } |
644 | } | 644 | } |
645 | } | 645 | } |
646 | catch (WebException we) | 646 | catch (WebException we) |
647 | { | 647 | { |
648 | sdata = we.Message; | 648 | sdata = we.Message; |
649 | m_log.Warn("[SendRemoteDataRequest]: Request failed"); | 649 | m_log.Warn("[SendRemoteDataRequest]: Request failed"); |
650 | m_log.Warn(we.StackTrace); | 650 | m_log.Warn(we.StackTrace); |
651 | } | 651 | } |
652 | 652 | ||
653 | finished = true; | 653 | finished = true; |
654 | } | 654 | } |
655 | 655 | ||
656 | public void Stop() | 656 | public void Stop() |
657 | { | 657 | { |
658 | try | 658 | try |
659 | { | 659 | { |
660 | httpThread.Abort(); | 660 | httpThread.Abort(); |
661 | } | 661 | } |
662 | catch (Exception) | 662 | catch (Exception) |
663 | { | 663 | { |
664 | } | 664 | } |
665 | } | 665 | } |
666 | 666 | ||
667 | public LLUUID GetReqID() | 667 | public LLUUID GetReqID() |
668 | { | 668 | { |
669 | return reqID; | 669 | return reqID; |
670 | } | 670 | } |
671 | } | 671 | } |
672 | } \ No newline at end of file | 672 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs index efc5234..9ac3cc3 100644 --- a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs +++ b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs | |||
@@ -1,1000 +1,1000 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using Axiom.Math; | 30 | using Axiom.Math; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using libsecondlife.Packets; | 32 | using libsecondlife.Packets; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | using OpenSim.Region.Physics.Manager; | 36 | using OpenSim.Region.Physics.Manager; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules.World.Land | 38 | namespace OpenSim.Region.Environment.Modules.World.Land |
39 | { | 39 | { |
40 | public class LandChannel : ILandChannel | 40 | public class LandChannel : ILandChannel |
41 | { | 41 | { |
42 | #region Constants | 42 | #region Constants |
43 | 43 | ||
44 | //Land types set with flags in ParcelOverlay. | 44 | //Land types set with flags in ParcelOverlay. |
45 | //Only one of these can be used. | 45 | //Only one of these can be used. |
46 | public const float BAN_LINE_SAFETY_HIEGHT = 100; | 46 | public const float BAN_LINE_SAFETY_HIEGHT = 100; |
47 | public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte) 128; //Equals 10000000 | 47 | public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte) 128; //Equals 10000000 |
48 | public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte) 64; //Equals 01000000 | 48 | public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte) 64; //Equals 01000000 |
49 | 49 | ||
50 | //RequestResults (I think these are right, they seem to work): | 50 | //RequestResults (I think these are right, they seem to work): |
51 | public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land | 51 | public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land |
52 | public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land | 52 | public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land |
53 | 53 | ||
54 | //ParcelSelectObjects | 54 | //ParcelSelectObjects |
55 | public const int LAND_SELECT_OBJECTS_GROUP = 4; | 55 | public const int LAND_SELECT_OBJECTS_GROUP = 4; |
56 | public const int LAND_SELECT_OBJECTS_OTHER = 8; | 56 | public const int LAND_SELECT_OBJECTS_OTHER = 8; |
57 | public const int LAND_SELECT_OBJECTS_OWNER = 2; | 57 | public const int LAND_SELECT_OBJECTS_OWNER = 2; |
58 | public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte) 5; //Equals 00000101 | 58 | public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte) 5; //Equals 00000101 |
59 | public const byte LAND_TYPE_IS_FOR_SALE = (byte) 4; //Equals 00000100 | 59 | public const byte LAND_TYPE_IS_FOR_SALE = (byte) 4; //Equals 00000100 |
60 | public const byte LAND_TYPE_OWNED_BY_GROUP = (byte) 2; //Equals 00000010 | 60 | public const byte LAND_TYPE_OWNED_BY_GROUP = (byte) 2; //Equals 00000010 |
61 | public const byte LAND_TYPE_OWNED_BY_OTHER = (byte) 1; //Equals 00000001 | 61 | public const byte LAND_TYPE_OWNED_BY_OTHER = (byte) 1; //Equals 00000001 |
62 | public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte) 3; //Equals 00000011 | 62 | public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte) 3; //Equals 00000011 |
63 | public const byte LAND_TYPE_PUBLIC = (byte) 0; //Equals 00000000 | 63 | public const byte LAND_TYPE_PUBLIC = (byte) 0; //Equals 00000000 |
64 | 64 | ||
65 | //These are other constants. Yay! | 65 | //These are other constants. Yay! |
66 | public const int START_LAND_LOCAL_ID = 1; | 66 | public const int START_LAND_LOCAL_ID = 1; |
67 | 67 | ||
68 | #endregion | 68 | #endregion |
69 | 69 | ||
70 | private int[,] landIDList = new int[64,64]; | 70 | private int[,] landIDList = new int[64,64]; |
71 | private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>(); | 71 | private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>(); |
72 | 72 | ||
73 | private bool landPrimCountTainted = false; | 73 | private bool landPrimCountTainted = false; |
74 | private int lastLandLocalID = START_LAND_LOCAL_ID - 1; | 74 | private int lastLandLocalID = START_LAND_LOCAL_ID - 1; |
75 | 75 | ||
76 | private bool m_allowedForcefulBans = true; | 76 | private bool m_allowedForcefulBans = true; |
77 | private Scene m_scene; | 77 | private Scene m_scene; |
78 | 78 | ||
79 | public LandChannel(Scene scene) | 79 | public LandChannel(Scene scene) |
80 | { | 80 | { |
81 | m_scene = scene; | 81 | m_scene = scene; |
82 | landIDList.Initialize(); | 82 | landIDList.Initialize(); |
83 | } | 83 | } |
84 | 84 | ||
85 | #region Land Object From Storage Functions | 85 | #region Land Object From Storage Functions |
86 | 86 | ||
87 | public void IncomingLandObjectsFromStorage(List<LandData> data) | 87 | public void IncomingLandObjectsFromStorage(List<LandData> data) |
88 | { | 88 | { |
89 | for (int i = 0; i < data.Count; i++) | 89 | for (int i = 0; i < data.Count; i++) |
90 | { | 90 | { |
91 | //try | 91 | //try |
92 | //{ | 92 | //{ |
93 | IncomingLandObjectFromStorage(data[i]); | 93 | IncomingLandObjectFromStorage(data[i]); |
94 | //} | 94 | //} |
95 | //catch (Exception ex) | 95 | //catch (Exception ex) |
96 | //{ | 96 | //{ |
97 | //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString()); | 97 | //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString()); |
98 | //throw ex; | 98 | //throw ex; |
99 | //} | 99 | //} |
100 | } | 100 | } |
101 | //foreach (LandData parcel in data) | 101 | //foreach (LandData parcel in data) |
102 | //{ | 102 | //{ |
103 | // IncomingLandObjectFromStorage(parcel); | 103 | // IncomingLandObjectFromStorage(parcel); |
104 | //} | 104 | //} |
105 | } | 105 | } |
106 | 106 | ||
107 | public void IncomingLandObjectFromStorage(LandData data) | 107 | public void IncomingLandObjectFromStorage(LandData data) |
108 | { | 108 | { |
109 | ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene); | 109 | ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene); |
110 | new_land.landData = data.Copy(); | 110 | new_land.landData = data.Copy(); |
111 | new_land.setLandBitmapFromByteArray(); | 111 | new_land.setLandBitmapFromByteArray(); |
112 | addLandObject(new_land); | 112 | addLandObject(new_land); |
113 | } | 113 | } |
114 | 114 | ||
115 | public void NoLandDataFromStorage() | 115 | public void NoLandDataFromStorage() |
116 | { | 116 | { |
117 | resetSimLandObjects(); | 117 | resetSimLandObjects(); |
118 | } | 118 | } |
119 | 119 | ||
120 | #endregion | 120 | #endregion |
121 | 121 | ||
122 | #region Parcel Add/Remove/Get/Create | 122 | #region Parcel Add/Remove/Get/Create |
123 | 123 | ||
124 | public void updateLandObject(int local_id, LandData newData) | 124 | public void updateLandObject(int local_id, LandData newData) |
125 | { | 125 | { |
126 | if (landList.ContainsKey(local_id)) | 126 | if (landList.ContainsKey(local_id)) |
127 | { | 127 | { |
128 | landList[local_id].landData = newData.Copy(); | 128 | landList[local_id].landData = newData.Copy(); |
129 | m_scene.EventManager.TriggerLandObjectUpdated((uint) local_id, landList[local_id]); | 129 | m_scene.EventManager.TriggerLandObjectUpdated((uint) local_id, landList[local_id]); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | 132 | ||
133 | /// <summary> | 133 | /// <summary> |
134 | /// Get the land object at the specified point | 134 | /// Get the land object at the specified point |
135 | /// </summary> | 135 | /// </summary> |
136 | /// <param name="x">Value between 0 - 256 on the x axis of the point</param> | 136 | /// <param name="x">Value between 0 - 256 on the x axis of the point</param> |
137 | /// <param name="y">Value between 0 - 256 on the y axis of the point</param> | 137 | /// <param name="y">Value between 0 - 256 on the y axis of the point</param> |
138 | /// <returns>Land object at the point supplied</returns> | 138 | /// <returns>Land object at the point supplied</returns> |
139 | public ILandObject getLandObject(float x_float, float y_float) | 139 | public ILandObject getLandObject(float x_float, float y_float) |
140 | { | 140 | { |
141 | int x; | 141 | int x; |
142 | int y; | 142 | int y; |
143 | 143 | ||
144 | try | 144 | try |
145 | { | 145 | { |
146 | x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0))); | 146 | x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0))); |
147 | y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0))); | 147 | y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0))); |
148 | } | 148 | } |
149 | catch (OverflowException) | 149 | catch (OverflowException) |
150 | { | 150 | { |
151 | return null; | 151 | return null; |
152 | } | 152 | } |
153 | 153 | ||
154 | if (x >= 64 || y >= 64 || x < 0 || y < 0) | 154 | if (x >= 64 || y >= 64 || x < 0 || y < 0) |
155 | { | 155 | { |
156 | return null; | 156 | return null; |
157 | } | 157 | } |
158 | else | 158 | else |
159 | { | 159 | { |
160 | return landList[landIDList[x, y]]; | 160 | return landList[landIDList[x, y]]; |
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
164 | public ILandObject getLandObject(int x, int y) | 164 | public ILandObject getLandObject(int x, int y) |
165 | { | 165 | { |
166 | if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) | 166 | if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) |
167 | { | 167 | { |
168 | // These exceptions here will cause a lot of complaints from the users specifically because | 168 | // These exceptions here will cause a lot of complaints from the users specifically because |
169 | // they happen every time at border crossings | 169 | // they happen every time at border crossings |
170 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | 170 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); |
171 | } | 171 | } |
172 | else | 172 | else |
173 | { | 173 | { |
174 | return landList[landIDList[x / 4, y / 4]]; | 174 | return landList[landIDList[x / 4, y / 4]]; |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
178 | /// <summary> | 178 | /// <summary> |
179 | /// Creates a basic Parcel object without an owner (a zeroed key) | 179 | /// Creates a basic Parcel object without an owner (a zeroed key) |
180 | /// </summary> | 180 | /// </summary> |
181 | /// <returns></returns> | 181 | /// <returns></returns> |
182 | public ILandObject createBaseLand() | 182 | public ILandObject createBaseLand() |
183 | { | 183 | { |
184 | return new LandObject(LLUUID.Zero, false, m_scene); | 184 | return new LandObject(LLUUID.Zero, false, m_scene); |
185 | } | 185 | } |
186 | 186 | ||
187 | /// <summary> | 187 | /// <summary> |
188 | /// Adds a land object to the stored list and adds them to the landIDList to what they own | 188 | /// Adds a land object to the stored list and adds them to the landIDList to what they own |
189 | /// </summary> | 189 | /// </summary> |
190 | /// <param name="new_land">The land object being added</param> | 190 | /// <param name="new_land">The land object being added</param> |
191 | public ILandObject addLandObject(ILandObject new_land) | 191 | public ILandObject addLandObject(ILandObject new_land) |
192 | { | 192 | { |
193 | lastLandLocalID++; | 193 | lastLandLocalID++; |
194 | new_land.landData.localID = lastLandLocalID; | 194 | new_land.landData.localID = lastLandLocalID; |
195 | landList.Add(lastLandLocalID, (LandObject) new_land.Copy()); | 195 | landList.Add(lastLandLocalID, (LandObject) new_land.Copy()); |
196 | 196 | ||
197 | 197 | ||
198 | bool[,] landBitmap = new_land.getLandBitmap(); | 198 | bool[,] landBitmap = new_land.getLandBitmap(); |
199 | int x, y; | 199 | int x, y; |
200 | for (x = 0; x < 64; x++) | 200 | for (x = 0; x < 64; x++) |
201 | { | 201 | { |
202 | for (y = 0; y < 64; y++) | 202 | for (y = 0; y < 64; y++) |
203 | { | 203 | { |
204 | if (landBitmap[x, y]) | 204 | if (landBitmap[x, y]) |
205 | { | 205 | { |
206 | landIDList[x, y] = lastLandLocalID; | 206 | landIDList[x, y] = lastLandLocalID; |
207 | } | 207 | } |
208 | } | 208 | } |
209 | } | 209 | } |
210 | landList[lastLandLocalID].forceUpdateLandInfo(); | 210 | landList[lastLandLocalID].forceUpdateLandInfo(); |
211 | m_scene.EventManager.TriggerLandObjectAdded(new_land); | 211 | m_scene.EventManager.TriggerLandObjectAdded(new_land); |
212 | return new_land; | 212 | return new_land; |
213 | } | 213 | } |
214 | 214 | ||
215 | /// <summary> | 215 | /// <summary> |
216 | /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList | 216 | /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList |
217 | /// </summary> | 217 | /// </summary> |
218 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> | 218 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> |
219 | public void removeLandObject(int local_id) | 219 | public void removeLandObject(int local_id) |
220 | { | 220 | { |
221 | int x, y; | 221 | int x, y; |
222 | for (x = 0; x < 64; x++) | 222 | for (x = 0; x < 64; x++) |
223 | { | 223 | { |
224 | for (y = 0; y < 64; y++) | 224 | for (y = 0; y < 64; y++) |
225 | { | 225 | { |
226 | if (landIDList[x, y] == local_id) | 226 | if (landIDList[x, y] == local_id) |
227 | { | 227 | { |
228 | return; | 228 | return; |
229 | //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); | 229 | //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); |
230 | } | 230 | } |
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID); | 234 | m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID); |
235 | landList.Remove(local_id); | 235 | landList.Remove(local_id); |
236 | } | 236 | } |
237 | 237 | ||
238 | private void performFinalLandJoin(ILandObject master, ILandObject slave) | 238 | private void performFinalLandJoin(ILandObject master, ILandObject slave) |
239 | { | 239 | { |
240 | int x, y; | 240 | int x, y; |
241 | bool[,] landBitmapSlave = slave.getLandBitmap(); | 241 | bool[,] landBitmapSlave = slave.getLandBitmap(); |
242 | for (x = 0; x < 64; x++) | 242 | for (x = 0; x < 64; x++) |
243 | { | 243 | { |
244 | for (y = 0; y < 64; y++) | 244 | for (y = 0; y < 64; y++) |
245 | { | 245 | { |
246 | if (landBitmapSlave[x, y]) | 246 | if (landBitmapSlave[x, y]) |
247 | { | 247 | { |
248 | landIDList[x, y] = master.landData.localID; | 248 | landIDList[x, y] = master.landData.localID; |
249 | } | 249 | } |
250 | } | 250 | } |
251 | } | 251 | } |
252 | 252 | ||
253 | removeLandObject(slave.landData.localID); | 253 | removeLandObject(slave.landData.localID); |
254 | updateLandObject(master.landData.localID, master.landData); | 254 | updateLandObject(master.landData.localID, master.landData); |
255 | } | 255 | } |
256 | 256 | ||
257 | public ILandObject getLandObject(int parcelLocalID) | 257 | public ILandObject getLandObject(int parcelLocalID) |
258 | { | 258 | { |
259 | lock (landList) | 259 | lock (landList) |
260 | { | 260 | { |
261 | if (landList.ContainsKey(parcelLocalID)) | 261 | if (landList.ContainsKey(parcelLocalID)) |
262 | { | 262 | { |
263 | return landList[parcelLocalID]; | 263 | return landList[parcelLocalID]; |
264 | } | 264 | } |
265 | } | 265 | } |
266 | return null; | 266 | return null; |
267 | } | 267 | } |
268 | 268 | ||
269 | #endregion | 269 | #endregion |
270 | 270 | ||
271 | #region Parcel Modification | 271 | #region Parcel Modification |
272 | 272 | ||
273 | public void resetAllLandPrimCounts() | 273 | public void resetAllLandPrimCounts() |
274 | { | 274 | { |
275 | foreach (LandObject p in landList.Values) | 275 | foreach (LandObject p in landList.Values) |
276 | { | 276 | { |
277 | p.resetLandPrimCounts(); | 277 | p.resetLandPrimCounts(); |
278 | } | 278 | } |
279 | } | 279 | } |
280 | 280 | ||
281 | public void setPrimsTainted() | 281 | public void setPrimsTainted() |
282 | { | 282 | { |
283 | landPrimCountTainted = true; | 283 | landPrimCountTainted = true; |
284 | } | 284 | } |
285 | 285 | ||
286 | public bool isLandPrimCountTainted() | 286 | public bool isLandPrimCountTainted() |
287 | { | 287 | { |
288 | return landPrimCountTainted; | 288 | return landPrimCountTainted; |
289 | } | 289 | } |
290 | 290 | ||
291 | public void addPrimToLandPrimCounts(SceneObjectGroup obj) | 291 | public void addPrimToLandPrimCounts(SceneObjectGroup obj) |
292 | { | 292 | { |
293 | LLVector3 position = obj.AbsolutePosition; | 293 | LLVector3 position = obj.AbsolutePosition; |
294 | ILandObject landUnderPrim = getLandObject(position.X, position.Y); | 294 | ILandObject landUnderPrim = getLandObject(position.X, position.Y); |
295 | if (landUnderPrim != null) | 295 | if (landUnderPrim != null) |
296 | { | 296 | { |
297 | landUnderPrim.addPrimToCount(obj); | 297 | landUnderPrim.addPrimToCount(obj); |
298 | } | 298 | } |
299 | } | 299 | } |
300 | 300 | ||
301 | public void removePrimFromLandPrimCounts(SceneObjectGroup obj) | 301 | public void removePrimFromLandPrimCounts(SceneObjectGroup obj) |
302 | { | 302 | { |
303 | foreach (LandObject p in landList.Values) | 303 | foreach (LandObject p in landList.Values) |
304 | { | 304 | { |
305 | p.removePrimFromCount(obj); | 305 | p.removePrimFromCount(obj); |
306 | } | 306 | } |
307 | } | 307 | } |
308 | 308 | ||
309 | public void finalizeLandPrimCountUpdate() | 309 | public void finalizeLandPrimCountUpdate() |
310 | { | 310 | { |
311 | //Get Simwide prim count for owner | 311 | //Get Simwide prim count for owner |
312 | Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>(); | 312 | Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>(); |
313 | foreach (LandObject p in landList.Values) | 313 | foreach (LandObject p in landList.Values) |
314 | { | 314 | { |
315 | if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) | 315 | if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) |
316 | { | 316 | { |
317 | List<LandObject> tempList = new List<LandObject>(); | 317 | List<LandObject> tempList = new List<LandObject>(); |
318 | tempList.Add(p); | 318 | tempList.Add(p); |
319 | landOwnersAndParcels.Add(p.landData.ownerID, tempList); | 319 | landOwnersAndParcels.Add(p.landData.ownerID, tempList); |
320 | } | 320 | } |
321 | else | 321 | else |
322 | { | 322 | { |
323 | landOwnersAndParcels[p.landData.ownerID].Add(p); | 323 | landOwnersAndParcels[p.landData.ownerID].Add(p); |
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
327 | foreach (LLUUID owner in landOwnersAndParcels.Keys) | 327 | foreach (LLUUID owner in landOwnersAndParcels.Keys) |
328 | { | 328 | { |
329 | int simArea = 0; | 329 | int simArea = 0; |
330 | int simPrims = 0; | 330 | int simPrims = 0; |
331 | foreach (LandObject p in landOwnersAndParcels[owner]) | 331 | foreach (LandObject p in landOwnersAndParcels[owner]) |
332 | { | 332 | { |
333 | simArea += p.landData.area; | 333 | simArea += p.landData.area; |
334 | simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + | 334 | simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + |
335 | p.landData.selectedPrims; | 335 | p.landData.selectedPrims; |
336 | } | 336 | } |
337 | 337 | ||
338 | foreach (LandObject p in landOwnersAndParcels[owner]) | 338 | foreach (LandObject p in landOwnersAndParcels[owner]) |
339 | { | 339 | { |
340 | p.landData.simwideArea = simArea; | 340 | p.landData.simwideArea = simArea; |
341 | p.landData.simwidePrims = simPrims; | 341 | p.landData.simwidePrims = simPrims; |
342 | } | 342 | } |
343 | } | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
346 | public void updateLandPrimCounts() | 346 | public void updateLandPrimCounts() |
347 | { | 347 | { |
348 | foreach (EntityBase obj in m_scene.Entities.Values) | 348 | foreach (EntityBase obj in m_scene.Entities.Values) |
349 | { | 349 | { |
350 | if (obj is SceneObjectGroup) | 350 | if (obj is SceneObjectGroup) |
351 | { | 351 | { |
352 | m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup) obj); | 352 | m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup) obj); |
353 | } | 353 | } |
354 | } | 354 | } |
355 | } | 355 | } |
356 | 356 | ||
357 | public void performParcelPrimCountUpdate() | 357 | public void performParcelPrimCountUpdate() |
358 | { | 358 | { |
359 | resetAllLandPrimCounts(); | 359 | resetAllLandPrimCounts(); |
360 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); | 360 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); |
361 | finalizeLandPrimCountUpdate(); | 361 | finalizeLandPrimCountUpdate(); |
362 | landPrimCountTainted = false; | 362 | landPrimCountTainted = false; |
363 | } | 363 | } |
364 | 364 | ||
365 | /// <summary> | 365 | /// <summary> |
366 | /// Subdivides a piece of land | 366 | /// Subdivides a piece of land |
367 | /// </summary> | 367 | /// </summary> |
368 | /// <param name="start_x">West Point</param> | 368 | /// <param name="start_x">West Point</param> |
369 | /// <param name="start_y">South Point</param> | 369 | /// <param name="start_y">South Point</param> |
370 | /// <param name="end_x">East Point</param> | 370 | /// <param name="end_x">East Point</param> |
371 | /// <param name="end_y">North Point</param> | 371 | /// <param name="end_y">North Point</param> |
372 | /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> | 372 | /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> |
373 | /// <returns>Returns true if successful</returns> | 373 | /// <returns>Returns true if successful</returns> |
374 | private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | 374 | private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) |
375 | { | 375 | { |
376 | //First, lets loop through the points and make sure they are all in the same peice of land | 376 | //First, lets loop through the points and make sure they are all in the same peice of land |
377 | //Get the land object at start | 377 | //Get the land object at start |
378 | ILandObject startLandObject = null; | 378 | ILandObject startLandObject = null; |
379 | try | 379 | try |
380 | { | 380 | { |
381 | startLandObject = getLandObject(start_x, start_y); | 381 | startLandObject = getLandObject(start_x, start_y); |
382 | } | 382 | } |
383 | catch (Exception) | 383 | catch (Exception) |
384 | { | 384 | { |
385 | //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y); | 385 | //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y); |
386 | } | 386 | } |
387 | if (startLandObject == null) return false; //No such land object at the beginning | 387 | if (startLandObject == null) return false; //No such land object at the beginning |
388 | 388 | ||
389 | //Loop through the points | 389 | //Loop through the points |
390 | try | 390 | try |
391 | { | 391 | { |
392 | int totalX = end_x - start_x; | 392 | int totalX = end_x - start_x; |
393 | int totalY = end_y - start_y; | 393 | int totalY = end_y - start_y; |
394 | int x, y; | 394 | int x, y; |
395 | for (y = 0; y < totalY; y++) | 395 | for (y = 0; y < totalY; y++) |
396 | { | 396 | { |
397 | for (x = 0; x < totalX; x++) | 397 | for (x = 0; x < totalX; x++) |
398 | { | 398 | { |
399 | ILandObject tempLandObject = getLandObject(start_x + x, start_y + y); | 399 | ILandObject tempLandObject = getLandObject(start_x + x, start_y + y); |
400 | if (tempLandObject == null) return false; //No such land object at that point | 400 | if (tempLandObject == null) return false; //No such land object at that point |
401 | if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no | 401 | if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no |
402 | } | 402 | } |
403 | } | 403 | } |
404 | } | 404 | } |
405 | catch (Exception) | 405 | catch (Exception) |
406 | { | 406 | { |
407 | return false; //Exception. For now, lets skip subdivision | 407 | return false; //Exception. For now, lets skip subdivision |
408 | } | 408 | } |
409 | 409 | ||
410 | //If we are still here, then they are subdividing within one piece of land | 410 | //If we are still here, then they are subdividing within one piece of land |
411 | //Check owner | 411 | //Check owner |
412 | if (startLandObject.landData.ownerID != attempting_user_id) | 412 | if (startLandObject.landData.ownerID != attempting_user_id) |
413 | { | 413 | { |
414 | return false; //They cant do this! | 414 | return false; //They cant do this! |
415 | } | 415 | } |
416 | 416 | ||
417 | //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) | 417 | //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) |
418 | ILandObject newLand = startLandObject.Copy(); | 418 | ILandObject newLand = startLandObject.Copy(); |
419 | newLand.landData.landName = "Subdivision of " + newLand.landData.landName; | 419 | newLand.landData.landName = "Subdivision of " + newLand.landData.landName; |
420 | newLand.landData.globalID = LLUUID.Random(); | 420 | newLand.landData.globalID = LLUUID.Random(); |
421 | 421 | ||
422 | newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y)); | 422 | newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y)); |
423 | 423 | ||
424 | //Now, lets set the subdivision area of the original to false | 424 | //Now, lets set the subdivision area of the original to false |
425 | int startLandObjectIndex = startLandObject.landData.localID; | 425 | int startLandObjectIndex = startLandObject.landData.localID; |
426 | landList[startLandObjectIndex].setLandBitmap( | 426 | landList[startLandObjectIndex].setLandBitmap( |
427 | newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); | 427 | newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); |
428 | landList[startLandObjectIndex].forceUpdateLandInfo(); | 428 | landList[startLandObjectIndex].forceUpdateLandInfo(); |
429 | 429 | ||
430 | setPrimsTainted(); | 430 | setPrimsTainted(); |
431 | 431 | ||
432 | //Now add the new land object | 432 | //Now add the new land object |
433 | ILandObject result = addLandObject(newLand); | 433 | ILandObject result = addLandObject(newLand); |
434 | updateLandObject(startLandObject.landData.localID, startLandObject.landData); | 434 | updateLandObject(startLandObject.landData.localID, startLandObject.landData); |
435 | result.sendLandUpdateToAvatarsOverMe(); | 435 | result.sendLandUpdateToAvatarsOverMe(); |
436 | 436 | ||
437 | 437 | ||
438 | return true; | 438 | return true; |
439 | } | 439 | } |
440 | 440 | ||
441 | /// <summary> | 441 | /// <summary> |
442 | /// Join 2 land objects together | 442 | /// Join 2 land objects together |
443 | /// </summary> | 443 | /// </summary> |
444 | /// <param name="start_x">x value in first piece of land</param> | 444 | /// <param name="start_x">x value in first piece of land</param> |
445 | /// <param name="start_y">y value in first piece of land</param> | 445 | /// <param name="start_y">y value in first piece of land</param> |
446 | /// <param name="end_x">x value in second peice of land</param> | 446 | /// <param name="end_x">x value in second peice of land</param> |
447 | /// <param name="end_y">y value in second peice of land</param> | 447 | /// <param name="end_y">y value in second peice of land</param> |
448 | /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param> | 448 | /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param> |
449 | /// <returns>Returns true if successful</returns> | 449 | /// <returns>Returns true if successful</returns> |
450 | private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | 450 | private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) |
451 | { | 451 | { |
452 | end_x -= 4; | 452 | end_x -= 4; |
453 | end_y -= 4; | 453 | end_y -= 4; |
454 | 454 | ||
455 | List<ILandObject> selectedLandObjects = new List<ILandObject>(); | 455 | List<ILandObject> selectedLandObjects = new List<ILandObject>(); |
456 | int stepXSelected = 0; | 456 | int stepXSelected = 0; |
457 | int stepYSelected = 0; | 457 | int stepYSelected = 0; |
458 | for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) | 458 | for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) |
459 | { | 459 | { |
460 | for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) | 460 | for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) |
461 | { | 461 | { |
462 | ILandObject p = null; | 462 | ILandObject p = null; |
463 | try | 463 | try |
464 | { | 464 | { |
465 | p = getLandObject(stepXSelected, stepYSelected); | 465 | p = getLandObject(stepXSelected, stepYSelected); |
466 | } | 466 | } |
467 | catch (Exception) | 467 | catch (Exception) |
468 | { | 468 | { |
469 | //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected); | 469 | //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected); |
470 | } | 470 | } |
471 | if (p != null) | 471 | if (p != null) |
472 | { | 472 | { |
473 | if (!selectedLandObjects.Contains(p)) | 473 | if (!selectedLandObjects.Contains(p)) |
474 | { | 474 | { |
475 | selectedLandObjects.Add(p); | 475 | selectedLandObjects.Add(p); |
476 | } | 476 | } |
477 | } | 477 | } |
478 | } | 478 | } |
479 | } | 479 | } |
480 | ILandObject masterLandObject = selectedLandObjects[0]; | 480 | ILandObject masterLandObject = selectedLandObjects[0]; |
481 | selectedLandObjects.RemoveAt(0); | 481 | selectedLandObjects.RemoveAt(0); |
482 | 482 | ||
483 | 483 | ||
484 | if (selectedLandObjects.Count < 1) | 484 | if (selectedLandObjects.Count < 1) |
485 | { | 485 | { |
486 | return false; //Only one piece of land selected | 486 | return false; //Only one piece of land selected |
487 | } | 487 | } |
488 | if (masterLandObject.landData.ownerID != attempting_user_id) | 488 | if (masterLandObject.landData.ownerID != attempting_user_id) |
489 | { | 489 | { |
490 | return false; //Not the same owner | 490 | return false; //Not the same owner |
491 | } | 491 | } |
492 | foreach (ILandObject p in selectedLandObjects) | 492 | foreach (ILandObject p in selectedLandObjects) |
493 | { | 493 | { |
494 | if (p.landData.ownerID != masterLandObject.landData.ownerID) | 494 | if (p.landData.ownerID != masterLandObject.landData.ownerID) |
495 | { | 495 | { |
496 | return false; //Over multiple users. TODO: make this just ignore this piece of land? | 496 | return false; //Over multiple users. TODO: make this just ignore this piece of land? |
497 | } | 497 | } |
498 | } | 498 | } |
499 | foreach (ILandObject slaveLandObject in selectedLandObjects) | 499 | foreach (ILandObject slaveLandObject in selectedLandObjects) |
500 | { | 500 | { |
501 | landList[masterLandObject.landData.localID].setLandBitmap( | 501 | landList[masterLandObject.landData.localID].setLandBitmap( |
502 | slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); | 502 | slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); |
503 | performFinalLandJoin(masterLandObject, slaveLandObject); | 503 | performFinalLandJoin(masterLandObject, slaveLandObject); |
504 | } | 504 | } |
505 | 505 | ||
506 | 506 | ||
507 | setPrimsTainted(); | 507 | setPrimsTainted(); |
508 | 508 | ||
509 | masterLandObject.sendLandUpdateToAvatarsOverMe(); | 509 | masterLandObject.sendLandUpdateToAvatarsOverMe(); |
510 | 510 | ||
511 | return true; | 511 | return true; |
512 | } | 512 | } |
513 | 513 | ||
514 | #endregion | 514 | #endregion |
515 | 515 | ||
516 | #region Parcel Updating | 516 | #region Parcel Updating |
517 | 517 | ||
518 | /// <summary> | 518 | /// <summary> |
519 | /// Where we send the ParcelOverlay packet to the client | 519 | /// Where we send the ParcelOverlay packet to the client |
520 | /// </summary> | 520 | /// </summary> |
521 | /// <param name="remote_client">The object representing the client</param> | 521 | /// <param name="remote_client">The object representing the client</param> |
522 | public void sendParcelOverlay(IClientAPI remote_client) | 522 | public void sendParcelOverlay(IClientAPI remote_client) |
523 | { | 523 | { |
524 | const int LAND_BLOCKS_PER_PACKET = 1024; | 524 | const int LAND_BLOCKS_PER_PACKET = 1024; |
525 | int x, y = 0; | 525 | int x, y = 0; |
526 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 526 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
527 | int byteArrayCount = 0; | 527 | int byteArrayCount = 0; |
528 | int sequenceID = 0; | 528 | int sequenceID = 0; |
529 | ParcelOverlayPacket packet; | 529 | ParcelOverlayPacket packet; |
530 | 530 | ||
531 | for (y = 0; y < 64; y++) | 531 | for (y = 0; y < 64; y++) |
532 | { | 532 | { |
533 | for (x = 0; x < 64; x++) | 533 | for (x = 0; x < 64; x++) |
534 | { | 534 | { |
535 | byte tempByte = (byte) 0; //This represents the byte for the current 4x4 | 535 | byte tempByte = (byte) 0; //This represents the byte for the current 4x4 |
536 | ILandObject currentParcelBlock = null; | 536 | ILandObject currentParcelBlock = null; |
537 | 537 | ||
538 | try | 538 | try |
539 | { | 539 | { |
540 | currentParcelBlock = getLandObject(x * 4, y * 4); | 540 | currentParcelBlock = getLandObject(x * 4, y * 4); |
541 | } | 541 | } |
542 | catch (Exception) | 542 | catch (Exception) |
543 | { | 543 | { |
544 | //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4)); | 544 | //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4)); |
545 | } | 545 | } |
546 | 546 | ||
547 | 547 | ||
548 | if (currentParcelBlock != null) | 548 | if (currentParcelBlock != null) |
549 | { | 549 | { |
550 | if (currentParcelBlock.landData.ownerID == remote_client.AgentId) | 550 | if (currentParcelBlock.landData.ownerID == remote_client.AgentId) |
551 | { | 551 | { |
552 | //Owner Flag | 552 | //Owner Flag |
553 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); | 553 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); |
554 | } | 554 | } |
555 | else if (currentParcelBlock.landData.salePrice > 0 && | 555 | else if (currentParcelBlock.landData.salePrice > 0 && |
556 | (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || | 556 | (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || |
557 | currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) | 557 | currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) |
558 | { | 558 | { |
559 | //Sale Flag | 559 | //Sale Flag |
560 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); | 560 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); |
561 | } | 561 | } |
562 | else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) | 562 | else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) |
563 | { | 563 | { |
564 | //Public Flag | 564 | //Public Flag |
565 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); | 565 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); |
566 | } | 566 | } |
567 | else | 567 | else |
568 | { | 568 | { |
569 | //Other Flag | 569 | //Other Flag |
570 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); | 570 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); |
571 | } | 571 | } |
572 | 572 | ||
573 | 573 | ||
574 | //Now for border control | 574 | //Now for border control |
575 | try | 575 | try |
576 | { | 576 | { |
577 | ILandObject westParcel = null; | 577 | ILandObject westParcel = null; |
578 | ILandObject southParcel = null; | 578 | ILandObject southParcel = null; |
579 | if (x > 0) | 579 | if (x > 0) |
580 | { | 580 | { |
581 | westParcel = getLandObject((x - 1) * 4, y * 4); | 581 | westParcel = getLandObject((x - 1) * 4, y * 4); |
582 | } | 582 | } |
583 | if (y > 0) | 583 | if (y > 0) |
584 | { | 584 | { |
585 | southParcel = getLandObject(x * 4, (y - 1) * 4); | 585 | southParcel = getLandObject(x * 4, (y - 1) * 4); |
586 | } | 586 | } |
587 | 587 | ||
588 | if (x == 0) | 588 | if (x == 0) |
589 | { | 589 | { |
590 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); | 590 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); |
591 | } | 591 | } |
592 | else if (westParcel != null && westParcel != currentParcelBlock) | 592 | else if (westParcel != null && westParcel != currentParcelBlock) |
593 | { | 593 | { |
594 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); | 594 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); |
595 | } | 595 | } |
596 | 596 | ||
597 | if (y == 0) | 597 | if (y == 0) |
598 | { | 598 | { |
599 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); | 599 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); |
600 | } | 600 | } |
601 | else if (southParcel != null && southParcel != currentParcelBlock) | 601 | else if (southParcel != null && southParcel != currentParcelBlock) |
602 | { | 602 | { |
603 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); | 603 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); |
604 | } | 604 | } |
605 | 605 | ||
606 | byteArray[byteArrayCount] = tempByte; | 606 | byteArray[byteArrayCount] = tempByte; |
607 | byteArrayCount++; | 607 | byteArrayCount++; |
608 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | 608 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) |
609 | { | 609 | { |
610 | byteArrayCount = 0; | 610 | byteArrayCount = 0; |
611 | packet = (ParcelOverlayPacket) PacketPool.Instance.GetPacket(PacketType.ParcelOverlay); | 611 | packet = (ParcelOverlayPacket) PacketPool.Instance.GetPacket(PacketType.ParcelOverlay); |
612 | packet.ParcelData.Data = byteArray; | 612 | packet.ParcelData.Data = byteArray; |
613 | packet.ParcelData.SequenceID = sequenceID; | 613 | packet.ParcelData.SequenceID = sequenceID; |
614 | remote_client.OutPacket((Packet) packet, ThrottleOutPacketType.Task); | 614 | remote_client.OutPacket((Packet) packet, ThrottleOutPacketType.Task); |
615 | sequenceID++; | 615 | sequenceID++; |
616 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 616 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
617 | } | 617 | } |
618 | } | 618 | } |
619 | catch (Exception) | 619 | catch (Exception) |
620 | { | 620 | { |
621 | //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message); | 621 | //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message); |
622 | } | 622 | } |
623 | } | 623 | } |
624 | } | 624 | } |
625 | } | 625 | } |
626 | } | 626 | } |
627 | 627 | ||
628 | public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, | 628 | public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, |
629 | bool snap_selection, IClientAPI remote_client) | 629 | bool snap_selection, IClientAPI remote_client) |
630 | { | 630 | { |
631 | //Get the land objects within the bounds | 631 | //Get the land objects within the bounds |
632 | List<ILandObject> temp = new List<ILandObject>(); | 632 | List<ILandObject> temp = new List<ILandObject>(); |
633 | int x, y, i; | 633 | int x, y, i; |
634 | int inc_x = end_x - start_x; | 634 | int inc_x = end_x - start_x; |
635 | int inc_y = end_y - start_y; | 635 | int inc_y = end_y - start_y; |
636 | for (x = 0; x < inc_x; x++) | 636 | for (x = 0; x < inc_x; x++) |
637 | { | 637 | { |
638 | for (y = 0; y < inc_y; y++) | 638 | for (y = 0; y < inc_y; y++) |
639 | { | 639 | { |
640 | ILandObject currentParcel = null; | 640 | ILandObject currentParcel = null; |
641 | try | 641 | try |
642 | { | 642 | { |
643 | currentParcel = getLandObject(start_x + x, start_y + y); | 643 | currentParcel = getLandObject(start_x + x, start_y + y); |
644 | } | 644 | } |
645 | catch (Exception) | 645 | catch (Exception) |
646 | { | 646 | { |
647 | //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y)); | 647 | //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y)); |
648 | } | 648 | } |
649 | if (currentParcel != null) | 649 | if (currentParcel != null) |
650 | { | 650 | { |
651 | if (!temp.Contains(currentParcel)) | 651 | if (!temp.Contains(currentParcel)) |
652 | { | 652 | { |
653 | currentParcel.forceUpdateLandInfo(); | 653 | currentParcel.forceUpdateLandInfo(); |
654 | temp.Add(currentParcel); | 654 | temp.Add(currentParcel); |
655 | } | 655 | } |
656 | } | 656 | } |
657 | } | 657 | } |
658 | } | 658 | } |
659 | 659 | ||
660 | int requestResult = LAND_RESULT_SINGLE; | 660 | int requestResult = LAND_RESULT_SINGLE; |
661 | if (temp.Count > 1) | 661 | if (temp.Count > 1) |
662 | { | 662 | { |
663 | requestResult = LAND_RESULT_MULTIPLE; | 663 | requestResult = LAND_RESULT_MULTIPLE; |
664 | } | 664 | } |
665 | 665 | ||
666 | for (i = 0; i < temp.Count; i++) | 666 | for (i = 0; i < temp.Count; i++) |
667 | { | 667 | { |
668 | temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); | 668 | temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); |
669 | } | 669 | } |
670 | 670 | ||
671 | 671 | ||
672 | sendParcelOverlay(remote_client); | 672 | sendParcelOverlay(remote_client); |
673 | } | 673 | } |
674 | 674 | ||
675 | public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) | 675 | public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) |
676 | { | 676 | { |
677 | if (landList.ContainsKey(packet.ParcelData.LocalID)) | 677 | if (landList.ContainsKey(packet.ParcelData.LocalID)) |
678 | { | 678 | { |
679 | landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); | 679 | landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); |
680 | } | 680 | } |
681 | } | 681 | } |
682 | 682 | ||
683 | public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) | 683 | public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) |
684 | { | 684 | { |
685 | subdivide(west, south, east, north, remote_client.AgentId); | 685 | subdivide(west, south, east, north, remote_client.AgentId); |
686 | } | 686 | } |
687 | 687 | ||
688 | public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) | 688 | public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) |
689 | { | 689 | { |
690 | join(west, south, east, north, remote_client.AgentId); | 690 | join(west, south, east, north, remote_client.AgentId); |
691 | } | 691 | } |
692 | 692 | ||
693 | public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) | 693 | public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) |
694 | { | 694 | { |
695 | landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); | 695 | landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); |
696 | } | 696 | } |
697 | 697 | ||
698 | public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) | 698 | public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) |
699 | { | 699 | { |
700 | landList[local_id].sendLandObjectOwners(remote_client); | 700 | landList[local_id].sendLandObjectOwners(remote_client); |
701 | } | 701 | } |
702 | 702 | ||
703 | #endregion | 703 | #endregion |
704 | 704 | ||
705 | #region ILandChannel Members | 705 | #region ILandChannel Members |
706 | 706 | ||
707 | public bool allowedForcefulBans | 707 | public bool allowedForcefulBans |
708 | { | 708 | { |
709 | get { return m_allowedForcefulBans; } | 709 | get { return m_allowedForcefulBans; } |
710 | set { m_allowedForcefulBans = value; } | 710 | set { m_allowedForcefulBans = value; } |
711 | } | 711 | } |
712 | 712 | ||
713 | /// <summary> | 713 | /// <summary> |
714 | /// Resets the sim to the default land object (full sim piece of land owned by the default user) | 714 | /// Resets the sim to the default land object (full sim piece of land owned by the default user) |
715 | /// </summary> | 715 | /// </summary> |
716 | public void resetSimLandObjects() | 716 | public void resetSimLandObjects() |
717 | { | 717 | { |
718 | //Remove all the land objects in the sim and add a blank, full sim land object set to public | 718 | //Remove all the land objects in the sim and add a blank, full sim land object set to public |
719 | landList.Clear(); | 719 | landList.Clear(); |
720 | lastLandLocalID = START_LAND_LOCAL_ID - 1; | 720 | lastLandLocalID = START_LAND_LOCAL_ID - 1; |
721 | landIDList.Initialize(); | 721 | landIDList.Initialize(); |
722 | 722 | ||
723 | ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene); | 723 | ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene); |
724 | 724 | ||
725 | fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize)); | 725 | fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize)); |
726 | fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 726 | fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
727 | 727 | ||
728 | addLandObject(fullSimParcel); | 728 | addLandObject(fullSimParcel); |
729 | } | 729 | } |
730 | 730 | ||
731 | public List<ILandObject> parcelsNearPoint(LLVector3 position) | 731 | public List<ILandObject> parcelsNearPoint(LLVector3 position) |
732 | { | 732 | { |
733 | List<ILandObject> parcelsNear = new List<ILandObject>(); | 733 | List<ILandObject> parcelsNear = new List<ILandObject>(); |
734 | int x, y; | 734 | int x, y; |
735 | for (x = -4; x <= 4; x += 4) | 735 | for (x = -4; x <= 4; x += 4) |
736 | { | 736 | { |
737 | for (y = -4; y <= 4; y += 4) | 737 | for (y = -4; y <= 4; y += 4) |
738 | { | 738 | { |
739 | ILandObject check = getLandObject(position.X + x, position.Y + y); | 739 | ILandObject check = getLandObject(position.X + x, position.Y + y); |
740 | if (check != null) | 740 | if (check != null) |
741 | { | 741 | { |
742 | if (!parcelsNear.Contains(check)) | 742 | if (!parcelsNear.Contains(check)) |
743 | { | 743 | { |
744 | parcelsNear.Add(check); | 744 | parcelsNear.Add(check); |
745 | } | 745 | } |
746 | } | 746 | } |
747 | } | 747 | } |
748 | } | 748 | } |
749 | 749 | ||
750 | return parcelsNear; | 750 | return parcelsNear; |
751 | } | 751 | } |
752 | 752 | ||
753 | public void sendYouAreBannedNotice(ScenePresence avatar) | 753 | public void sendYouAreBannedNotice(ScenePresence avatar) |
754 | { | 754 | { |
755 | if (allowedForcefulBans) | 755 | if (allowedForcefulBans) |
756 | { | 756 | { |
757 | avatar.ControllingClient.SendAlertMessage( | 757 | avatar.ControllingClient.SendAlertMessage( |
758 | "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers"); | 758 | "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers"); |
759 | 759 | ||
760 | avatar.PhysicsActor.Position = | 760 | avatar.PhysicsActor.Position = |
761 | new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y, | 761 | new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y, |
762 | avatar.lastKnownAllowedPosition.z); | 762 | avatar.lastKnownAllowedPosition.z); |
763 | avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0); | 763 | avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0); |
764 | } | 764 | } |
765 | else | 765 | else |
766 | { | 766 | { |
767 | avatar.ControllingClient.SendAlertMessage( | 767 | avatar.ControllingClient.SendAlertMessage( |
768 | "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim! <3 OpenSim Developers"); | 768 | "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim! <3 OpenSim Developers"); |
769 | } | 769 | } |
770 | } | 770 | } |
771 | 771 | ||
772 | public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID) | 772 | public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID) |
773 | { | 773 | { |
774 | if (m_scene.RegionInfo.RegionID == regionID) | 774 | if (m_scene.RegionInfo.RegionID == regionID) |
775 | { | 775 | { |
776 | if (landList[localLandID] != null) | 776 | if (landList[localLandID] != null) |
777 | { | 777 | { |
778 | ILandObject parcelAvatarIsEntering = landList[localLandID]; | 778 | ILandObject parcelAvatarIsEntering = landList[localLandID]; |
779 | if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT) | 779 | if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT) |
780 | { | 780 | { |
781 | if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) | 781 | if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) |
782 | { | 782 | { |
783 | sendYouAreBannedNotice(avatar); | 783 | sendYouAreBannedNotice(avatar); |
784 | } | 784 | } |
785 | else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID)) | 785 | else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID)) |
786 | { | 786 | { |
787 | avatar.ControllingClient.SendAlertMessage( | 787 | avatar.ControllingClient.SendAlertMessage( |
788 | "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers"); | 788 | "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers"); |
789 | } | 789 | } |
790 | else | 790 | else |
791 | { | 791 | { |
792 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; | 792 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; |
793 | } | 793 | } |
794 | } | 794 | } |
795 | else | 795 | else |
796 | { | 796 | { |
797 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; | 797 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; |
798 | } | 798 | } |
799 | } | 799 | } |
800 | } | 800 | } |
801 | } | 801 | } |
802 | 802 | ||
803 | public void sendOutNearestBanLine(IClientAPI avatar) | 803 | public void sendOutNearestBanLine(IClientAPI avatar) |
804 | { | 804 | { |
805 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 805 | List<ScenePresence> avatars = m_scene.GetAvatars(); |
806 | foreach (ScenePresence presence in avatars) | 806 | foreach (ScenePresence presence in avatars) |
807 | { | 807 | { |
808 | if (presence.UUID == avatar.AgentId) | 808 | if (presence.UUID == avatar.AgentId) |
809 | { | 809 | { |
810 | List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition); | 810 | List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition); |
811 | foreach (ILandObject checkBan in checkLandParcels) | 811 | foreach (ILandObject checkBan in checkLandParcels) |
812 | { | 812 | { |
813 | if (checkBan.isBannedFromLand(avatar.AgentId)) | 813 | if (checkBan.isBannedFromLand(avatar.AgentId)) |
814 | { | 814 | { |
815 | checkBan.sendLandProperties(-30000, false, (int) ParcelManager.ParcelResult.Single, avatar); | 815 | checkBan.sendLandProperties(-30000, false, (int) ParcelManager.ParcelResult.Single, avatar); |
816 | return; //Only send one | 816 | return; //Only send one |
817 | } | 817 | } |
818 | else if (checkBan.isRestrictedFromLand(avatar.AgentId)) | 818 | else if (checkBan.isRestrictedFromLand(avatar.AgentId)) |
819 | { | 819 | { |
820 | checkBan.sendLandProperties(-40000, false, (int) ParcelManager.ParcelResult.Single, avatar); | 820 | checkBan.sendLandProperties(-40000, false, (int) ParcelManager.ParcelResult.Single, avatar); |
821 | return; //Only send one | 821 | return; //Only send one |
822 | } | 822 | } |
823 | } | 823 | } |
824 | return; | 824 | return; |
825 | } | 825 | } |
826 | } | 826 | } |
827 | } | 827 | } |
828 | 828 | ||
829 | public void sendLandUpdate(ScenePresence avatar, bool force) | 829 | public void sendLandUpdate(ScenePresence avatar, bool force) |
830 | { | 830 | { |
831 | ILandObject over = null; | 831 | ILandObject over = null; |
832 | try | 832 | try |
833 | { | 833 | { |
834 | over = getLandObject((int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), | 834 | over = getLandObject((int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), |
835 | (int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); | 835 | (int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); |
836 | } | 836 | } |
837 | catch (Exception) | 837 | catch (Exception) |
838 | { | 838 | { |
839 | //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y)); | 839 | //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y)); |
840 | } | 840 | } |
841 | 841 | ||
842 | if (over != null) | 842 | if (over != null) |
843 | { | 843 | { |
844 | if (force) | 844 | if (force) |
845 | { | 845 | { |
846 | if (!avatar.IsChildAgent) | 846 | if (!avatar.IsChildAgent) |
847 | { | 847 | { |
848 | over.sendLandUpdateToClient(avatar.ControllingClient); | 848 | over.sendLandUpdateToClient(avatar.ControllingClient); |
849 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, | 849 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, |
850 | m_scene.RegionInfo.RegionID); | 850 | m_scene.RegionInfo.RegionID); |
851 | } | 851 | } |
852 | } | 852 | } |
853 | 853 | ||
854 | if (avatar.currentParcelUUID != over.landData.globalID) | 854 | if (avatar.currentParcelUUID != over.landData.globalID) |
855 | { | 855 | { |
856 | if (!avatar.IsChildAgent) | 856 | if (!avatar.IsChildAgent) |
857 | { | 857 | { |
858 | over.sendLandUpdateToClient(avatar.ControllingClient); | 858 | over.sendLandUpdateToClient(avatar.ControllingClient); |
859 | avatar.currentParcelUUID = over.landData.globalID; | 859 | avatar.currentParcelUUID = over.landData.globalID; |
860 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, | 860 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, |
861 | m_scene.RegionInfo.RegionID); | 861 | m_scene.RegionInfo.RegionID); |
862 | } | 862 | } |
863 | } | 863 | } |
864 | } | 864 | } |
865 | } | 865 | } |
866 | 866 | ||
867 | public void sendLandUpdate(ScenePresence avatar) | 867 | public void sendLandUpdate(ScenePresence avatar) |
868 | { | 868 | { |
869 | sendLandUpdate(avatar, false); | 869 | sendLandUpdate(avatar, false); |
870 | } | 870 | } |
871 | 871 | ||
872 | public void handleSignificantClientMovement(IClientAPI remote_client) | 872 | public void handleSignificantClientMovement(IClientAPI remote_client) |
873 | { | 873 | { |
874 | ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); | 874 | ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); |
875 | 875 | ||
876 | if (clientAvatar != null) | 876 | if (clientAvatar != null) |
877 | { | 877 | { |
878 | sendLandUpdate(clientAvatar); | 878 | sendLandUpdate(clientAvatar); |
879 | sendOutNearestBanLine(remote_client); | 879 | sendOutNearestBanLine(remote_client); |
880 | ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); | 880 | ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); |
881 | if (parcel != null) | 881 | if (parcel != null) |
882 | { | 882 | { |
883 | if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && | 883 | if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && |
884 | clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) | 884 | clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) |
885 | { | 885 | { |
886 | handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID); | 886 | handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID); |
887 | //They are going below the safety line! | 887 | //They are going below the safety line! |
888 | if (!parcel.isBannedFromLand(clientAvatar.UUID)) | 888 | if (!parcel.isBannedFromLand(clientAvatar.UUID)) |
889 | { | 889 | { |
890 | clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; | 890 | clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; |
891 | } | 891 | } |
892 | } | 892 | } |
893 | else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && | 893 | else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && |
894 | parcel.isBannedFromLand(clientAvatar.UUID)) | 894 | parcel.isBannedFromLand(clientAvatar.UUID)) |
895 | { | 895 | { |
896 | sendYouAreBannedNotice(clientAvatar); | 896 | sendYouAreBannedNotice(clientAvatar); |
897 | } | 897 | } |
898 | } | 898 | } |
899 | } | 899 | } |
900 | } | 900 | } |
901 | 901 | ||
902 | public void handleAnyClientMovement(ScenePresence avatar) | 902 | public void handleAnyClientMovement(ScenePresence avatar) |
903 | //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance. | 903 | //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance. |
904 | { | 904 | { |
905 | ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 905 | ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
906 | if (over != null) | 906 | if (over != null) |
907 | { | 907 | { |
908 | if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT) | 908 | if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT) |
909 | { | 909 | { |
910 | avatar.lastKnownAllowedPosition = | 910 | avatar.lastKnownAllowedPosition = |
911 | new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); | 911 | new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); |
912 | } | 912 | } |
913 | } | 913 | } |
914 | } | 914 | } |
915 | 915 | ||
916 | 916 | ||
917 | public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, | 917 | public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, |
918 | int landLocalID, IClientAPI remote_client) | 918 | int landLocalID, IClientAPI remote_client) |
919 | { | 919 | { |
920 | if (landList.ContainsKey(landLocalID)) | 920 | if (landList.ContainsKey(landLocalID)) |
921 | { | 921 | { |
922 | landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); | 922 | landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); |
923 | } | 923 | } |
924 | } | 924 | } |
925 | 925 | ||
926 | public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID, | 926 | public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID, |
927 | List<ParcelManager.ParcelAccessEntry> entries, | 927 | List<ParcelManager.ParcelAccessEntry> entries, |
928 | IClientAPI remote_client) | 928 | IClientAPI remote_client) |
929 | { | 929 | { |
930 | if (landList.ContainsKey(landLocalID)) | 930 | if (landList.ContainsKey(landLocalID)) |
931 | { | 931 | { |
932 | if (agentID == landList[landLocalID].landData.ownerID) | 932 | if (agentID == landList[landLocalID].landData.ownerID) |
933 | { | 933 | { |
934 | landList[landLocalID].updateAccessList(flags, entries, remote_client); | 934 | landList[landLocalID].updateAccessList(flags, entries, remote_client); |
935 | } | 935 | } |
936 | } | 936 | } |
937 | else | 937 | else |
938 | { | 938 | { |
939 | Console.WriteLine("INVALID LOCAL LAND ID"); | 939 | Console.WriteLine("INVALID LOCAL LAND ID"); |
940 | } | 940 | } |
941 | } | 941 | } |
942 | 942 | ||
943 | #endregion | 943 | #endregion |
944 | 944 | ||
945 | // If the economy has been validated by the economy module, | 945 | // If the economy has been validated by the economy module, |
946 | // and land has been validated as well, this method transfers | 946 | // and land has been validated as well, this method transfers |
947 | // the land ownership | 947 | // the land ownership |
948 | 948 | ||
949 | public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e) | 949 | public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e) |
950 | { | 950 | { |
951 | if (e.economyValidated && e.landValidated) | 951 | if (e.economyValidated && e.landValidated) |
952 | { | 952 | { |
953 | lock (landList) | 953 | lock (landList) |
954 | { | 954 | { |
955 | if (landList.ContainsKey(e.parcelLocalID)) | 955 | if (landList.ContainsKey(e.parcelLocalID)) |
956 | { | 956 | { |
957 | landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint) e.transactionID, e.parcelPrice, e.parcelArea); | 957 | landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint) e.transactionID, e.parcelPrice, e.parcelArea); |
958 | return; | 958 | return; |
959 | } | 959 | } |
960 | } | 960 | } |
961 | } | 961 | } |
962 | } | 962 | } |
963 | 963 | ||
964 | // After receiving a land buy packet, first the data needs to | 964 | // After receiving a land buy packet, first the data needs to |
965 | // be validated. This method validates the right to buy the | 965 | // be validated. This method validates the right to buy the |
966 | // parcel | 966 | // parcel |
967 | 967 | ||
968 | public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e) | 968 | public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e) |
969 | { | 969 | { |
970 | if (e.landValidated == false) | 970 | if (e.landValidated == false) |
971 | { | 971 | { |
972 | ILandObject lob = null; | 972 | ILandObject lob = null; |
973 | lock (landList) | 973 | lock (landList) |
974 | { | 974 | { |
975 | if (landList.ContainsKey(e.parcelLocalID)) | 975 | if (landList.ContainsKey(e.parcelLocalID)) |
976 | { | 976 | { |
977 | lob = landList[e.parcelLocalID]; | 977 | lob = landList[e.parcelLocalID]; |
978 | } | 978 | } |
979 | } | 979 | } |
980 | if (lob != null) | 980 | if (lob != null) |
981 | { | 981 | { |
982 | LLUUID AuthorizedID = lob.landData.authBuyerID; | 982 | LLUUID AuthorizedID = lob.landData.authBuyerID; |
983 | int saleprice = lob.landData.salePrice; | 983 | int saleprice = lob.landData.salePrice; |
984 | LLUUID pOwnerID = lob.landData.ownerID; | 984 | LLUUID pOwnerID = lob.landData.ownerID; |
985 | 985 | ||
986 | bool landforsale = ((lob.landData.landFlags & | 986 | bool landforsale = ((lob.landData.landFlags & |
987 | (uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); | 987 | (uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); |
988 | if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) | 988 | if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) |
989 | { | 989 | { |
990 | lock (e) | 990 | lock (e) |
991 | { | 991 | { |
992 | e.parcelOwnerID = pOwnerID; | 992 | e.parcelOwnerID = pOwnerID; |
993 | e.landValidated = true; | 993 | e.landValidated = true; |
994 | } | 994 | } |
995 | } | 995 | } |
996 | } | 996 | } |
997 | } | 997 | } |
998 | } | 998 | } |
999 | } | 999 | } |
1000 | } \ No newline at end of file | 1000 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs index 3f09bd5..877bed5 100644 --- a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs | |||
@@ -1,79 +1,79 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using Nini.Config; | 28 | using Nini.Config; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | using OpenSim.Region.Environment.Scenes; | 30 | using OpenSim.Region.Environment.Scenes; |
31 | 31 | ||
32 | namespace OpenSim.Region.Environment.Modules.World.Land | 32 | namespace OpenSim.Region.Environment.Modules.World.Land |
33 | { | 33 | { |
34 | public class LandManagementModule : IRegionModule | 34 | public class LandManagementModule : IRegionModule |
35 | { | 35 | { |
36 | private LandChannel landChannel; | 36 | private LandChannel landChannel; |
37 | private Scene m_scene; | 37 | private Scene m_scene; |
38 | 38 | ||
39 | #region IRegionModule Members | 39 | #region IRegionModule Members |
40 | 40 | ||
41 | public void Initialise(Scene scene, IConfigSource source) | 41 | public void Initialise(Scene scene, IConfigSource source) |
42 | { | 42 | { |
43 | m_scene = scene; | 43 | m_scene = scene; |
44 | landChannel = new LandChannel(scene); | 44 | landChannel = new LandChannel(scene); |
45 | 45 | ||
46 | m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts; | 46 | m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts; |
47 | m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts; | 47 | m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts; |
48 | m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel); | 48 | m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel); |
49 | m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement); | 49 | m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement); |
50 | m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest; | 50 | m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest; |
51 | m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest; | 51 | m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest; |
52 | 52 | ||
53 | lock (m_scene) | 53 | lock (m_scene) |
54 | { | 54 | { |
55 | m_scene.LandChannel = (ILandChannel) landChannel; | 55 | m_scene.LandChannel = (ILandChannel) landChannel; |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | public void PostInitialise() | 59 | public void PostInitialise() |
60 | { | 60 | { |
61 | } | 61 | } |
62 | 62 | ||
63 | public void Close() | 63 | public void Close() |
64 | { | 64 | { |
65 | } | 65 | } |
66 | 66 | ||
67 | public string Name | 67 | public string Name |
68 | { | 68 | { |
69 | get { return "LandManagementModule"; } | 69 | get { return "LandManagementModule"; } |
70 | } | 70 | } |
71 | 71 | ||
72 | public bool IsSharedModule | 72 | public bool IsSharedModule |
73 | { | 73 | { |
74 | get { return false; } | 74 | get { return false; } |
75 | } | 75 | } |
76 | 76 | ||
77 | #endregion | 77 | #endregion |
78 | } | 78 | } |
79 | } \ No newline at end of file | 79 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs index 368e113..e297b10 100644 --- a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs +++ b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs | |||
@@ -1,928 +1,928 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using libsecondlife.Packets; | 32 | using libsecondlife.Packets; |
33 | using log4net; | 33 | using log4net; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
36 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules.World.Land | 38 | namespace OpenSim.Region.Environment.Modules.World.Land |
39 | { | 39 | { |
40 | /// <summary> | 40 | /// <summary> |
41 | /// Keeps track of a specific piece of land's information | 41 | /// Keeps track of a specific piece of land's information |
42 | /// </summary> | 42 | /// </summary> |
43 | public class LandObject : ILandObject | 43 | public class LandObject : ILandObject |
44 | { | 44 | { |
45 | #region Member Variables | 45 | #region Member Variables |
46 | 46 | ||
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | private bool[,] m_landBitmap = new bool[64,64]; | 48 | private bool[,] m_landBitmap = new bool[64,64]; |
49 | 49 | ||
50 | protected LandData m_landData = new LandData(); | 50 | protected LandData m_landData = new LandData(); |
51 | protected Scene m_scene; | 51 | protected Scene m_scene; |
52 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); | 52 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); |
53 | 53 | ||
54 | public bool[,] landBitmap | 54 | public bool[,] landBitmap |
55 | { | 55 | { |
56 | get { return m_landBitmap; } | 56 | get { return m_landBitmap; } |
57 | set { m_landBitmap = value; } | 57 | set { m_landBitmap = value; } |
58 | } | 58 | } |
59 | 59 | ||
60 | #endregion | 60 | #endregion |
61 | 61 | ||
62 | #region ILandObject Members | 62 | #region ILandObject Members |
63 | 63 | ||
64 | public LandData landData | 64 | public LandData landData |
65 | { | 65 | { |
66 | get { return m_landData; } | 66 | get { return m_landData; } |
67 | 67 | ||
68 | set { m_landData = value; } | 68 | set { m_landData = value; } |
69 | } | 69 | } |
70 | 70 | ||
71 | public LLUUID regionUUID | 71 | public LLUUID regionUUID |
72 | { | 72 | { |
73 | get { return m_scene.RegionInfo.RegionID; } | 73 | get { return m_scene.RegionInfo.RegionID; } |
74 | } | 74 | } |
75 | 75 | ||
76 | #region Constructors | 76 | #region Constructors |
77 | 77 | ||
78 | public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene) | 78 | public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene) |
79 | { | 79 | { |
80 | m_scene = scene; | 80 | m_scene = scene; |
81 | landData.ownerID = owner_id; | 81 | landData.ownerID = owner_id; |
82 | landData.isGroupOwned = is_group_owned; | 82 | landData.isGroupOwned = is_group_owned; |
83 | } | 83 | } |
84 | 84 | ||
85 | #endregion | 85 | #endregion |
86 | 86 | ||
87 | #region Member Functions | 87 | #region Member Functions |
88 | 88 | ||
89 | #region General Functions | 89 | #region General Functions |
90 | 90 | ||
91 | /// <summary> | 91 | /// <summary> |
92 | /// Checks to see if this land object contains a point | 92 | /// Checks to see if this land object contains a point |
93 | /// </summary> | 93 | /// </summary> |
94 | /// <param name="x"></param> | 94 | /// <param name="x"></param> |
95 | /// <param name="y"></param> | 95 | /// <param name="y"></param> |
96 | /// <returns>Returns true if the piece of land contains the specified point</returns> | 96 | /// <returns>Returns true if the piece of land contains the specified point</returns> |
97 | public bool containsPoint(int x, int y) | 97 | public bool containsPoint(int x, int y) |
98 | { | 98 | { |
99 | if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) | 99 | if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) |
100 | { | 100 | { |
101 | return (landBitmap[x / 4, y / 4] == true); | 101 | return (landBitmap[x / 4, y / 4] == true); |
102 | } | 102 | } |
103 | else | 103 | else |
104 | { | 104 | { |
105 | return false; | 105 | return false; |
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | public ILandObject Copy() | 109 | public ILandObject Copy() |
110 | { | 110 | { |
111 | ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene); | 111 | ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene); |
112 | 112 | ||
113 | //Place all new variables here! | 113 | //Place all new variables here! |
114 | newLand.landBitmap = (bool[,]) (landBitmap.Clone()); | 114 | newLand.landBitmap = (bool[,]) (landBitmap.Clone()); |
115 | newLand.landData = landData.Copy(); | 115 | newLand.landData = landData.Copy(); |
116 | 116 | ||
117 | return newLand; | 117 | return newLand; |
118 | } | 118 | } |
119 | 119 | ||
120 | #endregion | 120 | #endregion |
121 | 121 | ||
122 | #region Packet Request Handling | 122 | #region Packet Request Handling |
123 | 123 | ||
124 | /// <summary> | 124 | /// <summary> |
125 | /// Sends land properties as requested | 125 | /// Sends land properties as requested |
126 | /// </summary> | 126 | /// </summary> |
127 | /// <param name="sequence_id">ID sent by client for them to keep track of</param> | 127 | /// <param name="sequence_id">ID sent by client for them to keep track of</param> |
128 | /// <param name="snap_selection">Bool sent by client for them to use</param> | 128 | /// <param name="snap_selection">Bool sent by client for them to use</param> |
129 | /// <param name="remote_client">Object representing the client</param> | 129 | /// <param name="remote_client">Object representing the client</param> |
130 | public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, | 130 | public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, |
131 | IClientAPI remote_client) | 131 | IClientAPI remote_client) |
132 | { | 132 | { |
133 | ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties); | 133 | ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties); |
134 | // TODO: don't create new blocks if recycling an old packet | 134 | // TODO: don't create new blocks if recycling an old packet |
135 | 135 | ||
136 | updatePacket.ParcelData.AABBMax = landData.AABBMax; | 136 | updatePacket.ParcelData.AABBMax = landData.AABBMax; |
137 | updatePacket.ParcelData.AABBMin = landData.AABBMin; | 137 | updatePacket.ParcelData.AABBMin = landData.AABBMin; |
138 | updatePacket.ParcelData.Area = landData.area; | 138 | updatePacket.ParcelData.Area = landData.area; |
139 | updatePacket.ParcelData.AuctionID = landData.auctionID; | 139 | updatePacket.ParcelData.AuctionID = landData.auctionID; |
140 | updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented | 140 | updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented |
141 | 141 | ||
142 | updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; | 142 | updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; |
143 | 143 | ||
144 | updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); | 144 | updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); |
145 | updatePacket.ParcelData.Category = (byte) landData.category; | 145 | updatePacket.ParcelData.Category = (byte) landData.category; |
146 | updatePacket.ParcelData.ClaimDate = landData.claimDate; | 146 | updatePacket.ParcelData.ClaimDate = landData.claimDate; |
147 | updatePacket.ParcelData.ClaimPrice = landData.claimPrice; | 147 | updatePacket.ParcelData.ClaimPrice = landData.claimPrice; |
148 | updatePacket.ParcelData.GroupID = landData.groupID; | 148 | updatePacket.ParcelData.GroupID = landData.groupID; |
149 | updatePacket.ParcelData.GroupPrims = landData.groupPrims; | 149 | updatePacket.ParcelData.GroupPrims = landData.groupPrims; |
150 | updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; | 150 | updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; |
151 | updatePacket.ParcelData.LandingType = (byte) landData.landingType; | 151 | updatePacket.ParcelData.LandingType = (byte) landData.landingType; |
152 | updatePacket.ParcelData.LocalID = landData.localID; | 152 | updatePacket.ParcelData.LocalID = landData.localID; |
153 | if (landData.area > 0) | 153 | if (landData.area > 0) |
154 | { | 154 | { |
155 | updatePacket.ParcelData.MaxPrims = | 155 | updatePacket.ParcelData.MaxPrims = |
156 | Convert.ToInt32( | 156 | Convert.ToInt32( |
157 | Math.Round((Convert.ToDecimal(landData.area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * | 157 | Math.Round((Convert.ToDecimal(landData.area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * |
158 | Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); | 158 | Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); |
159 | } | 159 | } |
160 | else | 160 | else |
161 | { | 161 | { |
162 | updatePacket.ParcelData.MaxPrims = 0; | 162 | updatePacket.ParcelData.MaxPrims = 0; |
163 | } | 163 | } |
164 | updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; | 164 | updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; |
165 | updatePacket.ParcelData.MediaID = landData.mediaID; | 165 | updatePacket.ParcelData.MediaID = landData.mediaID; |
166 | updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); | 166 | updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); |
167 | updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); | 167 | updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); |
168 | updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); | 168 | updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); |
169 | updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented | 169 | updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented |
170 | updatePacket.ParcelData.OtherCount = 0; //unemplemented | 170 | updatePacket.ParcelData.OtherCount = 0; //unemplemented |
171 | updatePacket.ParcelData.OtherPrims = landData.otherPrims; | 171 | updatePacket.ParcelData.OtherPrims = landData.otherPrims; |
172 | updatePacket.ParcelData.OwnerID = landData.ownerID; | 172 | updatePacket.ParcelData.OwnerID = landData.ownerID; |
173 | updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; | 173 | updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; |
174 | updatePacket.ParcelData.ParcelFlags = landData.landFlags; | 174 | updatePacket.ParcelData.ParcelFlags = landData.landFlags; |
175 | updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor; | 175 | updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor; |
176 | updatePacket.ParcelData.PassHours = landData.passHours; | 176 | updatePacket.ParcelData.PassHours = landData.passHours; |
177 | updatePacket.ParcelData.PassPrice = landData.passPrice; | 177 | updatePacket.ParcelData.PassPrice = landData.passPrice; |
178 | updatePacket.ParcelData.PublicCount = 0; //unemplemented | 178 | updatePacket.ParcelData.PublicCount = 0; //unemplemented |
179 | 179 | ||
180 | uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags; | 180 | uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags; |
181 | updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) > | 181 | updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) > |
182 | 0); | 182 | 0); |
183 | updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) > | 183 | updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) > |
184 | 0); | 184 | 0); |
185 | updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) > | 185 | updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) > |
186 | 0); | 186 | 0); |
187 | updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) > | 187 | updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) > |
188 | 0); | 188 | 0); |
189 | 189 | ||
190 | updatePacket.ParcelData.RentPrice = 0; | 190 | updatePacket.ParcelData.RentPrice = 0; |
191 | updatePacket.ParcelData.RequestResult = request_result; | 191 | updatePacket.ParcelData.RequestResult = request_result; |
192 | updatePacket.ParcelData.SalePrice = landData.salePrice; | 192 | updatePacket.ParcelData.SalePrice = landData.salePrice; |
193 | updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; | 193 | updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; |
194 | updatePacket.ParcelData.SelfCount = 0; //unemplemented | 194 | updatePacket.ParcelData.SelfCount = 0; //unemplemented |
195 | updatePacket.ParcelData.SequenceID = sequence_id; | 195 | updatePacket.ParcelData.SequenceID = sequence_id; |
196 | if (landData.simwideArea > 0) | 196 | if (landData.simwideArea > 0) |
197 | { | 197 | { |
198 | updatePacket.ParcelData.SimWideMaxPrims = | 198 | updatePacket.ParcelData.SimWideMaxPrims = |
199 | Convert.ToInt32( | 199 | Convert.ToInt32( |
200 | Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * | 200 | Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * |
201 | Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); | 201 | Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); |
202 | } | 202 | } |
203 | else | 203 | else |
204 | { | 204 | { |
205 | updatePacket.ParcelData.SimWideMaxPrims = 0; | 205 | updatePacket.ParcelData.SimWideMaxPrims = 0; |
206 | } | 206 | } |
207 | updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; | 207 | updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; |
208 | updatePacket.ParcelData.SnapSelection = snap_selection; | 208 | updatePacket.ParcelData.SnapSelection = snap_selection; |
209 | updatePacket.ParcelData.SnapshotID = landData.snapshotID; | 209 | updatePacket.ParcelData.SnapshotID = landData.snapshotID; |
210 | updatePacket.ParcelData.Status = (byte) landData.landStatus; | 210 | updatePacket.ParcelData.Status = (byte) landData.landStatus; |
211 | updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + | 211 | updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + |
212 | landData.selectedPrims; | 212 | landData.selectedPrims; |
213 | updatePacket.ParcelData.UserLocation = landData.userLocation; | 213 | updatePacket.ParcelData.UserLocation = landData.userLocation; |
214 | updatePacket.ParcelData.UserLookAt = landData.userLookAt; | 214 | updatePacket.ParcelData.UserLookAt = landData.userLookAt; |
215 | remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task); | 215 | remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task); |
216 | } | 216 | } |
217 | 217 | ||
218 | public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) | 218 | public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) |
219 | { | 219 | { |
220 | if (remote_client.AgentId == landData.ownerID) | 220 | if (remote_client.AgentId == landData.ownerID) |
221 | { | 221 | { |
222 | //Needs later group support | 222 | //Needs later group support |
223 | LandData newData = landData.Copy(); | 223 | LandData newData = landData.Copy(); |
224 | newData.authBuyerID = packet.ParcelData.AuthBuyerID; | 224 | newData.authBuyerID = packet.ParcelData.AuthBuyerID; |
225 | newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category; | 225 | newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category; |
226 | newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); | 226 | newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); |
227 | newData.groupID = packet.ParcelData.GroupID; | 227 | newData.groupID = packet.ParcelData.GroupID; |
228 | newData.landingType = packet.ParcelData.LandingType; | 228 | newData.landingType = packet.ParcelData.LandingType; |
229 | newData.mediaAutoScale = packet.ParcelData.MediaAutoScale; | 229 | newData.mediaAutoScale = packet.ParcelData.MediaAutoScale; |
230 | newData.mediaID = packet.ParcelData.MediaID; | 230 | newData.mediaID = packet.ParcelData.MediaID; |
231 | newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); | 231 | newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); |
232 | newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); | 232 | newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); |
233 | newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); | 233 | newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); |
234 | newData.landFlags = packet.ParcelData.ParcelFlags; | 234 | newData.landFlags = packet.ParcelData.ParcelFlags; |
235 | newData.passHours = packet.ParcelData.PassHours; | 235 | newData.passHours = packet.ParcelData.PassHours; |
236 | newData.passPrice = packet.ParcelData.PassPrice; | 236 | newData.passPrice = packet.ParcelData.PassPrice; |
237 | newData.salePrice = packet.ParcelData.SalePrice; | 237 | newData.salePrice = packet.ParcelData.SalePrice; |
238 | newData.snapshotID = packet.ParcelData.SnapshotID; | 238 | newData.snapshotID = packet.ParcelData.SnapshotID; |
239 | newData.userLocation = packet.ParcelData.UserLocation; | 239 | newData.userLocation = packet.ParcelData.UserLocation; |
240 | newData.userLookAt = packet.ParcelData.UserLookAt; | 240 | newData.userLookAt = packet.ParcelData.UserLookAt; |
241 | 241 | ||
242 | m_scene.LandChannel.updateLandObject(landData.localID, newData); | 242 | m_scene.LandChannel.updateLandObject(landData.localID, newData); |
243 | 243 | ||
244 | sendLandUpdateToAvatarsOverMe(); | 244 | sendLandUpdateToAvatarsOverMe(); |
245 | } | 245 | } |
246 | } | 246 | } |
247 | 247 | ||
248 | public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) | 248 | public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) |
249 | { | 249 | { |
250 | LandData newData = landData.Copy(); | 250 | LandData newData = landData.Copy(); |
251 | newData.ownerID = avatarID; | 251 | newData.ownerID = avatarID; |
252 | newData.groupID = groupID; | 252 | newData.groupID = groupID; |
253 | newData.isGroupOwned = groupOwned; | 253 | newData.isGroupOwned = groupOwned; |
254 | //newData.auctionID = AuctionID; | 254 | //newData.auctionID = AuctionID; |
255 | newData.claimDate = Util.UnixTimeSinceEpoch(); | 255 | newData.claimDate = Util.UnixTimeSinceEpoch(); |
256 | newData.claimPrice = claimprice; | 256 | newData.claimPrice = claimprice; |
257 | newData.salePrice = 0; | 257 | newData.salePrice = 0; |
258 | newData.authBuyerID = LLUUID.Zero; | 258 | newData.authBuyerID = LLUUID.Zero; |
259 | newData.landFlags &= ~(uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects); | 259 | newData.landFlags &= ~(uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects); |
260 | m_scene.LandChannel.updateLandObject(landData.localID, newData); | 260 | m_scene.LandChannel.updateLandObject(landData.localID, newData); |
261 | 261 | ||
262 | sendLandUpdateToAvatarsOverMe(); | 262 | sendLandUpdateToAvatarsOverMe(); |
263 | } | 263 | } |
264 | 264 | ||
265 | public bool isEitherBannedOrRestricted(LLUUID avatar) | 265 | public bool isEitherBannedOrRestricted(LLUUID avatar) |
266 | { | 266 | { |
267 | if (isBannedFromLand(avatar)) | 267 | if (isBannedFromLand(avatar)) |
268 | { | 268 | { |
269 | return true; | 269 | return true; |
270 | } | 270 | } |
271 | else if (isRestrictedFromLand(avatar)) | 271 | else if (isRestrictedFromLand(avatar)) |
272 | { | 272 | { |
273 | return true; | 273 | return true; |
274 | } | 274 | } |
275 | return false; | 275 | return false; |
276 | } | 276 | } |
277 | 277 | ||
278 | public bool isBannedFromLand(LLUUID avatar) | 278 | public bool isBannedFromLand(LLUUID avatar) |
279 | { | 279 | { |
280 | if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0) | 280 | if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0) |
281 | { | 281 | { |
282 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | 282 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); |
283 | entry.AgentID = avatar; | 283 | entry.AgentID = avatar; |
284 | entry.Flags = ParcelManager.AccessList.Ban; | 284 | entry.Flags = ParcelManager.AccessList.Ban; |
285 | entry.Time = new DateTime(); | 285 | entry.Time = new DateTime(); |
286 | if (landData.parcelAccessList.Contains(entry)) | 286 | if (landData.parcelAccessList.Contains(entry)) |
287 | { | 287 | { |
288 | //They are banned, so lets send them a notice about this parcel | 288 | //They are banned, so lets send them a notice about this parcel |
289 | return true; | 289 | return true; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | return false; | 292 | return false; |
293 | } | 293 | } |
294 | 294 | ||
295 | public bool isRestrictedFromLand(LLUUID avatar) | 295 | public bool isRestrictedFromLand(LLUUID avatar) |
296 | { | 296 | { |
297 | if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0) | 297 | if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0) |
298 | { | 298 | { |
299 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | 299 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); |
300 | entry.AgentID = avatar; | 300 | entry.AgentID = avatar; |
301 | entry.Flags = ParcelManager.AccessList.Access; | 301 | entry.Flags = ParcelManager.AccessList.Access; |
302 | entry.Time = new DateTime(); | 302 | entry.Time = new DateTime(); |
303 | if (!landData.parcelAccessList.Contains(entry)) | 303 | if (!landData.parcelAccessList.Contains(entry)) |
304 | { | 304 | { |
305 | //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel | 305 | //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel |
306 | return true; | 306 | return true; |
307 | } | 307 | } |
308 | } | 308 | } |
309 | return false; | 309 | return false; |
310 | } | 310 | } |
311 | 311 | ||
312 | public void sendLandUpdateToClient(IClientAPI remote_client) | 312 | public void sendLandUpdateToClient(IClientAPI remote_client) |
313 | { | 313 | { |
314 | sendLandProperties(0, false, 0, remote_client); | 314 | sendLandProperties(0, false, 0, remote_client); |
315 | } | 315 | } |
316 | 316 | ||
317 | public void sendLandUpdateToAvatarsOverMe() | 317 | public void sendLandUpdateToAvatarsOverMe() |
318 | { | 318 | { |
319 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 319 | List<ScenePresence> avatars = m_scene.GetAvatars(); |
320 | ILandObject over = null; | 320 | ILandObject over = null; |
321 | for (int i = 0; i < avatars.Count; i++) | 321 | for (int i = 0; i < avatars.Count; i++) |
322 | { | 322 | { |
323 | try | 323 | try |
324 | { | 324 | { |
325 | over = | 325 | over = |
326 | m_scene.LandChannel.getLandObject((int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.X))), | 326 | m_scene.LandChannel.getLandObject((int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.X))), |
327 | (int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.Y)))); | 327 | (int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.Y)))); |
328 | } | 328 | } |
329 | catch (Exception) | 329 | catch (Exception) |
330 | { | 330 | { |
331 | m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + | 331 | m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + |
332 | Math.Round(avatars[i].AbsolutePosition.Y)); | 332 | Math.Round(avatars[i].AbsolutePosition.Y)); |
333 | } | 333 | } |
334 | 334 | ||
335 | if (over != null) | 335 | if (over != null) |
336 | { | 336 | { |
337 | if (over.landData.localID == landData.localID) | 337 | if (over.landData.localID == landData.localID) |
338 | { | 338 | { |
339 | sendLandUpdateToClient(avatars[i].ControllingClient); | 339 | sendLandUpdateToClient(avatars[i].ControllingClient); |
340 | } | 340 | } |
341 | } | 341 | } |
342 | } | 342 | } |
343 | } | 343 | } |
344 | 344 | ||
345 | #endregion | 345 | #endregion |
346 | 346 | ||
347 | #region AccessList Functions | 347 | #region AccessList Functions |
348 | 348 | ||
349 | public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag) | 349 | public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag) |
350 | { | 350 | { |
351 | List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>(); | 351 | List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>(); |
352 | foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList) | 352 | foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList) |
353 | { | 353 | { |
354 | if (entry.Flags == flag) | 354 | if (entry.Flags == flag) |
355 | { | 355 | { |
356 | ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); | 356 | ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); |
357 | 357 | ||
358 | listBlock.Flags = (uint) 0; | 358 | listBlock.Flags = (uint) 0; |
359 | listBlock.ID = entry.AgentID; | 359 | listBlock.ID = entry.AgentID; |
360 | listBlock.Time = 0; | 360 | listBlock.Time = 0; |
361 | 361 | ||
362 | list.Add(listBlock); | 362 | list.Add(listBlock); |
363 | } | 363 | } |
364 | } | 364 | } |
365 | 365 | ||
366 | if (list.Count == 0) | 366 | if (list.Count == 0) |
367 | { | 367 | { |
368 | ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); | 368 | ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); |
369 | 369 | ||
370 | listBlock.Flags = (uint) 0; | 370 | listBlock.Flags = (uint) 0; |
371 | listBlock.ID = LLUUID.Zero; | 371 | listBlock.ID = LLUUID.Zero; |
372 | listBlock.Time = 0; | 372 | listBlock.Time = 0; |
373 | 373 | ||
374 | list.Add(listBlock); | 374 | list.Add(listBlock); |
375 | } | 375 | } |
376 | return list.ToArray(); | 376 | return list.ToArray(); |
377 | } | 377 | } |
378 | 378 | ||
379 | public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, | 379 | public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, |
380 | IClientAPI remote_client) | 380 | IClientAPI remote_client) |
381 | { | 381 | { |
382 | ParcelAccessListReplyPacket replyPacket; | 382 | ParcelAccessListReplyPacket replyPacket; |
383 | 383 | ||
384 | if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both) | 384 | if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both) |
385 | { | 385 | { |
386 | replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); | 386 | replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); |
387 | replyPacket.Data.AgentID = agentID; | 387 | replyPacket.Data.AgentID = agentID; |
388 | replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access; | 388 | replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access; |
389 | replyPacket.Data.LocalID = landData.localID; | 389 | replyPacket.Data.LocalID = landData.localID; |
390 | replyPacket.Data.SequenceID = 0; | 390 | replyPacket.Data.SequenceID = 0; |
391 | 391 | ||
392 | replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access); | 392 | replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access); |
393 | remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); | 393 | remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); |
394 | } | 394 | } |
395 | 395 | ||
396 | if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both) | 396 | if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both) |
397 | { | 397 | { |
398 | replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); | 398 | replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); |
399 | replyPacket.Data.AgentID = agentID; | 399 | replyPacket.Data.AgentID = agentID; |
400 | replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban; | 400 | replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban; |
401 | replyPacket.Data.LocalID = landData.localID; | 401 | replyPacket.Data.LocalID = landData.localID; |
402 | replyPacket.Data.SequenceID = 0; | 402 | replyPacket.Data.SequenceID = 0; |
403 | 403 | ||
404 | replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban); | 404 | replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban); |
405 | remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); | 405 | remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); |
406 | } | 406 | } |
407 | } | 407 | } |
408 | 408 | ||
409 | public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) | 409 | public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) |
410 | { | 410 | { |
411 | LandData newData = landData.Copy(); | 411 | LandData newData = landData.Copy(); |
412 | 412 | ||
413 | if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero) | 413 | if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero) |
414 | { | 414 | { |
415 | entries.Clear(); | 415 | entries.Clear(); |
416 | } | 416 | } |
417 | 417 | ||
418 | List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); | 418 | List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); |
419 | foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList) | 419 | foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList) |
420 | { | 420 | { |
421 | if (entry.Flags == (ParcelManager.AccessList) flags) | 421 | if (entry.Flags == (ParcelManager.AccessList) flags) |
422 | { | 422 | { |
423 | toRemove.Add(entry); | 423 | toRemove.Add(entry); |
424 | } | 424 | } |
425 | } | 425 | } |
426 | 426 | ||
427 | foreach (ParcelManager.ParcelAccessEntry entry in toRemove) | 427 | foreach (ParcelManager.ParcelAccessEntry entry in toRemove) |
428 | { | 428 | { |
429 | newData.parcelAccessList.Remove(entry); | 429 | newData.parcelAccessList.Remove(entry); |
430 | } | 430 | } |
431 | foreach (ParcelManager.ParcelAccessEntry entry in entries) | 431 | foreach (ParcelManager.ParcelAccessEntry entry in entries) |
432 | { | 432 | { |
433 | ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); | 433 | ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); |
434 | temp.AgentID = entry.AgentID; | 434 | temp.AgentID = entry.AgentID; |
435 | temp.Time = new DateTime(); //Pointless? Yes. | 435 | temp.Time = new DateTime(); //Pointless? Yes. |
436 | temp.Flags = (ParcelManager.AccessList) flags; | 436 | temp.Flags = (ParcelManager.AccessList) flags; |
437 | 437 | ||
438 | if (!newData.parcelAccessList.Contains(temp)) | 438 | if (!newData.parcelAccessList.Contains(temp)) |
439 | { | 439 | { |
440 | newData.parcelAccessList.Add(temp); | 440 | newData.parcelAccessList.Add(temp); |
441 | } | 441 | } |
442 | } | 442 | } |
443 | 443 | ||
444 | m_scene.LandChannel.updateLandObject(landData.localID, newData); | 444 | m_scene.LandChannel.updateLandObject(landData.localID, newData); |
445 | } | 445 | } |
446 | 446 | ||
447 | #endregion | 447 | #endregion |
448 | 448 | ||
449 | #region Update Functions | 449 | #region Update Functions |
450 | 450 | ||
451 | public void updateLandBitmapByteArray() | 451 | public void updateLandBitmapByteArray() |
452 | { | 452 | { |
453 | landData.landBitmapByteArray = convertLandBitmapToBytes(); | 453 | landData.landBitmapByteArray = convertLandBitmapToBytes(); |
454 | } | 454 | } |
455 | 455 | ||
456 | /// <summary> | 456 | /// <summary> |
457 | /// Update all settings in land such as area, bitmap byte array, etc | 457 | /// Update all settings in land such as area, bitmap byte array, etc |
458 | /// </summary> | 458 | /// </summary> |
459 | public void forceUpdateLandInfo() | 459 | public void forceUpdateLandInfo() |
460 | { | 460 | { |
461 | updateAABBAndAreaValues(); | 461 | updateAABBAndAreaValues(); |
462 | updateLandBitmapByteArray(); | 462 | updateLandBitmapByteArray(); |
463 | } | 463 | } |
464 | 464 | ||
465 | public void setLandBitmapFromByteArray() | 465 | public void setLandBitmapFromByteArray() |
466 | { | 466 | { |
467 | landBitmap = convertBytesToLandBitmap(); | 467 | landBitmap = convertBytesToLandBitmap(); |
468 | } | 468 | } |
469 | 469 | ||
470 | /// <summary> | 470 | /// <summary> |
471 | /// Updates the AABBMin and AABBMax values after area/shape modification of the land object | 471 | /// Updates the AABBMin and AABBMax values after area/shape modification of the land object |
472 | /// </summary> | 472 | /// </summary> |
473 | private void updateAABBAndAreaValues() | 473 | private void updateAABBAndAreaValues() |
474 | { | 474 | { |
475 | int min_x = 64; | 475 | int min_x = 64; |
476 | int min_y = 64; | 476 | int min_y = 64; |
477 | int max_x = 0; | 477 | int max_x = 0; |
478 | int max_y = 0; | 478 | int max_y = 0; |
479 | int tempArea = 0; | 479 | int tempArea = 0; |
480 | int x, y; | 480 | int x, y; |
481 | for (x = 0; x < 64; x++) | 481 | for (x = 0; x < 64; x++) |
482 | { | 482 | { |
483 | for (y = 0; y < 64; y++) | 483 | for (y = 0; y < 64; y++) |
484 | { | 484 | { |
485 | if (landBitmap[x, y] == true) | 485 | if (landBitmap[x, y] == true) |
486 | { | 486 | { |
487 | if (min_x > x) min_x = x; | 487 | if (min_x > x) min_x = x; |
488 | if (min_y > y) min_y = y; | 488 | if (min_y > y) min_y = y; |
489 | if (max_x < x) max_x = x; | 489 | if (max_x < x) max_x = x; |
490 | if (max_y < y) max_y = y; | 490 | if (max_y < y) max_y = y; |
491 | tempArea += 16; //16sqm peice of land | 491 | tempArea += 16; //16sqm peice of land |
492 | } | 492 | } |
493 | } | 493 | } |
494 | } | 494 | } |
495 | int tx = min_x * 4; | 495 | int tx = min_x * 4; |
496 | if (tx > 255) | 496 | if (tx > 255) |
497 | tx = 255; | 497 | tx = 255; |
498 | int ty = min_y * 4; | 498 | int ty = min_y * 4; |
499 | if (ty > 255) | 499 | if (ty > 255) |
500 | ty = 255; | 500 | ty = 255; |
501 | landData.AABBMin = | 501 | landData.AABBMin = |
502 | new LLVector3((float) (min_x * 4), (float) (min_y * 4), | 502 | new LLVector3((float) (min_x * 4), (float) (min_y * 4), |
503 | (float) m_scene.Heightmap[tx, ty]); | 503 | (float) m_scene.Heightmap[tx, ty]); |
504 | 504 | ||
505 | tx = max_x * 4; | 505 | tx = max_x * 4; |
506 | if (tx > 255) | 506 | if (tx > 255) |
507 | tx = 255; | 507 | tx = 255; |
508 | ty = max_y * 4; | 508 | ty = max_y * 4; |
509 | if (ty > 255) | 509 | if (ty > 255) |
510 | ty = 255; | 510 | ty = 255; |
511 | landData.AABBMax = | 511 | landData.AABBMax = |
512 | new LLVector3((float) (max_x * 4), (float) (max_y * 4), | 512 | new LLVector3((float) (max_x * 4), (float) (max_y * 4), |
513 | (float) m_scene.Heightmap[tx, ty]); | 513 | (float) m_scene.Heightmap[tx, ty]); |
514 | landData.area = tempArea; | 514 | landData.area = tempArea; |
515 | } | 515 | } |
516 | 516 | ||
517 | #endregion | 517 | #endregion |
518 | 518 | ||
519 | #region Land Bitmap Functions | 519 | #region Land Bitmap Functions |
520 | 520 | ||
521 | /// <summary> | 521 | /// <summary> |
522 | /// Sets the land's bitmap manually | 522 | /// Sets the land's bitmap manually |
523 | /// </summary> | 523 | /// </summary> |
524 | /// <param name="bitmap">64x64 block representing where this land is on a map</param> | 524 | /// <param name="bitmap">64x64 block representing where this land is on a map</param> |
525 | public void setLandBitmap(bool[,] bitmap) | 525 | public void setLandBitmap(bool[,] bitmap) |
526 | { | 526 | { |
527 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) | 527 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) |
528 | { | 528 | { |
529 | //Throw an exception - The bitmap is not 64x64 | 529 | //Throw an exception - The bitmap is not 64x64 |
530 | //throw new Exception("Error: Invalid Parcel Bitmap"); | 530 | //throw new Exception("Error: Invalid Parcel Bitmap"); |
531 | } | 531 | } |
532 | else | 532 | else |
533 | { | 533 | { |
534 | //Valid: Lets set it | 534 | //Valid: Lets set it |
535 | landBitmap = bitmap; | 535 | landBitmap = bitmap; |
536 | forceUpdateLandInfo(); | 536 | forceUpdateLandInfo(); |
537 | } | 537 | } |
538 | } | 538 | } |
539 | 539 | ||
540 | /// <summary> | 540 | /// <summary> |
541 | /// Gets the land's bitmap manually | 541 | /// Gets the land's bitmap manually |
542 | /// </summary> | 542 | /// </summary> |
543 | /// <returns></returns> | 543 | /// <returns></returns> |
544 | public bool[,] getLandBitmap() | 544 | public bool[,] getLandBitmap() |
545 | { | 545 | { |
546 | return landBitmap; | 546 | return landBitmap; |
547 | } | 547 | } |
548 | 548 | ||
549 | /// <summary> | 549 | /// <summary> |
550 | /// Full sim land object creation | 550 | /// Full sim land object creation |
551 | /// </summary> | 551 | /// </summary> |
552 | /// <returns></returns> | 552 | /// <returns></returns> |
553 | public bool[,] basicFullRegionLandBitmap() | 553 | public bool[,] basicFullRegionLandBitmap() |
554 | { | 554 | { |
555 | return getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); | 555 | return getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); |
556 | } | 556 | } |
557 | 557 | ||
558 | /// <summary> | 558 | /// <summary> |
559 | /// Used to modify the bitmap between the x and y points. Points use 64 scale | 559 | /// Used to modify the bitmap between the x and y points. Points use 64 scale |
560 | /// </summary> | 560 | /// </summary> |
561 | /// <param name="start_x"></param> | 561 | /// <param name="start_x"></param> |
562 | /// <param name="start_y"></param> | 562 | /// <param name="start_y"></param> |
563 | /// <param name="end_x"></param> | 563 | /// <param name="end_x"></param> |
564 | /// <param name="end_y"></param> | 564 | /// <param name="end_y"></param> |
565 | /// <returns></returns> | 565 | /// <returns></returns> |
566 | public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) | 566 | public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) |
567 | { | 567 | { |
568 | bool[,] tempBitmap = new bool[64,64]; | 568 | bool[,] tempBitmap = new bool[64,64]; |
569 | tempBitmap.Initialize(); | 569 | tempBitmap.Initialize(); |
570 | 570 | ||
571 | tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); | 571 | tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); |
572 | return tempBitmap; | 572 | return tempBitmap; |
573 | } | 573 | } |
574 | 574 | ||
575 | /// <summary> | 575 | /// <summary> |
576 | /// Change a land bitmap at within a square and set those points to a specific value | 576 | /// Change a land bitmap at within a square and set those points to a specific value |
577 | /// </summary> | 577 | /// </summary> |
578 | /// <param name="land_bitmap"></param> | 578 | /// <param name="land_bitmap"></param> |
579 | /// <param name="start_x"></param> | 579 | /// <param name="start_x"></param> |
580 | /// <param name="start_y"></param> | 580 | /// <param name="start_y"></param> |
581 | /// <param name="end_x"></param> | 581 | /// <param name="end_x"></param> |
582 | /// <param name="end_y"></param> | 582 | /// <param name="end_y"></param> |
583 | /// <param name="set_value"></param> | 583 | /// <param name="set_value"></param> |
584 | /// <returns></returns> | 584 | /// <returns></returns> |
585 | public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, | 585 | public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, |
586 | bool set_value) | 586 | bool set_value) |
587 | { | 587 | { |
588 | if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) | 588 | if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) |
589 | { | 589 | { |
590 | //Throw an exception - The bitmap is not 64x64 | 590 | //Throw an exception - The bitmap is not 64x64 |
591 | //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); | 591 | //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); |
592 | } | 592 | } |
593 | 593 | ||
594 | int x, y; | 594 | int x, y; |
595 | for (y = 0; y < 64; y++) | 595 | for (y = 0; y < 64; y++) |
596 | { | 596 | { |
597 | for (x = 0; x < 64; x++) | 597 | for (x = 0; x < 64; x++) |
598 | { | 598 | { |
599 | if (x >= start_x / 4 && x < end_x / 4 | 599 | if (x >= start_x / 4 && x < end_x / 4 |
600 | && y >= start_y / 4 && y < end_y / 4) | 600 | && y >= start_y / 4 && y < end_y / 4) |
601 | { | 601 | { |
602 | land_bitmap[x, y] = set_value; | 602 | land_bitmap[x, y] = set_value; |
603 | } | 603 | } |
604 | } | 604 | } |
605 | } | 605 | } |
606 | return land_bitmap; | 606 | return land_bitmap; |
607 | } | 607 | } |
608 | 608 | ||
609 | /// <summary> | 609 | /// <summary> |
610 | /// Join the true values of 2 bitmaps together | 610 | /// Join the true values of 2 bitmaps together |
611 | /// </summary> | 611 | /// </summary> |
612 | /// <param name="bitmap_base"></param> | 612 | /// <param name="bitmap_base"></param> |
613 | /// <param name="bitmap_add"></param> | 613 | /// <param name="bitmap_add"></param> |
614 | /// <returns></returns> | 614 | /// <returns></returns> |
615 | public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) | 615 | public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) |
616 | { | 616 | { |
617 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) | 617 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) |
618 | { | 618 | { |
619 | //Throw an exception - The bitmap is not 64x64 | 619 | //Throw an exception - The bitmap is not 64x64 |
620 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); | 620 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); |
621 | } | 621 | } |
622 | if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) | 622 | if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) |
623 | { | 623 | { |
624 | //Throw an exception - The bitmap is not 64x64 | 624 | //Throw an exception - The bitmap is not 64x64 |
625 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); | 625 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); |
626 | } | 626 | } |
627 | 627 | ||
628 | int x, y; | 628 | int x, y; |
629 | for (y = 0; y < 64; y++) | 629 | for (y = 0; y < 64; y++) |
630 | { | 630 | { |
631 | for (x = 0; x < 64; x++) | 631 | for (x = 0; x < 64; x++) |
632 | { | 632 | { |
633 | if (bitmap_add[x, y]) | 633 | if (bitmap_add[x, y]) |
634 | { | 634 | { |
635 | bitmap_base[x, y] = true; | 635 | bitmap_base[x, y] = true; |
636 | } | 636 | } |
637 | } | 637 | } |
638 | } | 638 | } |
639 | return bitmap_base; | 639 | return bitmap_base; |
640 | } | 640 | } |
641 | 641 | ||
642 | /// <summary> | 642 | /// <summary> |
643 | /// Converts the land bitmap to a packet friendly byte array | 643 | /// Converts the land bitmap to a packet friendly byte array |
644 | /// </summary> | 644 | /// </summary> |
645 | /// <returns></returns> | 645 | /// <returns></returns> |
646 | private byte[] convertLandBitmapToBytes() | 646 | private byte[] convertLandBitmapToBytes() |
647 | { | 647 | { |
648 | byte[] tempConvertArr = new byte[512]; | 648 | byte[] tempConvertArr = new byte[512]; |
649 | byte tempByte = 0; | 649 | byte tempByte = 0; |
650 | int x, y, i, byteNum = 0; | 650 | int x, y, i, byteNum = 0; |
651 | i = 0; | 651 | i = 0; |
652 | for (y = 0; y < 64; y++) | 652 | for (y = 0; y < 64; y++) |
653 | { | 653 | { |
654 | for (x = 0; x < 64; x++) | 654 | for (x = 0; x < 64; x++) |
655 | { | 655 | { |
656 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8)); | 656 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8)); |
657 | if (i % 8 == 0) | 657 | if (i % 8 == 0) |
658 | { | 658 | { |
659 | tempConvertArr[byteNum] = tempByte; | 659 | tempConvertArr[byteNum] = tempByte; |
660 | tempByte = (byte) 0; | 660 | tempByte = (byte) 0; |
661 | i = 0; | 661 | i = 0; |
662 | byteNum++; | 662 | byteNum++; |
663 | } | 663 | } |
664 | } | 664 | } |
665 | } | 665 | } |
666 | return tempConvertArr; | 666 | return tempConvertArr; |
667 | } | 667 | } |
668 | 668 | ||
669 | private bool[,] convertBytesToLandBitmap() | 669 | private bool[,] convertBytesToLandBitmap() |
670 | { | 670 | { |
671 | bool[,] tempConvertMap = new bool[64,64]; | 671 | bool[,] tempConvertMap = new bool[64,64]; |
672 | tempConvertMap.Initialize(); | 672 | tempConvertMap.Initialize(); |
673 | byte tempByte = 0; | 673 | byte tempByte = 0; |
674 | int x = 0, y = 0, i = 0, bitNum = 0; | 674 | int x = 0, y = 0, i = 0, bitNum = 0; |
675 | for (i = 0; i < 512; i++) | 675 | for (i = 0; i < 512; i++) |
676 | { | 676 | { |
677 | tempByte = landData.landBitmapByteArray[i]; | 677 | tempByte = landData.landBitmapByteArray[i]; |
678 | for (bitNum = 0; bitNum < 8; bitNum++) | 678 | for (bitNum = 0; bitNum < 8; bitNum++) |
679 | { | 679 | { |
680 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); | 680 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); |
681 | tempConvertMap[x, y] = bit; | 681 | tempConvertMap[x, y] = bit; |
682 | x++; | 682 | x++; |
683 | if (x > 63) | 683 | if (x > 63) |
684 | { | 684 | { |
685 | x = 0; | 685 | x = 0; |
686 | y++; | 686 | y++; |
687 | } | 687 | } |
688 | } | 688 | } |
689 | } | 689 | } |
690 | return tempConvertMap; | 690 | return tempConvertMap; |
691 | } | 691 | } |
692 | 692 | ||
693 | #endregion | 693 | #endregion |
694 | 694 | ||
695 | #region Object Select and Object Owner Listing | 695 | #region Object Select and Object Owner Listing |
696 | 696 | ||
697 | public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) | 697 | public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) |
698 | { | 698 | { |
699 | List<uint> resultLocalIDs = new List<uint>(); | 699 | List<uint> resultLocalIDs = new List<uint>(); |
700 | foreach (SceneObjectGroup obj in primsOverMe) | 700 | foreach (SceneObjectGroup obj in primsOverMe) |
701 | { | 701 | { |
702 | if (obj.LocalId > 0) | 702 | if (obj.LocalId > 0) |
703 | { | 703 | { |
704 | if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID) | 704 | if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID) |
705 | { | 705 | { |
706 | resultLocalIDs.Add(obj.LocalId); | 706 | resultLocalIDs.Add(obj.LocalId); |
707 | } | 707 | } |
708 | // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support | 708 | // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support |
709 | // { | 709 | // { |
710 | // } | 710 | // } |
711 | else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && | 711 | else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && |
712 | obj.OwnerID != remote_client.AgentId) | 712 | obj.OwnerID != remote_client.AgentId) |
713 | { | 713 | { |
714 | resultLocalIDs.Add(obj.LocalId); | 714 | resultLocalIDs.Add(obj.LocalId); |
715 | } | 715 | } |
716 | } | 716 | } |
717 | } | 717 | } |
718 | 718 | ||
719 | 719 | ||
720 | bool firstCall = true; | 720 | bool firstCall = true; |
721 | int MAX_OBJECTS_PER_PACKET = 251; | 721 | int MAX_OBJECTS_PER_PACKET = 251; |
722 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); | 722 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); |
723 | // TODO: don't create new blocks if recycling an old packet | 723 | // TODO: don't create new blocks if recycling an old packet |
724 | ForceObjectSelectPacket.DataBlock[] data; | 724 | ForceObjectSelectPacket.DataBlock[] data; |
725 | while (resultLocalIDs.Count > 0) | 725 | while (resultLocalIDs.Count > 0) |
726 | { | 726 | { |
727 | if (firstCall) | 727 | if (firstCall) |
728 | { | 728 | { |
729 | pack._Header.ResetList = true; | 729 | pack._Header.ResetList = true; |
730 | firstCall = false; | 730 | firstCall = false; |
731 | } | 731 | } |
732 | else | 732 | else |
733 | { | 733 | { |
734 | pack._Header.ResetList = false; | 734 | pack._Header.ResetList = false; |
735 | } | 735 | } |
736 | 736 | ||
737 | if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) | 737 | if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) |
738 | { | 738 | { |
739 | data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; | 739 | data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; |
740 | } | 740 | } |
741 | else | 741 | else |
742 | { | 742 | { |
743 | data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; | 743 | data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; |
744 | } | 744 | } |
745 | 745 | ||
746 | int i; | 746 | int i; |
747 | for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) | 747 | for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) |
748 | { | 748 | { |
749 | data[i] = new ForceObjectSelectPacket.DataBlock(); | 749 | data[i] = new ForceObjectSelectPacket.DataBlock(); |
750 | data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); | 750 | data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); |
751 | resultLocalIDs.RemoveAt(0); | 751 | resultLocalIDs.RemoveAt(0); |
752 | } | 752 | } |
753 | pack.Data = data; | 753 | pack.Data = data; |
754 | remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task); | 754 | remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task); |
755 | } | 755 | } |
756 | } | 756 | } |
757 | 757 | ||
758 | /// <summary> | 758 | /// <summary> |
759 | /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes | 759 | /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes |
760 | /// aggreagete details such as the number of prims. | 760 | /// aggreagete details such as the number of prims. |
761 | /// | 761 | /// |
762 | /// </summary> | 762 | /// </summary> |
763 | /// <param name="remote_client"> | 763 | /// <param name="remote_client"> |
764 | /// A <see cref="IClientAPI"/> | 764 | /// A <see cref="IClientAPI"/> |
765 | /// </param> | 765 | /// </param> |
766 | public void sendLandObjectOwners(IClientAPI remote_client) | 766 | public void sendLandObjectOwners(IClientAPI remote_client) |
767 | { | 767 | { |
768 | Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>(); | 768 | Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>(); |
769 | ParcelObjectOwnersReplyPacket pack | 769 | ParcelObjectOwnersReplyPacket pack |
770 | = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); | 770 | = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); |
771 | // TODO: don't create new blocks if recycling an old packet | 771 | // TODO: don't create new blocks if recycling an old packet |
772 | 772 | ||
773 | foreach (SceneObjectGroup obj in primsOverMe) | 773 | foreach (SceneObjectGroup obj in primsOverMe) |
774 | { | 774 | { |
775 | try | 775 | try |
776 | { | 776 | { |
777 | if (!primCount.ContainsKey(obj.OwnerID)) | 777 | if (!primCount.ContainsKey(obj.OwnerID)) |
778 | { | 778 | { |
779 | primCount.Add(obj.OwnerID, 0); | 779 | primCount.Add(obj.OwnerID, 0); |
780 | } | 780 | } |
781 | } | 781 | } |
782 | catch (NullReferenceException) | 782 | catch (NullReferenceException) |
783 | { | 783 | { |
784 | m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); | 784 | m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); |
785 | } | 785 | } |
786 | try | 786 | try |
787 | { | 787 | { |
788 | primCount[obj.OwnerID] += obj.PrimCount; | 788 | primCount[obj.OwnerID] += obj.PrimCount; |
789 | } | 789 | } |
790 | catch (KeyNotFoundException) | 790 | catch (KeyNotFoundException) |
791 | { | 791 | { |
792 | m_log.Error("[LAND]: Unable to match a prim with it's owner."); | 792 | m_log.Error("[LAND]: Unable to match a prim with it's owner."); |
793 | } | 793 | } |
794 | } | 794 | } |
795 | 795 | ||
796 | int notifyCount = primCount.Count; | 796 | int notifyCount = primCount.Count; |
797 | 797 | ||
798 | if (notifyCount > 0) | 798 | if (notifyCount > 0) |
799 | { | 799 | { |
800 | if (notifyCount > 32) | 800 | if (notifyCount > 32) |
801 | { | 801 | { |
802 | m_log.InfoFormat( | 802 | m_log.InfoFormat( |
803 | "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" | 803 | "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" |
804 | + " - a developer might want to investigate whether this is a hard limit", 32); | 804 | + " - a developer might want to investigate whether this is a hard limit", 32); |
805 | 805 | ||
806 | notifyCount = 32; | 806 | notifyCount = 32; |
807 | } | 807 | } |
808 | 808 | ||
809 | ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock | 809 | ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock |
810 | = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; | 810 | = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; |
811 | 811 | ||
812 | int num = 0; | 812 | int num = 0; |
813 | foreach (LLUUID owner in primCount.Keys) | 813 | foreach (LLUUID owner in primCount.Keys) |
814 | { | 814 | { |
815 | dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); | 815 | dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); |
816 | dataBlock[num].Count = primCount[owner]; | 816 | dataBlock[num].Count = primCount[owner]; |
817 | dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added | 817 | dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added |
818 | dataBlock[num].OnlineStatus = true; //TODO: fix me later | 818 | dataBlock[num].OnlineStatus = true; //TODO: fix me later |
819 | dataBlock[num].OwnerID = owner; | 819 | dataBlock[num].OwnerID = owner; |
820 | 820 | ||
821 | num++; | 821 | num++; |
822 | 822 | ||
823 | if (num >= notifyCount) | 823 | if (num >= notifyCount) |
824 | { | 824 | { |
825 | break; | 825 | break; |
826 | } | 826 | } |
827 | } | 827 | } |
828 | 828 | ||
829 | pack.Data = dataBlock; | 829 | pack.Data = dataBlock; |
830 | } | 830 | } |
831 | 831 | ||
832 | remote_client.OutPacket(pack, ThrottleOutPacketType.Task); | 832 | remote_client.OutPacket(pack, ThrottleOutPacketType.Task); |
833 | } | 833 | } |
834 | 834 | ||
835 | public Dictionary<LLUUID, int> getLandObjectOwners() | 835 | public Dictionary<LLUUID, int> getLandObjectOwners() |
836 | { | 836 | { |
837 | Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>(); | 837 | Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>(); |
838 | foreach (SceneObjectGroup obj in primsOverMe) | 838 | foreach (SceneObjectGroup obj in primsOverMe) |
839 | { | 839 | { |
840 | if (!ownersAndCount.ContainsKey(obj.OwnerID)) | 840 | if (!ownersAndCount.ContainsKey(obj.OwnerID)) |
841 | { | 841 | { |
842 | ownersAndCount.Add(obj.OwnerID, 0); | 842 | ownersAndCount.Add(obj.OwnerID, 0); |
843 | } | 843 | } |
844 | ownersAndCount[obj.OwnerID] += obj.PrimCount; | 844 | ownersAndCount[obj.OwnerID] += obj.PrimCount; |
845 | } | 845 | } |
846 | return ownersAndCount; | 846 | return ownersAndCount; |
847 | } | 847 | } |
848 | 848 | ||
849 | #endregion | 849 | #endregion |
850 | 850 | ||
851 | #region Object Returning | 851 | #region Object Returning |
852 | 852 | ||
853 | public void returnObject(SceneObjectGroup obj) | 853 | public void returnObject(SceneObjectGroup obj) |
854 | { | 854 | { |
855 | } | 855 | } |
856 | 856 | ||
857 | public void returnLandObjects(int type, LLUUID owner) | 857 | public void returnLandObjects(int type, LLUUID owner) |
858 | { | 858 | { |
859 | } | 859 | } |
860 | 860 | ||
861 | #endregion | 861 | #endregion |
862 | 862 | ||
863 | #region Object Adding/Removing from Parcel | 863 | #region Object Adding/Removing from Parcel |
864 | 864 | ||
865 | public void resetLandPrimCounts() | 865 | public void resetLandPrimCounts() |
866 | { | 866 | { |
867 | landData.groupPrims = 0; | 867 | landData.groupPrims = 0; |
868 | landData.ownerPrims = 0; | 868 | landData.ownerPrims = 0; |
869 | landData.otherPrims = 0; | 869 | landData.otherPrims = 0; |
870 | landData.selectedPrims = 0; | 870 | landData.selectedPrims = 0; |
871 | primsOverMe.Clear(); | 871 | primsOverMe.Clear(); |
872 | } | 872 | } |
873 | 873 | ||
874 | public void addPrimToCount(SceneObjectGroup obj) | 874 | public void addPrimToCount(SceneObjectGroup obj) |
875 | { | 875 | { |
876 | LLUUID prim_owner = obj.OwnerID; | 876 | LLUUID prim_owner = obj.OwnerID; |
877 | int prim_count = obj.PrimCount; | 877 | int prim_count = obj.PrimCount; |
878 | 878 | ||
879 | if (obj.IsSelected) | 879 | if (obj.IsSelected) |
880 | { | 880 | { |
881 | landData.selectedPrims += prim_count; | 881 | landData.selectedPrims += prim_count; |
882 | } | 882 | } |
883 | else | 883 | else |
884 | { | 884 | { |
885 | if (prim_owner == landData.ownerID) | 885 | if (prim_owner == landData.ownerID) |
886 | { | 886 | { |
887 | landData.ownerPrims += prim_count; | 887 | landData.ownerPrims += prim_count; |
888 | } | 888 | } |
889 | else | 889 | else |
890 | { | 890 | { |
891 | landData.otherPrims += prim_count; | 891 | landData.otherPrims += prim_count; |
892 | } | 892 | } |
893 | } | 893 | } |
894 | 894 | ||
895 | primsOverMe.Add(obj); | 895 | primsOverMe.Add(obj); |
896 | } | 896 | } |
897 | 897 | ||
898 | public void removePrimFromCount(SceneObjectGroup obj) | 898 | public void removePrimFromCount(SceneObjectGroup obj) |
899 | { | 899 | { |
900 | if (primsOverMe.Contains(obj)) | 900 | if (primsOverMe.Contains(obj)) |
901 | { | 901 | { |
902 | LLUUID prim_owner = obj.OwnerID; | 902 | LLUUID prim_owner = obj.OwnerID; |
903 | int prim_count = obj.PrimCount; | 903 | int prim_count = obj.PrimCount; |
904 | 904 | ||
905 | if (prim_owner == landData.ownerID) | 905 | if (prim_owner == landData.ownerID) |
906 | { | 906 | { |
907 | landData.ownerPrims -= prim_count; | 907 | landData.ownerPrims -= prim_count; |
908 | } | 908 | } |
909 | else if (prim_owner == landData.groupID) | 909 | else if (prim_owner == landData.groupID) |
910 | { | 910 | { |
911 | landData.groupPrims -= prim_count; | 911 | landData.groupPrims -= prim_count; |
912 | } | 912 | } |
913 | else | 913 | else |
914 | { | 914 | { |
915 | landData.otherPrims -= prim_count; | 915 | landData.otherPrims -= prim_count; |
916 | } | 916 | } |
917 | 917 | ||
918 | primsOverMe.Remove(obj); | 918 | primsOverMe.Remove(obj); |
919 | } | 919 | } |
920 | } | 920 | } |
921 | 921 | ||
922 | #endregion | 922 | #endregion |
923 | 923 | ||
924 | #endregion | 924 | #endregion |
925 | 925 | ||
926 | #endregion | 926 | #endregion |
927 | } | 927 | } |
928 | } \ No newline at end of file | 928 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs index fc3f75d..77a418f 100644 --- a/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs +++ b/OpenSim/Region/Environment/Modules/World/Serialiser/IFileSerialiser.cs | |||
@@ -1,36 +1,36 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Scenes; | 28 | using OpenSim.Region.Environment.Scenes; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser | 30 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser |
31 | { | 31 | { |
32 | internal interface IFileSerialiser | 32 | internal interface IFileSerialiser |
33 | { | 33 | { |
34 | string WriteToFile(Scene scene, string dir); | 34 | string WriteToFile(Scene scene, string dir); |
35 | } | 35 | } |
36 | } \ No newline at end of file | 36 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs index 0ea2f30..e1721ff 100644 --- a/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs +++ b/OpenSim/Region/Environment/Modules/World/Serialiser/IRegionSerialiser.cs | |||
@@ -1,37 +1,37 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using OpenSim.Region.Environment.Scenes; | 29 | using OpenSim.Region.Environment.Scenes; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser | 31 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser |
32 | { | 32 | { |
33 | public interface IRegionSerialiser | 33 | public interface IRegionSerialiser |
34 | { | 34 | { |
35 | List<string> SerialiseRegion(Scene scene, string saveDir); | 35 | List<string> SerialiseRegion(Scene scene, string saveDir); |
36 | } | 36 | } |
37 | } \ No newline at end of file | 37 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs index ef90fd4..40e1771 100644 --- a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs +++ b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseObjects.cs | |||
@@ -1,125 +1,125 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.IO.Compression; | 30 | using System.IO.Compression; |
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Xml; | 32 | using System.Xml; |
33 | using OpenSim.Region.Environment.Scenes; | 33 | using OpenSim.Region.Environment.Scenes; |
34 | 34 | ||
35 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser | 35 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser |
36 | { | 36 | { |
37 | internal class SerialiseObjects : IFileSerialiser | 37 | internal class SerialiseObjects : IFileSerialiser |
38 | { | 38 | { |
39 | #region IFileSerialiser Members | 39 | #region IFileSerialiser Members |
40 | 40 | ||
41 | public string WriteToFile(Scene scene, string dir) | 41 | public string WriteToFile(Scene scene, string dir) |
42 | { | 42 | { |
43 | string targetFileName = dir + "objects.xml"; | 43 | string targetFileName = dir + "objects.xml"; |
44 | 44 | ||
45 | SaveSerialisedToFile(targetFileName, scene); | 45 | SaveSerialisedToFile(targetFileName, scene); |
46 | 46 | ||
47 | return "objects.xml"; | 47 | return "objects.xml"; |
48 | } | 48 | } |
49 | 49 | ||
50 | #endregion | 50 | #endregion |
51 | 51 | ||
52 | public void SaveSerialisedToFile(string fileName, Scene scene) | 52 | public void SaveSerialisedToFile(string fileName, Scene scene) |
53 | { | 53 | { |
54 | string xmlstream = GetObjectXml(scene); | 54 | string xmlstream = GetObjectXml(scene); |
55 | 55 | ||
56 | MemoryStream stream = ReformatXmlString(xmlstream); | 56 | MemoryStream stream = ReformatXmlString(xmlstream); |
57 | 57 | ||
58 | stream.Seek(0, SeekOrigin.Begin); | 58 | stream.Seek(0, SeekOrigin.Begin); |
59 | CreateXmlFile(stream, fileName); | 59 | CreateXmlFile(stream, fileName); |
60 | 60 | ||
61 | stream.Seek(0, SeekOrigin.Begin); | 61 | stream.Seek(0, SeekOrigin.Begin); |
62 | CreateCompressedXmlFile(stream, fileName); | 62 | CreateCompressedXmlFile(stream, fileName); |
63 | } | 63 | } |
64 | 64 | ||
65 | private static MemoryStream ReformatXmlString(string xmlstream) | 65 | private static MemoryStream ReformatXmlString(string xmlstream) |
66 | { | 66 | { |
67 | MemoryStream stream = new MemoryStream(); | 67 | MemoryStream stream = new MemoryStream(); |
68 | XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8); | 68 | XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8); |
69 | XmlDocument doc = new XmlDocument(); | 69 | XmlDocument doc = new XmlDocument(); |
70 | 70 | ||
71 | doc.LoadXml(xmlstream); | 71 | doc.LoadXml(xmlstream); |
72 | formatter.Formatting = Formatting.Indented; | 72 | formatter.Formatting = Formatting.Indented; |
73 | doc.WriteContentTo(formatter); | 73 | doc.WriteContentTo(formatter); |
74 | formatter.Flush(); | 74 | formatter.Flush(); |
75 | return stream; | 75 | return stream; |
76 | } | 76 | } |
77 | 77 | ||
78 | private static string GetObjectXml(Scene scene) | 78 | private static string GetObjectXml(Scene scene) |
79 | { | 79 | { |
80 | string xmlstream = "<scene>"; | 80 | string xmlstream = "<scene>"; |
81 | 81 | ||
82 | List<EntityBase> EntityList = scene.GetEntities(); | 82 | List<EntityBase> EntityList = scene.GetEntities(); |
83 | List<string> EntityXml = new List<string>(); | 83 | List<string> EntityXml = new List<string>(); |
84 | 84 | ||
85 | foreach (EntityBase ent in EntityList) | 85 | foreach (EntityBase ent in EntityList) |
86 | { | 86 | { |
87 | if (ent is SceneObjectGroup) | 87 | if (ent is SceneObjectGroup) |
88 | { | 88 | { |
89 | EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2()); | 89 | EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2()); |
90 | } | 90 | } |
91 | } | 91 | } |
92 | EntityXml.Sort(); | 92 | EntityXml.Sort(); |
93 | 93 | ||
94 | foreach (string xml in EntityXml) | 94 | foreach (string xml in EntityXml) |
95 | xmlstream += xml; | 95 | xmlstream += xml; |
96 | 96 | ||
97 | xmlstream += "</scene>"; | 97 | xmlstream += "</scene>"; |
98 | return xmlstream; | 98 | return xmlstream; |
99 | } | 99 | } |
100 | 100 | ||
101 | private static void CreateXmlFile(MemoryStream xmlStream, string fileName) | 101 | private static void CreateXmlFile(MemoryStream xmlStream, string fileName) |
102 | { | 102 | { |
103 | FileStream objectsFile = new FileStream(fileName, FileMode.Create); | 103 | FileStream objectsFile = new FileStream(fileName, FileMode.Create); |
104 | 104 | ||
105 | xmlStream.WriteTo(objectsFile); | 105 | xmlStream.WriteTo(objectsFile); |
106 | objectsFile.Flush(); | 106 | objectsFile.Flush(); |
107 | objectsFile.Close(); | 107 | objectsFile.Close(); |
108 | } | 108 | } |
109 | 109 | ||
110 | private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName) | 110 | private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName) |
111 | { | 111 | { |
112 | #region GZip Compressed Version | 112 | #region GZip Compressed Version |
113 | 113 | ||
114 | FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create); | 114 | FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create); |
115 | MemoryStream gzipMSStream = new MemoryStream(); | 115 | MemoryStream gzipMSStream = new MemoryStream(); |
116 | GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress); | 116 | GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress); |
117 | xmlStream.WriteTo(gzipStream); | 117 | xmlStream.WriteTo(gzipStream); |
118 | gzipMSStream.WriteTo(objectsFileCompressed); | 118 | gzipMSStream.WriteTo(objectsFileCompressed); |
119 | objectsFileCompressed.Flush(); | 119 | objectsFileCompressed.Flush(); |
120 | objectsFileCompressed.Close(); | 120 | objectsFileCompressed.Close(); |
121 | 121 | ||
122 | #endregion | 122 | #endregion |
123 | } | 123 | } |
124 | } | 124 | } |
125 | } \ No newline at end of file | 125 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs index 03824e8..dacdbc8 100644 --- a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs +++ b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiseTerrain.cs | |||
@@ -1,53 +1,53 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Modules.World.Terrain; | 28 | using OpenSim.Region.Environment.Modules.World.Terrain; |
29 | using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders; | 29 | using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders; |
30 | using OpenSim.Region.Environment.Scenes; | 30 | using OpenSim.Region.Environment.Scenes; |
31 | 31 | ||
32 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser | 32 | namespace OpenSim.Region.Environment.Modules.ExportSerialiser |
33 | { | 33 | { |
34 | internal class SerialiseTerrain : IFileSerialiser | 34 | internal class SerialiseTerrain : IFileSerialiser |
35 | { | 35 | { |
36 | #region IFileSerialiser Members | 36 | #region IFileSerialiser Members |
37 | 37 | ||
38 | public string WriteToFile(Scene scene, string dir) | 38 | public string WriteToFile(Scene scene, string dir) |
39 | { | 39 | { |
40 | ITerrainLoader fileSystemExporter = new RAW32(); | 40 | ITerrainLoader fileSystemExporter = new RAW32(); |
41 | string targetFileName = dir + "heightmap.r32"; | 41 | string targetFileName = dir + "heightmap.r32"; |
42 | 42 | ||
43 | lock (scene.Heightmap) | 43 | lock (scene.Heightmap) |
44 | { | 44 | { |
45 | fileSystemExporter.SaveFile(targetFileName, scene.Heightmap); | 45 | fileSystemExporter.SaveFile(targetFileName, scene.Heightmap); |
46 | } | 46 | } |
47 | 47 | ||
48 | return "heightmap.r32"; | 48 | return "heightmap.r32"; |
49 | } | 49 | } |
50 | 50 | ||
51 | #endregion | 51 | #endregion |
52 | } | 52 | } |
53 | } \ No newline at end of file | 53 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs index b626f16..75fc428 100644 --- a/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Serialiser/SerialiserModule.cs | |||
@@ -1,169 +1,169 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Region.Environment.Interfaces; | 32 | using OpenSim.Region.Environment.Interfaces; |
33 | using OpenSim.Region.Environment.Modules.ExportSerialiser; | 33 | using OpenSim.Region.Environment.Modules.ExportSerialiser; |
34 | using OpenSim.Region.Environment.Modules.Framework; | 34 | using OpenSim.Region.Environment.Modules.Framework; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules.World.Serialiser | 37 | namespace OpenSim.Region.Environment.Modules.World.Serialiser |
38 | { | 38 | { |
39 | public class SerialiserModule : IRegionModule, IRegionSerialiser | 39 | public class SerialiserModule : IRegionModule, IRegionSerialiser |
40 | { | 40 | { |
41 | private Commander m_commander = new Commander("Export"); | 41 | private Commander m_commander = new Commander("Export"); |
42 | private List<Scene> m_regions = new List<Scene>(); | 42 | private List<Scene> m_regions = new List<Scene>(); |
43 | private string m_savedir = "exports" + "/"; | 43 | private string m_savedir = "exports" + "/"; |
44 | private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>(); | 44 | private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>(); |
45 | 45 | ||
46 | #region IRegionModule Members | 46 | #region IRegionModule Members |
47 | 47 | ||
48 | public void Initialise(Scene scene, IConfigSource source) | 48 | public void Initialise(Scene scene, IConfigSource source) |
49 | { | 49 | { |
50 | scene.RegisterModuleCommander("Export", m_commander); | 50 | scene.RegisterModuleCommander("Export", m_commander); |
51 | scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; | 51 | scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; |
52 | scene.RegisterModuleInterface<IRegionSerialiser>(this); | 52 | scene.RegisterModuleInterface<IRegionSerialiser>(this); |
53 | 53 | ||
54 | lock (m_regions) | 54 | lock (m_regions) |
55 | { | 55 | { |
56 | m_regions.Add(scene); | 56 | m_regions.Add(scene); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | public void PostInitialise() | 60 | public void PostInitialise() |
61 | { | 61 | { |
62 | lock (m_serialisers) | 62 | lock (m_serialisers) |
63 | { | 63 | { |
64 | m_serialisers.Add(new SerialiseTerrain()); | 64 | m_serialisers.Add(new SerialiseTerrain()); |
65 | m_serialisers.Add(new SerialiseObjects()); | 65 | m_serialisers.Add(new SerialiseObjects()); |
66 | } | 66 | } |
67 | 67 | ||
68 | LoadCommanderCommands(); | 68 | LoadCommanderCommands(); |
69 | } | 69 | } |
70 | 70 | ||
71 | public void Close() | 71 | public void Close() |
72 | { | 72 | { |
73 | m_regions.Clear(); | 73 | m_regions.Clear(); |
74 | } | 74 | } |
75 | 75 | ||
76 | public string Name | 76 | public string Name |
77 | { | 77 | { |
78 | get { return "ExportSerialisationModule"; } | 78 | get { return "ExportSerialisationModule"; } |
79 | } | 79 | } |
80 | 80 | ||
81 | public bool IsSharedModule | 81 | public bool IsSharedModule |
82 | { | 82 | { |
83 | get { return true; } | 83 | get { return true; } |
84 | } | 84 | } |
85 | 85 | ||
86 | #endregion | 86 | #endregion |
87 | 87 | ||
88 | #region IRegionSerialiser Members | 88 | #region IRegionSerialiser Members |
89 | 89 | ||
90 | public List<string> SerialiseRegion(Scene scene, string saveDir) | 90 | public List<string> SerialiseRegion(Scene scene, string saveDir) |
91 | { | 91 | { |
92 | List<string> results = new List<string>(); | 92 | List<string> results = new List<string>(); |
93 | 93 | ||
94 | if (!Directory.Exists(saveDir)) | 94 | if (!Directory.Exists(saveDir)) |
95 | { | 95 | { |
96 | Directory.CreateDirectory(saveDir); | 96 | Directory.CreateDirectory(saveDir); |
97 | } | 97 | } |
98 | 98 | ||
99 | lock (m_serialisers) | 99 | lock (m_serialisers) |
100 | { | 100 | { |
101 | foreach (IFileSerialiser serialiser in m_serialisers) | 101 | foreach (IFileSerialiser serialiser in m_serialisers) |
102 | { | 102 | { |
103 | results.Add(serialiser.WriteToFile(scene, saveDir)); | 103 | results.Add(serialiser.WriteToFile(scene, saveDir)); |
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT"); | 107 | TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT"); |
108 | regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName); | 108 | regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName); |
109 | regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString()); | 109 | regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString()); |
110 | regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString()); | 110 | regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString()); |
111 | regionInfoWriter.WriteLine("Serialise Version: 0.1"); | 111 | regionInfoWriter.WriteLine("Serialise Version: 0.1"); |
112 | regionInfoWriter.Close(); | 112 | regionInfoWriter.Close(); |
113 | 113 | ||
114 | TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest"); | 114 | TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest"); |
115 | foreach (string line in results) | 115 | foreach (string line in results) |
116 | { | 116 | { |
117 | manifestWriter.WriteLine(line); | 117 | manifestWriter.WriteLine(line); |
118 | } | 118 | } |
119 | manifestWriter.Close(); | 119 | manifestWriter.Close(); |
120 | 120 | ||
121 | return results; | 121 | return results; |
122 | } | 122 | } |
123 | 123 | ||
124 | #endregion | 124 | #endregion |
125 | 125 | ||
126 | private void EventManager_OnPluginConsole(string[] args) | 126 | private void EventManager_OnPluginConsole(string[] args) |
127 | { | 127 | { |
128 | if (args[0] == "export") | 128 | if (args[0] == "export") |
129 | { | 129 | { |
130 | string[] tmpArgs = new string[args.Length - 2]; | 130 | string[] tmpArgs = new string[args.Length - 2]; |
131 | int i = 0; | 131 | int i = 0; |
132 | for (i = 2; i < args.Length; i++) | 132 | for (i = 2; i < args.Length; i++) |
133 | tmpArgs[i - 2] = args[i]; | 133 | tmpArgs[i - 2] = args[i]; |
134 | 134 | ||
135 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); | 135 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); |
136 | } | 136 | } |
137 | } | 137 | } |
138 | 138 | ||
139 | private void InterfaceSaveRegion(Object[] args) | 139 | private void InterfaceSaveRegion(Object[] args) |
140 | { | 140 | { |
141 | foreach (Scene region in m_regions) | 141 | foreach (Scene region in m_regions) |
142 | { | 142 | { |
143 | if (region.RegionInfo.RegionName == (string) args[0]) | 143 | if (region.RegionInfo.RegionName == (string) args[0]) |
144 | { | 144 | { |
145 | List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/"); | 145 | List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/"); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
149 | 149 | ||
150 | private void InterfaceSaveAllRegions(Object[] args) | 150 | private void InterfaceSaveAllRegions(Object[] args) |
151 | { | 151 | { |
152 | foreach (Scene region in m_regions) | 152 | foreach (Scene region in m_regions) |
153 | { | 153 | { |
154 | List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/"); | 154 | List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/"); |
155 | } | 155 | } |
156 | } | 156 | } |
157 | 157 | ||
158 | private void LoadCommanderCommands() | 158 | private void LoadCommanderCommands() |
159 | { | 159 | { |
160 | Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory."); | 160 | Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory."); |
161 | serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String"); | 161 | serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String"); |
162 | 162 | ||
163 | Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory."); | 163 | Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory."); |
164 | 164 | ||
165 | m_commander.RegisterCommand("save", serialiseSceneCommand); | 165 | m_commander.RegisterCommand("save", serialiseSceneCommand); |
166 | m_commander.RegisterCommand("save-all", serialiseAllScenesCommand); | 166 | m_commander.RegisterCommand("save-all", serialiseAllScenesCommand); |
167 | } | 167 | } |
168 | } | 168 | } |
169 | } \ No newline at end of file | 169 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs b/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs index a12118e..85c4cdd 100644 --- a/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Sun/SunModule.cs | |||
@@ -1,199 +1,199 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.Modules | 36 | namespace OpenSim.Region.Environment.Modules |
37 | { | 37 | { |
38 | public class SunModule : IRegionModule | 38 | public class SunModule : IRegionModule |
39 | { | 39 | { |
40 | //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 40 | //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
41 | 41 | ||
42 | private const int m_default_frame = 100; | 42 | private const int m_default_frame = 100; |
43 | private const double m_real_day = 24.0; | 43 | private const double m_real_day = 24.0; |
44 | private double m_day_length; | 44 | private double m_day_length; |
45 | private int m_dilation; | 45 | private int m_dilation; |
46 | private int m_frame; | 46 | private int m_frame; |
47 | private int m_frame_mod; | 47 | private int m_frame_mod; |
48 | 48 | ||
49 | private Scene m_scene; | 49 | private Scene m_scene; |
50 | private long m_start; | 50 | private long m_start; |
51 | 51 | ||
52 | #region IRegionModule Members | 52 | #region IRegionModule Members |
53 | 53 | ||
54 | public void Initialise(Scene scene, IConfigSource config) | 54 | public void Initialise(Scene scene, IConfigSource config) |
55 | { | 55 | { |
56 | m_start = DateTime.Now.Ticks; | 56 | m_start = DateTime.Now.Ticks; |
57 | m_frame = 0; | 57 | m_frame = 0; |
58 | 58 | ||
59 | // Just in case they don't have the stanzas | 59 | // Just in case they don't have the stanzas |
60 | try | 60 | try |
61 | { | 61 | { |
62 | m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day); | 62 | m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day); |
63 | m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame); | 63 | m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame); |
64 | } | 64 | } |
65 | catch (Exception) | 65 | catch (Exception) |
66 | { | 66 | { |
67 | m_day_length = m_real_day; | 67 | m_day_length = m_real_day; |
68 | m_frame_mod = m_default_frame; | 68 | m_frame_mod = m_default_frame; |
69 | } | 69 | } |
70 | 70 | ||
71 | m_dilation = (int) (m_real_day / m_day_length); | 71 | m_dilation = (int) (m_real_day / m_day_length); |
72 | m_scene = scene; | 72 | m_scene = scene; |
73 | scene.EventManager.OnFrame += SunUpdate; | 73 | scene.EventManager.OnFrame += SunUpdate; |
74 | scene.EventManager.OnNewClient += SunToClient; | 74 | scene.EventManager.OnNewClient += SunToClient; |
75 | } | 75 | } |
76 | 76 | ||
77 | public void PostInitialise() | 77 | public void PostInitialise() |
78 | { | 78 | { |
79 | } | 79 | } |
80 | 80 | ||
81 | public void Close() | 81 | public void Close() |
82 | { | 82 | { |
83 | } | 83 | } |
84 | 84 | ||
85 | public string Name | 85 | public string Name |
86 | { | 86 | { |
87 | get { return "SunModule"; } | 87 | get { return "SunModule"; } |
88 | } | 88 | } |
89 | 89 | ||
90 | public bool IsSharedModule | 90 | public bool IsSharedModule |
91 | { | 91 | { |
92 | get { return false; } | 92 | get { return false; } |
93 | } | 93 | } |
94 | 94 | ||
95 | #endregion | 95 | #endregion |
96 | 96 | ||
97 | public void SunToClient(IClientAPI client) | 97 | public void SunToClient(IClientAPI client) |
98 | { | 98 | { |
99 | client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f)); | 99 | client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f)); |
100 | } | 100 | } |
101 | 101 | ||
102 | public void SunUpdate() | 102 | public void SunUpdate() |
103 | { | 103 | { |
104 | if (m_frame < m_frame_mod) | 104 | if (m_frame < m_frame_mod) |
105 | { | 105 | { |
106 | m_frame++; | 106 | m_frame++; |
107 | return; | 107 | return; |
108 | } | 108 | } |
109 | // m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay()); | 109 | // m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay()); |
110 | List<ScenePresence> avatars = m_scene.GetAvatars(); | 110 | List<ScenePresence> avatars = m_scene.GetAvatars(); |
111 | foreach (ScenePresence avatar in avatars) | 111 | foreach (ScenePresence avatar in avatars) |
112 | { | 112 | { |
113 | avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f)); | 113 | avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f)); |
114 | } | 114 | } |
115 | // set estate settings for region access to sun position | 115 | // set estate settings for region access to sun position |
116 | m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay()); | 116 | m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay()); |
117 | 117 | ||
118 | m_frame = 0; | 118 | m_frame = 0; |
119 | } | 119 | } |
120 | 120 | ||
121 | // Hour of the Day figures out the hour of the day as a float. | 121 | // Hour of the Day figures out the hour of the day as a float. |
122 | // The intent here is that we seed hour of the day with real | 122 | // The intent here is that we seed hour of the day with real |
123 | // time when the simulator starts, then run time forward | 123 | // time when the simulator starts, then run time forward |
124 | // faster based on time dilation factor. This means that | 124 | // faster based on time dilation factor. This means that |
125 | // ticks don't get out of hand | 125 | // ticks don't get out of hand |
126 | private double HourOfTheDay() | 126 | private double HourOfTheDay() |
127 | { | 127 | { |
128 | long m_addticks = (DateTime.Now.Ticks - m_start) * m_dilation; | 128 | long m_addticks = (DateTime.Now.Ticks - m_start) * m_dilation; |
129 | DateTime dt = new DateTime(m_start + m_addticks); | 129 | DateTime dt = new DateTime(m_start + m_addticks); |
130 | return (double) dt.Hour + ((double) dt.Minute / 60.0); | 130 | return (double) dt.Hour + ((double) dt.Minute / 60.0); |
131 | } | 131 | } |
132 | 132 | ||
133 | private LLVector3 SunPos(double hour) | 133 | private LLVector3 SunPos(double hour) |
134 | { | 134 | { |
135 | // now we have our radian position | 135 | // now we have our radian position |
136 | double rad = (hour / m_real_day) * 2 * Math.PI - (Math.PI / 2.0); | 136 | double rad = (hour / m_real_day) * 2 * Math.PI - (Math.PI / 2.0); |
137 | double z = Math.Sin(rad); | 137 | double z = Math.Sin(rad); |
138 | double x = Math.Cos(rad); | 138 | double x = Math.Cos(rad); |
139 | return new LLVector3((float) x, 0f, (float) z); | 139 | return new LLVector3((float) x, 0f, (float) z); |
140 | } | 140 | } |
141 | 141 | ||
142 | // TODO: clear this out. This is here so that I remember to | 142 | // TODO: clear this out. This is here so that I remember to |
143 | // figure out if we need those other packet fields that I've | 143 | // figure out if we need those other packet fields that I've |
144 | // left out so far | 144 | // left out so far |
145 | // | 145 | // |
146 | // public void SendViewerTime(int phase) | 146 | // public void SendViewerTime(int phase) |
147 | // { | 147 | // { |
148 | // Console.WriteLine("SunPhase: {0}", phase); | 148 | // Console.WriteLine("SunPhase: {0}", phase); |
149 | // SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket(); | 149 | // SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket(); |
150 | // //viewertime.TimeInfo.SecPerDay = 86400; | 150 | // //viewertime.TimeInfo.SecPerDay = 86400; |
151 | // // viewertime.TimeInfo.SecPerYear = 31536000; | 151 | // // viewertime.TimeInfo.SecPerYear = 31536000; |
152 | // viewertime.TimeInfo.SecPerDay = 1000; | 152 | // viewertime.TimeInfo.SecPerDay = 1000; |
153 | // viewertime.TimeInfo.SecPerYear = 365000; | 153 | // viewertime.TimeInfo.SecPerYear = 365000; |
154 | // viewertime.TimeInfo.SunPhase = 1; | 154 | // viewertime.TimeInfo.SunPhase = 1; |
155 | // int sunPhase = (phase + 2)/2; | 155 | // int sunPhase = (phase + 2)/2; |
156 | // if ((sunPhase < 6) || (sunPhase > 36)) | 156 | // if ((sunPhase < 6) || (sunPhase > 36)) |
157 | // { | 157 | // { |
158 | // viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f); | 158 | // viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f); |
159 | // Console.WriteLine("sending night"); | 159 | // Console.WriteLine("sending night"); |
160 | // } | 160 | // } |
161 | // else | 161 | // else |
162 | // { | 162 | // { |
163 | // if (sunPhase < 12) | 163 | // if (sunPhase < 12) |
164 | // { | 164 | // { |
165 | // sunPhase = 12; | 165 | // sunPhase = 12; |
166 | // } | 166 | // } |
167 | // sunPhase = sunPhase - 12; | 167 | // sunPhase = sunPhase - 12; |
168 | // | 168 | // |
169 | // float yValue = 0.1f*(sunPhase); | 169 | // float yValue = 0.1f*(sunPhase); |
170 | // Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue); | 170 | // Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue); |
171 | // if (yValue > 1.2f) | 171 | // if (yValue > 1.2f) |
172 | // { | 172 | // { |
173 | // yValue = yValue - 1.2f; | 173 | // yValue = yValue - 1.2f; |
174 | // } | 174 | // } |
175 | // if (yValue > 1) | 175 | // if (yValue > 1) |
176 | // { | 176 | // { |
177 | // yValue = 1; | 177 | // yValue = 1; |
178 | // } | 178 | // } |
179 | // if (yValue < 0) | 179 | // if (yValue < 0) |
180 | // { | 180 | // { |
181 | // yValue = 0; | 181 | // yValue = 0; |
182 | // } | 182 | // } |
183 | // if (sunPhase < 14) | 183 | // if (sunPhase < 14) |
184 | // { | 184 | // { |
185 | // yValue = 1 - yValue; | 185 | // yValue = 1 - yValue; |
186 | // } | 186 | // } |
187 | // if (sunPhase < 12) | 187 | // if (sunPhase < 12) |
188 | // { | 188 | // { |
189 | // yValue *= -1; | 189 | // yValue *= -1; |
190 | // } | 190 | // } |
191 | // viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f); | 191 | // viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f); |
192 | // Console.WriteLine("sending sun update " + yValue); | 192 | // Console.WriteLine("sending sun update " + yValue); |
193 | // } | 193 | // } |
194 | // viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f); | 194 | // viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f); |
195 | // viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch(); | 195 | // viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch(); |
196 | // // OutPacket(viewertime); | 196 | // // OutPacket(viewertime); |
197 | // } | 197 | // } |
198 | } | 198 | } |
199 | } \ No newline at end of file | 199 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs index 731326e..a2e0c40 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/CookieCutter.cs | |||
@@ -1,124 +1,124 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes; | 29 | using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes; |
30 | using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; | 30 | using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; |
31 | 31 | ||
32 | namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects | 32 | namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects |
33 | { | 33 | { |
34 | internal class CookieCutter : ITerrainEffect | 34 | internal class CookieCutter : ITerrainEffect |
35 | { | 35 | { |
36 | #region ITerrainEffect Members | 36 | #region ITerrainEffect Members |
37 | 37 | ||
38 | public void RunEffect(ITerrainChannel map) | 38 | public void RunEffect(ITerrainChannel map) |
39 | { | 39 | { |
40 | SmoothArea smooth = new SmoothArea(); | 40 | SmoothArea smooth = new SmoothArea(); |
41 | ITerrainPaintableEffect eroder = new WeatherSphere(); | 41 | ITerrainPaintableEffect eroder = new WeatherSphere(); |
42 | 42 | ||
43 | bool[,] cliffMask = new bool[map.Width,map.Height]; | 43 | bool[,] cliffMask = new bool[map.Width,map.Height]; |
44 | bool[,] channelMask = new bool[map.Width,map.Height]; | 44 | bool[,] channelMask = new bool[map.Width,map.Height]; |
45 | bool[,] smoothMask = new bool[map.Width,map.Height]; | 45 | bool[,] smoothMask = new bool[map.Width,map.Height]; |
46 | 46 | ||
47 | Console.WriteLine("S1"); | 47 | Console.WriteLine("S1"); |
48 | 48 | ||
49 | // Step one, generate rough mask | 49 | // Step one, generate rough mask |
50 | int x, y; | 50 | int x, y; |
51 | for (x = 0; x < map.Width; x++) | 51 | for (x = 0; x < map.Width; x++) |
52 | { | 52 | { |
53 | for (y = 0; y < map.Height; y++) | 53 | for (y = 0; y < map.Height; y++) |
54 | { | 54 | { |
55 | Console.Write("."); | 55 | Console.Write("."); |
56 | smoothMask[x, y] = true; | 56 | smoothMask[x, y] = true; |
57 | 57 | ||
58 | // Start underwater | 58 | // Start underwater |
59 | map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5; | 59 | map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5; |
60 | // Add a little height. (terrain should now be above water, mostly.) | 60 | // Add a little height. (terrain should now be above water, mostly.) |
61 | map[x, y] += 20; | 61 | map[x, y] += 20; |
62 | 62 | ||
63 | int channelsX = 4; | 63 | int channelsX = 4; |
64 | int channelWidth = (map.Width / channelsX / 4); | 64 | int channelWidth = (map.Width / channelsX / 4); |
65 | int channelsY = 4; | 65 | int channelsY = 4; |
66 | int channelHeight = (map.Height / channelsY / 4); | 66 | int channelHeight = (map.Height / channelsY / 4); |
67 | 67 | ||
68 | SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x); | 68 | SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x); |
69 | SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y); | 69 | SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y); |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | Console.WriteLine("S2"); | 73 | Console.WriteLine("S2"); |
74 | //smooth.FloodEffect(map, smoothMask, 4.0); | 74 | //smooth.FloodEffect(map, smoothMask, 4.0); |
75 | 75 | ||
76 | Console.WriteLine("S3"); | 76 | Console.WriteLine("S3"); |
77 | for (x = 0; x < map.Width; x++) | 77 | for (x = 0; x < map.Width; x++) |
78 | { | 78 | { |
79 | for (y = 0; y < map.Height; y++) | 79 | for (y = 0; y < map.Height; y++) |
80 | { | 80 | { |
81 | if (cliffMask[x, y] == true) | 81 | if (cliffMask[x, y] == true) |
82 | eroder.PaintEffect(map, x, y, 4, 0.1); | 82 | eroder.PaintEffect(map, x, y, 4, 0.1); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | for (x = 0; x < map.Width; x += 2) | 86 | for (x = 0; x < map.Width; x += 2) |
87 | { | 87 | { |
88 | for (y = 0; y < map.Height; y += 2) | 88 | for (y = 0; y < map.Height; y += 2) |
89 | { | 89 | { |
90 | if (map[x, y] < 0.1) | 90 | if (map[x, y] < 0.1) |
91 | map[x, y] = 0.1; | 91 | map[x, y] = 0.1; |
92 | if (map[x, y] > 256) | 92 | if (map[x, y] > 256) |
93 | map[x, y] = 256; | 93 | map[x, y] = 256; |
94 | } | 94 | } |
95 | } | 95 | } |
96 | //smooth.FloodEffect(map, smoothMask, 4.0); | 96 | //smooth.FloodEffect(map, smoothMask, 4.0); |
97 | } | 97 | } |
98 | 98 | ||
99 | #endregion | 99 | #endregion |
100 | 100 | ||
101 | private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth, | 101 | private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth, |
102 | int mapSize, int rp) | 102 | int mapSize, int rp) |
103 | { | 103 | { |
104 | for (int i = 0; i < numChannels; i++) | 104 | for (int i = 0; i < numChannels; i++) |
105 | { | 105 | { |
106 | double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i)); | 106 | double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i)); |
107 | 107 | ||
108 | if (distanceToLine < channelWidth) | 108 | if (distanceToLine < channelWidth) |
109 | { | 109 | { |
110 | if (channelMask[x, y]) | 110 | if (channelMask[x, y]) |
111 | return; | 111 | return; |
112 | 112 | ||
113 | // Remove channels | 113 | // Remove channels |
114 | map[x, y] -= 10; | 114 | map[x, y] -= 10; |
115 | channelMask[x, y] = true; | 115 | channelMask[x, y] = true; |
116 | } | 116 | } |
117 | if (distanceToLine < 1) | 117 | if (distanceToLine < 1) |
118 | { | 118 | { |
119 | cliffMask[x, y] = true; | 119 | cliffMask[x, y] = true; |
120 | } | 120 | } |
121 | } | 121 | } |
122 | } | 122 | } |
123 | } | 123 | } |
124 | } \ No newline at end of file | 124 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs index 9c35d4e..5bc6799 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/Effects/DefaultTerrainGenerator.cs | |||
@@ -1,55 +1,55 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using OpenSim.Framework; | 27 | using OpenSim.Framework; |
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects |
31 | { | 31 | { |
32 | internal class DefaultTerrainGenerator : ITerrainEffect | 32 | internal class DefaultTerrainGenerator : ITerrainEffect |
33 | { | 33 | { |
34 | #region ITerrainEffect Members | 34 | #region ITerrainEffect Members |
35 | 35 | ||
36 | public void RunEffect(ITerrainChannel map) | 36 | public void RunEffect(ITerrainChannel map) |
37 | { | 37 | { |
38 | int x, y; | 38 | int x, y; |
39 | for (x = 0; x < map.Width; x++) | 39 | for (x = 0; x < map.Width; x++) |
40 | { | 40 | { |
41 | for (y = 0; y < map.Height; y++) | 41 | for (y = 0; y < map.Height; y++) |
42 | { | 42 | { |
43 | map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; | 43 | map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; |
44 | double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01; | 44 | double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01; |
45 | if (map[x, y] < spherFac) | 45 | if (map[x, y] < spherFac) |
46 | { | 46 | { |
47 | map[x, y] = spherFac; | 47 | map[x, y] = spherFac; |
48 | } | 48 | } |
49 | } | 49 | } |
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | #endregion | 53 | #endregion |
54 | } | 54 | } |
55 | } \ No newline at end of file | 55 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs index 4705dad..eb981d9 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs | |||
@@ -1,62 +1,62 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System.Drawing; | 27 | using System.Drawing; |
28 | using System.Drawing.Imaging; | 28 | using System.Drawing.Imaging; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
32 | { | 32 | { |
33 | /// <summary> | 33 | /// <summary> |
34 | /// A generic windows bitmap loader. | 34 | /// A generic windows bitmap loader. |
35 | /// Should be capable of handling 24-bit RGB images. | 35 | /// Should be capable of handling 24-bit RGB images. |
36 | /// | 36 | /// |
37 | /// Uses the System.Drawing filesystem loader. | 37 | /// Uses the System.Drawing filesystem loader. |
38 | /// </summary> | 38 | /// </summary> |
39 | internal class BMP : GenericSystemDrawing | 39 | internal class BMP : GenericSystemDrawing |
40 | { | 40 | { |
41 | /// <summary> | 41 | /// <summary> |
42 | /// Exports a file to a image on the disk using a System.Drawing exporter. | 42 | /// Exports a file to a image on the disk using a System.Drawing exporter. |
43 | /// </summary> | 43 | /// </summary> |
44 | /// <param name="filename">The target filename</param> | 44 | /// <param name="filename">The target filename</param> |
45 | /// <param name="map">The terrain channel being saved</param> | 45 | /// <param name="map">The terrain channel being saved</param> |
46 | public override void SaveFile(string filename, ITerrainChannel map) | 46 | public override void SaveFile(string filename, ITerrainChannel map) |
47 | { | 47 | { |
48 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); | 48 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); |
49 | 49 | ||
50 | colours.Save(filename, ImageFormat.Bmp); | 50 | colours.Save(filename, ImageFormat.Bmp); |
51 | } | 51 | } |
52 | 52 | ||
53 | /// <summary> | 53 | /// <summary> |
54 | /// The human readable version of the file format(s) this loader handles | 54 | /// The human readable version of the file format(s) this loader handles |
55 | /// </summary> | 55 | /// </summary> |
56 | /// <returns></returns> | 56 | /// <returns></returns> |
57 | public override string ToString() | 57 | public override string ToString() |
58 | { | 58 | { |
59 | return "BMP"; | 59 | return "BMP"; |
60 | } | 60 | } |
61 | } | 61 | } |
62 | } \ No newline at end of file | 62 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs index 9c2fedc..9bfe851 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs | |||
@@ -1,47 +1,47 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System.Drawing; | 27 | using System.Drawing; |
28 | using System.Drawing.Imaging; | 28 | using System.Drawing.Imaging; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
32 | { | 32 | { |
33 | internal class GIF : GenericSystemDrawing | 33 | internal class GIF : GenericSystemDrawing |
34 | { | 34 | { |
35 | public override void SaveFile(string filename, ITerrainChannel map) | 35 | public override void SaveFile(string filename, ITerrainChannel map) |
36 | { | 36 | { |
37 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); | 37 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); |
38 | 38 | ||
39 | colours.Save(filename, ImageFormat.Gif); | 39 | colours.Save(filename, ImageFormat.Gif); |
40 | } | 40 | } |
41 | 41 | ||
42 | public override string ToString() | 42 | public override string ToString() |
43 | { | 43 | { |
44 | return "GIF"; | 44 | return "GIF"; |
45 | } | 45 | } |
46 | } | 46 | } |
47 | } \ No newline at end of file | 47 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index b5e6bd9..9730b16 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs | |||
@@ -1,172 +1,172 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using System.Drawing.Imaging; | 30 | using System.Drawing.Imaging; |
31 | using OpenSim.Region.Environment.Interfaces; | 31 | using OpenSim.Region.Environment.Interfaces; |
32 | 32 | ||
33 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 33 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
34 | { | 34 | { |
35 | /// <summary> | 35 | /// <summary> |
36 | /// A virtual class designed to have methods overloaded, | 36 | /// A virtual class designed to have methods overloaded, |
37 | /// this class provides an interface for a generic image | 37 | /// this class provides an interface for a generic image |
38 | /// saving and loading mechanism, but does not specify the | 38 | /// saving and loading mechanism, but does not specify the |
39 | /// format. It should not be insubstantiated directly. | 39 | /// format. It should not be insubstantiated directly. |
40 | /// </summary> | 40 | /// </summary> |
41 | public class GenericSystemDrawing : ITerrainLoader | 41 | public class GenericSystemDrawing : ITerrainLoader |
42 | { | 42 | { |
43 | #region ITerrainLoader Members | 43 | #region ITerrainLoader Members |
44 | 44 | ||
45 | public string FileExtension | 45 | public string FileExtension |
46 | { | 46 | { |
47 | get { return ".gsd"; } | 47 | get { return ".gsd"; } |
48 | } | 48 | } |
49 | 49 | ||
50 | /// <summary> | 50 | /// <summary> |
51 | /// Loads a file from a specified filename on the disk, | 51 | /// Loads a file from a specified filename on the disk, |
52 | /// parses the image using the System.Drawing parsers | 52 | /// parses the image using the System.Drawing parsers |
53 | /// then returns a terrain channel. Values are | 53 | /// then returns a terrain channel. Values are |
54 | /// returned based on HSL brightness between 0m and 128m | 54 | /// returned based on HSL brightness between 0m and 128m |
55 | /// </summary> | 55 | /// </summary> |
56 | /// <param name="filename">The target image to load</param> | 56 | /// <param name="filename">The target image to load</param> |
57 | /// <returns>A terrain channel generated from the image.</returns> | 57 | /// <returns>A terrain channel generated from the image.</returns> |
58 | public virtual ITerrainChannel LoadFile(string filename) | 58 | public virtual ITerrainChannel LoadFile(string filename) |
59 | { | 59 | { |
60 | Bitmap file = new Bitmap(filename); | 60 | Bitmap file = new Bitmap(filename); |
61 | 61 | ||
62 | ITerrainChannel retval = new TerrainChannel(file.Width, file.Height); | 62 | ITerrainChannel retval = new TerrainChannel(file.Width, file.Height); |
63 | 63 | ||
64 | int x, y; | 64 | int x, y; |
65 | for (x = 0; x < file.Width; x++) | 65 | for (x = 0; x < file.Width; x++) |
66 | { | 66 | { |
67 | for (y = 0; y < file.Height; y++) | 67 | for (y = 0; y < file.Height; y++) |
68 | { | 68 | { |
69 | retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128; | 69 | retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128; |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | return retval; | 73 | return retval; |
74 | } | 74 | } |
75 | 75 | ||
76 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | 76 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) |
77 | { | 77 | { |
78 | throw new NotImplementedException(); | 78 | throw new NotImplementedException(); |
79 | } | 79 | } |
80 | 80 | ||
81 | /// <summary> | 81 | /// <summary> |
82 | /// Exports a file to a image on the disk using a System.Drawing exporter. | 82 | /// Exports a file to a image on the disk using a System.Drawing exporter. |
83 | /// </summary> | 83 | /// </summary> |
84 | /// <param name="filename">The target filename</param> | 84 | /// <param name="filename">The target filename</param> |
85 | /// <param name="map">The terrain channel being saved</param> | 85 | /// <param name="map">The terrain channel being saved</param> |
86 | public virtual void SaveFile(string filename, ITerrainChannel map) | 86 | public virtual void SaveFile(string filename, ITerrainChannel map) |
87 | { | 87 | { |
88 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); | 88 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); |
89 | 89 | ||
90 | colours.Save(filename, ImageFormat.Png); | 90 | colours.Save(filename, ImageFormat.Png); |
91 | } | 91 | } |
92 | 92 | ||
93 | #endregion | 93 | #endregion |
94 | 94 | ||
95 | public override string ToString() | 95 | public override string ToString() |
96 | { | 96 | { |
97 | return "SYS.DRAWING"; | 97 | return "SYS.DRAWING"; |
98 | } | 98 | } |
99 | 99 | ||
100 | /// <summary> | 100 | /// <summary> |
101 | /// Protected method, generates a grayscale bitmap | 101 | /// Protected method, generates a grayscale bitmap |
102 | /// image from a specified terrain channel. | 102 | /// image from a specified terrain channel. |
103 | /// </summary> | 103 | /// </summary> |
104 | /// <param name="map">The terrain channel to export to bitmap</param> | 104 | /// <param name="map">The terrain channel to export to bitmap</param> |
105 | /// <returns>A System.Drawing.Bitmap containing a grayscale image</returns> | 105 | /// <returns>A System.Drawing.Bitmap containing a grayscale image</returns> |
106 | protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map) | 106 | protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map) |
107 | { | 107 | { |
108 | Bitmap bmp = new Bitmap(map.Width, map.Height); | 108 | Bitmap bmp = new Bitmap(map.Width, map.Height); |
109 | 109 | ||
110 | int pallete = 256; | 110 | int pallete = 256; |
111 | 111 | ||
112 | Color[] grays = new Color[pallete]; | 112 | Color[] grays = new Color[pallete]; |
113 | for (int i = 0; i < grays.Length; i++) | 113 | for (int i = 0; i < grays.Length; i++) |
114 | { | 114 | { |
115 | grays[i] = Color.FromArgb(i, i, i); | 115 | grays[i] = Color.FromArgb(i, i, i); |
116 | } | 116 | } |
117 | 117 | ||
118 | for (int y = 0; y < map.Height; y++) | 118 | for (int y = 0; y < map.Height; y++) |
119 | { | 119 | { |
120 | for (int x = 0; x < map.Width; x++) | 120 | for (int x = 0; x < map.Width; x++) |
121 | { | 121 | { |
122 | // 512 is the largest possible height before colours clamp | 122 | // 512 is the largest possible height before colours clamp |
123 | int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 128.0), 0.0) * (pallete - 1)); | 123 | int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 128.0), 0.0) * (pallete - 1)); |
124 | 124 | ||
125 | // Handle error conditions | 125 | // Handle error conditions |
126 | if (colorindex > pallete - 1 || colorindex < 0) | 126 | if (colorindex > pallete - 1 || colorindex < 0) |
127 | bmp.SetPixel(x, map.Height - y - 1, Color.Red); | 127 | bmp.SetPixel(x, map.Height - y - 1, Color.Red); |
128 | else | 128 | else |
129 | bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]); | 129 | bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | return bmp; | 132 | return bmp; |
133 | } | 133 | } |
134 | 134 | ||
135 | /// <summary> | 135 | /// <summary> |
136 | /// Protected method, generates a coloured bitmap | 136 | /// Protected method, generates a coloured bitmap |
137 | /// image from a specified terrain channel. | 137 | /// image from a specified terrain channel. |
138 | /// </summary> | 138 | /// </summary> |
139 | /// <param name="map">The terrain channel to export to bitmap</param> | 139 | /// <param name="map">The terrain channel to export to bitmap</param> |
140 | /// <returns>A System.Drawing.Bitmap containing a coloured image</returns> | 140 | /// <returns>A System.Drawing.Bitmap containing a coloured image</returns> |
141 | protected Bitmap CreateBitmapFromMap(ITerrainChannel map) | 141 | protected Bitmap CreateBitmapFromMap(ITerrainChannel map) |
142 | { | 142 | { |
143 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); | 143 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); |
144 | 144 | ||
145 | int pallete = gradientmapLd.Height; | 145 | int pallete = gradientmapLd.Height; |
146 | 146 | ||
147 | Bitmap bmp = new Bitmap(map.Width, map.Height); | 147 | Bitmap bmp = new Bitmap(map.Width, map.Height); |
148 | Color[] colours = new Color[pallete]; | 148 | Color[] colours = new Color[pallete]; |
149 | 149 | ||
150 | for (int i = 0; i < pallete; i++) | 150 | for (int i = 0; i < pallete; i++) |
151 | { | 151 | { |
152 | colours[i] = gradientmapLd.GetPixel(0, i); | 152 | colours[i] = gradientmapLd.GetPixel(0, i); |
153 | } | 153 | } |
154 | 154 | ||
155 | for (int y = 0; y < map.Height; y++) | 155 | for (int y = 0; y < map.Height; y++) |
156 | { | 156 | { |
157 | for (int x = 0; x < map.Width; x++) | 157 | for (int x = 0; x < map.Width; x++) |
158 | { | 158 | { |
159 | // 512 is the largest possible height before colours clamp | 159 | // 512 is the largest possible height before colours clamp |
160 | int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1)); | 160 | int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1)); |
161 | 161 | ||
162 | // Handle error conditions | 162 | // Handle error conditions |
163 | if (colorindex > pallete - 1 || colorindex < 0) | 163 | if (colorindex > pallete - 1 || colorindex < 0) |
164 | bmp.SetPixel(x, map.Height - y - 1, Color.Red); | 164 | bmp.SetPixel(x, map.Height - y - 1, Color.Red); |
165 | else | 165 | else |
166 | bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]); | 166 | bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]); |
167 | } | 167 | } |
168 | } | 168 | } |
169 | return bmp; | 169 | return bmp; |
170 | } | 170 | } |
171 | } | 171 | } |
172 | } \ No newline at end of file | 172 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs index 39ade10..d58926e 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs | |||
@@ -1,94 +1,94 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using System.Drawing.Imaging; | 30 | using System.Drawing.Imaging; |
31 | using OpenSim.Region.Environment.Interfaces; | 31 | using OpenSim.Region.Environment.Interfaces; |
32 | 32 | ||
33 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 33 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
34 | { | 34 | { |
35 | public class JPEG : ITerrainLoader | 35 | public class JPEG : ITerrainLoader |
36 | { | 36 | { |
37 | #region ITerrainLoader Members | 37 | #region ITerrainLoader Members |
38 | 38 | ||
39 | public string FileExtension | 39 | public string FileExtension |
40 | { | 40 | { |
41 | get { return ".jpg"; } | 41 | get { return ".jpg"; } |
42 | } | 42 | } |
43 | 43 | ||
44 | public ITerrainChannel LoadFile(string filename) | 44 | public ITerrainChannel LoadFile(string filename) |
45 | { | 45 | { |
46 | throw new NotImplementedException(); | 46 | throw new NotImplementedException(); |
47 | } | 47 | } |
48 | 48 | ||
49 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | 49 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) |
50 | { | 50 | { |
51 | throw new NotImplementedException(); | 51 | throw new NotImplementedException(); |
52 | } | 52 | } |
53 | 53 | ||
54 | public void SaveFile(string filename, ITerrainChannel map) | 54 | public void SaveFile(string filename, ITerrainChannel map) |
55 | { | 55 | { |
56 | Bitmap colours = CreateBitmapFromMap(map); | 56 | Bitmap colours = CreateBitmapFromMap(map); |
57 | 57 | ||
58 | colours.Save(filename, ImageFormat.Jpeg); | 58 | colours.Save(filename, ImageFormat.Jpeg); |
59 | } | 59 | } |
60 | 60 | ||
61 | #endregion | 61 | #endregion |
62 | 62 | ||
63 | public override string ToString() | 63 | public override string ToString() |
64 | { | 64 | { |
65 | return "JPEG"; | 65 | return "JPEG"; |
66 | } | 66 | } |
67 | 67 | ||
68 | private Bitmap CreateBitmapFromMap(ITerrainChannel map) | 68 | private Bitmap CreateBitmapFromMap(ITerrainChannel map) |
69 | { | 69 | { |
70 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); | 70 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); |
71 | 71 | ||
72 | int pallete = gradientmapLd.Height; | 72 | int pallete = gradientmapLd.Height; |
73 | 73 | ||
74 | Bitmap bmp = new Bitmap(map.Width, map.Height); | 74 | Bitmap bmp = new Bitmap(map.Width, map.Height); |
75 | Color[] colours = new Color[pallete]; | 75 | Color[] colours = new Color[pallete]; |
76 | 76 | ||
77 | for (int i = 0; i < pallete; i++) | 77 | for (int i = 0; i < pallete; i++) |
78 | { | 78 | { |
79 | colours[i] = gradientmapLd.GetPixel(0, i); | 79 | colours[i] = gradientmapLd.GetPixel(0, i); |
80 | } | 80 | } |
81 | 81 | ||
82 | for (int y = 0; y < map.Height; y++) | 82 | for (int y = 0; y < map.Height; y++) |
83 | { | 83 | { |
84 | for (int x = 0; x < map.Width; x++) | 84 | for (int x = 0; x < map.Width; x++) |
85 | { | 85 | { |
86 | // 512 is the largest possible height before colours clamp | 86 | // 512 is the largest possible height before colours clamp |
87 | int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1)); | 87 | int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1)); |
88 | bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]); | 88 | bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]); |
89 | } | 89 | } |
90 | } | 90 | } |
91 | return bmp; | 91 | return bmp; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | } \ No newline at end of file | 94 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs index 468ecc9..5d6723f 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs | |||
@@ -1,148 +1,148 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using OpenSim.Region.Environment.Interfaces; | 30 | using OpenSim.Region.Environment.Interfaces; |
31 | 31 | ||
32 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 32 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
33 | { | 33 | { |
34 | public class LLRAW : ITerrainLoader | 34 | public class LLRAW : ITerrainLoader |
35 | { | 35 | { |
36 | #region ITerrainLoader Members | 36 | #region ITerrainLoader Members |
37 | 37 | ||
38 | public ITerrainChannel LoadFile(string filename) | 38 | public ITerrainChannel LoadFile(string filename) |
39 | { | 39 | { |
40 | TerrainChannel retval = new TerrainChannel(); | 40 | TerrainChannel retval = new TerrainChannel(); |
41 | 41 | ||
42 | FileInfo file = new FileInfo(filename); | 42 | FileInfo file = new FileInfo(filename); |
43 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); | 43 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); |
44 | BinaryReader bs = new BinaryReader(s); | 44 | BinaryReader bs = new BinaryReader(s); |
45 | int x, y; | 45 | int x, y; |
46 | for (y = 0; y < retval.Height; y++) | 46 | for (y = 0; y < retval.Height; y++) |
47 | { | 47 | { |
48 | for (x = 0; x < retval.Width; x++) | 48 | for (x = 0; x < retval.Width; x++) |
49 | { | 49 | { |
50 | retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0); | 50 | retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0); |
51 | bs.ReadBytes(11); // Advance the stream to next bytes. | 51 | bs.ReadBytes(11); // Advance the stream to next bytes. |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | bs.Close(); | 55 | bs.Close(); |
56 | s.Close(); | 56 | s.Close(); |
57 | 57 | ||
58 | return retval; | 58 | return retval; |
59 | } | 59 | } |
60 | 60 | ||
61 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | 61 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) |
62 | { | 62 | { |
63 | throw new NotImplementedException(); | 63 | throw new NotImplementedException(); |
64 | } | 64 | } |
65 | 65 | ||
66 | public void SaveFile(string filename, ITerrainChannel map) | 66 | public void SaveFile(string filename, ITerrainChannel map) |
67 | { | 67 | { |
68 | FileInfo file = new FileInfo(filename); | 68 | FileInfo file = new FileInfo(filename); |
69 | FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); | 69 | FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); |
70 | BinaryWriter binStream = new BinaryWriter(s); | 70 | BinaryWriter binStream = new BinaryWriter(s); |
71 | 71 | ||
72 | // Generate a smegging big lookup table to speed the operation up (it needs it) | 72 | // Generate a smegging big lookup table to speed the operation up (it needs it) |
73 | double[] lookupHeightTable = new double[65536]; | 73 | double[] lookupHeightTable = new double[65536]; |
74 | int i, j, x, y; | 74 | int i, j, x, y; |
75 | for (i = 0; i < 256; i++) | 75 | for (i = 0; i < 256; i++) |
76 | { | 76 | { |
77 | for (j = 0; j < 256; j++) | 77 | for (j = 0; j < 256; j++) |
78 | { | 78 | { |
79 | lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0)); | 79 | lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0)); |
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | // Output the calculated raw | 83 | // Output the calculated raw |
84 | for (y = 0; y < map.Height; y++) | 84 | for (y = 0; y < map.Height; y++) |
85 | { | 85 | { |
86 | for (x = 0; x < map.Width; x++) | 86 | for (x = 0; x < map.Width; x++) |
87 | { | 87 | { |
88 | double t = map[x, y]; | 88 | double t = map[x, y]; |
89 | double min = double.MaxValue; | 89 | double min = double.MaxValue; |
90 | int index = 0; | 90 | int index = 0; |
91 | 91 | ||
92 | for (i = 0; i < 65536; i++) | 92 | for (i = 0; i < 65536; i++) |
93 | { | 93 | { |
94 | if (Math.Abs(t - lookupHeightTable[i]) < min) | 94 | if (Math.Abs(t - lookupHeightTable[i]) < min) |
95 | { | 95 | { |
96 | min = Math.Abs(t - lookupHeightTable[i]); | 96 | min = Math.Abs(t - lookupHeightTable[i]); |
97 | index = i; | 97 | index = i; |
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | byte red = (byte) (index & 0xFF); | 101 | byte red = (byte) (index & 0xFF); |
102 | byte green = (byte) ((index >> 8) & 0xFF); | 102 | byte green = (byte) ((index >> 8) & 0xFF); |
103 | byte blue = 20; | 103 | byte blue = 20; |
104 | byte alpha1 = 0; // Land Parcels | 104 | byte alpha1 = 0; // Land Parcels |
105 | byte alpha2 = 0; // For Sale Land | 105 | byte alpha2 = 0; // For Sale Land |
106 | byte alpha3 = 0; // Public Edit Object | 106 | byte alpha3 = 0; // Public Edit Object |
107 | byte alpha4 = 0; // Public Edit Land | 107 | byte alpha4 = 0; // Public Edit Land |
108 | byte alpha5 = 255; // Safe Land | 108 | byte alpha5 = 255; // Safe Land |
109 | byte alpha6 = 255; // Flying Allowed | 109 | byte alpha6 = 255; // Flying Allowed |
110 | byte alpha7 = 255; // Create Landmark | 110 | byte alpha7 = 255; // Create Landmark |
111 | byte alpha8 = 255; // Outside Scripts | 111 | byte alpha8 = 255; // Outside Scripts |
112 | byte alpha9 = red; | 112 | byte alpha9 = red; |
113 | byte alpha10 = green; | 113 | byte alpha10 = green; |
114 | 114 | ||
115 | binStream.Write(red); | 115 | binStream.Write(red); |
116 | binStream.Write(green); | 116 | binStream.Write(green); |
117 | binStream.Write(blue); | 117 | binStream.Write(blue); |
118 | binStream.Write(alpha1); | 118 | binStream.Write(alpha1); |
119 | binStream.Write(alpha2); | 119 | binStream.Write(alpha2); |
120 | binStream.Write(alpha3); | 120 | binStream.Write(alpha3); |
121 | binStream.Write(alpha4); | 121 | binStream.Write(alpha4); |
122 | binStream.Write(alpha5); | 122 | binStream.Write(alpha5); |
123 | binStream.Write(alpha6); | 123 | binStream.Write(alpha6); |
124 | binStream.Write(alpha7); | 124 | binStream.Write(alpha7); |
125 | binStream.Write(alpha8); | 125 | binStream.Write(alpha8); |
126 | binStream.Write(alpha9); | 126 | binStream.Write(alpha9); |
127 | binStream.Write(alpha10); | 127 | binStream.Write(alpha10); |
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
131 | binStream.Close(); | 131 | binStream.Close(); |
132 | s.Close(); | 132 | s.Close(); |
133 | } | 133 | } |
134 | 134 | ||
135 | 135 | ||
136 | public string FileExtension | 136 | public string FileExtension |
137 | { | 137 | { |
138 | get { return ".raw"; } | 138 | get { return ".raw"; } |
139 | } | 139 | } |
140 | 140 | ||
141 | #endregion | 141 | #endregion |
142 | 142 | ||
143 | public override string ToString() | 143 | public override string ToString() |
144 | { | 144 | { |
145 | return "LL/SL RAW"; | 145 | return "LL/SL RAW"; |
146 | } | 146 | } |
147 | } | 147 | } |
148 | } \ No newline at end of file | 148 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs index 2925c7d..b893f70 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs | |||
@@ -1,47 +1,47 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System.Drawing; | 27 | using System.Drawing; |
28 | using System.Drawing.Imaging; | 28 | using System.Drawing.Imaging; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
32 | { | 32 | { |
33 | internal class PNG : GenericSystemDrawing | 33 | internal class PNG : GenericSystemDrawing |
34 | { | 34 | { |
35 | public override void SaveFile(string filename, ITerrainChannel map) | 35 | public override void SaveFile(string filename, ITerrainChannel map) |
36 | { | 36 | { |
37 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); | 37 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); |
38 | 38 | ||
39 | colours.Save(filename, ImageFormat.Png); | 39 | colours.Save(filename, ImageFormat.Png); |
40 | } | 40 | } |
41 | 41 | ||
42 | public override string ToString() | 42 | public override string ToString() |
43 | { | 43 | { |
44 | return "PNG"; | 44 | return "PNG"; |
45 | } | 45 | } |
46 | } | 46 | } |
47 | } \ No newline at end of file | 47 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs index 71f56c5..fd2136c 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs | |||
@@ -1,153 +1,153 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.IO; | 28 | using System.IO; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
32 | { | 32 | { |
33 | public class RAW32 : ITerrainLoader | 33 | public class RAW32 : ITerrainLoader |
34 | { | 34 | { |
35 | #region ITerrainLoader Members | 35 | #region ITerrainLoader Members |
36 | 36 | ||
37 | public string FileExtension | 37 | public string FileExtension |
38 | { | 38 | { |
39 | get { return ".r32"; } | 39 | get { return ".r32"; } |
40 | } | 40 | } |
41 | 41 | ||
42 | public ITerrainChannel LoadFile(string filename) | 42 | public ITerrainChannel LoadFile(string filename) |
43 | { | 43 | { |
44 | TerrainChannel retval = new TerrainChannel(); | 44 | TerrainChannel retval = new TerrainChannel(); |
45 | 45 | ||
46 | FileInfo file = new FileInfo(filename); | 46 | FileInfo file = new FileInfo(filename); |
47 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); | 47 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); |
48 | BinaryReader bs = new BinaryReader(s); | 48 | BinaryReader bs = new BinaryReader(s); |
49 | int x, y; | 49 | int x, y; |
50 | for (y = 0; y < retval.Height; y++) | 50 | for (y = 0; y < retval.Height; y++) |
51 | { | 51 | { |
52 | for (x = 0; x < retval.Width; x++) | 52 | for (x = 0; x < retval.Width; x++) |
53 | { | 53 | { |
54 | retval[x, y] = bs.ReadSingle(); | 54 | retval[x, y] = bs.ReadSingle(); |
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | bs.Close(); | 58 | bs.Close(); |
59 | s.Close(); | 59 | s.Close(); |
60 | 60 | ||
61 | return retval; | 61 | return retval; |
62 | } | 62 | } |
63 | 63 | ||
64 | public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight) | 64 | public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight) |
65 | { | 65 | { |
66 | TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight); | 66 | TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight); |
67 | 67 | ||
68 | FileInfo file = new FileInfo(filename); | 68 | FileInfo file = new FileInfo(filename); |
69 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); | 69 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); |
70 | BinaryReader bs = new BinaryReader(s); | 70 | BinaryReader bs = new BinaryReader(s); |
71 | 71 | ||
72 | int currFileXOffset = 0; | 72 | int currFileXOffset = 0; |
73 | int currFileYOffset = 0; | 73 | int currFileYOffset = 0; |
74 | 74 | ||
75 | // if our region isn't on the first Y section of the areas to be landscaped, then | 75 | // if our region isn't on the first Y section of the areas to be landscaped, then |
76 | // advance to our section of the file | 76 | // advance to our section of the file |
77 | while (currFileYOffset < offsetY) | 77 | while (currFileYOffset < offsetY) |
78 | { | 78 | { |
79 | // read a whole strip of regions | 79 | // read a whole strip of regions |
80 | int heightsToRead = sectionHeight * (fileWidth * sectionWidth); | 80 | int heightsToRead = sectionHeight * (fileWidth * sectionWidth); |
81 | bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file | 81 | bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file |
82 | currFileYOffset++; | 82 | currFileYOffset++; |
83 | } | 83 | } |
84 | 84 | ||
85 | // got to the Y start offset within the file of our region | 85 | // got to the Y start offset within the file of our region |
86 | // so read the file bits associated with our region | 86 | // so read the file bits associated with our region |
87 | int x, y; | 87 | int x, y; |
88 | // for each Y within our Y offset | 88 | // for each Y within our Y offset |
89 | for (y = 0; y < sectionHeight; y++) | 89 | for (y = 0; y < sectionHeight; y++) |
90 | { | 90 | { |
91 | currFileXOffset = 0; | 91 | currFileXOffset = 0; |
92 | 92 | ||
93 | // if our region isn't the first X section of the areas to be landscaped, then | 93 | // if our region isn't the first X section of the areas to be landscaped, then |
94 | // advance the stream to the X start pos of our section in the file | 94 | // advance the stream to the X start pos of our section in the file |
95 | // i.e. eat X upto where we start | 95 | // i.e. eat X upto where we start |
96 | while (currFileXOffset < offsetX) | 96 | while (currFileXOffset < offsetX) |
97 | { | 97 | { |
98 | bs.ReadBytes(sectionWidth * 4); // 4 bytes = single | 98 | bs.ReadBytes(sectionWidth * 4); // 4 bytes = single |
99 | currFileXOffset++; | 99 | currFileXOffset++; |
100 | } | 100 | } |
101 | 101 | ||
102 | // got to our X offset, so write our regions X line | 102 | // got to our X offset, so write our regions X line |
103 | for (x = 0; x < sectionWidth; x++) | 103 | for (x = 0; x < sectionWidth; x++) |
104 | { | 104 | { |
105 | // Read a strip and continue | 105 | // Read a strip and continue |
106 | retval[x, y] = bs.ReadSingle(); | 106 | retval[x, y] = bs.ReadSingle(); |
107 | } | 107 | } |
108 | // record that we wrote it | 108 | // record that we wrote it |
109 | currFileXOffset++; | 109 | currFileXOffset++; |
110 | 110 | ||
111 | // if our region isn't the last X section of the areas to be landscaped, then | 111 | // if our region isn't the last X section of the areas to be landscaped, then |
112 | // advance the stream to the end of this Y column | 112 | // advance the stream to the end of this Y column |
113 | while (currFileXOffset < fileWidth) | 113 | while (currFileXOffset < fileWidth) |
114 | { | 114 | { |
115 | // eat the next regions x line | 115 | // eat the next regions x line |
116 | bs.ReadBytes(sectionWidth * 4); // 4 bytes = single | 116 | bs.ReadBytes(sectionWidth * 4); // 4 bytes = single |
117 | currFileXOffset++; | 117 | currFileXOffset++; |
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
121 | bs.Close(); | 121 | bs.Close(); |
122 | s.Close(); | 122 | s.Close(); |
123 | 123 | ||
124 | return retval; | 124 | return retval; |
125 | } | 125 | } |
126 | 126 | ||
127 | public void SaveFile(string filename, ITerrainChannel map) | 127 | public void SaveFile(string filename, ITerrainChannel map) |
128 | { | 128 | { |
129 | FileInfo file = new FileInfo(filename); | 129 | FileInfo file = new FileInfo(filename); |
130 | FileStream s = file.Open(FileMode.Create, FileAccess.Write); | 130 | FileStream s = file.Open(FileMode.Create, FileAccess.Write); |
131 | BinaryWriter bs = new BinaryWriter(s); | 131 | BinaryWriter bs = new BinaryWriter(s); |
132 | 132 | ||
133 | int x, y; | 133 | int x, y; |
134 | for (y = 0; y < map.Height; y++) | 134 | for (y = 0; y < map.Height; y++) |
135 | { | 135 | { |
136 | for (x = 0; x < map.Width; x++) | 136 | for (x = 0; x < map.Width; x++) |
137 | { | 137 | { |
138 | bs.Write((float) map[x, y]); | 138 | bs.Write((float) map[x, y]); |
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | bs.Close(); | 142 | bs.Close(); |
143 | s.Close(); | 143 | s.Close(); |
144 | } | 144 | } |
145 | 145 | ||
146 | #endregion | 146 | #endregion |
147 | 147 | ||
148 | public override string ToString() | 148 | public override string ToString() |
149 | { | 149 | { |
150 | return "RAW32"; | 150 | return "RAW32"; |
151 | } | 151 | } |
152 | } | 152 | } |
153 | } \ No newline at end of file | 153 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs index 3a137ae..c081aea 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs | |||
@@ -1,47 +1,47 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System.Drawing; | 27 | using System.Drawing; |
28 | using System.Drawing.Imaging; | 28 | using System.Drawing.Imaging; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
32 | { | 32 | { |
33 | internal class TIFF : GenericSystemDrawing | 33 | internal class TIFF : GenericSystemDrawing |
34 | { | 34 | { |
35 | public override void SaveFile(string filename, ITerrainChannel map) | 35 | public override void SaveFile(string filename, ITerrainChannel map) |
36 | { | 36 | { |
37 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); | 37 | Bitmap colours = CreateGrayscaleBitmapFromMap(map); |
38 | 38 | ||
39 | colours.Save(filename, ImageFormat.Tiff); | 39 | colours.Save(filename, ImageFormat.Tiff); |
40 | } | 40 | } |
41 | 41 | ||
42 | public override string ToString() | 42 | public override string ToString() |
43 | { | 43 | { |
44 | return "TIFF"; | 44 | return "TIFF"; |
45 | } | 45 | } |
46 | } | 46 | } |
47 | } \ No newline at end of file | 47 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs index f2672ad..7cb4b00 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs | |||
@@ -1,127 +1,127 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Text; | 30 | using System.Text; |
31 | using OpenSim.Region.Environment.Interfaces; | 31 | using OpenSim.Region.Environment.Interfaces; |
32 | 32 | ||
33 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders | 33 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders |
34 | { | 34 | { |
35 | /// <summary> | 35 | /// <summary> |
36 | /// Terragen File Format Loader | 36 | /// Terragen File Format Loader |
37 | /// Built from specification at | 37 | /// Built from specification at |
38 | /// http://www.planetside.co.uk/terragen/dev/tgterrain.html | 38 | /// http://www.planetside.co.uk/terragen/dev/tgterrain.html |
39 | /// </summary> | 39 | /// </summary> |
40 | internal class Terragen : ITerrainLoader | 40 | internal class Terragen : ITerrainLoader |
41 | { | 41 | { |
42 | #region ITerrainLoader Members | 42 | #region ITerrainLoader Members |
43 | 43 | ||
44 | public ITerrainChannel LoadFile(string filename) | 44 | public ITerrainChannel LoadFile(string filename) |
45 | { | 45 | { |
46 | TerrainChannel retval = new TerrainChannel(); | 46 | TerrainChannel retval = new TerrainChannel(); |
47 | 47 | ||
48 | FileInfo file = new FileInfo(filename); | 48 | FileInfo file = new FileInfo(filename); |
49 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); | 49 | FileStream s = file.Open(FileMode.Open, FileAccess.Read); |
50 | BinaryReader bs = new BinaryReader(s); | 50 | BinaryReader bs = new BinaryReader(s); |
51 | 51 | ||
52 | bool eof = false; | 52 | bool eof = false; |
53 | if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") | 53 | if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") |
54 | { | 54 | { |
55 | // Terragen file | 55 | // Terragen file |
56 | while (eof == false) | 56 | while (eof == false) |
57 | { | 57 | { |
58 | int w = 256; | 58 | int w = 256; |
59 | int h = 256; | 59 | int h = 256; |
60 | string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4)); | 60 | string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4)); |
61 | switch (tmp) | 61 | switch (tmp) |
62 | { | 62 | { |
63 | case "SIZE": | 63 | case "SIZE": |
64 | int sztmp = bs.ReadInt16() + 1; | 64 | int sztmp = bs.ReadInt16() + 1; |
65 | w = sztmp; | 65 | w = sztmp; |
66 | h = sztmp; | 66 | h = sztmp; |
67 | bs.ReadInt16(); | 67 | bs.ReadInt16(); |
68 | break; | 68 | break; |
69 | case "XPTS": | 69 | case "XPTS": |
70 | w = bs.ReadInt16(); | 70 | w = bs.ReadInt16(); |
71 | bs.ReadInt16(); | 71 | bs.ReadInt16(); |
72 | break; | 72 | break; |
73 | case "YPTS": | 73 | case "YPTS": |
74 | h = bs.ReadInt16(); | 74 | h = bs.ReadInt16(); |
75 | bs.ReadInt16(); | 75 | bs.ReadInt16(); |
76 | break; | 76 | break; |
77 | case "ALTW": | 77 | case "ALTW": |
78 | eof = true; | 78 | eof = true; |
79 | Int16 heightScale = bs.ReadInt16(); | 79 | Int16 heightScale = bs.ReadInt16(); |
80 | Int16 baseHeight = bs.ReadInt16(); | 80 | Int16 baseHeight = bs.ReadInt16(); |
81 | retval = new TerrainChannel(w, h); | 81 | retval = new TerrainChannel(w, h); |
82 | int x, y; | 82 | int x, y; |
83 | for (x = 0; x < w; x++) | 83 | for (x = 0; x < w; x++) |
84 | { | 84 | { |
85 | for (y = 0; y < h; y++) | 85 | for (y = 0; y < h; y++) |
86 | { | 86 | { |
87 | retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0; | 87 | retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0; |
88 | } | 88 | } |
89 | } | 89 | } |
90 | break; | 90 | break; |
91 | default: | 91 | default: |
92 | bs.ReadInt32(); | 92 | bs.ReadInt32(); |
93 | break; | 93 | break; |
94 | } | 94 | } |
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | bs.Close(); | 98 | bs.Close(); |
99 | s.Close(); | 99 | s.Close(); |
100 | 100 | ||
101 | return retval; | 101 | return retval; |
102 | } | 102 | } |
103 | 103 | ||
104 | public void SaveFile(string filename, ITerrainChannel map) | 104 | public void SaveFile(string filename, ITerrainChannel map) |
105 | { | 105 | { |
106 | char[] header = "TERRAGENTERRAIN".ToCharArray(); | 106 | char[] header = "TERRAGENTERRAIN".ToCharArray(); |
107 | throw new NotImplementedException(); | 107 | throw new NotImplementedException(); |
108 | } | 108 | } |
109 | 109 | ||
110 | public string FileExtension | 110 | public string FileExtension |
111 | { | 111 | { |
112 | get { return ".ter"; } | 112 | get { return ".ter"; } |
113 | } | 113 | } |
114 | 114 | ||
115 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) | 115 | public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) |
116 | { | 116 | { |
117 | throw new NotImplementedException(); | 117 | throw new NotImplementedException(); |
118 | } | 118 | } |
119 | 119 | ||
120 | #endregion | 120 | #endregion |
121 | 121 | ||
122 | public override string ToString() | 122 | public override string ToString() |
123 | { | 123 | { |
124 | return "Terragen"; | 124 | return "Terragen"; |
125 | } | 125 | } |
126 | } | 126 | } |
127 | } \ No newline at end of file | 127 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs index 7bf81d3..496da63 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/FlattenArea.cs | |||
@@ -1,71 +1,71 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes |
31 | { | 31 | { |
32 | public class FlattenArea : ITerrainFloodEffect | 32 | public class FlattenArea : ITerrainFloodEffect |
33 | { | 33 | { |
34 | #region ITerrainFloodEffect Members | 34 | #region ITerrainFloodEffect Members |
35 | 35 | ||
36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) | 36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) |
37 | { | 37 | { |
38 | double sum = 0.0; | 38 | double sum = 0.0; |
39 | double steps = 0.0; | 39 | double steps = 0.0; |
40 | double avg; | 40 | double avg; |
41 | 41 | ||
42 | int x, y; | 42 | int x, y; |
43 | for (x = 0; x < map.Width; x++) | 43 | for (x = 0; x < map.Width; x++) |
44 | { | 44 | { |
45 | for (y = 0; y < map.Height; y++) | 45 | for (y = 0; y < map.Height; y++) |
46 | { | 46 | { |
47 | if (fillArea[x, y]) | 47 | if (fillArea[x, y]) |
48 | { | 48 | { |
49 | sum += map[x, y]; | 49 | sum += map[x, y]; |
50 | steps += 1.0; | 50 | steps += 1.0; |
51 | } | 51 | } |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | avg = sum / steps; | 55 | avg = sum / steps; |
56 | 56 | ||
57 | double str = 0.1 * strength; // == 0.2 in the default client | 57 | double str = 0.1 * strength; // == 0.2 in the default client |
58 | 58 | ||
59 | for (x = 0; x < map.Width; x++) | 59 | for (x = 0; x < map.Width; x++) |
60 | { | 60 | { |
61 | for (y = 0; y < map.Height; y++) | 61 | for (y = 0; y < map.Height; y++) |
62 | { | 62 | { |
63 | if (fillArea[x, y]) | 63 | if (fillArea[x, y]) |
64 | map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str); | 64 | map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str); |
65 | } | 65 | } |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
69 | #endregion | 69 | #endregion |
70 | } | 70 | } |
71 | } \ No newline at end of file | 71 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs index a7a4431..3646d61 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/LowerArea.cs | |||
@@ -1,54 +1,54 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes |
31 | { | 31 | { |
32 | public class LowerArea : ITerrainFloodEffect | 32 | public class LowerArea : ITerrainFloodEffect |
33 | { | 33 | { |
34 | #region ITerrainFloodEffect Members | 34 | #region ITerrainFloodEffect Members |
35 | 35 | ||
36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) | 36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) |
37 | { | 37 | { |
38 | int x; | 38 | int x; |
39 | for (x = 0; x < map.Width; x++) | 39 | for (x = 0; x < map.Width; x++) |
40 | { | 40 | { |
41 | int y; | 41 | int y; |
42 | for (y = 0; y < map.Height; y++) | 42 | for (y = 0; y < map.Height; y++) |
43 | { | 43 | { |
44 | if (fillArea[x, y]) | 44 | if (fillArea[x, y]) |
45 | { | 45 | { |
46 | map[x, y] -= strength; | 46 | map[x, y] -= strength; |
47 | } | 47 | } |
48 | } | 48 | } |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | #endregion | 52 | #endregion |
53 | } | 53 | } |
54 | } \ No newline at end of file | 54 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs index 3da3826..6c8e76e 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/NoiseArea.cs | |||
@@ -1,56 +1,56 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Framework; | 28 | using OpenSim.Framework; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes |
32 | { | 32 | { |
33 | public class NoiseArea : ITerrainFloodEffect | 33 | public class NoiseArea : ITerrainFloodEffect |
34 | { | 34 | { |
35 | #region ITerrainFloodEffect Members | 35 | #region ITerrainFloodEffect Members |
36 | 36 | ||
37 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) | 37 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) |
38 | { | 38 | { |
39 | int x, y; | 39 | int x, y; |
40 | for (x = 0; x < map.Width; x++) | 40 | for (x = 0; x < map.Width; x++) |
41 | { | 41 | { |
42 | for (y = 0; y < map.Height; y++) | 42 | for (y = 0; y < map.Height; y++) |
43 | { | 43 | { |
44 | if (fillArea[x, y]) | 44 | if (fillArea[x, y]) |
45 | { | 45 | { |
46 | double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0); | 46 | double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0); |
47 | 47 | ||
48 | map[x, y] += noise * strength; | 48 | map[x, y] += noise * strength; |
49 | } | 49 | } |
50 | } | 50 | } |
51 | } | 51 | } |
52 | } | 52 | } |
53 | 53 | ||
54 | #endregion | 54 | #endregion |
55 | } | 55 | } |
56 | } \ No newline at end of file | 56 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs index b57caed..5cb236c 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RaiseArea.cs | |||
@@ -1,53 +1,53 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes |
31 | { | 31 | { |
32 | public class RaiseArea : ITerrainFloodEffect | 32 | public class RaiseArea : ITerrainFloodEffect |
33 | { | 33 | { |
34 | #region ITerrainFloodEffect Members | 34 | #region ITerrainFloodEffect Members |
35 | 35 | ||
36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) | 36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) |
37 | { | 37 | { |
38 | int x, y; | 38 | int x, y; |
39 | for (x = 0; x < map.Width; x++) | 39 | for (x = 0; x < map.Width; x++) |
40 | { | 40 | { |
41 | for (y = 0; y < map.Height; y++) | 41 | for (y = 0; y < map.Height; y++) |
42 | { | 42 | { |
43 | if (fillArea[x, y]) | 43 | if (fillArea[x, y]) |
44 | { | 44 | { |
45 | map[x, y] += strength; | 45 | map[x, y] += strength; |
46 | } | 46 | } |
47 | } | 47 | } |
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | #endregion | 51 | #endregion |
52 | } | 52 | } |
53 | } \ No newline at end of file | 53 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs index 76a2cae..f1d9ce6 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/RevertArea.cs | |||
@@ -1,60 +1,60 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes |
31 | { | 31 | { |
32 | public class RevertArea : ITerrainFloodEffect | 32 | public class RevertArea : ITerrainFloodEffect |
33 | { | 33 | { |
34 | private readonly ITerrainChannel m_revertmap; | 34 | private readonly ITerrainChannel m_revertmap; |
35 | 35 | ||
36 | public RevertArea(ITerrainChannel revertmap) | 36 | public RevertArea(ITerrainChannel revertmap) |
37 | { | 37 | { |
38 | m_revertmap = revertmap; | 38 | m_revertmap = revertmap; |
39 | } | 39 | } |
40 | 40 | ||
41 | #region ITerrainFloodEffect Members | 41 | #region ITerrainFloodEffect Members |
42 | 42 | ||
43 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) | 43 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) |
44 | { | 44 | { |
45 | int x, y; | 45 | int x, y; |
46 | for (x = 0; x < map.Width; x++) | 46 | for (x = 0; x < map.Width; x++) |
47 | { | 47 | { |
48 | for (y = 0; y < map.Height; y++) | 48 | for (y = 0; y < map.Height; y++) |
49 | { | 49 | { |
50 | if (fillArea[x, y]) | 50 | if (fillArea[x, y]) |
51 | { | 51 | { |
52 | map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength); | 52 | map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength); |
53 | } | 53 | } |
54 | } | 54 | } |
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | #endregion | 58 | #endregion |
59 | } | 59 | } |
60 | } \ No newline at end of file | 60 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs index bdd9f18..d17d9cb 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FloodBrushes/SmoothArea.cs | |||
@@ -1,114 +1,114 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes |
31 | { | 31 | { |
32 | public class SmoothArea : ITerrainFloodEffect | 32 | public class SmoothArea : ITerrainFloodEffect |
33 | { | 33 | { |
34 | #region ITerrainFloodEffect Members | 34 | #region ITerrainFloodEffect Members |
35 | 35 | ||
36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) | 36 | public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength) |
37 | { | 37 | { |
38 | double area = strength; | 38 | double area = strength; |
39 | double step = strength / 4.0; | 39 | double step = strength / 4.0; |
40 | 40 | ||
41 | double[,] manipulate = new double[map.Width,map.Height]; | 41 | double[,] manipulate = new double[map.Width,map.Height]; |
42 | int x, y; | 42 | int x, y; |
43 | for (x = 0; x < map.Width; x++) | 43 | for (x = 0; x < map.Width; x++) |
44 | { | 44 | { |
45 | for (y = 0; y < map.Height; y++) | 45 | for (y = 0; y < map.Height; y++) |
46 | { | 46 | { |
47 | if (!fillArea[x, y]) | 47 | if (!fillArea[x, y]) |
48 | continue; | 48 | continue; |
49 | 49 | ||
50 | double average = 0.0; | 50 | double average = 0.0; |
51 | int avgsteps = 0; | 51 | int avgsteps = 0; |
52 | 52 | ||
53 | double n; | 53 | double n; |
54 | for (n = 0.0 - area; n < area; n += step) | 54 | for (n = 0.0 - area; n < area; n += step) |
55 | { | 55 | { |
56 | double l; | 56 | double l; |
57 | for (l = 0.0 - area; l < area; l += step) | 57 | for (l = 0.0 - area; l < area; l += step) |
58 | { | 58 | { |
59 | avgsteps++; | 59 | avgsteps++; |
60 | average += GetBilinearInterpolate(x + n, y + l, map); | 60 | average += GetBilinearInterpolate(x + n, y + l, map); |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | manipulate[x, y] = average / avgsteps; | 64 | manipulate[x, y] = average / avgsteps; |
65 | } | 65 | } |
66 | } | 66 | } |
67 | for (x = 0; x < map.Width; x++) | 67 | for (x = 0; x < map.Width; x++) |
68 | { | 68 | { |
69 | for (y = 0; y < map.Height; y++) | 69 | for (y = 0; y < map.Height; y++) |
70 | { | 70 | { |
71 | if (!fillArea[x, y]) | 71 | if (!fillArea[x, y]) |
72 | continue; | 72 | continue; |
73 | 73 | ||
74 | map[x, y] = manipulate[x, y]; | 74 | map[x, y] = manipulate[x, y]; |
75 | } | 75 | } |
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | #endregion | 79 | #endregion |
80 | 80 | ||
81 | private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map) | 81 | private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map) |
82 | { | 82 | { |
83 | int w = map.Width; | 83 | int w = map.Width; |
84 | int h = map.Height; | 84 | int h = map.Height; |
85 | 85 | ||
86 | if (x > w - 2.0) | 86 | if (x > w - 2.0) |
87 | x = w - 2.0; | 87 | x = w - 2.0; |
88 | if (y > h - 2.0) | 88 | if (y > h - 2.0) |
89 | y = h - 2.0; | 89 | y = h - 2.0; |
90 | if (x < 0.0) | 90 | if (x < 0.0) |
91 | x = 0.0; | 91 | x = 0.0; |
92 | if (y < 0.0) | 92 | if (y < 0.0) |
93 | y = 0.0; | 93 | y = 0.0; |
94 | 94 | ||
95 | int stepSize = 1; | 95 | int stepSize = 1; |
96 | double h00 = map[(int) x, (int) y]; | 96 | double h00 = map[(int) x, (int) y]; |
97 | double h10 = map[(int) x + stepSize, (int) y]; | 97 | double h10 = map[(int) x + stepSize, (int) y]; |
98 | double h01 = map[(int) x, (int) y + stepSize]; | 98 | double h01 = map[(int) x, (int) y + stepSize]; |
99 | double h11 = map[(int) x + stepSize, (int) y + stepSize]; | 99 | double h11 = map[(int) x + stepSize, (int) y + stepSize]; |
100 | double h1 = h00; | 100 | double h1 = h00; |
101 | double h2 = h10; | 101 | double h2 = h10; |
102 | double h3 = h01; | 102 | double h3 = h01; |
103 | double h4 = h11; | 103 | double h4 = h11; |
104 | double a00 = h1; | 104 | double a00 = h1; |
105 | double a10 = h2 - h1; | 105 | double a10 = h2 - h1; |
106 | double a01 = h3 - h1; | 106 | double a01 = h3 - h1; |
107 | double a11 = h1 - h2 - h3 + h4; | 107 | double a11 = h1 - h2 - h3 + h4; |
108 | double partialx = x - (int) x; | 108 | double partialx = x - (int) x; |
109 | double partialz = y - (int) y; | 109 | double partialz = y - (int) y; |
110 | double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); | 110 | double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); |
111 | return hi; | 111 | return hi; |
112 | } | 112 | } |
113 | } | 113 | } |
114 | } \ No newline at end of file | 114 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs index 821fc4b..bbbe2a3 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainEffect.cs | |||
@@ -1,36 +1,36 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
31 | { | 31 | { |
32 | public interface ITerrainEffect | 32 | public interface ITerrainEffect |
33 | { | 33 | { |
34 | void RunEffect(ITerrainChannel map); | 34 | void RunEffect(ITerrainChannel map); |
35 | } | 35 | } |
36 | } \ No newline at end of file | 36 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs index 6b0d7f9..9fe93a2 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainFloodEffect.cs | |||
@@ -1,37 +1,37 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
32 | { | 32 | { |
33 | public interface ITerrainFloodEffect | 33 | public interface ITerrainFloodEffect |
34 | { | 34 | { |
35 | void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength); | 35 | void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength); |
36 | } | 36 | } |
37 | } \ No newline at end of file | 37 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs index 6211892..4c16c1c 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs | |||
@@ -1,39 +1,39 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
31 | { | 31 | { |
32 | public interface ITerrainLoader | 32 | public interface ITerrainLoader |
33 | { | 33 | { |
34 | string FileExtension { get; } | 34 | string FileExtension { get; } |
35 | ITerrainChannel LoadFile(string filename); | 35 | ITerrainChannel LoadFile(string filename); |
36 | ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight); | 36 | ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight); |
37 | void SaveFile(string filename, ITerrainChannel map); | 37 | void SaveFile(string filename, ITerrainChannel map); |
38 | } | 38 | } |
39 | } \ No newline at end of file | 39 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs index 756354a..224cc3a 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs | |||
@@ -1,8 +1,8 @@ | |||
1 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 1 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
2 | { | 2 | { |
3 | public interface ITerrainModule | 3 | public interface ITerrainModule |
4 | { | 4 | { |
5 | void LoadFromFile(string filename); | 5 | void LoadFromFile(string filename); |
6 | void SaveToFile(string filename); | 6 | void SaveToFile(string filename); |
7 | } | 7 | } |
8 | } \ No newline at end of file | 8 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs index d73f44d..cf2e58a 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainPaintableEffect.cs | |||
@@ -1,36 +1,36 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
31 | { | 31 | { |
32 | public interface ITerrainPaintableEffect | 32 | public interface ITerrainPaintableEffect |
33 | { | 33 | { |
34 | void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration); | 34 | void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration); |
35 | } | 35 | } |
36 | } \ No newline at end of file | 36 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs index dbaec0f..fe26902 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/MapImageModule.cs | |||
@@ -1,168 +1,168 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using Nini.Config; | 30 | using Nini.Config; |
31 | using OpenJPEGNet; | 31 | using OpenJPEGNet; |
32 | using OpenSim.Region.Environment.Interfaces; | 32 | using OpenSim.Region.Environment.Interfaces; |
33 | using OpenSim.Region.Environment.Scenes; | 33 | using OpenSim.Region.Environment.Scenes; |
34 | 34 | ||
35 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 35 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
36 | { | 36 | { |
37 | internal class MapImageModule : IMapImageGenerator, IRegionModule | 37 | internal class MapImageModule : IMapImageGenerator, IRegionModule |
38 | { | 38 | { |
39 | private Scene m_scene; | 39 | private Scene m_scene; |
40 | 40 | ||
41 | #region IMapImageGenerator Members | 41 | #region IMapImageGenerator Members |
42 | 42 | ||
43 | public byte[] WriteJpeg2000Image(string gradientmap) | 43 | public byte[] WriteJpeg2000Image(string gradientmap) |
44 | { | 44 | { |
45 | byte[] imageData = null; | 45 | byte[] imageData = null; |
46 | 46 | ||
47 | Bitmap bmp = TerrainToBitmap(gradientmap); | 47 | Bitmap bmp = TerrainToBitmap(gradientmap); |
48 | 48 | ||
49 | try | 49 | try |
50 | { | 50 | { |
51 | imageData = OpenJPEG.EncodeFromImage(bmp, true); | 51 | imageData = OpenJPEG.EncodeFromImage(bmp, true); |
52 | } | 52 | } |
53 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | 53 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke |
54 | { | 54 | { |
55 | Console.WriteLine("Failed generating terrain map: " + e); | 55 | Console.WriteLine("Failed generating terrain map: " + e); |
56 | } | 56 | } |
57 | 57 | ||
58 | return imageData; | 58 | return imageData; |
59 | } | 59 | } |
60 | 60 | ||
61 | #endregion | 61 | #endregion |
62 | 62 | ||
63 | #region IRegionModule Members | 63 | #region IRegionModule Members |
64 | 64 | ||
65 | public void Initialise(Scene scene, IConfigSource source) | 65 | public void Initialise(Scene scene, IConfigSource source) |
66 | { | 66 | { |
67 | m_scene = scene; | 67 | m_scene = scene; |
68 | m_scene.RegisterModuleInterface<IMapImageGenerator>(this); | 68 | m_scene.RegisterModuleInterface<IMapImageGenerator>(this); |
69 | } | 69 | } |
70 | 70 | ||
71 | public void PostInitialise() | 71 | public void PostInitialise() |
72 | { | 72 | { |
73 | } | 73 | } |
74 | 74 | ||
75 | public void Close() | 75 | public void Close() |
76 | { | 76 | { |
77 | } | 77 | } |
78 | 78 | ||
79 | public string Name | 79 | public string Name |
80 | { | 80 | { |
81 | get { return "MapImageModule"; } | 81 | get { return "MapImageModule"; } |
82 | } | 82 | } |
83 | 83 | ||
84 | public bool IsSharedModule | 84 | public bool IsSharedModule |
85 | { | 85 | { |
86 | get { return false; } | 86 | get { return false; } |
87 | } | 87 | } |
88 | 88 | ||
89 | #endregion | 89 | #endregion |
90 | 90 | ||
91 | private void ShadeBuildings(ref Bitmap map) | 91 | private void ShadeBuildings(ref Bitmap map) |
92 | { | 92 | { |
93 | lock (map) | 93 | lock (map) |
94 | { | 94 | { |
95 | lock (m_scene.Entities) | 95 | lock (m_scene.Entities) |
96 | { | 96 | { |
97 | foreach (EntityBase entity in m_scene.Entities.Values) | 97 | foreach (EntityBase entity in m_scene.Entities.Values) |
98 | { | 98 | { |
99 | if (entity is SceneObjectGroup) | 99 | if (entity is SceneObjectGroup) |
100 | { | 100 | { |
101 | SceneObjectGroup sog = (SceneObjectGroup) entity; | 101 | SceneObjectGroup sog = (SceneObjectGroup) entity; |
102 | 102 | ||
103 | foreach (SceneObjectPart primitive in sog.Children.Values) | 103 | foreach (SceneObjectPart primitive in sog.Children.Values) |
104 | { | 104 | { |
105 | int x, y, w, h; | 105 | int x, y, w, h; |
106 | x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2)); | 106 | x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2)); |
107 | y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2)); | 107 | y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2)); |
108 | w = (int) primitive.Scale.X; | 108 | w = (int) primitive.Scale.X; |
109 | h = (int) primitive.Scale.Y; | 109 | h = (int) primitive.Scale.Y; |
110 | 110 | ||
111 | int dx; | 111 | int dx; |
112 | for (dx = x; dx < x + w; dx++) | 112 | for (dx = x; dx < x + w; dx++) |
113 | { | 113 | { |
114 | int dy; | 114 | int dy; |
115 | for (dy = y; dy < y + h; dy++) | 115 | for (dy = y; dy < y + h; dy++) |
116 | { | 116 | { |
117 | if (x < 0 || y < 0) | 117 | if (x < 0 || y < 0) |
118 | continue; | 118 | continue; |
119 | if (x >= map.Width || y >= map.Height) | 119 | if (x >= map.Width || y >= map.Height) |
120 | continue; | 120 | continue; |
121 | 121 | ||
122 | map.SetPixel(dx, dy, Color.DarkGray); | 122 | map.SetPixel(dx, dy, Color.DarkGray); |
123 | } | 123 | } |
124 | } | 124 | } |
125 | } | 125 | } |
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | private Bitmap TerrainToBitmap(string gradientmap) | 132 | private Bitmap TerrainToBitmap(string gradientmap) |
133 | { | 133 | { |
134 | Bitmap gradientmapLd = new Bitmap(gradientmap); | 134 | Bitmap gradientmapLd = new Bitmap(gradientmap); |
135 | 135 | ||
136 | int pallete = gradientmapLd.Height; | 136 | int pallete = gradientmapLd.Height; |
137 | 137 | ||
138 | Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height); | 138 | Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height); |
139 | Color[] colours = new Color[pallete]; | 139 | Color[] colours = new Color[pallete]; |
140 | 140 | ||
141 | for (int i = 0; i < pallete; i++) | 141 | for (int i = 0; i < pallete; i++) |
142 | { | 142 | { |
143 | colours[i] = gradientmapLd.GetPixel(0, i); | 143 | colours[i] = gradientmapLd.GetPixel(0, i); |
144 | } | 144 | } |
145 | 145 | ||
146 | lock (m_scene.Heightmap) | 146 | lock (m_scene.Heightmap) |
147 | { | 147 | { |
148 | ITerrainChannel copy = m_scene.Heightmap; | 148 | ITerrainChannel copy = m_scene.Heightmap; |
149 | for (int y = 0; y < copy.Height; y++) | 149 | for (int y = 0; y < copy.Height; y++) |
150 | { | 150 | { |
151 | for (int x = 0; x < copy.Width; x++) | 151 | for (int x = 0; x < copy.Width; x++) |
152 | { | 152 | { |
153 | // 512 is the largest possible height before colours clamp | 153 | // 512 is the largest possible height before colours clamp |
154 | int colorindex = (int) (Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1)); | 154 | int colorindex = (int) (Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1)); |
155 | 155 | ||
156 | // Handle error conditions | 156 | // Handle error conditions |
157 | if (colorindex > pallete - 1 || colorindex < 0) | 157 | if (colorindex > pallete - 1 || colorindex < 0) |
158 | bmp.SetPixel(x, copy.Height - y - 1, Color.Red); | 158 | bmp.SetPixel(x, copy.Height - y - 1, Color.Red); |
159 | else | 159 | else |
160 | bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]); | 160 | bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]); |
161 | } | 161 | } |
162 | } | 162 | } |
163 | ShadeBuildings(ref bmp); | 163 | ShadeBuildings(ref bmp); |
164 | return bmp; | 164 | return bmp; |
165 | } | 165 | } |
166 | } | 166 | } |
167 | } | 167 | } |
168 | } \ No newline at end of file | 168 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs index 29448aa..e036988 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/ErodeSphere.cs | |||
@@ -1,312 +1,312 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
32 | { | 32 | { |
33 | /// <summary> | 33 | /// <summary> |
34 | /// Hydraulic Erosion Brush | 34 | /// Hydraulic Erosion Brush |
35 | /// </summary> | 35 | /// </summary> |
36 | public class ErodeSphere : ITerrainPaintableEffect | 36 | public class ErodeSphere : ITerrainPaintableEffect |
37 | { | 37 | { |
38 | private double rainHeight = 0.2; | 38 | private double rainHeight = 0.2; |
39 | private int rounds = 10; | 39 | private int rounds = 10; |
40 | private NeighbourSystem type = NeighbourSystem.Moore; // Parameter | 40 | private NeighbourSystem type = NeighbourSystem.Moore; // Parameter |
41 | private double waterSaturation = 0.30; // Can carry 1% of water in height | 41 | private double waterSaturation = 0.30; // Can carry 1% of water in height |
42 | 42 | ||
43 | #region Supporting Functions | 43 | #region Supporting Functions |
44 | 44 | ||
45 | private int[] Neighbours(NeighbourSystem type, int index) | 45 | private int[] Neighbours(NeighbourSystem type, int index) |
46 | { | 46 | { |
47 | int[] coord = new int[2]; | 47 | int[] coord = new int[2]; |
48 | 48 | ||
49 | index++; | 49 | index++; |
50 | 50 | ||
51 | switch (type) | 51 | switch (type) |
52 | { | 52 | { |
53 | case NeighbourSystem.Moore: | 53 | case NeighbourSystem.Moore: |
54 | switch (index) | 54 | switch (index) |
55 | { | 55 | { |
56 | case 1: | 56 | case 1: |
57 | coord[0] = -1; | 57 | coord[0] = -1; |
58 | coord[1] = -1; | 58 | coord[1] = -1; |
59 | break; | 59 | break; |
60 | 60 | ||
61 | case 2: | 61 | case 2: |
62 | coord[0] = -0; | 62 | coord[0] = -0; |
63 | coord[1] = -1; | 63 | coord[1] = -1; |
64 | break; | 64 | break; |
65 | 65 | ||
66 | case 3: | 66 | case 3: |
67 | coord[0] = +1; | 67 | coord[0] = +1; |
68 | coord[1] = -1; | 68 | coord[1] = -1; |
69 | break; | 69 | break; |
70 | 70 | ||
71 | case 4: | 71 | case 4: |
72 | coord[0] = -1; | 72 | coord[0] = -1; |
73 | coord[1] = -0; | 73 | coord[1] = -0; |
74 | break; | 74 | break; |
75 | 75 | ||
76 | case 5: | 76 | case 5: |
77 | coord[0] = -0; | 77 | coord[0] = -0; |
78 | coord[1] = -0; | 78 | coord[1] = -0; |
79 | break; | 79 | break; |
80 | 80 | ||
81 | case 6: | 81 | case 6: |
82 | coord[0] = +1; | 82 | coord[0] = +1; |
83 | coord[1] = -0; | 83 | coord[1] = -0; |
84 | break; | 84 | break; |
85 | 85 | ||
86 | case 7: | 86 | case 7: |
87 | coord[0] = -1; | 87 | coord[0] = -1; |
88 | coord[1] = +1; | 88 | coord[1] = +1; |
89 | break; | 89 | break; |
90 | 90 | ||
91 | case 8: | 91 | case 8: |
92 | coord[0] = -0; | 92 | coord[0] = -0; |
93 | coord[1] = +1; | 93 | coord[1] = +1; |
94 | break; | 94 | break; |
95 | 95 | ||
96 | case 9: | 96 | case 9: |
97 | coord[0] = +1; | 97 | coord[0] = +1; |
98 | coord[1] = +1; | 98 | coord[1] = +1; |
99 | break; | 99 | break; |
100 | 100 | ||
101 | default: | 101 | default: |
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | break; | 104 | break; |
105 | 105 | ||
106 | case NeighbourSystem.VonNeumann: | 106 | case NeighbourSystem.VonNeumann: |
107 | switch (index) | 107 | switch (index) |
108 | { | 108 | { |
109 | case 1: | 109 | case 1: |
110 | coord[0] = 0; | 110 | coord[0] = 0; |
111 | coord[1] = -1; | 111 | coord[1] = -1; |
112 | break; | 112 | break; |
113 | 113 | ||
114 | case 2: | 114 | case 2: |
115 | coord[0] = -1; | 115 | coord[0] = -1; |
116 | coord[1] = 0; | 116 | coord[1] = 0; |
117 | break; | 117 | break; |
118 | 118 | ||
119 | case 3: | 119 | case 3: |
120 | coord[0] = +1; | 120 | coord[0] = +1; |
121 | coord[1] = 0; | 121 | coord[1] = 0; |
122 | break; | 122 | break; |
123 | 123 | ||
124 | case 4: | 124 | case 4: |
125 | coord[0] = 0; | 125 | coord[0] = 0; |
126 | coord[1] = +1; | 126 | coord[1] = +1; |
127 | break; | 127 | break; |
128 | 128 | ||
129 | case 5: | 129 | case 5: |
130 | coord[0] = -0; | 130 | coord[0] = -0; |
131 | coord[1] = -0; | 131 | coord[1] = -0; |
132 | break; | 132 | break; |
133 | 133 | ||
134 | default: | 134 | default: |
135 | break; | 135 | break; |
136 | } | 136 | } |
137 | break; | 137 | break; |
138 | } | 138 | } |
139 | 139 | ||
140 | return coord; | 140 | return coord; |
141 | } | 141 | } |
142 | 142 | ||
143 | private enum NeighbourSystem | 143 | private enum NeighbourSystem |
144 | { | 144 | { |
145 | Moore, | 145 | Moore, |
146 | VonNeumann | 146 | VonNeumann |
147 | } ; | 147 | } ; |
148 | 148 | ||
149 | #endregion | 149 | #endregion |
150 | 150 | ||
151 | #region ITerrainPaintableEffect Members | 151 | #region ITerrainPaintableEffect Members |
152 | 152 | ||
153 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 153 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
154 | { | 154 | { |
155 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 155 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
156 | 156 | ||
157 | int x, y; | 157 | int x, y; |
158 | // Using one 'rain' round for this, so skipping a useless loop | 158 | // Using one 'rain' round for this, so skipping a useless loop |
159 | // Will need to adapt back in for the Flood brush | 159 | // Will need to adapt back in for the Flood brush |
160 | 160 | ||
161 | ITerrainChannel water = new TerrainChannel(map.Width, map.Height); | 161 | ITerrainChannel water = new TerrainChannel(map.Width, map.Height); |
162 | ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height); | 162 | ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height); |
163 | 163 | ||
164 | // Fill with rain | 164 | // Fill with rain |
165 | for (x = 0; x < water.Width; x++) | 165 | for (x = 0; x < water.Width; x++) |
166 | for (y = 0; y < water.Height; y++) | 166 | for (y = 0; y < water.Height; y++) |
167 | water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration); | 167 | water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration); |
168 | 168 | ||
169 | for (int i = 0; i < rounds; i++) | 169 | for (int i = 0; i < rounds; i++) |
170 | { | 170 | { |
171 | // Erode underlying terrain | 171 | // Erode underlying terrain |
172 | for (x = 0; x < water.Width; x++) | 172 | for (x = 0; x < water.Width; x++) |
173 | { | 173 | { |
174 | for (y = 0; y < water.Height; y++) | 174 | for (y = 0; y < water.Height; y++) |
175 | { | 175 | { |
176 | double solConst = (1.0 / rounds); | 176 | double solConst = (1.0 / rounds); |
177 | double sedDelta = water[x, y] * solConst; | 177 | double sedDelta = water[x, y] * solConst; |
178 | map[x, y] -= sedDelta; | 178 | map[x, y] -= sedDelta; |
179 | sediment[x, y] += sedDelta; | 179 | sediment[x, y] += sedDelta; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | // Move water | 183 | // Move water |
184 | for (x = 0; x < water.Width; x++) | 184 | for (x = 0; x < water.Width; x++) |
185 | { | 185 | { |
186 | for (y = 0; y < water.Height; y++) | 186 | for (y = 0; y < water.Height; y++) |
187 | { | 187 | { |
188 | if (water[x, y] <= 0) | 188 | if (water[x, y] <= 0) |
189 | continue; | 189 | continue; |
190 | 190 | ||
191 | // Step 1. Calculate average of neighbours | 191 | // Step 1. Calculate average of neighbours |
192 | 192 | ||
193 | int neighbours = 0; | 193 | int neighbours = 0; |
194 | double altitudeTotal = 0.0; | 194 | double altitudeTotal = 0.0; |
195 | double altitudeMe = map[x, y] + water[x, y]; | 195 | double altitudeMe = map[x, y] + water[x, y]; |
196 | 196 | ||
197 | int NEIGHBOUR_ME = 4; | 197 | int NEIGHBOUR_ME = 4; |
198 | 198 | ||
199 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; | 199 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; |
200 | 200 | ||
201 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 201 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
202 | { | 202 | { |
203 | if (j != NEIGHBOUR_ME) | 203 | if (j != NEIGHBOUR_ME) |
204 | { | 204 | { |
205 | int[] coords = Neighbours(type, j); | 205 | int[] coords = Neighbours(type, j); |
206 | 206 | ||
207 | coords[0] += x; | 207 | coords[0] += x; |
208 | coords[1] += y; | 208 | coords[1] += y; |
209 | 209 | ||
210 | if (coords[0] > map.Width - 1) | 210 | if (coords[0] > map.Width - 1) |
211 | continue; | 211 | continue; |
212 | if (coords[1] > map.Height - 1) | 212 | if (coords[1] > map.Height - 1) |
213 | continue; | 213 | continue; |
214 | if (coords[0] < 0) | 214 | if (coords[0] < 0) |
215 | continue; | 215 | continue; |
216 | if (coords[1] < 0) | 216 | if (coords[1] < 0) |
217 | continue; | 217 | continue; |
218 | 218 | ||
219 | // Calculate total height of this neighbour | 219 | // Calculate total height of this neighbour |
220 | double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]]; | 220 | double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]]; |
221 | 221 | ||
222 | // If it's greater than me... | 222 | // If it's greater than me... |
223 | if (altitudeNeighbour - altitudeMe < 0) | 223 | if (altitudeNeighbour - altitudeMe < 0) |
224 | { | 224 | { |
225 | // Add it to our calculations | 225 | // Add it to our calculations |
226 | neighbours++; | 226 | neighbours++; |
227 | altitudeTotal += altitudeNeighbour; | 227 | altitudeTotal += altitudeNeighbour; |
228 | } | 228 | } |
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | if (neighbours == 0) | 232 | if (neighbours == 0) |
233 | continue; | 233 | continue; |
234 | 234 | ||
235 | double altitudeAvg = altitudeTotal / neighbours; | 235 | double altitudeAvg = altitudeTotal / neighbours; |
236 | 236 | ||
237 | // Step 2. Allocate water to neighbours. | 237 | // Step 2. Allocate water to neighbours. |
238 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 238 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
239 | { | 239 | { |
240 | if (j != NEIGHBOUR_ME) | 240 | if (j != NEIGHBOUR_ME) |
241 | { | 241 | { |
242 | int[] coords = Neighbours(type, j); | 242 | int[] coords = Neighbours(type, j); |
243 | 243 | ||
244 | coords[0] += x; | 244 | coords[0] += x; |
245 | coords[1] += y; | 245 | coords[1] += y; |
246 | 246 | ||
247 | if (coords[0] > map.Width - 1) | 247 | if (coords[0] > map.Width - 1) |
248 | continue; | 248 | continue; |
249 | if (coords[1] > map.Height - 1) | 249 | if (coords[1] > map.Height - 1) |
250 | continue; | 250 | continue; |
251 | if (coords[0] < 0) | 251 | if (coords[0] < 0) |
252 | continue; | 252 | continue; |
253 | if (coords[1] < 0) | 253 | if (coords[1] < 0) |
254 | continue; | 254 | continue; |
255 | 255 | ||
256 | // Skip if we dont have water to begin with. | 256 | // Skip if we dont have water to begin with. |
257 | if (water[x, y] < 0) | 257 | if (water[x, y] < 0) |
258 | continue; | 258 | continue; |
259 | 259 | ||
260 | // Calculate our delta average | 260 | // Calculate our delta average |
261 | double altitudeDelta = altitudeMe - altitudeAvg; | 261 | double altitudeDelta = altitudeMe - altitudeAvg; |
262 | 262 | ||
263 | if (altitudeDelta < 0) | 263 | if (altitudeDelta < 0) |
264 | continue; | 264 | continue; |
265 | 265 | ||
266 | // Calculate how much water we can move | 266 | // Calculate how much water we can move |
267 | double waterMin = Math.Min(water[x, y], altitudeDelta); | 267 | double waterMin = Math.Min(water[x, y], altitudeDelta); |
268 | double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]]) | 268 | double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]]) |
269 | / altitudeTotal); | 269 | / altitudeTotal); |
270 | 270 | ||
271 | double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]); | 271 | double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]); |
272 | 272 | ||
273 | if (sedimentDelta > 0) | 273 | if (sedimentDelta > 0) |
274 | { | 274 | { |
275 | sediment[x, y] -= sedimentDelta; | 275 | sediment[x, y] -= sedimentDelta; |
276 | sediment[coords[0], coords[1]] += sedimentDelta; | 276 | sediment[coords[0], coords[1]] += sedimentDelta; |
277 | } | 277 | } |
278 | } | 278 | } |
279 | } | 279 | } |
280 | } | 280 | } |
281 | } | 281 | } |
282 | 282 | ||
283 | // Evaporate | 283 | // Evaporate |
284 | 284 | ||
285 | for (x = 0; x < water.Width; x++) | 285 | for (x = 0; x < water.Width; x++) |
286 | { | 286 | { |
287 | for (y = 0; y < water.Height; y++) | 287 | for (y = 0; y < water.Height; y++) |
288 | { | 288 | { |
289 | water[x, y] *= 1.0 - (rainHeight / rounds); | 289 | water[x, y] *= 1.0 - (rainHeight / rounds); |
290 | 290 | ||
291 | double waterCapacity = waterSaturation * water[x, y]; | 291 | double waterCapacity = waterSaturation * water[x, y]; |
292 | 292 | ||
293 | double sedimentDeposit = sediment[x, y] - waterCapacity; | 293 | double sedimentDeposit = sediment[x, y] - waterCapacity; |
294 | if (sedimentDeposit > 0) | 294 | if (sedimentDeposit > 0) |
295 | { | 295 | { |
296 | sediment[x, y] -= sedimentDeposit; | 296 | sediment[x, y] -= sedimentDeposit; |
297 | map[x, y] += sedimentDeposit; | 297 | map[x, y] += sedimentDeposit; |
298 | } | 298 | } |
299 | } | 299 | } |
300 | } | 300 | } |
301 | } | 301 | } |
302 | 302 | ||
303 | // Deposit any remainder (should be minimal) | 303 | // Deposit any remainder (should be minimal) |
304 | for (x = 0; x < water.Width; x++) | 304 | for (x = 0; x < water.Width; x++) |
305 | for (y = 0; y < water.Height; y++) | 305 | for (y = 0; y < water.Height; y++) |
306 | if (sediment[x, y] > 0) | 306 | if (sediment[x, y] > 0) |
307 | map[x, y] += sediment[x, y]; | 307 | map[x, y] += sediment[x, y]; |
308 | } | 308 | } |
309 | 309 | ||
310 | #endregion | 310 | #endregion |
311 | } | 311 | } |
312 | } \ No newline at end of file | 312 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs index d4f3b9f..dee455f 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/FlattenSphere.cs | |||
@@ -1,94 +1,94 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
31 | { | 31 | { |
32 | public class FlattenSphere : ITerrainPaintableEffect | 32 | public class FlattenSphere : ITerrainPaintableEffect |
33 | { | 33 | { |
34 | 34 | ||
35 | #region ITerrainPaintableEffect Members | 35 | #region ITerrainPaintableEffect Members |
36 | 36 | ||
37 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 37 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
38 | { | 38 | { |
39 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 39 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
40 | 40 | ||
41 | int x, y; | 41 | int x, y; |
42 | double[,] tweak = new double[map.Width,map.Height]; | 42 | double[,] tweak = new double[map.Width,map.Height]; |
43 | 43 | ||
44 | double area = strength; | 44 | double area = strength; |
45 | double step = strength / 4.0; | 45 | double step = strength / 4.0; |
46 | 46 | ||
47 | double sum = 0.0; | 47 | double sum = 0.0; |
48 | double step2 = 0.0; | 48 | double step2 = 0.0; |
49 | double avg = 0.0; | 49 | double avg = 0.0; |
50 | 50 | ||
51 | // compute delta map | 51 | // compute delta map |
52 | for (x = 0; x < map.Width; x++) | 52 | for (x = 0; x < map.Width; x++) |
53 | { | 53 | { |
54 | for (y = 0; y < map.Height; y++) | 54 | for (y = 0; y < map.Height; y++) |
55 | { | 55 | { |
56 | double z = SphericalFactor(x, y, rx, ry, strength); | 56 | double z = SphericalFactor(x, y, rx, ry, strength); |
57 | 57 | ||
58 | if (z > 0) // add in non-zero amount | 58 | if (z > 0) // add in non-zero amount |
59 | { | 59 | { |
60 | sum += map[x, y] * z; | 60 | sum += map[x, y] * z; |
61 | step2 += z; | 61 | step2 += z; |
62 | } | 62 | } |
63 | } | 63 | } |
64 | } | 64 | } |
65 | 65 | ||
66 | avg = sum / step2; | 66 | avg = sum / step2; |
67 | 67 | ||
68 | // blend in map | 68 | // blend in map |
69 | for (x = 0; x < map.Width; x++) | 69 | for (x = 0; x < map.Width; x++) |
70 | { | 70 | { |
71 | for (y = 0; y < map.Height; y++) | 71 | for (y = 0; y < map.Height; y++) |
72 | { | 72 | { |
73 | double z = SphericalFactor(x, y, rx, ry, strength) * duration; | 73 | double z = SphericalFactor(x, y, rx, ry, strength) * duration; |
74 | 74 | ||
75 | if (z > 0) // add in non-zero amount | 75 | if (z > 0) // add in non-zero amount |
76 | { | 76 | { |
77 | if (z > 1.0) | 77 | if (z > 1.0) |
78 | z = 1.0; | 78 | z = 1.0; |
79 | 79 | ||
80 | map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z); | 80 | map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z); |
81 | } | 81 | } |
82 | } | 82 | } |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | #endregion | 86 | #endregion |
87 | 87 | ||
88 | private double SphericalFactor(double x, double y, double rx, double ry, double size) | 88 | private double SphericalFactor(double x, double y, double rx, double ry, double size) |
89 | { | 89 | { |
90 | double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry)); | 90 | double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry)); |
91 | return z; | 91 | return z; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | } \ No newline at end of file | 94 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs index 0b80407..092bd29 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/LowerSphere.cs | |||
@@ -1,67 +1,67 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
32 | { | 32 | { |
33 | public class LowerSphere : ITerrainPaintableEffect | 33 | public class LowerSphere : ITerrainPaintableEffect |
34 | { | 34 | { |
35 | #region ITerrainPaintableEffect Members | 35 | #region ITerrainPaintableEffect Members |
36 | 36 | ||
37 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 37 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
38 | { | 38 | { |
39 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 39 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
40 | 40 | ||
41 | int x, y; | 41 | int x, y; |
42 | for (x = 0; x < map.Width; x++) | 42 | for (x = 0; x < map.Width; x++) |
43 | { | 43 | { |
44 | // Skip everything unlikely to be affected | 44 | // Skip everything unlikely to be affected |
45 | if (Math.Abs(x - rx) > strength * 1.1) | 45 | if (Math.Abs(x - rx) > strength * 1.1) |
46 | continue; | 46 | continue; |
47 | 47 | ||
48 | for (y = 0; y < map.Height; y++) | 48 | for (y = 0; y < map.Height; y++) |
49 | { | 49 | { |
50 | // Skip everything unlikely to be affected | 50 | // Skip everything unlikely to be affected |
51 | if (Math.Abs(y - ry) > strength * 1.1) | 51 | if (Math.Abs(y - ry) > strength * 1.1) |
52 | continue; | 52 | continue; |
53 | 53 | ||
54 | // Calculate a sphere and add it to the heighmap | 54 | // Calculate a sphere and add it to the heighmap |
55 | double z = strength; | 55 | double z = strength; |
56 | z *= z; | 56 | z *= z; |
57 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); | 57 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); |
58 | 58 | ||
59 | if (z > 0.0) | 59 | if (z > 0.0) |
60 | map[x, y] -= z * duration; | 60 | map[x, y] -= z * duration; |
61 | } | 61 | } |
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
65 | #endregion | 65 | #endregion |
66 | } | 66 | } |
67 | } \ No newline at end of file | 67 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs index a188e9f..8ae583e 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/NoiseSphere.cs | |||
@@ -1,70 +1,70 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Framework; | 29 | using OpenSim.Framework; |
30 | using OpenSim.Region.Environment.Interfaces; | 30 | using OpenSim.Region.Environment.Interfaces; |
31 | 31 | ||
32 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 32 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
33 | { | 33 | { |
34 | public class NoiseSphere : ITerrainPaintableEffect | 34 | public class NoiseSphere : ITerrainPaintableEffect |
35 | { | 35 | { |
36 | #region ITerrainPaintableEffect Members | 36 | #region ITerrainPaintableEffect Members |
37 | 37 | ||
38 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 38 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
39 | { | 39 | { |
40 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 40 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
41 | 41 | ||
42 | int x, y; | 42 | int x, y; |
43 | for (x = 0; x < map.Width; x++) | 43 | for (x = 0; x < map.Width; x++) |
44 | { | 44 | { |
45 | // Skip everything unlikely to be affected | 45 | // Skip everything unlikely to be affected |
46 | if (Math.Abs(x - rx) > strength * 1.1) | 46 | if (Math.Abs(x - rx) > strength * 1.1) |
47 | continue; | 47 | continue; |
48 | 48 | ||
49 | for (y = 0; y < map.Height; y++) | 49 | for (y = 0; y < map.Height; y++) |
50 | { | 50 | { |
51 | // Skip everything unlikely to be affected | 51 | // Skip everything unlikely to be affected |
52 | if (Math.Abs(y - ry) > strength * 1.1) | 52 | if (Math.Abs(y - ry) > strength * 1.1) |
53 | continue; | 53 | continue; |
54 | 54 | ||
55 | // Calculate a sphere and add it to the heighmap | 55 | // Calculate a sphere and add it to the heighmap |
56 | double z = strength; | 56 | double z = strength; |
57 | z *= z; | 57 | z *= z; |
58 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); | 58 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); |
59 | 59 | ||
60 | double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0); | 60 | double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0); |
61 | 61 | ||
62 | if (z > 0.0) | 62 | if (z > 0.0) |
63 | map[x, y] += noise * z * duration; | 63 | map[x, y] += noise * z * duration; |
64 | } | 64 | } |
65 | } | 65 | } |
66 | } | 66 | } |
67 | 67 | ||
68 | #endregion | 68 | #endregion |
69 | } | 69 | } |
70 | } \ No newline at end of file | 70 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs index dc56cf1..ba01a01 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/OlsenSphere.cs | |||
@@ -1,225 +1,225 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
32 | { | 32 | { |
33 | /// <summary> | 33 | /// <summary> |
34 | /// Speed-Optimised Hybrid Erosion Brush | 34 | /// Speed-Optimised Hybrid Erosion Brush |
35 | /// | 35 | /// |
36 | /// As per Jacob Olsen's Paper | 36 | /// As per Jacob Olsen's Paper |
37 | /// http://www.oddlabs.com/download/terrain_generation.pdf | 37 | /// http://www.oddlabs.com/download/terrain_generation.pdf |
38 | /// </summary> | 38 | /// </summary> |
39 | public class OlsenSphere : ITerrainPaintableEffect | 39 | public class OlsenSphere : ITerrainPaintableEffect |
40 | { | 40 | { |
41 | private double nConst = 1024.0; | 41 | private double nConst = 1024.0; |
42 | private NeighbourSystem type = NeighbourSystem.Moore; // Parameter | 42 | private NeighbourSystem type = NeighbourSystem.Moore; // Parameter |
43 | 43 | ||
44 | #region Supporting Functions | 44 | #region Supporting Functions |
45 | 45 | ||
46 | private int[] Neighbours(NeighbourSystem type, int index) | 46 | private int[] Neighbours(NeighbourSystem type, int index) |
47 | { | 47 | { |
48 | int[] coord = new int[2]; | 48 | int[] coord = new int[2]; |
49 | 49 | ||
50 | index++; | 50 | index++; |
51 | 51 | ||
52 | switch (type) | 52 | switch (type) |
53 | { | 53 | { |
54 | case NeighbourSystem.Moore: | 54 | case NeighbourSystem.Moore: |
55 | switch (index) | 55 | switch (index) |
56 | { | 56 | { |
57 | case 1: | 57 | case 1: |
58 | coord[0] = -1; | 58 | coord[0] = -1; |
59 | coord[1] = -1; | 59 | coord[1] = -1; |
60 | break; | 60 | break; |
61 | 61 | ||
62 | case 2: | 62 | case 2: |
63 | coord[0] = -0; | 63 | coord[0] = -0; |
64 | coord[1] = -1; | 64 | coord[1] = -1; |
65 | break; | 65 | break; |
66 | 66 | ||
67 | case 3: | 67 | case 3: |
68 | coord[0] = +1; | 68 | coord[0] = +1; |
69 | coord[1] = -1; | 69 | coord[1] = -1; |
70 | break; | 70 | break; |
71 | 71 | ||
72 | case 4: | 72 | case 4: |
73 | coord[0] = -1; | 73 | coord[0] = -1; |
74 | coord[1] = -0; | 74 | coord[1] = -0; |
75 | break; | 75 | break; |
76 | 76 | ||
77 | case 5: | 77 | case 5: |
78 | coord[0] = -0; | 78 | coord[0] = -0; |
79 | coord[1] = -0; | 79 | coord[1] = -0; |
80 | break; | 80 | break; |
81 | 81 | ||
82 | case 6: | 82 | case 6: |
83 | coord[0] = +1; | 83 | coord[0] = +1; |
84 | coord[1] = -0; | 84 | coord[1] = -0; |
85 | break; | 85 | break; |
86 | 86 | ||
87 | case 7: | 87 | case 7: |
88 | coord[0] = -1; | 88 | coord[0] = -1; |
89 | coord[1] = +1; | 89 | coord[1] = +1; |
90 | break; | 90 | break; |
91 | 91 | ||
92 | case 8: | 92 | case 8: |
93 | coord[0] = -0; | 93 | coord[0] = -0; |
94 | coord[1] = +1; | 94 | coord[1] = +1; |
95 | break; | 95 | break; |
96 | 96 | ||
97 | case 9: | 97 | case 9: |
98 | coord[0] = +1; | 98 | coord[0] = +1; |
99 | coord[1] = +1; | 99 | coord[1] = +1; |
100 | break; | 100 | break; |
101 | 101 | ||
102 | default: | 102 | default: |
103 | break; | 103 | break; |
104 | } | 104 | } |
105 | break; | 105 | break; |
106 | 106 | ||
107 | case NeighbourSystem.VonNeumann: | 107 | case NeighbourSystem.VonNeumann: |
108 | switch (index) | 108 | switch (index) |
109 | { | 109 | { |
110 | case 1: | 110 | case 1: |
111 | coord[0] = 0; | 111 | coord[0] = 0; |
112 | coord[1] = -1; | 112 | coord[1] = -1; |
113 | break; | 113 | break; |
114 | 114 | ||
115 | case 2: | 115 | case 2: |
116 | coord[0] = -1; | 116 | coord[0] = -1; |
117 | coord[1] = 0; | 117 | coord[1] = 0; |
118 | break; | 118 | break; |
119 | 119 | ||
120 | case 3: | 120 | case 3: |
121 | coord[0] = +1; | 121 | coord[0] = +1; |
122 | coord[1] = 0; | 122 | coord[1] = 0; |
123 | break; | 123 | break; |
124 | 124 | ||
125 | case 4: | 125 | case 4: |
126 | coord[0] = 0; | 126 | coord[0] = 0; |
127 | coord[1] = +1; | 127 | coord[1] = +1; |
128 | break; | 128 | break; |
129 | 129 | ||
130 | case 5: | 130 | case 5: |
131 | coord[0] = -0; | 131 | coord[0] = -0; |
132 | coord[1] = -0; | 132 | coord[1] = -0; |
133 | break; | 133 | break; |
134 | 134 | ||
135 | default: | 135 | default: |
136 | break; | 136 | break; |
137 | } | 137 | } |
138 | break; | 138 | break; |
139 | } | 139 | } |
140 | 140 | ||
141 | return coord; | 141 | return coord; |
142 | } | 142 | } |
143 | 143 | ||
144 | private double SphericalFactor(double x, double y, double rx, double ry, double size) | 144 | private double SphericalFactor(double x, double y, double rx, double ry, double size) |
145 | { | 145 | { |
146 | double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry)); | 146 | double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry)); |
147 | return z; | 147 | return z; |
148 | } | 148 | } |
149 | 149 | ||
150 | private enum NeighbourSystem | 150 | private enum NeighbourSystem |
151 | { | 151 | { |
152 | Moore, | 152 | Moore, |
153 | VonNeumann | 153 | VonNeumann |
154 | } ; | 154 | } ; |
155 | 155 | ||
156 | #endregion | 156 | #endregion |
157 | 157 | ||
158 | #region ITerrainPaintableEffect Members | 158 | #region ITerrainPaintableEffect Members |
159 | 159 | ||
160 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 160 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
161 | { | 161 | { |
162 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 162 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
163 | 163 | ||
164 | int x, y; | 164 | int x, y; |
165 | 165 | ||
166 | for (x = 0; x < map.Width; x++) | 166 | for (x = 0; x < map.Width; x++) |
167 | { | 167 | { |
168 | for (y = 0; y < map.Height; y++) | 168 | for (y = 0; y < map.Height; y++) |
169 | { | 169 | { |
170 | double z = SphericalFactor(x, y, rx, ry, strength); | 170 | double z = SphericalFactor(x, y, rx, ry, strength); |
171 | 171 | ||
172 | if (z > 0) // add in non-zero amount | 172 | if (z > 0) // add in non-zero amount |
173 | { | 173 | { |
174 | int NEIGHBOUR_ME = 4; | 174 | int NEIGHBOUR_ME = 4; |
175 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; | 175 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; |
176 | 176 | ||
177 | double max = Double.MinValue; | 177 | double max = Double.MinValue; |
178 | int loc = 0; | 178 | int loc = 0; |
179 | double cellmax = 0; | 179 | double cellmax = 0; |
180 | 180 | ||
181 | 181 | ||
182 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 182 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
183 | { | 183 | { |
184 | if (j != NEIGHBOUR_ME) | 184 | if (j != NEIGHBOUR_ME) |
185 | { | 185 | { |
186 | int[] coords = Neighbours(type, j); | 186 | int[] coords = Neighbours(type, j); |
187 | 187 | ||
188 | coords[0] += x; | 188 | coords[0] += x; |
189 | coords[1] += y; | 189 | coords[1] += y; |
190 | 190 | ||
191 | if (coords[0] > map.Width - 1) | 191 | if (coords[0] > map.Width - 1) |
192 | continue; | 192 | continue; |
193 | if (coords[1] > map.Height - 1) | 193 | if (coords[1] > map.Height - 1) |
194 | continue; | 194 | continue; |
195 | if (coords[0] < 0) | 195 | if (coords[0] < 0) |
196 | continue; | 196 | continue; |
197 | if (coords[1] < 0) | 197 | if (coords[1] < 0) |
198 | continue; | 198 | continue; |
199 | 199 | ||
200 | cellmax = map[x, y] - map[coords[0], coords[1]]; | 200 | cellmax = map[x, y] - map[coords[0], coords[1]]; |
201 | if (cellmax > max) | 201 | if (cellmax > max) |
202 | { | 202 | { |
203 | max = cellmax; | 203 | max = cellmax; |
204 | loc = j; | 204 | loc = j; |
205 | } | 205 | } |
206 | } | 206 | } |
207 | } | 207 | } |
208 | 208 | ||
209 | double T = nConst / ((map.Width + map.Height) / 2); | 209 | double T = nConst / ((map.Width + map.Height) / 2); |
210 | // Apply results | 210 | // Apply results |
211 | if (0 < max && max <= T) | 211 | if (0 < max && max <= T) |
212 | { | 212 | { |
213 | int[] maxCoords = Neighbours(type, loc); | 213 | int[] maxCoords = Neighbours(type, loc); |
214 | double heightDelta = 0.5 * max * z * duration; | 214 | double heightDelta = 0.5 * max * z * duration; |
215 | map[x, y] -= heightDelta; | 215 | map[x, y] -= heightDelta; |
216 | map[x + maxCoords[0], y + maxCoords[1]] += heightDelta; | 216 | map[x + maxCoords[0], y + maxCoords[1]] += heightDelta; |
217 | } | 217 | } |
218 | } | 218 | } |
219 | } | 219 | } |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
223 | #endregion | 223 | #endregion |
224 | } | 224 | } |
225 | } \ No newline at end of file | 225 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs index cd5a22b..5d6f093 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RaiseSphere.cs | |||
@@ -1,67 +1,67 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
32 | { | 32 | { |
33 | public class RaiseSphere : ITerrainPaintableEffect | 33 | public class RaiseSphere : ITerrainPaintableEffect |
34 | { | 34 | { |
35 | #region ITerrainPaintableEffect Members | 35 | #region ITerrainPaintableEffect Members |
36 | 36 | ||
37 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 37 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
38 | { | 38 | { |
39 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 39 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
40 | 40 | ||
41 | int x, y; | 41 | int x, y; |
42 | for (x = 0; x < map.Width; x++) | 42 | for (x = 0; x < map.Width; x++) |
43 | { | 43 | { |
44 | // Skip everything unlikely to be affected | 44 | // Skip everything unlikely to be affected |
45 | if (Math.Abs(x - rx) > strength * 1.1) | 45 | if (Math.Abs(x - rx) > strength * 1.1) |
46 | continue; | 46 | continue; |
47 | 47 | ||
48 | for (y = 0; y < map.Height; y++) | 48 | for (y = 0; y < map.Height; y++) |
49 | { | 49 | { |
50 | // Skip everything unlikely to be affected | 50 | // Skip everything unlikely to be affected |
51 | if (Math.Abs(y - ry) > strength * 1.1) | 51 | if (Math.Abs(y - ry) > strength * 1.1) |
52 | continue; | 52 | continue; |
53 | 53 | ||
54 | // Calculate a sphere and add it to the heighmap | 54 | // Calculate a sphere and add it to the heighmap |
55 | double z = strength; | 55 | double z = strength; |
56 | z *= z; | 56 | z *= z; |
57 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); | 57 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); |
58 | 58 | ||
59 | if (z > 0.0) | 59 | if (z > 0.0) |
60 | map[x, y] += z * duration; | 60 | map[x, y] += z * duration; |
61 | } | 61 | } |
62 | } | 62 | } |
63 | } | 63 | } |
64 | 64 | ||
65 | #endregion | 65 | #endregion |
66 | } | 66 | } |
67 | } \ No newline at end of file | 67 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs index 5b92cb5..b47e041 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/RevertSphere.cs | |||
@@ -1,82 +1,82 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
32 | { | 32 | { |
33 | public class RevertSphere : ITerrainPaintableEffect | 33 | public class RevertSphere : ITerrainPaintableEffect |
34 | { | 34 | { |
35 | private ITerrainChannel m_revertmap; | 35 | private ITerrainChannel m_revertmap; |
36 | 36 | ||
37 | public RevertSphere(ITerrainChannel revertmap) | 37 | public RevertSphere(ITerrainChannel revertmap) |
38 | { | 38 | { |
39 | m_revertmap = revertmap; | 39 | m_revertmap = revertmap; |
40 | } | 40 | } |
41 | 41 | ||
42 | #region ITerrainPaintableEffect Members | 42 | #region ITerrainPaintableEffect Members |
43 | 43 | ||
44 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 44 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
45 | { | 45 | { |
46 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 46 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
47 | 47 | ||
48 | if (duration > 1.0) | 48 | if (duration > 1.0) |
49 | duration = 1.0; | 49 | duration = 1.0; |
50 | if (duration < 0) | 50 | if (duration < 0) |
51 | return; | 51 | return; |
52 | 52 | ||
53 | int x, y; | 53 | int x, y; |
54 | for (x = 0; x < map.Width; x++) | 54 | for (x = 0; x < map.Width; x++) |
55 | { | 55 | { |
56 | // Skip everything unlikely to be affected | 56 | // Skip everything unlikely to be affected |
57 | if (Math.Abs(x - rx) > strength * 1.1) | 57 | if (Math.Abs(x - rx) > strength * 1.1) |
58 | continue; | 58 | continue; |
59 | 59 | ||
60 | for (y = 0; y < map.Height; y++) | 60 | for (y = 0; y < map.Height; y++) |
61 | { | 61 | { |
62 | // Skip everything unlikely to be affected | 62 | // Skip everything unlikely to be affected |
63 | if (Math.Abs(y - ry) > strength * 1.1) | 63 | if (Math.Abs(y - ry) > strength * 1.1) |
64 | continue; | 64 | continue; |
65 | 65 | ||
66 | // Calculate a sphere and add it to the heighmap | 66 | // Calculate a sphere and add it to the heighmap |
67 | double z = strength; | 67 | double z = strength; |
68 | z *= z; | 68 | z *= z; |
69 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); | 69 | z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); |
70 | 70 | ||
71 | if (z > 0.0) | 71 | if (z > 0.0) |
72 | { | 72 | { |
73 | z *= duration; | 73 | z *= duration; |
74 | map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z); | 74 | map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z); |
75 | } | 75 | } |
76 | } | 76 | } |
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | #endregion | 80 | #endregion |
81 | } | 81 | } |
82 | } \ No newline at end of file | 82 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs index 305a875..51d5f0e 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/SmoothSphere.cs | |||
@@ -1,93 +1,93 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
31 | { | 31 | { |
32 | public class SmoothSphere : ITerrainPaintableEffect | 32 | public class SmoothSphere : ITerrainPaintableEffect |
33 | { | 33 | { |
34 | #region ITerrainPaintableEffect Members | 34 | #region ITerrainPaintableEffect Members |
35 | 35 | ||
36 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 36 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
37 | { | 37 | { |
38 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 38 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
39 | 39 | ||
40 | int x, y; | 40 | int x, y; |
41 | double[,] tweak = new double[map.Width,map.Height]; | 41 | double[,] tweak = new double[map.Width,map.Height]; |
42 | 42 | ||
43 | double n, l; | 43 | double n, l; |
44 | double area = strength; | 44 | double area = strength; |
45 | double step = strength / 4.0; | 45 | double step = strength / 4.0; |
46 | 46 | ||
47 | // compute delta map | 47 | // compute delta map |
48 | for (x = 0; x < map.Width; x++) | 48 | for (x = 0; x < map.Width; x++) |
49 | { | 49 | { |
50 | for (y = 0; y < map.Height; y++) | 50 | for (y = 0; y < map.Height; y++) |
51 | { | 51 | { |
52 | double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); | 52 | double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); |
53 | 53 | ||
54 | if (z > 0) // add in non-zero amount | 54 | if (z > 0) // add in non-zero amount |
55 | { | 55 | { |
56 | double average = 0.0; | 56 | double average = 0.0; |
57 | int avgsteps = 0; | 57 | int avgsteps = 0; |
58 | 58 | ||
59 | for (n = 0.0 - area; n < area; n += step) | 59 | for (n = 0.0 - area; n < area; n += step) |
60 | { | 60 | { |
61 | for (l = 0.0 - area; l < area; l += step) | 61 | for (l = 0.0 - area; l < area; l += step) |
62 | { | 62 | { |
63 | avgsteps++; | 63 | avgsteps++; |
64 | average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map); | 64 | average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map); |
65 | } | 65 | } |
66 | } | 66 | } |
67 | tweak[x, y] = average / avgsteps; | 67 | tweak[x, y] = average / avgsteps; |
68 | } | 68 | } |
69 | } | 69 | } |
70 | } | 70 | } |
71 | // blend in map | 71 | // blend in map |
72 | for (x = 0; x < map.Width; x++) | 72 | for (x = 0; x < map.Width; x++) |
73 | { | 73 | { |
74 | for (y = 0; y < map.Height; y++) | 74 | for (y = 0; y < map.Height; y++) |
75 | { | 75 | { |
76 | double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); | 76 | double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); |
77 | 77 | ||
78 | if (z > 0) // add in non-zero amount | 78 | if (z > 0) // add in non-zero amount |
79 | { | 79 | { |
80 | double da = z; | 80 | double da = z; |
81 | double a = (map[x, y] - tweak[x, y]) * da; | 81 | double a = (map[x, y] - tweak[x, y]) * da; |
82 | double newz = map[x, y] - (a * duration); | 82 | double newz = map[x, y] - (a * duration); |
83 | 83 | ||
84 | if (newz > 0.0) | 84 | if (newz > 0.0) |
85 | map[x, y] = newz; | 85 | map[x, y] = newz; |
86 | } | 86 | } |
87 | } | 87 | } |
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | #endregion | 91 | #endregion |
92 | } | 92 | } |
93 | } \ No newline at end of file | 93 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs index 2d81054..b48beb8 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/PaintBrushes/WeatherSphere.cs | |||
@@ -1,207 +1,207 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Region.Environment.Interfaces; | 28 | using OpenSim.Region.Environment.Interfaces; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes |
31 | { | 31 | { |
32 | /// <summary> | 32 | /// <summary> |
33 | /// Thermal Weathering Paint Brush | 33 | /// Thermal Weathering Paint Brush |
34 | /// </summary> | 34 | /// </summary> |
35 | public class WeatherSphere : ITerrainPaintableEffect | 35 | public class WeatherSphere : ITerrainPaintableEffect |
36 | { | 36 | { |
37 | private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required. | 37 | private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required. |
38 | private NeighbourSystem type = NeighbourSystem.Moore; // Parameter | 38 | private NeighbourSystem type = NeighbourSystem.Moore; // Parameter |
39 | 39 | ||
40 | #region Supporting Functions | 40 | #region Supporting Functions |
41 | 41 | ||
42 | private int[] Neighbours(NeighbourSystem type, int index) | 42 | private int[] Neighbours(NeighbourSystem type, int index) |
43 | { | 43 | { |
44 | int[] coord = new int[2]; | 44 | int[] coord = new int[2]; |
45 | 45 | ||
46 | index++; | 46 | index++; |
47 | 47 | ||
48 | switch (type) | 48 | switch (type) |
49 | { | 49 | { |
50 | case NeighbourSystem.Moore: | 50 | case NeighbourSystem.Moore: |
51 | switch (index) | 51 | switch (index) |
52 | { | 52 | { |
53 | case 1: | 53 | case 1: |
54 | coord[0] = -1; | 54 | coord[0] = -1; |
55 | coord[1] = -1; | 55 | coord[1] = -1; |
56 | break; | 56 | break; |
57 | 57 | ||
58 | case 2: | 58 | case 2: |
59 | coord[0] = -0; | 59 | coord[0] = -0; |
60 | coord[1] = -1; | 60 | coord[1] = -1; |
61 | break; | 61 | break; |
62 | 62 | ||
63 | case 3: | 63 | case 3: |
64 | coord[0] = +1; | 64 | coord[0] = +1; |
65 | coord[1] = -1; | 65 | coord[1] = -1; |
66 | break; | 66 | break; |
67 | 67 | ||
68 | case 4: | 68 | case 4: |
69 | coord[0] = -1; | 69 | coord[0] = -1; |
70 | coord[1] = -0; | 70 | coord[1] = -0; |
71 | break; | 71 | break; |
72 | 72 | ||
73 | case 5: | 73 | case 5: |
74 | coord[0] = -0; | 74 | coord[0] = -0; |
75 | coord[1] = -0; | 75 | coord[1] = -0; |
76 | break; | 76 | break; |
77 | 77 | ||
78 | case 6: | 78 | case 6: |
79 | coord[0] = +1; | 79 | coord[0] = +1; |
80 | coord[1] = -0; | 80 | coord[1] = -0; |
81 | break; | 81 | break; |
82 | 82 | ||
83 | case 7: | 83 | case 7: |
84 | coord[0] = -1; | 84 | coord[0] = -1; |
85 | coord[1] = +1; | 85 | coord[1] = +1; |
86 | break; | 86 | break; |
87 | 87 | ||
88 | case 8: | 88 | case 8: |
89 | coord[0] = -0; | 89 | coord[0] = -0; |
90 | coord[1] = +1; | 90 | coord[1] = +1; |
91 | break; | 91 | break; |
92 | 92 | ||
93 | case 9: | 93 | case 9: |
94 | coord[0] = +1; | 94 | coord[0] = +1; |
95 | coord[1] = +1; | 95 | coord[1] = +1; |
96 | break; | 96 | break; |
97 | 97 | ||
98 | default: | 98 | default: |
99 | break; | 99 | break; |
100 | } | 100 | } |
101 | break; | 101 | break; |
102 | 102 | ||
103 | case NeighbourSystem.VonNeumann: | 103 | case NeighbourSystem.VonNeumann: |
104 | switch (index) | 104 | switch (index) |
105 | { | 105 | { |
106 | case 1: | 106 | case 1: |
107 | coord[0] = 0; | 107 | coord[0] = 0; |
108 | coord[1] = -1; | 108 | coord[1] = -1; |
109 | break; | 109 | break; |
110 | 110 | ||
111 | case 2: | 111 | case 2: |
112 | coord[0] = -1; | 112 | coord[0] = -1; |
113 | coord[1] = 0; | 113 | coord[1] = 0; |
114 | break; | 114 | break; |
115 | 115 | ||
116 | case 3: | 116 | case 3: |
117 | coord[0] = +1; | 117 | coord[0] = +1; |
118 | coord[1] = 0; | 118 | coord[1] = 0; |
119 | break; | 119 | break; |
120 | 120 | ||
121 | case 4: | 121 | case 4: |
122 | coord[0] = 0; | 122 | coord[0] = 0; |
123 | coord[1] = +1; | 123 | coord[1] = +1; |
124 | break; | 124 | break; |
125 | 125 | ||
126 | case 5: | 126 | case 5: |
127 | coord[0] = -0; | 127 | coord[0] = -0; |
128 | coord[1] = -0; | 128 | coord[1] = -0; |
129 | break; | 129 | break; |
130 | 130 | ||
131 | default: | 131 | default: |
132 | break; | 132 | break; |
133 | } | 133 | } |
134 | break; | 134 | break; |
135 | } | 135 | } |
136 | 136 | ||
137 | return coord; | 137 | return coord; |
138 | } | 138 | } |
139 | 139 | ||
140 | private enum NeighbourSystem | 140 | private enum NeighbourSystem |
141 | { | 141 | { |
142 | Moore, | 142 | Moore, |
143 | VonNeumann | 143 | VonNeumann |
144 | } ; | 144 | } ; |
145 | 145 | ||
146 | #endregion | 146 | #endregion |
147 | 147 | ||
148 | #region ITerrainPaintableEffect Members | 148 | #region ITerrainPaintableEffect Members |
149 | 149 | ||
150 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) | 150 | public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration) |
151 | { | 151 | { |
152 | strength = TerrainUtil.MetersToSphericalStrength(strength); | 152 | strength = TerrainUtil.MetersToSphericalStrength(strength); |
153 | 153 | ||
154 | int x, y; | 154 | int x, y; |
155 | 155 | ||
156 | for (x = 0; x < map.Width; x++) | 156 | for (x = 0; x < map.Width; x++) |
157 | { | 157 | { |
158 | for (y = 0; y < map.Height; y++) | 158 | for (y = 0; y < map.Height; y++) |
159 | { | 159 | { |
160 | double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); | 160 | double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength); |
161 | 161 | ||
162 | if (z > 0) // add in non-zero amount | 162 | if (z > 0) // add in non-zero amount |
163 | { | 163 | { |
164 | int NEIGHBOUR_ME = 4; | 164 | int NEIGHBOUR_ME = 4; |
165 | 165 | ||
166 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; | 166 | int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; |
167 | 167 | ||
168 | for (int j = 0; j < NEIGHBOUR_MAX; j++) | 168 | for (int j = 0; j < NEIGHBOUR_MAX; j++) |
169 | { | 169 | { |
170 | if (j != NEIGHBOUR_ME) | 170 | if (j != NEIGHBOUR_ME) |
171 | { | 171 | { |
172 | int[] coords = Neighbours(type, j); | 172 | int[] coords = Neighbours(type, j); |
173 | 173 | ||
174 | coords[0] += x; | 174 | coords[0] += x; |
175 | coords[1] += y; | 175 | coords[1] += y; |
176 | 176 | ||
177 | if (coords[0] > map.Width - 1) | 177 | if (coords[0] > map.Width - 1) |
178 | continue; | 178 | continue; |
179 | if (coords[1] > map.Height - 1) | 179 | if (coords[1] > map.Height - 1) |
180 | continue; | 180 | continue; |
181 | if (coords[0] < 0) | 181 | if (coords[0] < 0) |
182 | continue; | 182 | continue; |
183 | if (coords[1] < 0) | 183 | if (coords[1] < 0) |
184 | continue; | 184 | continue; |
185 | 185 | ||
186 | double heightF = map[x, y]; | 186 | double heightF = map[x, y]; |
187 | double target = map[coords[0], coords[1]]; | 187 | double target = map[coords[0], coords[1]]; |
188 | 188 | ||
189 | if (target > heightF + talus) | 189 | if (target > heightF + talus) |
190 | { | 190 | { |
191 | double calc = duration * ((target - heightF) - talus) * z; | 191 | double calc = duration * ((target - heightF) - talus) * z; |
192 | heightF += calc; | 192 | heightF += calc; |
193 | target -= calc; | 193 | target -= calc; |
194 | } | 194 | } |
195 | 195 | ||
196 | map[x, y] = heightF; | 196 | map[x, y] = heightF; |
197 | map[coords[0], coords[1]] = target; | 197 | map[coords[0], coords[1]] = target; |
198 | } | 198 | } |
199 | } | 199 | } |
200 | } | 200 | } |
201 | } | 201 | } |
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | #endregion | 205 | #endregion |
206 | } | 206 | } |
207 | } \ No newline at end of file | 207 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs index e2df885..4f7d20c 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainChannel.cs | |||
@@ -1,157 +1,157 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using OpenSim.Framework; | 28 | using OpenSim.Framework; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
32 | { | 32 | { |
33 | /// <summary> | 33 | /// <summary> |
34 | /// A new version of the old Channel class, simplified | 34 | /// A new version of the old Channel class, simplified |
35 | /// </summary> | 35 | /// </summary> |
36 | public class TerrainChannel : ITerrainChannel | 36 | public class TerrainChannel : ITerrainChannel |
37 | { | 37 | { |
38 | private readonly bool[,] taint; | 38 | private readonly bool[,] taint; |
39 | private double[,] map; | 39 | private double[,] map; |
40 | 40 | ||
41 | public TerrainChannel() | 41 | public TerrainChannel() |
42 | { | 42 | { |
43 | map = new double[Constants.RegionSize,Constants.RegionSize]; | 43 | map = new double[Constants.RegionSize,Constants.RegionSize]; |
44 | taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; | 44 | taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; |
45 | 45 | ||
46 | int x; | 46 | int x; |
47 | for (x = 0; x < Constants.RegionSize; x++) | 47 | for (x = 0; x < Constants.RegionSize; x++) |
48 | { | 48 | { |
49 | int y; | 49 | int y; |
50 | for (y = 0; y < Constants.RegionSize; y++) | 50 | for (y = 0; y < Constants.RegionSize; y++) |
51 | { | 51 | { |
52 | map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; | 52 | map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10; |
53 | double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01; | 53 | double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01; |
54 | if (map[x, y] < spherFac) | 54 | if (map[x, y] < spherFac) |
55 | { | 55 | { |
56 | map[x, y] = spherFac; | 56 | map[x, y] = spherFac; |
57 | } | 57 | } |
58 | } | 58 | } |
59 | } | 59 | } |
60 | } | 60 | } |
61 | 61 | ||
62 | public TerrainChannel(double[,] import) | 62 | public TerrainChannel(double[,] import) |
63 | { | 63 | { |
64 | map = import; | 64 | map = import; |
65 | taint = new bool[import.GetLength(0),import.GetLength(1)]; | 65 | taint = new bool[import.GetLength(0),import.GetLength(1)]; |
66 | } | 66 | } |
67 | 67 | ||
68 | public TerrainChannel(bool createMap) | 68 | public TerrainChannel(bool createMap) |
69 | { | 69 | { |
70 | if (createMap) | 70 | if (createMap) |
71 | { | 71 | { |
72 | map = new double[Constants.RegionSize,Constants.RegionSize]; | 72 | map = new double[Constants.RegionSize,Constants.RegionSize]; |
73 | taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; | 73 | taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; |
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | public TerrainChannel(int w, int h) | 77 | public TerrainChannel(int w, int h) |
78 | { | 78 | { |
79 | map = new double[w,h]; | 79 | map = new double[w,h]; |
80 | taint = new bool[w / 16,h / 16]; | 80 | taint = new bool[w / 16,h / 16]; |
81 | } | 81 | } |
82 | 82 | ||
83 | #region ITerrainChannel Members | 83 | #region ITerrainChannel Members |
84 | 84 | ||
85 | public int Width | 85 | public int Width |
86 | { | 86 | { |
87 | get { return map.GetLength(0); } | 87 | get { return map.GetLength(0); } |
88 | } | 88 | } |
89 | 89 | ||
90 | public int Height | 90 | public int Height |
91 | { | 91 | { |
92 | get { return map.GetLength(1); } | 92 | get { return map.GetLength(1); } |
93 | } | 93 | } |
94 | 94 | ||
95 | public ITerrainChannel MakeCopy() | 95 | public ITerrainChannel MakeCopy() |
96 | { | 96 | { |
97 | TerrainChannel copy = new TerrainChannel(false); | 97 | TerrainChannel copy = new TerrainChannel(false); |
98 | copy.map = (double[,]) map.Clone(); | 98 | copy.map = (double[,]) map.Clone(); |
99 | 99 | ||
100 | return copy; | 100 | return copy; |
101 | } | 101 | } |
102 | 102 | ||
103 | public float[] GetFloatsSerialised() | 103 | public float[] GetFloatsSerialised() |
104 | { | 104 | { |
105 | float[] heights = new float[Width * Height]; | 105 | float[] heights = new float[Width * Height]; |
106 | int i; | 106 | int i; |
107 | 107 | ||
108 | for (i = 0; i < Width * Height; i++) | 108 | for (i = 0; i < Width * Height; i++) |
109 | { | 109 | { |
110 | heights[i] = (float) map[i % Width, i / Width]; | 110 | heights[i] = (float) map[i % Width, i / Width]; |
111 | } | 111 | } |
112 | 112 | ||
113 | return heights; | 113 | return heights; |
114 | } | 114 | } |
115 | 115 | ||
116 | public double[,] GetDoubles() | 116 | public double[,] GetDoubles() |
117 | { | 117 | { |
118 | return map; | 118 | return map; |
119 | } | 119 | } |
120 | 120 | ||
121 | public double this[int x, int y] | 121 | public double this[int x, int y] |
122 | { | 122 | { |
123 | get { return map[x, y]; } | 123 | get { return map[x, y]; } |
124 | set | 124 | set |
125 | { | 125 | { |
126 | if (map[x, y] != value) | 126 | if (map[x, y] != value) |
127 | { | 127 | { |
128 | taint[x / 16, y / 16] = true; | 128 | taint[x / 16, y / 16] = true; |
129 | map[x, y] = value; | 129 | map[x, y] = value; |
130 | } | 130 | } |
131 | } | 131 | } |
132 | } | 132 | } |
133 | 133 | ||
134 | public bool Tainted(int x, int y) | 134 | public bool Tainted(int x, int y) |
135 | { | 135 | { |
136 | if (taint[x / 16, y / 16]) | 136 | if (taint[x / 16, y / 16]) |
137 | { | 137 | { |
138 | taint[x / 16, y / 16] = false; | 138 | taint[x / 16, y / 16] = false; |
139 | return true; | 139 | return true; |
140 | } | 140 | } |
141 | else | 141 | else |
142 | { | 142 | { |
143 | return false; | 143 | return false; |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | #endregion | 147 | #endregion |
148 | 148 | ||
149 | public TerrainChannel Copy() | 149 | public TerrainChannel Copy() |
150 | { | 150 | { |
151 | TerrainChannel copy = new TerrainChannel(false); | 151 | TerrainChannel copy = new TerrainChannel(false); |
152 | copy.map = (double[,]) map.Clone(); | 152 | copy.map = (double[,]) map.Clone(); |
153 | 153 | ||
154 | return copy; | 154 | return copy; |
155 | } | 155 | } |
156 | } | 156 | } |
157 | } \ No newline at end of file | 157 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs index 1095cb9..f5c0fe4 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainException.cs | |||
@@ -1,46 +1,46 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | 29 | ||
30 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 30 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
31 | { | 31 | { |
32 | public class TerrainException : Exception | 32 | public class TerrainException : Exception |
33 | { | 33 | { |
34 | public TerrainException() : base() | 34 | public TerrainException() : base() |
35 | { | 35 | { |
36 | } | 36 | } |
37 | 37 | ||
38 | public TerrainException(string msg) : base(msg) | 38 | public TerrainException(string msg) : base(msg) |
39 | { | 39 | { |
40 | } | 40 | } |
41 | 41 | ||
42 | public TerrainException(string msg, Exception e) : base(msg, e) | 42 | public TerrainException(string msg, Exception e) : base(msg, e) |
43 | { | 43 | { |
44 | } | 44 | } |
45 | } | 45 | } |
46 | } \ No newline at end of file | 46 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs index 09c3117..eff6159 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs | |||
@@ -1,736 +1,736 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using log4net; | 33 | using log4net; |
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
37 | using OpenSim.Region.Environment.Modules.Framework; | 37 | using OpenSim.Region.Environment.Modules.Framework; |
38 | using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders; | 38 | using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders; |
39 | using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes; | 39 | using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes; |
40 | using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; | 40 | using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; |
41 | using OpenSim.Region.Environment.Scenes; | 41 | using OpenSim.Region.Environment.Scenes; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 43 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
44 | { | 44 | { |
45 | public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule | 45 | public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule |
46 | { | 46 | { |
47 | #region StandardTerrainEffects enum | 47 | #region StandardTerrainEffects enum |
48 | 48 | ||
49 | /// <summary> | 49 | /// <summary> |
50 | /// A standard set of terrain brushes and effects recognised by viewers | 50 | /// A standard set of terrain brushes and effects recognised by viewers |
51 | /// </summary> | 51 | /// </summary> |
52 | public enum StandardTerrainEffects : byte | 52 | public enum StandardTerrainEffects : byte |
53 | { | 53 | { |
54 | Flatten = 0, | 54 | Flatten = 0, |
55 | Raise = 1, | 55 | Raise = 1, |
56 | Lower = 2, | 56 | Lower = 2, |
57 | Smooth = 3, | 57 | Smooth = 3, |
58 | Noise = 4, | 58 | Noise = 4, |
59 | Revert = 5, | 59 | Revert = 5, |
60 | 60 | ||
61 | // Extended brushes | 61 | // Extended brushes |
62 | Erode = 255, | 62 | Erode = 255, |
63 | Weather = 254, | 63 | Weather = 254, |
64 | Olsen = 253 | 64 | Olsen = 253 |
65 | } | 65 | } |
66 | 66 | ||
67 | #endregion | 67 | #endregion |
68 | 68 | ||
69 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 69 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
70 | 70 | ||
71 | private readonly Commander m_commander = new Commander("Terrain"); | 71 | private readonly Commander m_commander = new Commander("Terrain"); |
72 | 72 | ||
73 | private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = | 73 | private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = |
74 | new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); | 74 | new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); |
75 | 75 | ||
76 | private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); | 76 | private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); |
77 | 77 | ||
78 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = | 78 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = |
79 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); | 79 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); |
80 | 80 | ||
81 | private ITerrainChannel m_channel; | 81 | private ITerrainChannel m_channel; |
82 | private Dictionary<Location, ITerrainChannel> m_channels; | 82 | private Dictionary<Location, ITerrainChannel> m_channels; |
83 | private Dictionary<string, ITerrainEffect> m_plugineffects; | 83 | private Dictionary<string, ITerrainEffect> m_plugineffects; |
84 | private ITerrainChannel m_revert; | 84 | private ITerrainChannel m_revert; |
85 | private Scene m_scene; | 85 | private Scene m_scene; |
86 | private bool m_tainted = false; | 86 | private bool m_tainted = false; |
87 | 87 | ||
88 | #region ICommandableModule Members | 88 | #region ICommandableModule Members |
89 | 89 | ||
90 | public ICommander CommandInterface | 90 | public ICommander CommandInterface |
91 | { | 91 | { |
92 | get { return m_commander; } | 92 | get { return m_commander; } |
93 | } | 93 | } |
94 | 94 | ||
95 | #endregion | 95 | #endregion |
96 | 96 | ||
97 | #region IRegionModule Members | 97 | #region IRegionModule Members |
98 | 98 | ||
99 | /// <summary> | 99 | /// <summary> |
100 | /// Creates and initialises a terrain module for a region | 100 | /// Creates and initialises a terrain module for a region |
101 | /// </summary> | 101 | /// </summary> |
102 | /// <param name="scene">Region initialising</param> | 102 | /// <param name="scene">Region initialising</param> |
103 | /// <param name="config">Config for the region</param> | 103 | /// <param name="config">Config for the region</param> |
104 | public void Initialise(Scene scene, IConfigSource config) | 104 | public void Initialise(Scene scene, IConfigSource config) |
105 | { | 105 | { |
106 | m_scene = scene; | 106 | m_scene = scene; |
107 | 107 | ||
108 | // Install terrain module in the simulator | 108 | // Install terrain module in the simulator |
109 | if (m_scene.Heightmap == null) | 109 | if (m_scene.Heightmap == null) |
110 | { | 110 | { |
111 | lock (m_scene) | 111 | lock (m_scene) |
112 | { | 112 | { |
113 | m_channel = new TerrainChannel(); | 113 | m_channel = new TerrainChannel(); |
114 | m_scene.Heightmap = m_channel; | 114 | m_scene.Heightmap = m_channel; |
115 | m_revert = new TerrainChannel(); | 115 | m_revert = new TerrainChannel(); |
116 | UpdateRevertMap(); | 116 | UpdateRevertMap(); |
117 | } | 117 | } |
118 | } | 118 | } |
119 | else | 119 | else |
120 | { | 120 | { |
121 | m_channel = m_scene.Heightmap; | 121 | m_channel = m_scene.Heightmap; |
122 | m_revert = new TerrainChannel(); | 122 | m_revert = new TerrainChannel(); |
123 | UpdateRevertMap(); | 123 | UpdateRevertMap(); |
124 | } | 124 | } |
125 | 125 | ||
126 | m_scene.RegisterModuleInterface<ITerrainModule>(this); | 126 | m_scene.RegisterModuleInterface<ITerrainModule>(this); |
127 | m_scene.EventManager.OnNewClient += EventManager_OnNewClient; | 127 | m_scene.EventManager.OnNewClient += EventManager_OnNewClient; |
128 | m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; | 128 | m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; |
129 | m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; | 129 | m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; |
130 | } | 130 | } |
131 | 131 | ||
132 | /// <summary> | 132 | /// <summary> |
133 | /// Enables terrain module when called | 133 | /// Enables terrain module when called |
134 | /// </summary> | 134 | /// </summary> |
135 | public void PostInitialise() | 135 | public void PostInitialise() |
136 | { | 136 | { |
137 | InstallDefaultEffects(); | 137 | InstallDefaultEffects(); |
138 | InstallInterfaces(); | 138 | InstallInterfaces(); |
139 | LoadPlugins(); | 139 | LoadPlugins(); |
140 | } | 140 | } |
141 | 141 | ||
142 | public void Close() | 142 | public void Close() |
143 | { | 143 | { |
144 | } | 144 | } |
145 | 145 | ||
146 | public string Name | 146 | public string Name |
147 | { | 147 | { |
148 | get { return "TerrainModule"; } | 148 | get { return "TerrainModule"; } |
149 | } | 149 | } |
150 | 150 | ||
151 | public bool IsSharedModule | 151 | public bool IsSharedModule |
152 | { | 152 | { |
153 | get { return false; } | 153 | get { return false; } |
154 | } | 154 | } |
155 | 155 | ||
156 | #endregion | 156 | #endregion |
157 | 157 | ||
158 | #region ITerrainModule Members | 158 | #region ITerrainModule Members |
159 | 159 | ||
160 | /// <summary> | 160 | /// <summary> |
161 | /// Loads a terrain file from disk and installs it in the scene. | 161 | /// Loads a terrain file from disk and installs it in the scene. |
162 | /// </summary> | 162 | /// </summary> |
163 | /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> | 163 | /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> |
164 | public void LoadFromFile(string filename) | 164 | public void LoadFromFile(string filename) |
165 | { | 165 | { |
166 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 166 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
167 | { | 167 | { |
168 | if (filename.EndsWith(loader.Key)) | 168 | if (filename.EndsWith(loader.Key)) |
169 | { | 169 | { |
170 | lock (m_scene) | 170 | lock (m_scene) |
171 | { | 171 | { |
172 | try | 172 | try |
173 | { | 173 | { |
174 | ITerrainChannel channel = loader.Value.LoadFile(filename); | 174 | ITerrainChannel channel = loader.Value.LoadFile(filename); |
175 | m_scene.Heightmap = channel; | 175 | m_scene.Heightmap = channel; |
176 | m_channel = channel; | 176 | m_channel = channel; |
177 | UpdateRevertMap(); | 177 | UpdateRevertMap(); |
178 | } | 178 | } |
179 | catch (NotImplementedException) | 179 | catch (NotImplementedException) |
180 | { | 180 | { |
181 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + | 181 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + |
182 | " parser does not support file loading. (May be save only)"); | 182 | " parser does not support file loading. (May be save only)"); |
183 | throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value)); | 183 | throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value)); |
184 | } | 184 | } |
185 | catch (FileNotFoundException) | 185 | catch (FileNotFoundException) |
186 | { | 186 | { |
187 | m_log.Error( | 187 | m_log.Error( |
188 | "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); | 188 | "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); |
189 | throw new TerrainException( | 189 | throw new TerrainException( |
190 | String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename)); | 190 | String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename)); |
191 | } | 191 | } |
192 | } | 192 | } |
193 | CheckForTerrainUpdates(); | 193 | CheckForTerrainUpdates(); |
194 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); | 194 | m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); |
195 | return; | 195 | return; |
196 | } | 196 | } |
197 | } | 197 | } |
198 | m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); | 198 | m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); |
199 | throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); | 199 | throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); |
200 | } | 200 | } |
201 | 201 | ||
202 | /// <summary> | 202 | /// <summary> |
203 | /// Saves the current heightmap to a specified file. | 203 | /// Saves the current heightmap to a specified file. |
204 | /// </summary> | 204 | /// </summary> |
205 | /// <param name="filename">The destination filename</param> | 205 | /// <param name="filename">The destination filename</param> |
206 | public void SaveToFile(string filename) | 206 | public void SaveToFile(string filename) |
207 | { | 207 | { |
208 | try | 208 | try |
209 | { | 209 | { |
210 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 210 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
211 | { | 211 | { |
212 | if (filename.EndsWith(loader.Key)) | 212 | if (filename.EndsWith(loader.Key)) |
213 | { | 213 | { |
214 | loader.Value.SaveFile(filename, m_channel); | 214 | loader.Value.SaveFile(filename, m_channel); |
215 | return; | 215 | return; |
216 | } | 216 | } |
217 | } | 217 | } |
218 | } | 218 | } |
219 | catch (NotImplementedException) | 219 | catch (NotImplementedException) |
220 | { | 220 | { |
221 | m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); | 221 | m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); |
222 | throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); | 222 | throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); |
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | #region Plugin Loading Methods | 226 | #region Plugin Loading Methods |
227 | 227 | ||
228 | private void LoadPlugins() | 228 | private void LoadPlugins() |
229 | { | 229 | { |
230 | m_plugineffects = new Dictionary<string, ITerrainEffect>(); | 230 | m_plugineffects = new Dictionary<string, ITerrainEffect>(); |
231 | // Load the files in the Terrain/ dir | 231 | // Load the files in the Terrain/ dir |
232 | string[] files = Directory.GetFiles("Terrain"); | 232 | string[] files = Directory.GetFiles("Terrain"); |
233 | foreach (string file in files) | 233 | foreach (string file in files) |
234 | { | 234 | { |
235 | m_log.Info("Loading effects in " + file); | 235 | m_log.Info("Loading effects in " + file); |
236 | try | 236 | try |
237 | { | 237 | { |
238 | Assembly library = Assembly.LoadFrom(file); | 238 | Assembly library = Assembly.LoadFrom(file); |
239 | foreach (Type pluginType in library.GetTypes()) | 239 | foreach (Type pluginType in library.GetTypes()) |
240 | { | 240 | { |
241 | try | 241 | try |
242 | { | 242 | { |
243 | if (pluginType.IsAbstract || pluginType.IsNotPublic) | 243 | if (pluginType.IsAbstract || pluginType.IsNotPublic) |
244 | continue; | 244 | continue; |
245 | 245 | ||
246 | if (pluginType.GetInterface("ITerrainEffect", false) != null) | 246 | if (pluginType.GetInterface("ITerrainEffect", false) != null) |
247 | { | 247 | { |
248 | ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString())); | 248 | ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString())); |
249 | if (!m_plugineffects.ContainsKey(pluginType.Name)) | 249 | if (!m_plugineffects.ContainsKey(pluginType.Name)) |
250 | { | 250 | { |
251 | m_plugineffects.Add(pluginType.Name, terEffect); | 251 | m_plugineffects.Add(pluginType.Name, terEffect); |
252 | m_log.Info("E ... " + pluginType.Name); | 252 | m_log.Info("E ... " + pluginType.Name); |
253 | } | 253 | } |
254 | else | 254 | else |
255 | { | 255 | { |
256 | m_log.Warn("E ... " + pluginType.Name + " (Already added)"); | 256 | m_log.Warn("E ... " + pluginType.Name + " (Already added)"); |
257 | } | 257 | } |
258 | } | 258 | } |
259 | else if (pluginType.GetInterface("ITerrainLoader", false) != null) | 259 | else if (pluginType.GetInterface("ITerrainLoader", false) != null) |
260 | { | 260 | { |
261 | ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); | 261 | ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); |
262 | m_loaders[terLoader.FileExtension] = terLoader; | 262 | m_loaders[terLoader.FileExtension] = terLoader; |
263 | m_log.Info("L ... " + pluginType.Name); | 263 | m_log.Info("L ... " + pluginType.Name); |
264 | } | 264 | } |
265 | } | 265 | } |
266 | catch (AmbiguousMatchException) | 266 | catch (AmbiguousMatchException) |
267 | { | 267 | { |
268 | } | 268 | } |
269 | } | 269 | } |
270 | } | 270 | } |
271 | catch (BadImageFormatException) | 271 | catch (BadImageFormatException) |
272 | { | 272 | { |
273 | } | 273 | } |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
277 | #endregion | 277 | #endregion |
278 | 278 | ||
279 | #endregion | 279 | #endregion |
280 | 280 | ||
281 | /// <summary> | 281 | /// <summary> |
282 | /// Installs into terrain module the standard suite of brushes | 282 | /// Installs into terrain module the standard suite of brushes |
283 | /// </summary> | 283 | /// </summary> |
284 | private void InstallDefaultEffects() | 284 | private void InstallDefaultEffects() |
285 | { | 285 | { |
286 | // Draggable Paint Brush Effects | 286 | // Draggable Paint Brush Effects |
287 | m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere(); | 287 | m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere(); |
288 | m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere(); | 288 | m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere(); |
289 | m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere(); | 289 | m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere(); |
290 | m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere(); | 290 | m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere(); |
291 | m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere(); | 291 | m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere(); |
292 | m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert); | 292 | m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert); |
293 | m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere(); | 293 | m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere(); |
294 | m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere(); | 294 | m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere(); |
295 | m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere(); | 295 | m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere(); |
296 | 296 | ||
297 | // Area of effect selection effects | 297 | // Area of effect selection effects |
298 | m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea(); | 298 | m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea(); |
299 | m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea(); | 299 | m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea(); |
300 | m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea(); | 300 | m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea(); |
301 | m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea(); | 301 | m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea(); |
302 | m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); | 302 | m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); |
303 | m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); | 303 | m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); |
304 | 304 | ||
305 | // Filesystem load/save loaders | 305 | // Filesystem load/save loaders |
306 | m_loaders[".r32"] = new RAW32(); | 306 | m_loaders[".r32"] = new RAW32(); |
307 | m_loaders[".f32"] = m_loaders[".r32"]; | 307 | m_loaders[".f32"] = m_loaders[".r32"]; |
308 | m_loaders[".ter"] = new Terragen(); | 308 | m_loaders[".ter"] = new Terragen(); |
309 | m_loaders[".raw"] = new LLRAW(); | 309 | m_loaders[".raw"] = new LLRAW(); |
310 | m_loaders[".jpg"] = new JPEG(); | 310 | m_loaders[".jpg"] = new JPEG(); |
311 | m_loaders[".jpeg"] = m_loaders[".jpg"]; | 311 | m_loaders[".jpeg"] = m_loaders[".jpg"]; |
312 | m_loaders[".bmp"] = new BMP(); | 312 | m_loaders[".bmp"] = new BMP(); |
313 | m_loaders[".png"] = new PNG(); | 313 | m_loaders[".png"] = new PNG(); |
314 | m_loaders[".gif"] = new GIF(); | 314 | m_loaders[".gif"] = new GIF(); |
315 | m_loaders[".tif"] = new TIFF(); | 315 | m_loaders[".tif"] = new TIFF(); |
316 | m_loaders[".tiff"] = m_loaders[".tif"]; | 316 | m_loaders[".tiff"] = m_loaders[".tif"]; |
317 | } | 317 | } |
318 | 318 | ||
319 | /// <summary> | 319 | /// <summary> |
320 | /// Saves the current state of the region into the revert map buffer. | 320 | /// Saves the current state of the region into the revert map buffer. |
321 | /// </summary> | 321 | /// </summary> |
322 | public void UpdateRevertMap() | 322 | public void UpdateRevertMap() |
323 | { | 323 | { |
324 | int x; | 324 | int x; |
325 | for (x = 0; x < m_channel.Width; x++) | 325 | for (x = 0; x < m_channel.Width; x++) |
326 | { | 326 | { |
327 | int y; | 327 | int y; |
328 | for (y = 0; y < m_channel.Height; y++) | 328 | for (y = 0; y < m_channel.Height; y++) |
329 | { | 329 | { |
330 | m_revert[x, y] = m_channel[x, y]; | 330 | m_revert[x, y] = m_channel[x, y]; |
331 | } | 331 | } |
332 | } | 332 | } |
333 | } | 333 | } |
334 | 334 | ||
335 | /// <summary> | 335 | /// <summary> |
336 | /// Loads a tile from a larger terrain file and installs it into the region. | 336 | /// Loads a tile from a larger terrain file and installs it into the region. |
337 | /// </summary> | 337 | /// </summary> |
338 | /// <param name="filename">The terrain file to load</param> | 338 | /// <param name="filename">The terrain file to load</param> |
339 | /// <param name="fileWidth">The width of the file in units</param> | 339 | /// <param name="fileWidth">The width of the file in units</param> |
340 | /// <param name="fileHeight">The height of the file in units</param> | 340 | /// <param name="fileHeight">The height of the file in units</param> |
341 | /// <param name="fileStartX">Where to begin our slice</param> | 341 | /// <param name="fileStartX">Where to begin our slice</param> |
342 | /// <param name="fileStartY">Where to begin our slice</param> | 342 | /// <param name="fileStartY">Where to begin our slice</param> |
343 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) | 343 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) |
344 | { | 344 | { |
345 | int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX; | 345 | int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX; |
346 | int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY; | 346 | int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY; |
347 | 347 | ||
348 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) | 348 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) |
349 | { | 349 | { |
350 | // this region is included in the tile request | 350 | // this region is included in the tile request |
351 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 351 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
352 | { | 352 | { |
353 | if (filename.EndsWith(loader.Key)) | 353 | if (filename.EndsWith(loader.Key)) |
354 | { | 354 | { |
355 | lock (m_scene) | 355 | lock (m_scene) |
356 | { | 356 | { |
357 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, | 357 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, |
358 | fileWidth, fileHeight, | 358 | fileWidth, fileHeight, |
359 | (int) Constants.RegionSize, | 359 | (int) Constants.RegionSize, |
360 | (int) Constants.RegionSize); | 360 | (int) Constants.RegionSize); |
361 | m_scene.Heightmap = channel; | 361 | m_scene.Heightmap = channel; |
362 | m_channel = channel; | 362 | m_channel = channel; |
363 | UpdateRevertMap(); | 363 | UpdateRevertMap(); |
364 | } | 364 | } |
365 | return; | 365 | return; |
366 | } | 366 | } |
367 | } | 367 | } |
368 | } | 368 | } |
369 | } | 369 | } |
370 | 370 | ||
371 | /// <summary> | 371 | /// <summary> |
372 | /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections | 372 | /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections |
373 | /// </summary> | 373 | /// </summary> |
374 | private void EventManager_OnTerrainTick() | 374 | private void EventManager_OnTerrainTick() |
375 | { | 375 | { |
376 | if (m_tainted) | 376 | if (m_tainted) |
377 | { | 377 | { |
378 | m_tainted = false; | 378 | m_tainted = false; |
379 | m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); | 379 | m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); |
380 | m_scene.SaveTerrain(); | 380 | m_scene.SaveTerrain(); |
381 | m_scene.CreateTerrainTexture(true); | 381 | m_scene.CreateTerrainTexture(true); |
382 | } | 382 | } |
383 | } | 383 | } |
384 | 384 | ||
385 | /// <summary> | 385 | /// <summary> |
386 | /// Processes commandline input. Do not call directly. | 386 | /// Processes commandline input. Do not call directly. |
387 | /// </summary> | 387 | /// </summary> |
388 | /// <param name="args">Commandline arguments</param> | 388 | /// <param name="args">Commandline arguments</param> |
389 | private void EventManager_OnPluginConsole(string[] args) | 389 | private void EventManager_OnPluginConsole(string[] args) |
390 | { | 390 | { |
391 | if (args[0] == "terrain") | 391 | if (args[0] == "terrain") |
392 | { | 392 | { |
393 | string[] tmpArgs = new string[args.Length - 2]; | 393 | string[] tmpArgs = new string[args.Length - 2]; |
394 | int i; | 394 | int i; |
395 | for (i = 2; i < args.Length; i++) | 395 | for (i = 2; i < args.Length; i++) |
396 | tmpArgs[i - 2] = args[i]; | 396 | tmpArgs[i - 2] = args[i]; |
397 | 397 | ||
398 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); | 398 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); |
399 | } | 399 | } |
400 | } | 400 | } |
401 | 401 | ||
402 | /// <summary> | 402 | /// <summary> |
403 | /// Installs terrain brush hook to IClientAPI | 403 | /// Installs terrain brush hook to IClientAPI |
404 | /// </summary> | 404 | /// </summary> |
405 | /// <param name="client"></param> | 405 | /// <param name="client"></param> |
406 | private void EventManager_OnNewClient(IClientAPI client) | 406 | private void EventManager_OnNewClient(IClientAPI client) |
407 | { | 407 | { |
408 | client.OnModifyTerrain += client_OnModifyTerrain; | 408 | client.OnModifyTerrain += client_OnModifyTerrain; |
409 | } | 409 | } |
410 | 410 | ||
411 | /// <summary> | 411 | /// <summary> |
412 | /// Checks to see if the terrain has been modified since last check | 412 | /// Checks to see if the terrain has been modified since last check |
413 | /// </summary> | 413 | /// </summary> |
414 | private void CheckForTerrainUpdates() | 414 | private void CheckForTerrainUpdates() |
415 | { | 415 | { |
416 | bool shouldTaint = false; | 416 | bool shouldTaint = false; |
417 | float[] serialised = m_channel.GetFloatsSerialised(); | 417 | float[] serialised = m_channel.GetFloatsSerialised(); |
418 | int x; | 418 | int x; |
419 | for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) | 419 | for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) |
420 | { | 420 | { |
421 | int y; | 421 | int y; |
422 | for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize) | 422 | for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize) |
423 | { | 423 | { |
424 | if (m_channel.Tainted(x, y)) | 424 | if (m_channel.Tainted(x, y)) |
425 | { | 425 | { |
426 | SendToClients(serialised, x, y); | 426 | SendToClients(serialised, x, y); |
427 | shouldTaint = true; | 427 | shouldTaint = true; |
428 | } | 428 | } |
429 | } | 429 | } |
430 | } | 430 | } |
431 | if (shouldTaint) | 431 | if (shouldTaint) |
432 | { | 432 | { |
433 | m_tainted = true; | 433 | m_tainted = true; |
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | /// <summary> | 437 | /// <summary> |
438 | /// Sends a copy of the current terrain to the scenes clients | 438 | /// Sends a copy of the current terrain to the scenes clients |
439 | /// </summary> | 439 | /// </summary> |
440 | /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> | 440 | /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> |
441 | /// <param name="x">The patch corner to send</param> | 441 | /// <param name="x">The patch corner to send</param> |
442 | /// <param name="y">The patch corner to send</param> | 442 | /// <param name="y">The patch corner to send</param> |
443 | private void SendToClients(float[] serialised, int x, int y) | 443 | private void SendToClients(float[] serialised, int x, int y) |
444 | { | 444 | { |
445 | m_scene.ForEachClient( | 445 | m_scene.ForEachClient( |
446 | delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); }); | 446 | delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); }); |
447 | } | 447 | } |
448 | 448 | ||
449 | private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, | 449 | private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, |
450 | float south, float east, IClientAPI remoteClient) | 450 | float south, float east, IClientAPI remoteClient) |
451 | { | 451 | { |
452 | // Not a good permissions check, if in area mode, need to check the entire area. | 452 | // Not a good permissions check, if in area mode, need to check the entire area. |
453 | if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0))) | 453 | if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0))) |
454 | { | 454 | { |
455 | if (north == south && east == west) | 455 | if (north == south && east == west) |
456 | { | 456 | { |
457 | if (m_painteffects.ContainsKey((StandardTerrainEffects) action)) | 457 | if (m_painteffects.ContainsKey((StandardTerrainEffects) action)) |
458 | { | 458 | { |
459 | m_painteffects[(StandardTerrainEffects) action].PaintEffect( | 459 | m_painteffects[(StandardTerrainEffects) action].PaintEffect( |
460 | m_channel, west, south, size, seconds); | 460 | m_channel, west, south, size, seconds); |
461 | 461 | ||
462 | CheckForTerrainUpdates(); | 462 | CheckForTerrainUpdates(); |
463 | } | 463 | } |
464 | else | 464 | else |
465 | { | 465 | { |
466 | m_log.Debug("Unknown terrain brush type " + action); | 466 | m_log.Debug("Unknown terrain brush type " + action); |
467 | } | 467 | } |
468 | } | 468 | } |
469 | else | 469 | else |
470 | { | 470 | { |
471 | if (m_floodeffects.ContainsKey((StandardTerrainEffects) action)) | 471 | if (m_floodeffects.ContainsKey((StandardTerrainEffects) action)) |
472 | { | 472 | { |
473 | bool[,] fillArea = new bool[m_channel.Width,m_channel.Height]; | 473 | bool[,] fillArea = new bool[m_channel.Width,m_channel.Height]; |
474 | fillArea.Initialize(); | 474 | fillArea.Initialize(); |
475 | 475 | ||
476 | int x; | 476 | int x; |
477 | for (x = 0; x < m_channel.Width; x++) | 477 | for (x = 0; x < m_channel.Width; x++) |
478 | { | 478 | { |
479 | int y; | 479 | int y; |
480 | for (y = 0; y < m_channel.Height; y++) | 480 | for (y = 0; y < m_channel.Height; y++) |
481 | { | 481 | { |
482 | if (x < east && x > west) | 482 | if (x < east && x > west) |
483 | { | 483 | { |
484 | if (y < north && y > south) | 484 | if (y < north && y > south) |
485 | { | 485 | { |
486 | fillArea[x, y] = true; | 486 | fillArea[x, y] = true; |
487 | } | 487 | } |
488 | } | 488 | } |
489 | } | 489 | } |
490 | } | 490 | } |
491 | 491 | ||
492 | m_floodeffects[(StandardTerrainEffects) action].FloodEffect( | 492 | m_floodeffects[(StandardTerrainEffects) action].FloodEffect( |
493 | m_channel, fillArea, size); | 493 | m_channel, fillArea, size); |
494 | 494 | ||
495 | CheckForTerrainUpdates(); | 495 | CheckForTerrainUpdates(); |
496 | } | 496 | } |
497 | else | 497 | else |
498 | { | 498 | { |
499 | m_log.Debug("Unknown terrain flood type " + action); | 499 | m_log.Debug("Unknown terrain flood type " + action); |
500 | } | 500 | } |
501 | } | 501 | } |
502 | } | 502 | } |
503 | } | 503 | } |
504 | 504 | ||
505 | #region Console Commands | 505 | #region Console Commands |
506 | 506 | ||
507 | private void InterfaceLoadFile(Object[] args) | 507 | private void InterfaceLoadFile(Object[] args) |
508 | { | 508 | { |
509 | LoadFromFile((string) args[0]); | 509 | LoadFromFile((string) args[0]); |
510 | CheckForTerrainUpdates(); | 510 | CheckForTerrainUpdates(); |
511 | } | 511 | } |
512 | 512 | ||
513 | private void InterfaceLoadTileFile(Object[] args) | 513 | private void InterfaceLoadTileFile(Object[] args) |
514 | { | 514 | { |
515 | LoadFromFile((string) args[0], | 515 | LoadFromFile((string) args[0], |
516 | (int) args[1], | 516 | (int) args[1], |
517 | (int) args[2], | 517 | (int) args[2], |
518 | (int) args[3], | 518 | (int) args[3], |
519 | (int) args[4]); | 519 | (int) args[4]); |
520 | CheckForTerrainUpdates(); | 520 | CheckForTerrainUpdates(); |
521 | } | 521 | } |
522 | 522 | ||
523 | private void InterfaceSaveFile(Object[] args) | 523 | private void InterfaceSaveFile(Object[] args) |
524 | { | 524 | { |
525 | SaveToFile((string) args[0]); | 525 | SaveToFile((string) args[0]); |
526 | } | 526 | } |
527 | 527 | ||
528 | private void InterfaceBakeTerrain(Object[] args) | 528 | private void InterfaceBakeTerrain(Object[] args) |
529 | { | 529 | { |
530 | UpdateRevertMap(); | 530 | UpdateRevertMap(); |
531 | } | 531 | } |
532 | 532 | ||
533 | private void InterfaceRevertTerrain(Object[] args) | 533 | private void InterfaceRevertTerrain(Object[] args) |
534 | { | 534 | { |
535 | int x, y; | 535 | int x, y; |
536 | for (x = 0; x < m_channel.Width; x++) | 536 | for (x = 0; x < m_channel.Width; x++) |
537 | for (y = 0; y < m_channel.Height; y++) | 537 | for (y = 0; y < m_channel.Height; y++) |
538 | m_channel[x, y] = m_revert[x, y]; | 538 | m_channel[x, y] = m_revert[x, y]; |
539 | 539 | ||
540 | CheckForTerrainUpdates(); | 540 | CheckForTerrainUpdates(); |
541 | } | 541 | } |
542 | 542 | ||
543 | private void InterfaceElevateTerrain(Object[] args) | 543 | private void InterfaceElevateTerrain(Object[] args) |
544 | { | 544 | { |
545 | int x, y; | 545 | int x, y; |
546 | for (x = 0; x < m_channel.Width; x++) | 546 | for (x = 0; x < m_channel.Width; x++) |
547 | for (y = 0; y < m_channel.Height; y++) | 547 | for (y = 0; y < m_channel.Height; y++) |
548 | m_channel[x, y] += (double) args[0]; | 548 | m_channel[x, y] += (double) args[0]; |
549 | CheckForTerrainUpdates(); | 549 | CheckForTerrainUpdates(); |
550 | } | 550 | } |
551 | 551 | ||
552 | private void InterfaceMultiplyTerrain(Object[] args) | 552 | private void InterfaceMultiplyTerrain(Object[] args) |
553 | { | 553 | { |
554 | int x, y; | 554 | int x, y; |
555 | for (x = 0; x < m_channel.Width; x++) | 555 | for (x = 0; x < m_channel.Width; x++) |
556 | for (y = 0; y < m_channel.Height; y++) | 556 | for (y = 0; y < m_channel.Height; y++) |
557 | m_channel[x, y] *= (double) args[0]; | 557 | m_channel[x, y] *= (double) args[0]; |
558 | CheckForTerrainUpdates(); | 558 | CheckForTerrainUpdates(); |
559 | } | 559 | } |
560 | 560 | ||
561 | private void InterfaceLowerTerrain(Object[] args) | 561 | private void InterfaceLowerTerrain(Object[] args) |
562 | { | 562 | { |
563 | int x, y; | 563 | int x, y; |
564 | for (x = 0; x < m_channel.Width; x++) | 564 | for (x = 0; x < m_channel.Width; x++) |
565 | for (y = 0; y < m_channel.Height; y++) | 565 | for (y = 0; y < m_channel.Height; y++) |
566 | m_channel[x, y] -= (double) args[0]; | 566 | m_channel[x, y] -= (double) args[0]; |
567 | CheckForTerrainUpdates(); | 567 | CheckForTerrainUpdates(); |
568 | } | 568 | } |
569 | 569 | ||
570 | private void InterfaceFillTerrain(Object[] args) | 570 | private void InterfaceFillTerrain(Object[] args) |
571 | { | 571 | { |
572 | int x, y; | 572 | int x, y; |
573 | 573 | ||
574 | for (x = 0; x < m_channel.Width; x++) | 574 | for (x = 0; x < m_channel.Width; x++) |
575 | for (y = 0; y < m_channel.Height; y++) | 575 | for (y = 0; y < m_channel.Height; y++) |
576 | m_channel[x, y] = (double) args[0]; | 576 | m_channel[x, y] = (double) args[0]; |
577 | CheckForTerrainUpdates(); | 577 | CheckForTerrainUpdates(); |
578 | } | 578 | } |
579 | 579 | ||
580 | private void InterfaceShowDebugStats(Object[] args) | 580 | private void InterfaceShowDebugStats(Object[] args) |
581 | { | 581 | { |
582 | double max = Double.MinValue; | 582 | double max = Double.MinValue; |
583 | double min = double.MaxValue; | 583 | double min = double.MaxValue; |
584 | double avg; | 584 | double avg; |
585 | double sum = 0; | 585 | double sum = 0; |
586 | 586 | ||
587 | int x; | 587 | int x; |
588 | for (x = 0; x < m_channel.Width; x++) | 588 | for (x = 0; x < m_channel.Width; x++) |
589 | { | 589 | { |
590 | int y; | 590 | int y; |
591 | for (y = 0; y < m_channel.Height; y++) | 591 | for (y = 0; y < m_channel.Height; y++) |
592 | { | 592 | { |
593 | sum += m_channel[x, y]; | 593 | sum += m_channel[x, y]; |
594 | if (max < m_channel[x, y]) | 594 | if (max < m_channel[x, y]) |
595 | max = m_channel[x, y]; | 595 | max = m_channel[x, y]; |
596 | if (min > m_channel[x, y]) | 596 | if (min > m_channel[x, y]) |
597 | min = m_channel[x, y]; | 597 | min = m_channel[x, y]; |
598 | } | 598 | } |
599 | } | 599 | } |
600 | 600 | ||
601 | avg = sum / (m_channel.Height * m_channel.Width); | 601 | avg = sum / (m_channel.Height * m_channel.Width); |
602 | 602 | ||
603 | m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height); | 603 | m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height); |
604 | m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum); | 604 | m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum); |
605 | } | 605 | } |
606 | 606 | ||
607 | private void InterfaceEnableExperimentalBrushes(Object[] args) | 607 | private void InterfaceEnableExperimentalBrushes(Object[] args) |
608 | { | 608 | { |
609 | if ((bool) args[0]) | 609 | if ((bool) args[0]) |
610 | { | 610 | { |
611 | m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere(); | 611 | m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere(); |
612 | m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere(); | 612 | m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere(); |
613 | m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere(); | 613 | m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere(); |
614 | } | 614 | } |
615 | else | 615 | else |
616 | { | 616 | { |
617 | InstallDefaultEffects(); | 617 | InstallDefaultEffects(); |
618 | } | 618 | } |
619 | } | 619 | } |
620 | 620 | ||
621 | private void InterfaceRunPluginEffect(Object[] args) | 621 | private void InterfaceRunPluginEffect(Object[] args) |
622 | { | 622 | { |
623 | if ((string) args[0] == "list") | 623 | if ((string) args[0] == "list") |
624 | { | 624 | { |
625 | m_log.Info("List of loaded plugins"); | 625 | m_log.Info("List of loaded plugins"); |
626 | foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) | 626 | foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) |
627 | { | 627 | { |
628 | m_log.Info(kvp.Key); | 628 | m_log.Info(kvp.Key); |
629 | } | 629 | } |
630 | return; | 630 | return; |
631 | } | 631 | } |
632 | if ((string) args[0] == "reload") | 632 | if ((string) args[0] == "reload") |
633 | { | 633 | { |
634 | LoadPlugins(); | 634 | LoadPlugins(); |
635 | return; | 635 | return; |
636 | } | 636 | } |
637 | if (m_plugineffects.ContainsKey((string) args[0])) | 637 | if (m_plugineffects.ContainsKey((string) args[0])) |
638 | { | 638 | { |
639 | m_plugineffects[(string) args[0]].RunEffect(m_channel); | 639 | m_plugineffects[(string) args[0]].RunEffect(m_channel); |
640 | CheckForTerrainUpdates(); | 640 | CheckForTerrainUpdates(); |
641 | } | 641 | } |
642 | else | 642 | else |
643 | { | 643 | { |
644 | m_log.Warn("No such plugin effect loaded."); | 644 | m_log.Warn("No such plugin effect loaded."); |
645 | } | 645 | } |
646 | } | 646 | } |
647 | 647 | ||
648 | private void InstallInterfaces() | 648 | private void InstallInterfaces() |
649 | { | 649 | { |
650 | // Load / Save | 650 | // Load / Save |
651 | string supportedFileExtensions = ""; | 651 | string supportedFileExtensions = ""; |
652 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 652 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
653 | supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")"; | 653 | supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")"; |
654 | 654 | ||
655 | Command loadFromFileCommand = | 655 | Command loadFromFileCommand = |
656 | new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file."); | 656 | new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file."); |
657 | loadFromFileCommand.AddArgument("filename", | 657 | loadFromFileCommand.AddArgument("filename", |
658 | "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + | 658 | "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + |
659 | supportedFileExtensions, "String"); | 659 | supportedFileExtensions, "String"); |
660 | 660 | ||
661 | Command saveToFileCommand = | 661 | Command saveToFileCommand = |
662 | new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file."); | 662 | new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file."); |
663 | saveToFileCommand.AddArgument("filename", | 663 | saveToFileCommand.AddArgument("filename", |
664 | "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " + | 664 | "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " + |
665 | supportedFileExtensions, "String"); | 665 | supportedFileExtensions, "String"); |
666 | 666 | ||
667 | Command loadFromTileCommand = | 667 | Command loadFromTileCommand = |
668 | new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file."); | 668 | new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file."); |
669 | loadFromTileCommand.AddArgument("filename", | 669 | loadFromTileCommand.AddArgument("filename", |
670 | "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + | 670 | "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + |
671 | supportedFileExtensions, "String"); | 671 | supportedFileExtensions, "String"); |
672 | loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); | 672 | loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); |
673 | loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); | 673 | loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); |
674 | loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", | 674 | loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", |
675 | "Integer"); | 675 | "Integer"); |
676 | loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", | 676 | loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", |
677 | "Integer"); | 677 | "Integer"); |
678 | 678 | ||
679 | // Terrain adjustments | 679 | // Terrain adjustments |
680 | Command fillRegionCommand = | 680 | Command fillRegionCommand = |
681 | new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); | 681 | new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); |
682 | fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", | 682 | fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", |
683 | "Double"); | 683 | "Double"); |
684 | 684 | ||
685 | Command elevateCommand = | 685 | Command elevateCommand = |
686 | new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount."); | 686 | new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount."); |
687 | elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double"); | 687 | elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double"); |
688 | 688 | ||
689 | Command lowerCommand = | 689 | Command lowerCommand = |
690 | new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount."); | 690 | new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount."); |
691 | lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double"); | 691 | lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double"); |
692 | 692 | ||
693 | Command multiplyCommand = | 693 | Command multiplyCommand = |
694 | new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified."); | 694 | new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified."); |
695 | multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double"); | 695 | multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double"); |
696 | 696 | ||
697 | Command bakeRegionCommand = | 697 | Command bakeRegionCommand = |
698 | new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map."); | 698 | new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map."); |
699 | Command revertRegionCommand = | 699 | Command revertRegionCommand = |
700 | new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap."); | 700 | new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap."); |
701 | 701 | ||
702 | // Debug | 702 | // Debug |
703 | Command showDebugStatsCommand = | 703 | Command showDebugStatsCommand = |
704 | new Command("stats", InterfaceShowDebugStats, | 704 | new Command("stats", InterfaceShowDebugStats, |
705 | "Shows some information about the regions heightmap for debugging purposes."); | 705 | "Shows some information about the regions heightmap for debugging purposes."); |
706 | 706 | ||
707 | Command experimentalBrushesCommand = | 707 | Command experimentalBrushesCommand = |
708 | new Command("newbrushes", InterfaceEnableExperimentalBrushes, | 708 | new Command("newbrushes", InterfaceEnableExperimentalBrushes, |
709 | "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); | 709 | "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); |
710 | experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); | 710 | experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); |
711 | 711 | ||
712 | //Plugins | 712 | //Plugins |
713 | Command pluginRunCommand = | 713 | Command pluginRunCommand = |
714 | new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect"); | 714 | new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect"); |
715 | pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String"); | 715 | pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String"); |
716 | 716 | ||
717 | m_commander.RegisterCommand("load", loadFromFileCommand); | 717 | m_commander.RegisterCommand("load", loadFromFileCommand); |
718 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); | 718 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); |
719 | m_commander.RegisterCommand("save", saveToFileCommand); | 719 | m_commander.RegisterCommand("save", saveToFileCommand); |
720 | m_commander.RegisterCommand("fill", fillRegionCommand); | 720 | m_commander.RegisterCommand("fill", fillRegionCommand); |
721 | m_commander.RegisterCommand("elevate", elevateCommand); | 721 | m_commander.RegisterCommand("elevate", elevateCommand); |
722 | m_commander.RegisterCommand("lower", lowerCommand); | 722 | m_commander.RegisterCommand("lower", lowerCommand); |
723 | m_commander.RegisterCommand("multiply", multiplyCommand); | 723 | m_commander.RegisterCommand("multiply", multiplyCommand); |
724 | m_commander.RegisterCommand("bake", bakeRegionCommand); | 724 | m_commander.RegisterCommand("bake", bakeRegionCommand); |
725 | m_commander.RegisterCommand("revert", revertRegionCommand); | 725 | m_commander.RegisterCommand("revert", revertRegionCommand); |
726 | m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); | 726 | m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); |
727 | m_commander.RegisterCommand("stats", showDebugStatsCommand); | 727 | m_commander.RegisterCommand("stats", showDebugStatsCommand); |
728 | m_commander.RegisterCommand("effect", pluginRunCommand); | 728 | m_commander.RegisterCommand("effect", pluginRunCommand); |
729 | 729 | ||
730 | // Add this to our scene so scripts can call these functions | 730 | // Add this to our scene so scripts can call these functions |
731 | m_scene.RegisterModuleCommander("Terrain", m_commander); | 731 | m_scene.RegisterModuleCommander("Terrain", m_commander); |
732 | } | 732 | } |
733 | 733 | ||
734 | #endregion | 734 | #endregion |
735 | } | 735 | } |
736 | } \ No newline at end of file | 736 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs index b593717..daef6bd 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainUtil.cs | |||
@@ -1,133 +1,133 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using OpenSim.Region.Environment.Interfaces; | 29 | using OpenSim.Region.Environment.Interfaces; |
30 | 30 | ||
31 | namespace OpenSim.Region.Environment.Modules.World.Terrain | 31 | namespace OpenSim.Region.Environment.Modules.World.Terrain |
32 | { | 32 | { |
33 | public static class TerrainUtil | 33 | public static class TerrainUtil |
34 | { | 34 | { |
35 | public static double MetersToSphericalStrength(double size) | 35 | public static double MetersToSphericalStrength(double size) |
36 | { | 36 | { |
37 | return Math.Pow(2, size); | 37 | return Math.Pow(2, size); |
38 | } | 38 | } |
39 | 39 | ||
40 | public static double SphericalFactor(double x, double y, double rx, double ry, double size) | 40 | public static double SphericalFactor(double x, double y, double rx, double ry, double size) |
41 | { | 41 | { |
42 | return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry)); | 42 | return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry)); |
43 | } | 43 | } |
44 | 44 | ||
45 | public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map) | 45 | public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map) |
46 | { | 46 | { |
47 | int w = map.Width; | 47 | int w = map.Width; |
48 | int h = map.Height; | 48 | int h = map.Height; |
49 | 49 | ||
50 | if (x > w - 2.0) | 50 | if (x > w - 2.0) |
51 | x = w - 2.0; | 51 | x = w - 2.0; |
52 | if (y > h - 2.0) | 52 | if (y > h - 2.0) |
53 | y = h - 2.0; | 53 | y = h - 2.0; |
54 | if (x < 0.0) | 54 | if (x < 0.0) |
55 | x = 0.0; | 55 | x = 0.0; |
56 | if (y < 0.0) | 56 | if (y < 0.0) |
57 | y = 0.0; | 57 | y = 0.0; |
58 | 58 | ||
59 | int stepSize = 1; | 59 | int stepSize = 1; |
60 | double h00 = map[(int) x, (int) y]; | 60 | double h00 = map[(int) x, (int) y]; |
61 | double h10 = map[(int) x + stepSize, (int) y]; | 61 | double h10 = map[(int) x + stepSize, (int) y]; |
62 | double h01 = map[(int) x, (int) y + stepSize]; | 62 | double h01 = map[(int) x, (int) y + stepSize]; |
63 | double h11 = map[(int) x + stepSize, (int) y + stepSize]; | 63 | double h11 = map[(int) x + stepSize, (int) y + stepSize]; |
64 | double h1 = h00; | 64 | double h1 = h00; |
65 | double h2 = h10; | 65 | double h2 = h10; |
66 | double h3 = h01; | 66 | double h3 = h01; |
67 | double h4 = h11; | 67 | double h4 = h11; |
68 | double a00 = h1; | 68 | double a00 = h1; |
69 | double a10 = h2 - h1; | 69 | double a10 = h2 - h1; |
70 | double a01 = h3 - h1; | 70 | double a01 = h3 - h1; |
71 | double a11 = h1 - h2 - h3 + h4; | 71 | double a11 = h1 - h2 - h3 + h4; |
72 | double partialx = x - (int) x; | 72 | double partialx = x - (int) x; |
73 | double partialz = y - (int) y; | 73 | double partialz = y - (int) y; |
74 | double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); | 74 | double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); |
75 | return hi; | 75 | return hi; |
76 | } | 76 | } |
77 | 77 | ||
78 | private static double Noise(double x, double y) | 78 | private static double Noise(double x, double y) |
79 | { | 79 | { |
80 | int n = (int) x + (int) (y * 749); | 80 | int n = (int) x + (int) (y * 749); |
81 | n = (n << 13) ^ n; | 81 | n = (n << 13) ^ n; |
82 | return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); | 82 | return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0); |
83 | } | 83 | } |
84 | 84 | ||
85 | private static double SmoothedNoise1(double x, double y) | 85 | private static double SmoothedNoise1(double x, double y) |
86 | { | 86 | { |
87 | double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16; | 87 | double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16; |
88 | double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8; | 88 | double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8; |
89 | double center = Noise(x, y) / 4; | 89 | double center = Noise(x, y) / 4; |
90 | return corners + sides + center; | 90 | return corners + sides + center; |
91 | } | 91 | } |
92 | 92 | ||
93 | private static double Interpolate(double x, double y, double z) | 93 | private static double Interpolate(double x, double y, double z) |
94 | { | 94 | { |
95 | return (x * (1.0 - z)) + (y * z); | 95 | return (x * (1.0 - z)) + (y * z); |
96 | } | 96 | } |
97 | 97 | ||
98 | private static double InterpolatedNoise(double x, double y) | 98 | private static double InterpolatedNoise(double x, double y) |
99 | { | 99 | { |
100 | int integer_X = (int) (x); | 100 | int integer_X = (int) (x); |
101 | double fractional_X = x - integer_X; | 101 | double fractional_X = x - integer_X; |
102 | 102 | ||
103 | int integer_Y = (int) y; | 103 | int integer_Y = (int) y; |
104 | double fractional_Y = y - integer_Y; | 104 | double fractional_Y = y - integer_Y; |
105 | 105 | ||
106 | double v1 = SmoothedNoise1(integer_X, integer_Y); | 106 | double v1 = SmoothedNoise1(integer_X, integer_Y); |
107 | double v2 = SmoothedNoise1(integer_X + 1, integer_Y); | 107 | double v2 = SmoothedNoise1(integer_X + 1, integer_Y); |
108 | double v3 = SmoothedNoise1(integer_X, integer_Y + 1); | 108 | double v3 = SmoothedNoise1(integer_X, integer_Y + 1); |
109 | double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1); | 109 | double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1); |
110 | 110 | ||
111 | double i1 = Interpolate(v1, v2, fractional_X); | 111 | double i1 = Interpolate(v1, v2, fractional_X); |
112 | double i2 = Interpolate(v3, v4, fractional_X); | 112 | double i2 = Interpolate(v3, v4, fractional_X); |
113 | 113 | ||
114 | return Interpolate(i1, i2, fractional_Y); | 114 | return Interpolate(i1, i2, fractional_Y); |
115 | } | 115 | } |
116 | 116 | ||
117 | public static double PerlinNoise2D(double x, double y, int octaves, double persistence) | 117 | public static double PerlinNoise2D(double x, double y, int octaves, double persistence) |
118 | { | 118 | { |
119 | double frequency = 0.0; | 119 | double frequency = 0.0; |
120 | double amplitude = 0.0; | 120 | double amplitude = 0.0; |
121 | double total = 0.0; | 121 | double total = 0.0; |
122 | 122 | ||
123 | for (int i = 0; i < octaves; i++) | 123 | for (int i = 0; i < octaves; i++) |
124 | { | 124 | { |
125 | frequency = Math.Pow(2, i); | 125 | frequency = Math.Pow(2, i); |
126 | amplitude = Math.Pow(persistence, i); | 126 | amplitude = Math.Pow(persistence, i); |
127 | 127 | ||
128 | total += InterpolatedNoise(x * frequency, y * frequency) * amplitude; | 128 | total += InterpolatedNoise(x * frequency, y * frequency) * amplitude; |
129 | } | 129 | } |
130 | return total; | 130 | return total; |
131 | } | 131 | } |
132 | } | 132 | } |
133 | } \ No newline at end of file | 133 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/Tests/TerrainTest.cs b/OpenSim/Region/Environment/Modules/World/Terrain/Tests/TerrainTest.cs index ccb0561..842e2ee 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/Tests/TerrainTest.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/Tests/TerrainTest.cs | |||
@@ -1,59 +1,59 @@ | |||
1 | using System; | 1 | using System; |
2 | using NUnit.Framework; | 2 | using NUnit.Framework; |
3 | using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; | 3 | using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; |
4 | 4 | ||
5 | namespace OpenSim.Region.Environment.Modules.World.Terrain.Tests | 5 | namespace OpenSim.Region.Environment.Modules.World.Terrain.Tests |
6 | { | 6 | { |
7 | [TestFixture] | 7 | [TestFixture] |
8 | public class TerrainTest | 8 | public class TerrainTest |
9 | { | 9 | { |
10 | [Test] | 10 | [Test] |
11 | public void BrushTest() | 11 | public void BrushTest() |
12 | { | 12 | { |
13 | TerrainChannel x = new TerrainChannel(256, 256); | 13 | TerrainChannel x = new TerrainChannel(256, 256); |
14 | ITerrainPaintableEffect effect = new RaiseSphere(); | 14 | ITerrainPaintableEffect effect = new RaiseSphere(); |
15 | 15 | ||
16 | effect.PaintEffect(x, 128.0, 128.0, 50, 0.1); | 16 | effect.PaintEffect(x, 128.0, 128.0, 50, 0.1); |
17 | Assert.That(x[128, 128] > 0.0, "Raise brush not raising values."); | 17 | Assert.That(x[128, 128] > 0.0, "Raise brush not raising values."); |
18 | Assert.That(x[0, 128] > 0.0, "Raise brush lowering edge values."); | 18 | Assert.That(x[0, 128] > 0.0, "Raise brush lowering edge values."); |
19 | 19 | ||
20 | x = new TerrainChannel(256, 256); | 20 | x = new TerrainChannel(256, 256); |
21 | effect = new LowerSphere(); | 21 | effect = new LowerSphere(); |
22 | 22 | ||
23 | effect.PaintEffect(x, 128.0, 128.0, 50, 0.1); | 23 | effect.PaintEffect(x, 128.0, 128.0, 50, 0.1); |
24 | Assert.That(x[128, 128] < 0.0, "Lower not lowering values."); | 24 | Assert.That(x[128, 128] < 0.0, "Lower not lowering values."); |
25 | Assert.That(x[0, 128] < 0.0, "Lower brush affecting edge values."); | 25 | Assert.That(x[0, 128] < 0.0, "Lower brush affecting edge values."); |
26 | } | 26 | } |
27 | 27 | ||
28 | [Test] | 28 | [Test] |
29 | public void TerrainChannelTest() | 29 | public void TerrainChannelTest() |
30 | { | 30 | { |
31 | TerrainChannel x = new TerrainChannel(256, 256); | 31 | TerrainChannel x = new TerrainChannel(256, 256); |
32 | Assert.That(x[0, 0] == 0.0, "Terrain not initialising correctly."); | 32 | Assert.That(x[0, 0] == 0.0, "Terrain not initialising correctly."); |
33 | 33 | ||
34 | x[0, 0] = 1.0; | 34 | x[0, 0] = 1.0; |
35 | Assert.That(x[0, 0] == 1.0, "Terrain not setting values correctly."); | 35 | Assert.That(x[0, 0] == 1.0, "Terrain not setting values correctly."); |
36 | 36 | ||
37 | x[0, 0] = 0; | 37 | x[0, 0] = 0; |
38 | x[0, 0] += 5.0; | 38 | x[0, 0] += 5.0; |
39 | x[0, 0] -= 1.0; | 39 | x[0, 0] -= 1.0; |
40 | Assert.That(x[0, 0] == 4.0, "Terrain addition/subtraction error."); | 40 | Assert.That(x[0, 0] == 4.0, "Terrain addition/subtraction error."); |
41 | 41 | ||
42 | x[0, 0] = Math.PI; | 42 | x[0, 0] = Math.PI; |
43 | double[,] doublesExport = x.GetDoubles(); | 43 | double[,] doublesExport = x.GetDoubles(); |
44 | Assert.That(doublesExport[0, 0] == Math.PI, "Export to double[,] array not working correctly."); | 44 | Assert.That(doublesExport[0, 0] == Math.PI, "Export to double[,] array not working correctly."); |
45 | 45 | ||
46 | x[0, 0] = 1.0; | 46 | x[0, 0] = 1.0; |
47 | float[] floatsExport = x.GetFloatsSerialised(); | 47 | float[] floatsExport = x.GetFloatsSerialised(); |
48 | Assert.That(floatsExport[0] == 1.0f, "Export to float[] not working correctly."); | 48 | Assert.That(floatsExport[0] == 1.0f, "Export to float[] not working correctly."); |
49 | 49 | ||
50 | x[0, 0] = 1.0; | 50 | x[0, 0] = 1.0; |
51 | Assert.That(x.Tainted(0, 0), "Terrain channel tainting not working correctly."); | 51 | Assert.That(x.Tainted(0, 0), "Terrain channel tainting not working correctly."); |
52 | Assert.That(!x.Tainted(0, 0), "Terrain channel tainting not working correctly."); | 52 | Assert.That(!x.Tainted(0, 0), "Terrain channel tainting not working correctly."); |
53 | 53 | ||
54 | TerrainChannel y = x.Copy(); | 54 | TerrainChannel y = x.Copy(); |
55 | Assert.That(!ReferenceEquals(x, y), "Terrain copy not duplicating correctly."); | 55 | Assert.That(!ReferenceEquals(x, y), "Terrain copy not duplicating correctly."); |
56 | Assert.That(!ReferenceEquals(x.GetDoubles(), y.GetDoubles()), "Terrain array not duplicating correctly."); | 56 | Assert.That(!ReferenceEquals(x.GetDoubles(), y.GetDoubles()), "Terrain array not duplicating correctly."); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | } \ No newline at end of file | 59 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs index f144444..32e45b7 100644 --- a/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs | |||
@@ -1,251 +1,251 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Timers; | 31 | using System.Timers; |
32 | using Axiom.Math; | 32 | using Axiom.Math; |
33 | using libsecondlife; | 33 | using libsecondlife; |
34 | using log4net; | 34 | using log4net; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | 39 | ||
40 | namespace OpenSim.Region.Environment.Modules | 40 | namespace OpenSim.Region.Environment.Modules |
41 | { | 41 | { |
42 | /// <summary> | 42 | /// <summary> |
43 | /// Version 2.0 - Very hacky compared to the original. Will fix original and release as 0.3 later. | 43 | /// Version 2.0 - Very hacky compared to the original. Will fix original and release as 0.3 later. |
44 | /// </summary> | 44 | /// </summary> |
45 | public class TreePopulatorModule : IRegionModule | 45 | public class TreePopulatorModule : IRegionModule |
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | private Scene m_scene; | 48 | private Scene m_scene; |
49 | 49 | ||
50 | public double m_tree_density = 50.0; // Aim for this many per region | 50 | public double m_tree_density = 50.0; // Aim for this many per region |
51 | public double m_tree_updates = 1000.0; // MS between updates | 51 | public double m_tree_updates = 1000.0; // MS between updates |
52 | private List<LLUUID> m_trees; | 52 | private List<LLUUID> m_trees; |
53 | 53 | ||
54 | #region IRegionModule Members | 54 | #region IRegionModule Members |
55 | 55 | ||
56 | public void Initialise(Scene scene, IConfigSource config) | 56 | public void Initialise(Scene scene, IConfigSource config) |
57 | { | 57 | { |
58 | try | 58 | try |
59 | { | 59 | { |
60 | m_tree_density = config.Configs["Trees"].GetDouble("tree_density", m_tree_density); | 60 | m_tree_density = config.Configs["Trees"].GetDouble("tree_density", m_tree_density); |
61 | } | 61 | } |
62 | catch (Exception) | 62 | catch (Exception) |
63 | { | 63 | { |
64 | } | 64 | } |
65 | 65 | ||
66 | m_trees = new List<LLUUID>(); | 66 | m_trees = new List<LLUUID>(); |
67 | m_scene = scene; | 67 | m_scene = scene; |
68 | 68 | ||
69 | m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole); | 69 | m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole); |
70 | 70 | ||
71 | Timer CalculateTrees = new Timer(m_tree_updates); | 71 | Timer CalculateTrees = new Timer(m_tree_updates); |
72 | CalculateTrees.Elapsed += new ElapsedEventHandler(CalculateTrees_Elapsed); | 72 | CalculateTrees.Elapsed += new ElapsedEventHandler(CalculateTrees_Elapsed); |
73 | CalculateTrees.Start(); | 73 | CalculateTrees.Start(); |
74 | m_log.Debug("[TREES]: Initialised tree module"); | 74 | m_log.Debug("[TREES]: Initialised tree module"); |
75 | } | 75 | } |
76 | 76 | ||
77 | public void PostInitialise() | 77 | public void PostInitialise() |
78 | { | 78 | { |
79 | } | 79 | } |
80 | 80 | ||
81 | public void Close() | 81 | public void Close() |
82 | { | 82 | { |
83 | } | 83 | } |
84 | 84 | ||
85 | public string Name | 85 | public string Name |
86 | { | 86 | { |
87 | get { return "TreePopulatorModule"; } | 87 | get { return "TreePopulatorModule"; } |
88 | } | 88 | } |
89 | 89 | ||
90 | public bool IsSharedModule | 90 | public bool IsSharedModule |
91 | { | 91 | { |
92 | get { return false; } | 92 | get { return false; } |
93 | } | 93 | } |
94 | 94 | ||
95 | #endregion | 95 | #endregion |
96 | 96 | ||
97 | private void EventManager_OnPluginConsole(string[] args) | 97 | private void EventManager_OnPluginConsole(string[] args) |
98 | { | 98 | { |
99 | if (args[0] == "tree") | 99 | if (args[0] == "tree") |
100 | { | 100 | { |
101 | m_log.Debug("[TREES]: New tree planting"); | 101 | m_log.Debug("[TREES]: New tree planting"); |
102 | CreateTree(new LLVector3(128.0f, 128.0f, 0.0f)); | 102 | CreateTree(new LLVector3(128.0f, 128.0f, 0.0f)); |
103 | } | 103 | } |
104 | } | 104 | } |
105 | 105 | ||
106 | private void growTrees() | 106 | private void growTrees() |
107 | { | 107 | { |
108 | foreach (LLUUID tree in m_trees) | 108 | foreach (LLUUID tree in m_trees) |
109 | { | 109 | { |
110 | if (m_scene.Entities.ContainsKey(tree)) | 110 | if (m_scene.Entities.ContainsKey(tree)) |
111 | { | 111 | { |
112 | SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart; | 112 | SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart; |
113 | 113 | ||
114 | // 100 seconds to grow 1m | 114 | // 100 seconds to grow 1m |
115 | s_tree.Scale += new LLVector3(0.1f, 0.1f, 0.1f); | 115 | s_tree.Scale += new LLVector3(0.1f, 0.1f, 0.1f); |
116 | s_tree.SendFullUpdateToAllClients(); | 116 | s_tree.SendFullUpdateToAllClients(); |
117 | //s_tree.ScheduleTerseUpdate(); | 117 | //s_tree.ScheduleTerseUpdate(); |
118 | } | 118 | } |
119 | else | 119 | else |
120 | { | 120 | { |
121 | m_trees.Remove(tree); | 121 | m_trees.Remove(tree); |
122 | } | 122 | } |
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | private void seedTrees() | 126 | private void seedTrees() |
127 | { | 127 | { |
128 | foreach (LLUUID tree in m_trees) | 128 | foreach (LLUUID tree in m_trees) |
129 | { | 129 | { |
130 | if (m_scene.Entities.ContainsKey(tree)) | 130 | if (m_scene.Entities.ContainsKey(tree)) |
131 | { | 131 | { |
132 | SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart; | 132 | SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart; |
133 | 133 | ||
134 | if (s_tree.Scale.X > 0.5) | 134 | if (s_tree.Scale.X > 0.5) |
135 | { | 135 | { |
136 | if (Util.RandomClass.NextDouble() > 0.75) | 136 | if (Util.RandomClass.NextDouble() > 0.75) |
137 | { | 137 | { |
138 | SpawnChild(s_tree); | 138 | SpawnChild(s_tree); |
139 | } | 139 | } |
140 | } | 140 | } |
141 | } | 141 | } |
142 | else | 142 | else |
143 | { | 143 | { |
144 | m_trees.Remove(tree); | 144 | m_trees.Remove(tree); |
145 | } | 145 | } |
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | private void killTrees() | 149 | private void killTrees() |
150 | { | 150 | { |
151 | foreach (LLUUID tree in m_trees) | 151 | foreach (LLUUID tree in m_trees) |
152 | { | 152 | { |
153 | double killLikelyhood = 0.0; | 153 | double killLikelyhood = 0.0; |
154 | 154 | ||
155 | if (m_scene.Entities.ContainsKey(tree)) | 155 | if (m_scene.Entities.ContainsKey(tree)) |
156 | { | 156 | { |
157 | SceneObjectPart selectedTree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart; | 157 | SceneObjectPart selectedTree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart; |
158 | double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) + | 158 | double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) + |
159 | Math.Pow(selectedTree.Scale.Y, 2) + | 159 | Math.Pow(selectedTree.Scale.Y, 2) + |
160 | Math.Pow(selectedTree.Scale.Z, 2)); | 160 | Math.Pow(selectedTree.Scale.Z, 2)); |
161 | 161 | ||
162 | foreach (LLUUID picktree in m_trees) | 162 | foreach (LLUUID picktree in m_trees) |
163 | { | 163 | { |
164 | if (picktree != tree) | 164 | if (picktree != tree) |
165 | { | 165 | { |
166 | SceneObjectPart pickedTree = ((SceneObjectGroup) m_scene.Entities[picktree]).RootPart; | 166 | SceneObjectPart pickedTree = ((SceneObjectGroup) m_scene.Entities[picktree]).RootPart; |
167 | 167 | ||
168 | double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) + | 168 | double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) + |
169 | Math.Pow(pickedTree.Scale.Y, 2) + | 169 | Math.Pow(pickedTree.Scale.Y, 2) + |
170 | Math.Pow(pickedTree.Scale.Z, 2)); | 170 | Math.Pow(pickedTree.Scale.Z, 2)); |
171 | 171 | ||
172 | double pickedTreeDistance = Math.Sqrt(Math.Pow(Math.Abs(pickedTree.AbsolutePosition.X - selectedTree.AbsolutePosition.X), 2) + | 172 | double pickedTreeDistance = Math.Sqrt(Math.Pow(Math.Abs(pickedTree.AbsolutePosition.X - selectedTree.AbsolutePosition.X), 2) + |
173 | Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Y - selectedTree.AbsolutePosition.Y), 2) + | 173 | Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Y - selectedTree.AbsolutePosition.Y), 2) + |
174 | Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Z - selectedTree.AbsolutePosition.Z), 2)); | 174 | Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Z - selectedTree.AbsolutePosition.Z), 2)); |
175 | 175 | ||
176 | killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1; | 176 | killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1; |
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | if (Util.RandomClass.NextDouble() < killLikelyhood) | 180 | if (Util.RandomClass.NextDouble() < killLikelyhood) |
181 | { | 181 | { |
182 | m_scene.RemoveEntity(selectedTree.ParentGroup); | 182 | m_scene.RemoveEntity(selectedTree.ParentGroup); |
183 | m_trees.Remove(selectedTree.ParentGroup.UUID); | 183 | m_trees.Remove(selectedTree.ParentGroup.UUID); |
184 | 184 | ||
185 | m_scene.ForEachClient(delegate(IClientAPI controller) | 185 | m_scene.ForEachClient(delegate(IClientAPI controller) |
186 | { | 186 | { |
187 | controller.SendKillObject(m_scene.RegionInfo.RegionHandle, | 187 | controller.SendKillObject(m_scene.RegionInfo.RegionHandle, |
188 | selectedTree.LocalId); | 188 | selectedTree.LocalId); |
189 | }); | 189 | }); |
190 | 190 | ||
191 | break; | 191 | break; |
192 | } | 192 | } |
193 | else | 193 | else |
194 | { | 194 | { |
195 | selectedTree.SetText(killLikelyhood.ToString(), new Vector3(1.0f, 1.0f, 1.0f), 1.0); | 195 | selectedTree.SetText(killLikelyhood.ToString(), new Vector3(1.0f, 1.0f, 1.0f), 1.0); |
196 | } | 196 | } |
197 | } | 197 | } |
198 | else | 198 | else |
199 | { | 199 | { |
200 | m_trees.Remove(tree); | 200 | m_trees.Remove(tree); |
201 | } | 201 | } |
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | private void SpawnChild(SceneObjectPart s_tree) | 205 | private void SpawnChild(SceneObjectPart s_tree) |
206 | { | 206 | { |
207 | LLVector3 position = new LLVector3(); | 207 | LLVector3 position = new LLVector3(); |
208 | 208 | ||
209 | position.X = s_tree.AbsolutePosition.X + (1 * (-1 * Util.RandomClass.Next(1))); | 209 | position.X = s_tree.AbsolutePosition.X + (1 * (-1 * Util.RandomClass.Next(1))); |
210 | if (position.X > 255) | 210 | if (position.X > 255) |
211 | position.X = 255; | 211 | position.X = 255; |
212 | if (position.X < 0) | 212 | if (position.X < 0) |
213 | position.X = 0; | 213 | position.X = 0; |
214 | position.Y = s_tree.AbsolutePosition.Y + (1 * (-1 * Util.RandomClass.Next(1))); | 214 | position.Y = s_tree.AbsolutePosition.Y + (1 * (-1 * Util.RandomClass.Next(1))); |
215 | if (position.Y > 255) | 215 | if (position.Y > 255) |
216 | position.Y = 255; | 216 | position.Y = 255; |
217 | if (position.Y < 0) | 217 | if (position.Y < 0) |
218 | position.Y = 0; | 218 | position.Y = 0; |
219 | 219 | ||
220 | double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3); | 220 | double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3); |
221 | double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3); | 221 | double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3); |
222 | 222 | ||
223 | position.X += (float) randX; | 223 | position.X += (float) randX; |
224 | position.Y += (float) randY; | 224 | position.Y += (float) randY; |
225 | 225 | ||
226 | CreateTree(position); | 226 | CreateTree(position); |
227 | } | 227 | } |
228 | 228 | ||
229 | private void CreateTree(LLVector3 position) | 229 | private void CreateTree(LLVector3 position) |
230 | { | 230 | { |
231 | position.Z = (float) m_scene.Heightmap[(int) position.X, (int) position.Y]; | 231 | position.Z = (float) m_scene.Heightmap[(int) position.X, (int) position.Y]; |
232 | 232 | ||
233 | SceneObjectGroup tree = | 233 | SceneObjectGroup tree = |
234 | m_scene.AddTree(new LLVector3(0.1f, 0.1f, 0.1f), | 234 | m_scene.AddTree(new LLVector3(0.1f, 0.1f, 0.1f), |
235 | LLQuaternion.Identity, | 235 | LLQuaternion.Identity, |
236 | position, | 236 | position, |
237 | Tree.Cypress1, | 237 | Tree.Cypress1, |
238 | false); | 238 | false); |
239 | 239 | ||
240 | m_trees.Add(tree.UUID); | 240 | m_trees.Add(tree.UUID); |
241 | tree.SendGroupFullUpdate(); | 241 | tree.SendGroupFullUpdate(); |
242 | } | 242 | } |
243 | 243 | ||
244 | private void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e) | 244 | private void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e) |
245 | { | 245 | { |
246 | growTrees(); | 246 | growTrees(); |
247 | seedTrees(); | 247 | seedTrees(); |
248 | killTrees(); | 248 | killTrees(); |
249 | } | 249 | } |
250 | } | 250 | } |
251 | } \ No newline at end of file | 251 | } \ No newline at end of file |