aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:16:36 +0000
committerAdam Frisby2008-04-30 21:16:36 +0000
commitf5c312bc3c2567449c7268a54a08a54119f58d53 (patch)
tree424668a4bbec6873ebc5b8256f3671db102f5e9c
parent* Adds the AuthbuyerID field to sqlite and makes use of it. (diff)
downloadopensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.zip
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.gz
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.bz2
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.xz
* Refactored Environment/Modules directory - modules now reside in their own directory with any associated module-specific classes.
* Each module directory is currently inside one of the following category folders: Agent (Anything relating to do with Client<->Server communications.), Avatar (Anything to do with the avatar or presence inworld), Framework (Classes modules can use), Grid (Grid traffic, new OGS2 grid comms), Scripting (Scripting functions, etc), World (The enrivonment/scene, IE Sun/Tree modules.) * This should be moved into a seperate project file.
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs (renamed from OpenSim/Region/Environment/Modules/AssetDownloadModule.cs)666
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs (renamed from OpenSim/Region/Environment/Modules/AgentAssetsTransactions.cs)815
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs (renamed from OpenSim/Region/Environment/Modules/AgentAssetTransactionModule.cs)572
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs (renamed from OpenSim/Region/Environment/Modules/TextureDownloadModule.cs)433
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs (renamed from OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs)186
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs (renamed from OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs)502
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs (renamed from OpenSim/Region/Environment/Modules/TextureSender.cs)440
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs (renamed from OpenSim/Region/Environment/Modules/XferModule.cs)450
-rw-r--r--OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs244
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs (renamed from OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs)676
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs (renamed from OpenSim/Region/Environment/Modules/ChatModule.cs)1662
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs (renamed from OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs)2981
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs (renamed from OpenSim/Region/Environment/Modules/FriendsModule.cs)1008
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs (renamed from OpenSim/Region/Environment/Modules/GroupsModule.cs)556
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs (renamed from OpenSim/Region/Environment/Modules/InstantMessageModule.cs)316
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs (renamed from OpenSim/Region/Environment/Modules/InventoryModule.cs)432
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs (renamed from OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs)258
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs (renamed from OpenSim/Region/Environment/Modules/AsteriskVoiceModule.cs)570
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs (renamed from OpenSim/Region/Environment/Modules/VoiceModule.cs)394
-rw-r--r--OpenSim/Region/Environment/Modules/CommanderTestModule.cs89
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs15
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs174
-rw-r--r--OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs50
-rw-r--r--OpenSim/Region/Environment/Modules/EmailModule.cs33
-rw-r--r--OpenSim/Region/Environment/Modules/ExportSerialiser/ExportSerialisationModule.cs168
-rw-r--r--OpenSim/Region/Environment/Modules/ExportSerialiser/IFileSerialiser.cs36
-rw-r--r--OpenSim/Region/Environment/Modules/ExportSerialiser/IRegionSerialiser.cs37
-rw-r--r--OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseObjects.cs123
-rw-r--r--OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseTerrain.cs53
-rw-r--r--OpenSim/Region/Environment/Modules/LandManagement/LandChannel.cs1008
-rw-r--r--OpenSim/Region/Environment/Modules/LandManagement/LandManagementModule.cs85
-rw-r--r--OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs947
-rw-r--r--OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs308
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs (renamed from OpenSim/Region/Environment/Modules/DynamicTextureModule.cs)554
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs (renamed from OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs)720
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs (renamed from OpenSim/Region/Environment/Modules/LoadImageURLModule.cs)359
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs (renamed from OpenSim/Region/Environment/Modules/VectorRenderModule.cs)722
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs (renamed from OpenSim/Region/Environment/Modules/WorldCommModule.cs)1162
-rw-r--r--OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs (renamed from OpenSim/Region/Environment/Modules/XMLRPCModule.cs)1352
-rw-r--r--OpenSim/Region/Environment/Modules/SunModule.cs195
-rw-r--r--OpenSim/Region/Environment/Modules/TeleportModule.cs33
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/Effects/CookieCutter.cs124
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/Effects/DefaultTerrainGenerator.cs55
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/BMP.cs62
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GIF.cs47
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GenericSystemDrawing.cs172
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs94
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs148
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/PNG.cs47
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs153
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/TIFF.cs47
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs127
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs71
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/LowerArea.cs54
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs56
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RaiseArea.cs53
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RevertArea.cs60
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/SmoothArea.cs114
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs36
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs37
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs39
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/ITerrainModule.cs8
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs36
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/MapImageModule.cs168
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/ErodeSphere.cs312
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/FlattenSphere.cs127
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/LowerSphere.cs67
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs70
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/OlsenSphere.cs225
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RaiseSphere.cs67
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RevertSphere.cs82
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/SmoothSphere.cs93
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/WeatherSphere.cs207
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs157
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/TerrainException.cs46
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs734
-rw-r--r--OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs133
-rw-r--r--OpenSim/Region/Environment/Modules/TreePopulatorModule.cs248
78 files changed, 8880 insertions, 16880 deletions
diff --git a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
index 97db31e..47c1479 100644
--- a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
@@ -1,333 +1,333 @@
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
28using System.Collections.Generic; 28using System.Collections.Generic;
29using libsecondlife; 29using libsecondlife;
30using libsecondlife.Packets; 30using libsecondlife.Packets;
31using Nini.Config; 31using Nini.Config;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35 35
36namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload
37{ 37{
38 public class AssetDownloadModule : IRegionModule 38 public class AssetDownloadModule : IRegionModule
39 { 39 {
40 private Scene m_scene; 40 private Scene m_scene;
41 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); 41 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
42 /// 42 ///
43 /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests 43 /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests
44 /// </summary> 44 /// </summary>
45 private Dictionary<LLUUID, Dictionary<LLUUID,AssetRequest>> RequestedAssets; 45 private Dictionary<LLUUID, Dictionary<LLUUID,AssetRequest>> RequestedAssets;
46 46
47 /// <summary> 47 /// <summary>
48 /// Asset requests with data which are ready to be sent back to requesters. This includes textures. 48 /// Asset requests with data which are ready to be sent back to requesters. This includes textures.
49 /// </summary> 49 /// </summary>
50 private List<AssetRequest> AssetRequests; 50 private List<AssetRequest> AssetRequests;
51 51
52 public AssetDownloadModule() 52 public AssetDownloadModule()
53 { 53 {
54 RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>(); 54 RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>();
55 AssetRequests = new List<AssetRequest>(); 55 AssetRequests = new List<AssetRequest>();
56 } 56 }
57 57
58 public void Initialise(Scene scene, IConfigSource config) 58 public void Initialise(Scene scene, IConfigSource config)
59 { 59 {
60 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 60 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
61 { 61 {
62 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 62 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
63 // scene.EventManager.OnNewClient += NewClient; 63 // scene.EventManager.OnNewClient += NewClient;
64 } 64 }
65 65
66 if (m_scene == null) 66 if (m_scene == null)
67 { 67 {
68 m_scene = scene; 68 m_scene = scene;
69 // m_thread = new Thread(new ThreadStart(RunAssetQueue)); 69 // m_thread = new Thread(new ThreadStart(RunAssetQueue));
70 // m_thread.Name = "AssetDownloadQueueThread"; 70 // m_thread.Name = "AssetDownloadQueueThread";
71 // m_thread.IsBackground = true; 71 // m_thread.IsBackground = true;
72 // m_thread.Start(); 72 // m_thread.Start();
73 // OpenSim.Framework.ThreadTracker.Add(m_thread); 73 // OpenSim.Framework.ThreadTracker.Add(m_thread);
74 } 74 }
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 "AssetDownloadModule"; } 87 get { return "AssetDownloadModule"; }
88 } 88 }
89 89
90 public bool IsSharedModule 90 public bool IsSharedModule
91 { 91 {
92 get { return true; } 92 get { return true; }
93 } 93 }
94 94
95 public void NewClient(IClientAPI client) 95 public void NewClient(IClientAPI client)
96 { 96 {
97 // client.OnRequestAsset += AddAssetRequest; 97 // client.OnRequestAsset += AddAssetRequest;
98 } 98 }
99 99
100 /// <summary> 100 /// <summary>
101 /// Make an asset request the result of which will be packeted up and sent directly back to the client. 101 /// Make an asset request the result of which will be packeted up and sent directly back to the client.
102 /// </summary> 102 /// </summary>
103 /// <param name="userInfo"></param> 103 /// <param name="userInfo"></param>
104 /// <param name="transferRequest"></param> 104 /// <param name="transferRequest"></param>
105 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) 105 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
106 { 106 {
107 LLUUID requestID = null; 107 LLUUID requestID = null;
108 byte source = 2; 108 byte source = 2;
109 if (transferRequest.TransferInfo.SourceType == 2) 109 if (transferRequest.TransferInfo.SourceType == 2)
110 { 110 {
111 //direct asset request 111 //direct asset request
112 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); 112 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
113 } 113 }
114 else if (transferRequest.TransferInfo.SourceType == 3) 114 else if (transferRequest.TransferInfo.SourceType == 3)
115 { 115 {
116 //inventory asset request 116 //inventory asset request
117 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); 117 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
118 source = 3; 118 source = 3;
119 //Console.WriteLine("asset request " + requestID); 119 //Console.WriteLine("asset request " + requestID);
120 } 120 }
121 121
122 //not found asset 122 //not found asset
123 // so request from asset server 123 // so request from asset server
124 Dictionary<LLUUID, AssetRequest> userRequests = null; 124 Dictionary<LLUUID, AssetRequest> userRequests = null;
125 if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests)) 125 if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests))
126 { 126 {
127 if (!userRequests.ContainsKey(requestID)) 127 if (!userRequests.ContainsKey(requestID))
128 { 128 {
129 AssetRequest request = new AssetRequest(); 129 AssetRequest request = new AssetRequest();
130 request.RequestUser = userInfo; 130 request.RequestUser = userInfo;
131 request.RequestAssetID = requestID; 131 request.RequestAssetID = requestID;
132 request.TransferRequestID = transferRequest.TransferInfo.TransferID; 132 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
133 request.AssetRequestSource = source; 133 request.AssetRequestSource = source;
134 request.Params = transferRequest.TransferInfo.Params; 134 request.Params = transferRequest.TransferInfo.Params;
135 userRequests[requestID] = request; 135 userRequests[requestID] = request;
136 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); 136 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
137 } 137 }
138 } 138 }
139 else 139 else
140 { 140 {
141 userRequests = new Dictionary<LLUUID, AssetRequest>(); 141 userRequests = new Dictionary<LLUUID, AssetRequest>();
142 AssetRequest request = new AssetRequest(); 142 AssetRequest request = new AssetRequest();
143 request.RequestUser = userInfo; 143 request.RequestUser = userInfo;
144 request.RequestAssetID = requestID; 144 request.RequestAssetID = requestID;
145 request.TransferRequestID = transferRequest.TransferInfo.TransferID; 145 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
146 request.AssetRequestSource = source; 146 request.AssetRequestSource = source;
147 request.Params = transferRequest.TransferInfo.Params; 147 request.Params = transferRequest.TransferInfo.Params;
148 userRequests.Add(requestID, request); 148 userRequests.Add(requestID, request);
149 RequestedAssets[userInfo.AgentId] = userRequests; 149 RequestedAssets[userInfo.AgentId] = userRequests;
150 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); 150 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
151 } 151 }
152 } 152 }
153 153
154 public void AssetCallback(LLUUID assetID, AssetBase asset) 154 public void AssetCallback(LLUUID assetID, AssetBase asset)
155 { 155 {
156 if (asset != null) 156 if (asset != null)
157 { 157 {
158 foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values) 158 foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values)
159 { 159 {
160 if (userRequests.ContainsKey(assetID)) 160 if (userRequests.ContainsKey(assetID))
161 { 161 {
162 AssetRequest req = userRequests[assetID]; 162 AssetRequest req = userRequests[assetID];
163 if (req != null) 163 if (req != null)
164 { 164 {
165 req.AssetInf = asset; 165 req.AssetInf = asset;
166 req.NumPackets = CalculateNumPackets(asset.Data); 166 req.NumPackets = CalculateNumPackets(asset.Data);
167 167
168 userRequests.Remove(assetID); 168 userRequests.Remove(assetID);
169 AssetRequests.Add(req); 169 AssetRequests.Add(req);
170 } 170 }
171 } 171 }
172 } 172 }
173 } 173 }
174 } 174 }
175 175
176// TODO: unused 176// TODO: unused
177// private void RunAssetQueue() 177// private void RunAssetQueue()
178// { 178// {
179// while (true) 179// while (true)
180// { 180// {
181// try 181// try
182// { 182// {
183// ProcessAssetQueue(); 183// ProcessAssetQueue();
184// Thread.Sleep(500); 184// Thread.Sleep(500);
185// } 185// }
186// catch (Exception) 186// catch (Exception)
187// { 187// {
188// // m_log.Error("[ASSET CACHE]: " + e.ToString()); 188// // m_log.Error("[ASSET CACHE]: " + e.ToString());
189// } 189// }
190// } 190// }
191// } 191// }
192 192
193// TODO: unused 193// TODO: unused
194// /// <summary> 194// /// <summary>
195// /// Process the asset queue which sends packets directly back to the client. 195// /// Process the asset queue which sends packets directly back to the client.
196// /// </summary> 196// /// </summary>
197// private void ProcessAssetQueue() 197// private void ProcessAssetQueue()
198// { 198// {
199// //should move the asset downloading to a module, like has been done with texture downloading 199// //should move the asset downloading to a module, like has been done with texture downloading
200// if (AssetRequests.Count == 0) 200// if (AssetRequests.Count == 0)
201// { 201// {
202// //no requests waiting 202// //no requests waiting
203// return; 203// return;
204// } 204// }
205// // if less than 5, do all of them 205// // if less than 5, do all of them
206// int num = Math.Min(5, AssetRequests.Count); 206// int num = Math.Min(5, AssetRequests.Count);
207 207
208// AssetRequest req; 208// AssetRequest req;
209// for (int i = 0; i < num; i++) 209// for (int i = 0; i < num; i++)
210// { 210// {
211// req = (AssetRequest)AssetRequests[i]; 211// req = (AssetRequest)AssetRequests[i];
212// //Console.WriteLine("sending asset " + req.RequestAssetID); 212// //Console.WriteLine("sending asset " + req.RequestAssetID);
213// TransferInfoPacket Transfer = new TransferInfoPacket(); 213// TransferInfoPacket Transfer = new TransferInfoPacket();
214// Transfer.TransferInfo.ChannelType = 2; 214// Transfer.TransferInfo.ChannelType = 2;
215// Transfer.TransferInfo.Status = 0; 215// Transfer.TransferInfo.Status = 0;
216// Transfer.TransferInfo.TargetType = 0; 216// Transfer.TransferInfo.TargetType = 0;
217// if (req.AssetRequestSource == 2) 217// if (req.AssetRequestSource == 2)
218// { 218// {
219// Transfer.TransferInfo.Params = new byte[20]; 219// Transfer.TransferInfo.Params = new byte[20];
220// Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 220// Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
221// int assType = (int)req.AssetInf.Type; 221// int assType = (int)req.AssetInf.Type;
222// Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); 222// Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
223// } 223// }
224// else if (req.AssetRequestSource == 3) 224// else if (req.AssetRequestSource == 3)
225// { 225// {
226// Transfer.TransferInfo.Params = req.Params; 226// Transfer.TransferInfo.Params = req.Params;
227// // Transfer.TransferInfo.Params = new byte[100]; 227// // Transfer.TransferInfo.Params = new byte[100];
228// //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 228// //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
229// //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); 229// //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
230// } 230// }
231// Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; 231// Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
232// Transfer.TransferInfo.TransferID = req.TransferRequestID; 232// Transfer.TransferInfo.TransferID = req.TransferRequestID;
233// req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset); 233// req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
234 234
235// if (req.NumPackets == 1) 235// if (req.NumPackets == 1)
236// { 236// {
237// TransferPacketPacket TransferPacket = new TransferPacketPacket(); 237// TransferPacketPacket TransferPacket = new TransferPacketPacket();
238// TransferPacket.TransferData.Packet = 0; 238// TransferPacket.TransferData.Packet = 0;
239// TransferPacket.TransferData.ChannelType = 2; 239// TransferPacket.TransferData.ChannelType = 2;
240// TransferPacket.TransferData.TransferID = req.TransferRequestID; 240// TransferPacket.TransferData.TransferID = req.TransferRequestID;
241// TransferPacket.TransferData.Data = req.AssetInf.Data; 241// TransferPacket.TransferData.Data = req.AssetInf.Data;
242// TransferPacket.TransferData.Status = 1; 242// TransferPacket.TransferData.Status = 1;
243// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 243// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
244// } 244// }
245// else 245// else
246// { 246// {
247// int processedLength = 0; 247// int processedLength = 0;
248// // libsecondlife hardcodes 1500 as the maximum data chunk size 248// // libsecondlife hardcodes 1500 as the maximum data chunk size
249// int maxChunkSize = 1250; 249// int maxChunkSize = 1250;
250// int packetNumber = 0; 250// int packetNumber = 0;
251 251
252// while (processedLength < req.AssetInf.Data.Length) 252// while (processedLength < req.AssetInf.Data.Length)
253// { 253// {
254// TransferPacketPacket TransferPacket = new TransferPacketPacket(); 254// TransferPacketPacket TransferPacket = new TransferPacketPacket();
255// TransferPacket.TransferData.Packet = packetNumber; 255// TransferPacket.TransferData.Packet = packetNumber;
256// TransferPacket.TransferData.ChannelType = 2; 256// TransferPacket.TransferData.ChannelType = 2;
257// TransferPacket.TransferData.TransferID = req.TransferRequestID; 257// TransferPacket.TransferData.TransferID = req.TransferRequestID;
258 258
259// int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); 259// int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
260// byte[] chunk = new byte[chunkSize]; 260// byte[] chunk = new byte[chunkSize];
261// Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); 261// Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
262 262
263// TransferPacket.TransferData.Data = chunk; 263// TransferPacket.TransferData.Data = chunk;
264 264
265// // 0 indicates more packets to come, 1 indicates last packet 265// // 0 indicates more packets to come, 1 indicates last packet
266// if (req.AssetInf.Data.Length - processedLength > maxChunkSize) 266// if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
267// { 267// {
268// TransferPacket.TransferData.Status = 0; 268// TransferPacket.TransferData.Status = 0;
269// } 269// }
270// else 270// else
271// { 271// {
272// TransferPacket.TransferData.Status = 1; 272// TransferPacket.TransferData.Status = 1;
273// } 273// }
274 274
275// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 275// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
276 276
277// processedLength += chunkSize; 277// processedLength += chunkSize;
278// packetNumber++; 278// packetNumber++;
279// } 279// }
280// } 280// }
281// } 281// }
282 282
283// //remove requests that have been completed 283// //remove requests that have been completed
284// for (int i = 0; i < num; i++) 284// for (int i = 0; i < num; i++)
285// { 285// {
286// AssetRequests.RemoveAt(0); 286// AssetRequests.RemoveAt(0);
287// } 287// }
288// } 288// }
289 289
290 /// <summary> 290 /// <summary>
291 /// Calculate the number of packets required to send the asset to the client. 291 /// Calculate the number of packets required to send the asset to the client.
292 /// </summary> 292 /// </summary>
293 /// <param name="data"></param> 293 /// <param name="data"></param>
294 /// <returns></returns> 294 /// <returns></returns>
295 private int CalculateNumPackets(byte[] data) 295 private int CalculateNumPackets(byte[] data)
296 { 296 {
297 const uint m_maxPacketSize = 600; 297 const uint m_maxPacketSize = 600;
298 int numPackets = 1; 298 int numPackets = 1;
299 299
300 if (data.LongLength > m_maxPacketSize) 300 if (data.LongLength > m_maxPacketSize)
301 { 301 {
302 // over max number of bytes so split up file 302 // over max number of bytes so split up file
303 long restData = data.LongLength - m_maxPacketSize; 303 long restData = data.LongLength - m_maxPacketSize;
304 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize); 304 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
305 numPackets += restPackets; 305 numPackets += restPackets;
306 } 306 }
307 307
308 return numPackets; 308 return numPackets;
309 } 309 }
310 310
311 public class AssetRequest 311 public class AssetRequest
312 { 312 {
313 public IClientAPI RequestUser; 313 public IClientAPI RequestUser;
314 public LLUUID RequestAssetID; 314 public LLUUID RequestAssetID;
315 public AssetBase AssetInf; 315 public AssetBase AssetInf;
316 public AssetBase ImageInfo; 316 public AssetBase ImageInfo;
317 public LLUUID TransferRequestID; 317 public LLUUID TransferRequestID;
318 public long DataPointer = 0; 318 public long DataPointer = 0;
319 public int NumPackets = 0; 319 public int NumPackets = 0;
320 public int PacketCounter = 0; 320 public int PacketCounter = 0;
321 public bool IsTextureRequest; 321 public bool IsTextureRequest;
322 public byte AssetRequestSource = 2; 322 public byte AssetRequestSource = 2;
323 public byte[] Params = null; 323 public byte[] Params = null;
324 //public bool AssetInCache; 324 //public bool AssetInCache;
325 //public int TimeRequested; 325 //public int TimeRequested;
326 public int DiscardLevel = -1; 326 public int DiscardLevel = -1;
327 327
328 public AssetRequest() 328 public AssetRequest()
329 { 329 {
330 } 330 }
331 } 331 }
332 } 332 }
333} 333} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/AgentAssetsTransactions.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 9fa173d..74bb247 100644
--- a/OpenSim/Region/Environment/Modules/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -1,408 +1,407 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using libsecondlife; 31using libsecondlife;
32using libsecondlife.Packets; 32using libsecondlife.Packets;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Cache; 34using OpenSim.Framework.Communications.Cache;
35 35
36namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
37{ 37{
38 38 /// <summary>
39 /// <summary> 39 /// Manage asset transactions for a single agent.
40 /// Manage asset transactions for a single agent. 40 /// </summary>
41 /// </summary> 41 public class AgentAssetTransactions
42 public class AgentAssetTransactions 42 {
43 { 43 //private static readonly log4net.ILog m_log
44 //private static readonly log4net.ILog m_log 44 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
45 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 45
46 46 // Fields
47 // Fields 47 public LLUUID UserID;
48 public LLUUID UserID; 48 public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
49 public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>(); 49 public AgentAssetTransactionsManager Manager;
50 public AgentAssetTransactionsManager Manager; 50 private bool m_dumpAssetsToFile;
51 private bool m_dumpAssetsToFile; 51
52 52 // Methods
53 // Methods 53 public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile)
54 public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile) 54 {
55 { 55 UserID = agentID;
56 UserID = agentID; 56 Manager = manager;
57 Manager = manager; 57 m_dumpAssetsToFile = dumpAssetsToFile;
58 m_dumpAssetsToFile = dumpAssetsToFile; 58 }
59 } 59
60 60 public AssetXferUploader RequestXferUploader(LLUUID transactionID)
61 public AssetXferUploader RequestXferUploader(LLUUID transactionID) 61 {
62 { 62 if (!XferUploaders.ContainsKey(transactionID))
63 if (!XferUploaders.ContainsKey(transactionID)) 63 {
64 { 64 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
65 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); 65
66 66 lock (XferUploaders)
67 lock (XferUploaders) 67 {
68 { 68 XferUploaders.Add(transactionID, uploader);
69 XferUploaders.Add(transactionID, uploader); 69 }
70 } 70
71 71 return uploader;
72 return uploader; 72 }
73 } 73 return null;
74 return null; 74 }
75 } 75
76 76 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
77 public void HandleXfer(ulong xferID, uint packetID, byte[] data) 77 {
78 { 78 // AssetXferUploader uploaderFound = null;
79 // AssetXferUploader uploaderFound = null; 79
80 80 lock (XferUploaders)
81 lock (XferUploaders) 81 {
82 { 82 foreach (AssetXferUploader uploader in XferUploaders.Values)
83 foreach (AssetXferUploader uploader in XferUploaders.Values) 83 {
84 { 84 if (uploader.XferID == xferID)
85 if (uploader.XferID == xferID) 85 {
86 { 86 uploader.HandleXferPacket(xferID, packetID, data);
87 uploader.HandleXferPacket(xferID, packetID, data); 87 break;
88 break; 88 }
89 } 89 }
90 } 90 }
91 } 91 }
92 } 92
93 93 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
94 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 94 uint callbackID, string description, string name, sbyte invType,
95 uint callbackID, string description, string name, sbyte invType, 95 sbyte type, byte wearableType, uint nextOwnerMask)
96 sbyte type, byte wearableType, uint nextOwnerMask) 96 {
97 { 97 if (XferUploaders.ContainsKey(transactionID))
98 if (XferUploaders.ContainsKey(transactionID)) 98 {
99 { 99 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID,
100 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, 100 callbackID, description, name, invType, type,
101 callbackID, description, name, invType, type, 101 wearableType, nextOwnerMask);
102 wearableType, nextOwnerMask); 102 }
103 } 103 }
104 } 104
105 105 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
106 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, 106 InventoryItemBase item)
107 InventoryItemBase item) 107 {
108 { 108 if (XferUploaders.ContainsKey(transactionID))
109 if (XferUploaders.ContainsKey(transactionID)) 109 {
110 { 110 XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item);
111 XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item); 111 }
112 } 112 }
113 } 113
114 114 /// <summary>
115 /// <summary> 115 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed.
116 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. 116 /// </summary>
117 /// </summary> 117 /// <param name="transactionID"></param>
118 /// <param name="transactionID"></param> 118 /// <returns>The asset if the upload has completed, null if it has not.</returns>
119 /// <returns>The asset if the upload has completed, null if it has not.</returns> 119 public AssetBase GetTransactionAsset(LLUUID transactionID)
120 public AssetBase GetTransactionAsset(LLUUID transactionID) 120 {
121 { 121 if (XferUploaders.ContainsKey(transactionID))
122 if (XferUploaders.ContainsKey(transactionID)) 122 {
123 { 123 AssetXferUploader uploader = XferUploaders[transactionID];
124 AssetXferUploader uploader = XferUploaders[transactionID]; 124 AssetBase asset = uploader.GetAssetData();
125 AssetBase asset = uploader.GetAssetData(); 125
126 126 lock (XferUploaders)
127 lock (XferUploaders) 127 {
128 { 128 XferUploaders.Remove(transactionID);
129 XferUploaders.Remove(transactionID); 129 }
130 } 130
131 131 return asset;
132 return asset; 132 }
133 } 133
134 134 return null;
135 return null; 135 }
136 } 136
137 137 // Nested Types
138 // Nested Types 138 public class AssetXferUploader
139 public class AssetXferUploader 139 {
140 { 140 // Fields
141 // Fields 141 public bool AddToInventory;
142 public bool AddToInventory; 142 public AssetBase Asset;
143 public AssetBase Asset; 143 public LLUUID InventFolder = LLUUID.Zero;
144 public LLUUID InventFolder = LLUUID.Zero; 144 private IClientAPI ourClient;
145 private IClientAPI ourClient; 145 public LLUUID TransactionID = LLUUID.Zero;
146 public LLUUID TransactionID = LLUUID.Zero; 146 public bool UploadComplete;
147 public bool UploadComplete; 147 public ulong XferID;
148 public ulong XferID; 148 private string m_name = String.Empty;
149 private string m_name = String.Empty; 149 private string m_description = String.Empty;
150 private string m_description = String.Empty; 150 private sbyte type = 0;
151 private sbyte type = 0; 151 private sbyte invType = 0;
152 private sbyte invType = 0; 152 private byte wearableType = 0;
153 private byte wearableType = 0; 153 private uint nextPerm = 0;
154 private uint nextPerm = 0; 154 private bool m_finished = false;
155 private bool m_finished = false; 155 private bool m_createItem = false;
156 private bool m_createItem = false; 156 private AgentAssetTransactions m_userTransactions;
157 private AgentAssetTransactions m_userTransactions; 157 private bool m_storeLocal;
158 private bool m_storeLocal; 158 private bool m_dumpAssetToFile;
159 private bool m_dumpAssetToFile; 159
160 160 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
161 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) 161 {
162 { 162 m_userTransactions = transactions;
163 m_userTransactions = transactions; 163 m_dumpAssetToFile = dumpAssetToFile;
164 m_dumpAssetToFile = dumpAssetToFile; 164 }
165 } 165
166 166 /// <summary>
167 /// <summary> 167 /// Process transfer data received from the client.
168 /// Process transfer data received from the client. 168 /// </summary>
169 /// </summary> 169 /// <param name="xferID"></param>
170 /// <param name="xferID"></param> 170 /// <param name="packetID"></param>
171 /// <param name="packetID"></param> 171 /// <param name="data"></param>
172 /// <param name="data"></param> 172 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
173 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> 173 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
174 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) 174 {
175 { 175 if (XferID == xferID)
176 if (XferID == xferID) 176 {
177 { 177 if (Asset.Data.Length > 1)
178 if (Asset.Data.Length > 1) 178 {
179 { 179 byte[] destinationArray = new byte[Asset.Data.Length + data.Length];
180 byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; 180 Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length);
181 Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); 181 Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length);
182 Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); 182 Asset.Data = destinationArray;
183 Asset.Data = destinationArray; 183 }
184 } 184 else
185 else 185 {
186 { 186 byte[] buffer2 = new byte[data.Length - 4];
187 byte[] buffer2 = new byte[data.Length - 4]; 187 Array.Copy(data, 4, buffer2, 0, data.Length - 4);
188 Array.Copy(data, 4, buffer2, 0, data.Length - 4); 188 Asset.Data = buffer2;
189 Asset.Data = buffer2; 189 }
190 } 190 ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
191 ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); 191 newPack.XferID.ID = xferID;
192 newPack.XferID.ID = xferID; 192 newPack.XferID.Packet = packetID;
193 newPack.XferID.Packet = packetID; 193 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
194 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); 194 if ((packetID & 0x80000000) != 0)
195 if ((packetID & 0x80000000) != 0) 195 {
196 { 196 SendCompleteMessage();
197 SendCompleteMessage(); 197 return true;
198 return true; 198 }
199 } 199 }
200 } 200
201 201 return false;
202 return false; 202 }
203 } 203
204 204 /// <summary>
205 /// <summary> 205 /// Initialise asset transfer from the client
206 /// Initialise asset transfer from the client 206 /// </summary>
207 /// </summary> 207 /// <param name="xferID"></param>
208 /// <param name="xferID"></param> 208 /// <param name="packetID"></param>
209 /// <param name="packetID"></param> 209 /// <param name="data"></param>
210 /// <param name="data"></param> 210 /// <returns>True if the transfer is complete, false otherwise</returns>
211 /// <returns>True if the transfer is complete, false otherwise</returns> 211 public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data,
212 public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, 212 bool storeLocal, bool tempFile)
213 bool storeLocal, bool tempFile) 213 {
214 { 214 ourClient = remoteClient;
215 ourClient = remoteClient; 215 Asset = new AssetBase();
216 Asset = new AssetBase(); 216 Asset.FullID = assetID;
217 Asset.FullID = assetID; 217 Asset.InvType = type;
218 Asset.InvType = type; 218 Asset.Type = type;
219 Asset.Type = type; 219 Asset.Data = data;
220 Asset.Data = data; 220 Asset.Name = "blank";
221 Asset.Name = "blank"; 221 Asset.Description = "empty";
222 Asset.Description = "empty"; 222 Asset.Local = storeLocal;
223 Asset.Local = storeLocal; 223 Asset.Temporary = tempFile;
224 Asset.Temporary = tempFile; 224
225 225 TransactionID = transaction;
226 TransactionID = transaction; 226 m_storeLocal = storeLocal;
227 m_storeLocal = storeLocal; 227 if (Asset.Data.Length > 2)
228 if (Asset.Data.Length > 2) 228 {
229 { 229 SendCompleteMessage();
230 SendCompleteMessage(); 230 return true;
231 return true; 231 }
232 } 232 else
233 else 233 {
234 { 234 RequestStartXfer();
235 RequestStartXfer(); 235 }
236 } 236
237 237 return false;
238 return false; 238 }
239 } 239
240 240 protected void RequestStartXfer()
241 protected void RequestStartXfer() 241 {
242 { 242 UploadComplete = false;
243 UploadComplete = false; 243 XferID = Util.GetNextXferID();
244 XferID = Util.GetNextXferID(); 244 RequestXferPacket newPack = new RequestXferPacket();
245 RequestXferPacket newPack = new RequestXferPacket(); 245 newPack.XferID.ID = XferID;
246 newPack.XferID.ID = XferID; 246 newPack.XferID.VFileType = Asset.Type;
247 newPack.XferID.VFileType = Asset.Type; 247 newPack.XferID.VFileID = Asset.FullID;
248 newPack.XferID.VFileID = Asset.FullID; 248 newPack.XferID.FilePath = 0;
249 newPack.XferID.FilePath = 0; 249 newPack.XferID.Filename = new byte[0];
250 newPack.XferID.Filename = new byte[0]; 250 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
251 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); 251 }
252 } 252
253 253 protected void SendCompleteMessage()
254 protected void SendCompleteMessage() 254 {
255 { 255 UploadComplete = true;
256 UploadComplete = true; 256 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
257 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 257 newPack.AssetBlock.Type = Asset.Type;
258 newPack.AssetBlock.Type = Asset.Type; 258 newPack.AssetBlock.Success = true;
259 newPack.AssetBlock.Success = true; 259 newPack.AssetBlock.UUID = Asset.FullID;
260 newPack.AssetBlock.UUID = Asset.FullID; 260 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
261 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); 261 m_finished = true;
262 m_finished = true; 262 if (m_createItem)
263 if (m_createItem) 263 {
264 { 264 DoCreateItem();
265 DoCreateItem(); 265 }
266 } 266 else if (m_storeLocal)
267 else if (m_storeLocal) 267 {
268 { 268 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
269 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); 269 }
270 } 270
271 271 // Console.WriteLine("upload complete "+ this.TransactionID);
272 // Console.WriteLine("upload complete "+ this.TransactionID); 272
273 273 if (m_dumpAssetToFile)
274 if (m_dumpAssetToFile) 274 {
275 { 275 DateTime now = DateTime.Now;
276 DateTime now = DateTime.Now; 276 string filename =
277 string filename = 277 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day,
278 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, 278 now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type);
279 now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); 279 SaveAssetToFile(filename, Asset.Data);
280 SaveAssetToFile(filename, Asset.Data); 280 }
281 } 281 }
282 } 282
283 283 ///Left this in and commented in case there are unforseen issues
284 ///Left this in and commented in case there are unforseen issues 284 //private void SaveAssetToFile(string filename, byte[] data)
285 //private void SaveAssetToFile(string filename, byte[] data) 285 //{
286 //{ 286 // FileStream fs = File.Create(filename);
287 // FileStream fs = File.Create(filename); 287 // BinaryWriter bw = new BinaryWriter(fs);
288 // BinaryWriter bw = new BinaryWriter(fs); 288 // bw.Write(data);
289 // bw.Write(data); 289 // bw.Close();
290 // bw.Close(); 290 // fs.Close();
291 // fs.Close(); 291 //}
292 //} 292 private void SaveAssetToFile(string filename, byte[] data)
293 private void SaveAssetToFile(string filename, byte[] data) 293 {
294 { 294 string assetPath = "UserAssets";
295 string assetPath = "UserAssets"; 295 if (!Directory.Exists(assetPath))
296 if (!Directory.Exists(assetPath)) 296 {
297 { 297 Directory.CreateDirectory(assetPath);
298 Directory.CreateDirectory(assetPath); 298 }
299 } 299 FileStream fs = File.Create(Path.Combine(assetPath, filename));
300 FileStream fs = File.Create(Path.Combine(assetPath, filename)); 300 BinaryWriter bw = new BinaryWriter(fs);
301 BinaryWriter bw = new BinaryWriter(fs); 301 bw.Write(data);
302 bw.Write(data); 302 bw.Close();
303 bw.Close(); 303 fs.Close();
304 fs.Close(); 304 }
305 } 305
306 306 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
307 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 307 uint callbackID, string description, string name, sbyte invType,
308 uint callbackID, string description, string name, sbyte invType, 308 sbyte type, byte wearableType, uint nextOwnerMask)
309 sbyte type, byte wearableType, uint nextOwnerMask) 309 {
310 { 310 if (TransactionID == transactionID)
311 if (TransactionID == transactionID) 311 {
312 { 312 InventFolder = folderID;
313 InventFolder = folderID; 313 m_name = name;
314 m_name = name; 314 m_description = description;
315 m_description = description; 315 this.type = type;
316 this.type = type; 316 this.invType = invType;
317 this.invType = invType; 317 this.wearableType = wearableType;
318 this.wearableType = wearableType; 318 nextPerm = nextOwnerMask;
319 nextPerm = nextOwnerMask; 319 Asset.Name = name;
320 Asset.Name = name; 320 Asset.Description = description;
321 Asset.Description = description; 321 Asset.Type = type;
322 Asset.Type = type; 322 Asset.InvType = invType;
323 Asset.InvType = invType; 323 m_createItem = true;
324 m_createItem = true; 324 if (m_finished)
325 if (m_finished) 325 {
326 { 326 DoCreateItem();
327 DoCreateItem(); 327 }
328 } 328 }
329 } 329 }
330 } 330
331 331 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
332 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, 332 InventoryItemBase item)
333 InventoryItemBase item) 333 {
334 { 334 if (TransactionID == transactionID)
335 if (TransactionID == transactionID) 335 {
336 { 336 CachedUserInfo userInfo =
337 CachedUserInfo userInfo = 337 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
338 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails( 338 remoteClient.AgentId);
339 remoteClient.AgentId); 339
340 340 if (userInfo != null)
341 if (userInfo != null) 341 {
342 { 342 LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId);
343 LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId); 343
344 344 AssetBase asset
345 AssetBase asset 345 = m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset(
346 = m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset( 346 assetID, (item.AssetType == (int) AssetType.Texture ? true : false));
347 assetID, (item.AssetType == (int) AssetType.Texture ? true : false)); 347
348 348 if (asset == null)
349 if (asset == null) 349 {
350 { 350 asset = m_userTransactions.GetTransactionAsset(transactionID);
351 asset = m_userTransactions.GetTransactionAsset(transactionID); 351 }
352 } 352
353 353 if (asset != null && asset.FullID == assetID)
354 if (asset != null && asset.FullID == assetID) 354 {
355 { 355 asset.Name = item.Name;
356 asset.Name = item.Name; 356 asset.Description = item.Description;
357 asset.Description = item.Description; 357 asset.InvType = (sbyte) item.InvType;
358 asset.InvType = (sbyte) item.InvType; 358 asset.Type = (sbyte) item.AssetType;
359 asset.Type = (sbyte) item.AssetType; 359 item.AssetID = asset.FullID;
360 item.AssetID = asset.FullID; 360
361 361 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
362 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); 362 }
363 } 363
364 364 userInfo.UpdateItem(remoteClient.AgentId, item);
365 userInfo.UpdateItem(remoteClient.AgentId, item); 365 }
366 } 366 }
367 } 367 }
368 } 368
369 369 private void DoCreateItem()
370 private void DoCreateItem() 370 {
371 { 371 //really need to fix this call, if lbsa71 saw this he would die.
372 //really need to fix this call, if lbsa71 saw this he would die. 372 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
373 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); 373 CachedUserInfo userInfo =
374 CachedUserInfo userInfo = 374 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId);
375 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); 375 if (userInfo != null)
376 if (userInfo != null) 376 {
377 { 377 InventoryItemBase item = new InventoryItemBase();
378 InventoryItemBase item = new InventoryItemBase(); 378 item.Owner = ourClient.AgentId;
379 item.Owner = ourClient.AgentId; 379 item.Creator = ourClient.AgentId;
380 item.Creator = ourClient.AgentId; 380 item.ID = LLUUID.Random();
381 item.ID = LLUUID.Random(); 381 item.AssetID = Asset.FullID;
382 item.AssetID = Asset.FullID; 382 item.Description = m_description;
383 item.Description = m_description; 383 item.Name = m_name;
384 item.Name = m_name; 384 item.AssetType = type;
385 item.AssetType = type; 385 item.InvType = invType;
386 item.InvType = invType; 386 item.Folder = InventFolder;
387 item.Folder = InventFolder; 387 item.BasePermissions = 2147483647;
388 item.BasePermissions = 2147483647; 388 item.CurrentPermissions = 2147483647;
389 item.CurrentPermissions = 2147483647; 389 item.NextPermissions = nextPerm;
390 item.NextPermissions = nextPerm; 390 item.Flags = (uint)wearableType;
391 item.Flags = (uint)wearableType; 391
392 392 userInfo.AddItem(ourClient.AgentId, item);
393 userInfo.AddItem(ourClient.AgentId, item); 393 ourClient.SendInventoryItemCreateUpdate(item);
394 ourClient.SendInventoryItemCreateUpdate(item); 394 }
395 } 395 }
396 } 396
397 397 public AssetBase GetAssetData()
398 public AssetBase GetAssetData() 398 {
399 { 399 if (m_finished)
400 if (m_finished) 400 {
401 { 401 return Asset;
402 return Asset; 402 }
403 } 403 return null;
404 return null; 404 }
405 } 405 }
406 } 406 }
407 } 407} \ No newline at end of file
408}
diff --git a/OpenSim/Region/Environment/Modules/AgentAssetTransactionModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs
index cec7192..ef81625 100644
--- a/OpenSim/Region/Environment/Modules/AgentAssetTransactionModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -1,286 +1,286 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using libsecondlife; 31using libsecondlife;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Scenes; 36using OpenSim.Region.Environment.Modules.Agent.AssetTransaction;
37 37using OpenSim.Region.Environment.Scenes;
38namespace OpenSim.Region.Environment.Modules 38
39{ 39namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
40 public class AgentAssetTransactionModule : IRegionModule, IAgentAssetTransactions 40{
41 { 41 public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions
42 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); 42 {
43 private Scene m_scene = null; 43 private readonly Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
44 private bool m_dumpAssetsToFile = false; 44 private Scene m_scene = null;
45 45 private bool m_dumpAssetsToFile = false;
46 private AgentAssetTransactionsManager m_transactionManager; 46
47 47 private AgentAssetTransactionsManager m_transactionManager;
48 public AgentAssetTransactionModule() 48
49 { 49 public AssetTransactionModule()
50 // System.Console.WriteLine("creating AgentAssetTransactionModule"); 50 {
51 } 51 // System.Console.WriteLine("creating AgentAssetTransactionModule");
52 52 }
53 public void Initialise(Scene scene, IConfigSource config) 53
54 { 54 public void Initialise(Scene scene, IConfigSource config)
55 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 55 {
56 { 56 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
57 // System.Console.WriteLine("initialising AgentAssetTransactionModule"); 57 {
58 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 58 // System.Console.WriteLine("initialising AgentAssetTransactionModule");
59 scene.RegisterModuleInterface<IAgentAssetTransactions>(this); 59 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
60 60 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
61 scene.EventManager.OnNewClient += NewClient; 61
62 } 62 scene.EventManager.OnNewClient += NewClient;
63 63 }
64 if (m_scene == null) 64
65 { 65 if (m_scene == null)
66 m_scene = scene; 66 {
67 if (config.Configs["StandAlone"] != null) 67 m_scene = scene;
68 { 68 if (config.Configs["StandAlone"] != null)
69 try 69 {
70 { 70 try
71 m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false); 71 {
72 m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile); 72 m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false);
73 } 73 m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile);
74 catch (Exception) 74 }
75 { 75 catch (Exception)
76 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); 76 {
77 } 77 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
78 } 78 }
79 else 79 }
80 { 80 else
81 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); 81 {
82 } 82 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
83 83 }
84 } 84
85 } 85 }
86 86 }
87 public void PostInitialise() 87
88 { 88 public void PostInitialise()
89 89 {
90 } 90
91 91 }
92 public void Close() 92
93 { 93 public void Close()
94 } 94 {
95 95 }
96 public string Name 96
97 { 97 public string Name
98 get { return "AgentTransactionModule"; } 98 {
99 } 99 get { return "AgentTransactionModule"; }
100 100 }
101 public bool IsSharedModule 101
102 { 102 public bool IsSharedModule
103 get { return true; } 103 {
104 } 104 get { return true; }
105 105 }
106 public void NewClient(IClientAPI client) 106
107 { 107 public void NewClient(IClientAPI client)
108 client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest; 108 {
109 client.OnXferReceive += m_transactionManager.HandleXfer; 109 client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest;
110 } 110 client.OnXferReceive += m_transactionManager.HandleXfer;
111 111 }
112 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 112
113 uint callbackID, string description, string name, sbyte invType, 113 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
114 sbyte type, byte wearableType, uint nextOwnerMask) 114 uint callbackID, string description, string name, sbyte invType,
115 { 115 sbyte type, byte wearableType, uint nextOwnerMask)
116 m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); 116 {
117 } 117 m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask);
118 118 }
119 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, 119
120 InventoryItemBase item) 120 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
121 { 121 InventoryItemBase item)
122 m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); 122 {
123 } 123 m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
124 124 }
125 public void RemoveAgentAssetTransactions(LLUUID userID) 125
126 { 126 public void RemoveAgentAssetTransactions(LLUUID userID)
127 m_transactionManager.RemoveAgentAssetTransactions(userID); 127 {
128 } 128 m_transactionManager.RemoveAgentAssetTransactions(userID);
129 } 129 }
130 130 }
131 //should merge this classes and clean up 131
132 public class AgentAssetTransactionsManager 132 public class AgentAssetTransactionsManager
133 { 133 {
134 private static readonly ILog m_log 134 private static readonly ILog m_log
135 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 135 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
136 136
137 // Fields 137 // Fields
138 public Scene MyScene; 138 public Scene MyScene;
139 139
140 /// <summary> 140 /// <summary>
141 /// Each agent has its own singleton collection of transactions 141 /// Each agent has its own singleton collection of transactions
142 /// </summary> 142 /// </summary>
143 private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions = 143 private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions =
144 new Dictionary<LLUUID, AgentAssetTransactions>(); 144 new Dictionary<LLUUID, AgentAssetTransactions>();
145 145
146 /// <summary> 146 /// <summary>
147 /// Should we dump uploaded assets to the filesystem? 147 /// Should we dump uploaded assets to the filesystem?
148 /// </summary> 148 /// </summary>
149 private bool m_dumpAssetsToFile; 149 private bool m_dumpAssetsToFile;
150 150
151 public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile) 151 public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile)
152 { 152 {
153 MyScene = scene; 153 MyScene = scene;
154 m_dumpAssetsToFile = dumpAssetsToFile; 154 m_dumpAssetsToFile = dumpAssetsToFile;
155 } 155 }
156 156
157 /// <summary> 157 /// <summary>
158 /// Get the collection of asset transactions for the given user. If one does not already exist, it 158 /// Get the collection of asset transactions for the given user. If one does not already exist, it
159 /// is created. 159 /// is created.
160 /// </summary> 160 /// </summary>
161 /// <param name="userID"></param> 161 /// <param name="userID"></param>
162 /// <returns></returns> 162 /// <returns></returns>
163 private AgentAssetTransactions GetUserTransactions(LLUUID userID) 163 private AgentAssetTransactions GetUserTransactions(LLUUID userID)
164 { 164 {
165 lock (AgentTransactions) 165 lock (AgentTransactions)
166 { 166 {
167 if (!AgentTransactions.ContainsKey(userID)) 167 if (!AgentTransactions.ContainsKey(userID))
168 { 168 {
169 AgentAssetTransactions transactions 169 AgentAssetTransactions transactions
170 = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); 170 = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile);
171 AgentTransactions.Add(userID, transactions); 171 AgentTransactions.Add(userID, transactions);
172 } 172 }
173 173
174 return AgentTransactions[userID]; 174 return AgentTransactions[userID];
175 } 175 }
176 } 176 }
177 177
178 /// <summary> 178 /// <summary>
179 /// Remove the given agent asset transactions. This should be called when a client is departing 179 /// Remove the given agent asset transactions. This should be called when a client is departing
180 /// from a scene (and hence won't be making any more transactions here). 180 /// from a scene (and hence won't be making any more transactions here).
181 /// </summary> 181 /// </summary>
182 /// <param name="userID"></param> 182 /// <param name="userID"></param>
183 public void RemoveAgentAssetTransactions(LLUUID userID) 183 public void RemoveAgentAssetTransactions(LLUUID userID)
184 { 184 {
185 // m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID); 185 // m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID);
186 186
187 lock (AgentTransactions) 187 lock (AgentTransactions)
188 { 188 {
189 AgentTransactions.Remove(userID); 189 AgentTransactions.Remove(userID);
190 } 190 }
191 } 191 }
192 192
193 /// <summary> 193 /// <summary>
194 /// Create an inventory item from data that has been received through a transaction. 194 /// Create an inventory item from data that has been received through a transaction.
195 /// 195 ///
196 /// This is called when new clothing or body parts are created. It may also be called in other 196 /// This is called when new clothing or body parts are created. It may also be called in other
197 /// situations. 197 /// situations.
198 /// </summary> 198 /// </summary>
199 /// <param name="remoteClient"></param> 199 /// <param name="remoteClient"></param>
200 /// <param name="transactionID"></param> 200 /// <param name="transactionID"></param>
201 /// <param name="folderID"></param> 201 /// <param name="folderID"></param>
202 /// <param name="callbackID"></param> 202 /// <param name="callbackID"></param>
203 /// <param name="description"></param> 203 /// <param name="description"></param>
204 /// <param name="name"></param> 204 /// <param name="name"></param>
205 /// <param name="invType"></param> 205 /// <param name="invType"></param>
206 /// <param name="type"></param> 206 /// <param name="type"></param>
207 /// <param name="wearableType"></param> 207 /// <param name="wearableType"></param>
208 /// <param name="nextOwnerMask"></param> 208 /// <param name="nextOwnerMask"></param>
209 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 209 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
210 uint callbackID, string description, string name, sbyte invType, 210 uint callbackID, string description, string name, sbyte invType,
211 sbyte type, byte wearableType, uint nextOwnerMask) 211 sbyte type, byte wearableType, uint nextOwnerMask)
212 { 212 {
213 m_log.DebugFormat( 213 m_log.DebugFormat(
214 "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); 214 "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
215 215
216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
217 217
218 transactions.RequestCreateInventoryItem( 218 transactions.RequestCreateInventoryItem(
219 remoteClient, transactionID, folderID, callbackID, description, 219 remoteClient, transactionID, folderID, callbackID, description,
220 name, invType, type, wearableType, nextOwnerMask); 220 name, invType, type, wearableType, nextOwnerMask);
221 } 221 }
222 222
223 /// <summary> 223 /// <summary>
224 /// Update an inventory item with data that has been received through a transaction. 224 /// Update an inventory item with data that has been received through a transaction.
225 /// 225 ///
226 /// This is called when clothing or body parts are updated (for instance, with new textures or 226 /// This is called when clothing or body parts are updated (for instance, with new textures or
227 /// colours). It may also be called in other situations. 227 /// colours). It may also be called in other situations.
228 /// </summary> 228 /// </summary>
229 /// <param name="remoteClient"></param> 229 /// <param name="remoteClient"></param>
230 /// <param name="transactionID"></param> 230 /// <param name="transactionID"></param>
231 /// <param name="item"></param> 231 /// <param name="item"></param>
232 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, 232 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
233 InventoryItemBase item) 233 InventoryItemBase item)
234 { 234 {
235 m_log.DebugFormat( 235 m_log.DebugFormat(
236 "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 236 "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
237 item.Name); 237 item.Name);
238 238
239 AgentAssetTransactions transactions 239 AgentAssetTransactions transactions
240 = GetUserTransactions(remoteClient.AgentId); 240 = GetUserTransactions(remoteClient.AgentId);
241 241
242 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); 242 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
243 } 243 }
244 244
245 /// <summary> 245 /// <summary>
246 /// Request that a client (agent) begin an asset transfer. 246 /// Request that a client (agent) begin an asset transfer.
247 /// </summary> 247 /// </summary>
248 /// <param name="remoteClient"></param> 248 /// <param name="remoteClient"></param>
249 /// <param name="assetID"></param> 249 /// <param name="assetID"></param>
250 /// <param name="transaction"></param> 250 /// <param name="transaction"></param>
251 /// <param name="type"></param> 251 /// <param name="type"></param>
252 /// <param name="data"></param></param> 252 /// <param name="data"></param></param>
253 /// <param name="tempFile"></param> 253 /// <param name="tempFile"></param>
254 public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, 254 public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type,
255 byte[] data, bool storeLocal, bool tempFile) 255 byte[] data, bool storeLocal, bool tempFile)
256 { 256 {
257 // Console.WriteLine("asset upload of " + assetID); 257 // Console.WriteLine("asset upload of " + assetID);
258 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 258 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
259 259
260 AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); 260 AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
261 if (uploader != null) 261 if (uploader != null)
262 { 262 {
263 263
264 if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) 264 if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile))
265 { 265 {
266 266
267 } 267 }
268 } 268 }
269 } 269 }
270 270
271 /// <summary> 271 /// <summary>
272 /// Handle asset transfer data packets received in response to the asset upload request in 272 /// Handle asset transfer data packets received in response to the asset upload request in
273 /// HandleUDPUploadRequest() 273 /// HandleUDPUploadRequest()
274 /// </summary> 274 /// </summary>
275 /// <param name="remoteClient"></param> 275 /// <param name="remoteClient"></param>
276 /// <param name="xferID"></param> 276 /// <param name="xferID"></param>
277 /// <param name="packetID"></param> 277 /// <param name="packetID"></param>
278 /// <param name="data"></param> 278 /// <param name="data"></param>
279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) 279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
280 { 280 {
281 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 281 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
282 282
283 transactions.HandleXfer(xferID, packetID, data); 283 transactions.HandleXfer(xferID, packetID, data);
284 } 284 }
285 } 285 }
286} 286} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs
index bde0dc0..b8899d2 100644
--- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs
@@ -1,218 +1,215 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Threading; 30using System.Threading;
31using libsecondlife; 31using libsecondlife;
32using Nini.Config; 32using Nini.Config;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Scenes;
36 36
37namespace OpenSim.Region.Environment.Modules 37namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
38{ 38{
39 //this is a first attempt, to start breaking the mess thats called the assetcache up. 39 public class TextureDownloadModule : IRegionModule
40 // basically this should be the texture sending (to clients) code moved out of assetcache 40 {
41 //and some small clean up 41 //private static readonly log4net.ILog m_log
42 public class TextureDownloadModule : IRegionModule 42 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
43 { 43
44 //private static readonly log4net.ILog m_log 44 private Scene m_scene;
45 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 45 private List<Scene> m_scenes = new List<Scene>();
46 46
47 private Scene m_scene; 47 /// <summary>
48 private List<Scene> m_scenes = new List<Scene>(); 48 /// There is one queue for all textures waiting to be sent, regardless of the requesting user.
49 49 /// </summary>
50 /// <summary> 50 private readonly BlockingQueue<ITextureSender> m_queueSenders
51 /// There is one queue for all textures waiting to be sent, regardless of the requesting user. 51 = new BlockingQueue<ITextureSender>();
52 /// </summary> 52
53 private readonly BlockingQueue<ITextureSender> m_queueSenders 53 /// <summary>
54 = new BlockingQueue<ITextureSender>(); 54 /// Each user has their own texture download service.
55 55 /// </summary>
56 /// <summary> 56 private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
57 /// Each user has their own texture download service. 57 new Dictionary<LLUUID, UserTextureDownloadService>();
58 /// </summary> 58
59 private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = 59 private Thread m_thread;
60 new Dictionary<LLUUID, UserTextureDownloadService>(); 60
61 61 public TextureDownloadModule()
62 private Thread m_thread; 62 {
63 63 }
64 public TextureDownloadModule() 64
65 { 65 public void Initialise(Scene scene, IConfigSource config)
66 } 66 {
67 67 if (m_scene == null)
68 public void Initialise(Scene scene, IConfigSource config) 68 {
69 { 69 //Console.WriteLine("Creating Texture download module");
70 if (m_scene == null) 70 m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
71 { 71 m_thread.Name = "ProcessTextureSenderThread";
72 //Console.WriteLine("Creating Texture download module"); 72 m_thread.IsBackground = true;
73 m_thread = new Thread(new ThreadStart(ProcessTextureSenders)); 73 m_thread.Start();
74 m_thread.Name = "ProcessTextureSenderThread"; 74 ThreadTracker.Add(m_thread);
75 m_thread.IsBackground = true; 75 }
76 m_thread.Start(); 76
77 ThreadTracker.Add(m_thread); 77 if (!m_scenes.Contains(scene))
78 } 78 {
79 79 m_scenes.Add(scene);
80 if (!m_scenes.Contains(scene)) 80 m_scene = scene;
81 { 81 m_scene.EventManager.OnNewClient += NewClient;
82 m_scenes.Add(scene); 82 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
83 m_scene = scene; 83 }
84 m_scene.EventManager.OnNewClient += NewClient; 84 }
85 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence; 85
86 } 86 /// <summary>
87 } 87 /// Cleanup the texture service related objects for the removed presence.
88 88 /// </summary>
89 /// <summary> 89 /// <param name="agentId"> </param>
90 /// Cleanup the texture service related objects for the removed presence. 90 private void EventManager_OnRemovePresence(LLUUID agentId)
91 /// </summary> 91 {
92 /// <param name="agentId"> </param> 92 UserTextureDownloadService textureService;
93 private void EventManager_OnRemovePresence(LLUUID agentId) 93
94 { 94 lock (m_userTextureServices)
95 UserTextureDownloadService textureService; 95 {
96 96 if (m_userTextureServices.TryGetValue(agentId, out textureService))
97 lock (m_userTextureServices) 97 {
98 { 98 textureService.Close();
99 if (m_userTextureServices.TryGetValue(agentId, out textureService)) 99
100 { 100 m_userTextureServices.Remove(agentId);
101 textureService.Close(); 101 }
102 102 }
103 m_userTextureServices.Remove(agentId); 103 }
104 } 104
105 } 105 public void PostInitialise()
106 } 106 {
107 107 }
108 public void PostInitialise() 108
109 { 109 public void Close()
110 } 110 {
111 111 }
112 public void Close() 112
113 { 113 public string Name
114 } 114 {
115 115 get { return "TextureDownloadModule"; }
116 public string Name 116 }
117 { 117
118 get { return "TextureDownloadModule"; } 118 public bool IsSharedModule
119 } 119 {
120 120 get { return false; }
121 public bool IsSharedModule 121 }
122 { 122
123 get { return false; } 123 public void NewClient(IClientAPI client)
124 } 124 {
125 125 client.OnRequestTexture += TextureRequest;
126 public void NewClient(IClientAPI client) 126 }
127 { 127
128 client.OnRequestTexture += TextureRequest; 128 /// <summary>
129 } 129 /// Does this user have a registered texture download service?
130 130 /// </summary>
131 /// <summary> 131 /// <param name="userID"></param>
132 /// Does this user have a registered texture download service? 132 /// <param name="textureService"></param>
133 /// </summary> 133 /// <returns>Always returns true, since a service is created if one does not already exist</returns>
134 /// <param name="userID"></param> 134 private bool TryGetUserTextureService(
135 /// <param name="textureService"></param> 135 IClientAPI client, out UserTextureDownloadService textureService)
136 /// <returns>Always returns true, since a service is created if one does not already exist</returns> 136 {
137 private bool TryGetUserTextureService( 137 lock (m_userTextureServices)
138 IClientAPI client, out UserTextureDownloadService textureService) 138 {
139 { 139 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
140 lock (m_userTextureServices) 140 {
141 { 141 return true;
142 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) 142 }
143 { 143
144 return true; 144 textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
145 } 145 m_userTextureServices.Add(client.AgentId, textureService);
146 146
147 textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders); 147 return true;
148 m_userTextureServices.Add(client.AgentId, textureService); 148 }
149 149 }
150 return true; 150
151 } 151 /// <summary>
152 } 152 /// Start the process of requesting a given texture.
153 153 /// </summary>
154 /// <summary> 154 /// <param name="sender"> </param>
155 /// Start the process of requesting a given texture. 155 /// <param name="e"></param>
156 /// </summary> 156 public void TextureRequest(Object sender, TextureRequestArgs e)
157 /// <param name="sender"> </param> 157 {
158 /// <param name="e"></param> 158 IClientAPI client = (IClientAPI) sender;
159 public void TextureRequest(Object sender, TextureRequestArgs e) 159 UserTextureDownloadService textureService;
160 { 160
161 IClientAPI client = (IClientAPI) sender; 161 if (TryGetUserTextureService(client, out textureService))
162 UserTextureDownloadService textureService; 162 {
163 163 textureService.HandleTextureRequest(e);
164 if (TryGetUserTextureService(client, out textureService)) 164 }
165 { 165 }
166 textureService.HandleTextureRequest(e); 166
167 } 167 /// <summary>
168 } 168 /// Entry point for the thread dedicated to processing the texture queue.
169 169 /// </summary>
170 /// <summary> 170 public void ProcessTextureSenders()
171 /// Entry point for the thread dedicated to processing the texture queue. 171 {
172 /// </summary> 172 ITextureSender sender = null;
173 public void ProcessTextureSenders() 173
174 { 174 while (true)
175 ITextureSender sender = null; 175 {
176 176 sender = m_queueSenders.Dequeue();
177 while (true) 177
178 { 178 if (sender.Cancel)
179 sender = m_queueSenders.Dequeue(); 179 {
180 180 TextureSent(sender);
181 if (sender.Cancel) 181
182 { 182 sender.Cancel = false;
183 TextureSent(sender); 183 }
184 184 else
185 sender.Cancel = false; 185 {
186 } 186 bool finished = sender.SendTexturePacket();
187 else 187 if (finished)
188 { 188 {
189 bool finished = sender.SendTexturePacket(); 189 TextureSent(sender);
190 if (finished) 190 }
191 { 191 else
192 TextureSent(sender); 192 {
193 } 193 m_queueSenders.Enqueue(sender);
194 else 194 }
195 { 195 }
196 m_queueSenders.Enqueue(sender); 196
197 } 197 // Make sure that any sender we currently have can get garbage collected
198 } 198 sender = null;
199 199
200 // Make sure that any sender we currently have can get garbage collected 200 //m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count());
201 sender = null; 201 }
202 202 }
203 //m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count()); 203
204 } 204 /// <summary>
205 } 205 /// Called when the texture has finished sending.
206 206 /// </summary>
207 /// <summary> 207 /// <param name="sender"></param>
208 /// Called when the texture has finished sending. 208 private void TextureSent(ITextureSender sender)
209 /// </summary> 209 {
210 /// <param name="sender"></param> 210 sender.Sending = false;
211 private void TextureSent(ITextureSender sender) 211 //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID);
212 { 212 m_scene.AddPendingDownloads(-1);
213 sender.Sending = false; 213 }
214 //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID); 214 }
215 m_scene.AddPendingDownloads(-1); 215} \ No newline at end of file
216 }
217 }
218}
diff --git a/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs
index 7b835a1..6f11f73 100644
--- a/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.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
28using libsecondlife; 28using libsecondlife;
29using libsecondlife.Packets; 29using libsecondlife.Packets;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenSim.Region.Environment.Interfaces; 31using OpenSim.Region.Environment.Interfaces;
32 32
33namespace OpenSim.Region.Environment.Modules 33namespace 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 LLUUID m_textureId; 43 private LLUUID m_textureId;
44 private IClientAPI m_client; 44 private IClientAPI m_client;
45 45
46 // See ITextureSender 46 // See ITextureSender
47 public bool Sending 47 public bool Sending
48 { 48 {
49 get { return false; } 49 get { return false; }
50 set { m_sending = value; } 50 set { m_sending = value; }
51 } 51 }
52 52
53 private bool m_sending = false; 53 private bool m_sending = false;
54 54
55 // See ITextureSender 55 // See ITextureSender
56 public bool Cancel 56 public bool Cancel
57 { 57 {
58 get { return false; } 58 get { return false; }
59 set { m_cancel = value; } 59 set { m_cancel = value; }
60 } 60 }
61 61
62 private bool m_cancel = false; 62 private bool m_cancel = false;
63 63
64 public TextureNotFoundSender(IClientAPI client, LLUUID textureID) 64 public TextureNotFoundSender(IClientAPI client, LLUUID textureID)
65 { 65 {
66 m_client = client; 66 m_client = client;
67 m_textureId = textureID; 67 m_textureId = textureID;
68 } 68 }
69 69
70 // See ITextureSender 70 // See ITextureSender
71 public void UpdateRequest(int discardLevel, uint packetNumber) 71 public void UpdateRequest(int discardLevel, uint packetNumber)
72 { 72 {
73 // Not need to implement since priority changes don't affect this operation 73 // Not need to implement since priority changes don't affect this operation
74 } 74 }
75 75
76 // See ITextureSender 76 // See ITextureSender
77 public bool SendTexturePacket() 77 public bool SendTexturePacket()
78 { 78 {
79 //m_log.InfoFormat( 79 //m_log.InfoFormat(
80 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found", 80 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
81 // m_textureId); 81 // m_textureId);
82 82
83 ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket(); 83 ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
84 notFound.ImageID.ID = m_textureId; 84 notFound.ImageID.ID = m_textureId;
85 85
86 // XXX Temporarily disabling as this appears to be causing client crashes on at least 86 // XXX Temporarily disabling as this appears to be causing client crashes on at least
87 // 1.19.0(5) of the Linden Second Life client. 87 // 1.19.0(5) of the Linden Second Life client.
88 // m_client.OutPacket(notFound, ThrottleOutPacketType.Texture); 88 // m_client.OutPacket(notFound, ThrottleOutPacketType.Texture);
89 89
90 return true; 90 return true;
91 } 91 }
92 } 92 }
93} 93} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs
index e46bf6d..08a22d6 100644
--- a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs
@@ -1,250 +1,252 @@
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
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife; 30using libsecondlife;
31using log4net; 31using log4net;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Communications.Limit; 33using OpenSim.Framework.Communications.Limit;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Modules.Agent.TextureDownload;
36 36using OpenSim.Region.Environment.Modules.Agent.TextureSender;
37namespace OpenSim.Region.Environment.Modules 37using OpenSim.Region.Environment.Scenes;
38{ 38
39 /// <summary> 39namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
40 /// This module sets up texture senders in response to client texture requests, and places them on a 40{
41 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the 41 /// <summary>
42 /// asset cache). 42 /// This module sets up texture senders in response to client texture requests, and places them on a
43 /// </summary> 43 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
44 public class UserTextureDownloadService 44 /// asset cache).
45 { 45 /// </summary>
46 private static readonly ILog m_log 46 public class UserTextureDownloadService
47 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 {
48 48 private static readonly ILog m_log
49 /// <summary> 49 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 /// We will allow the client to request the same texture n times before dropping further requests 50
51 /// 51 /// <summary>
52 /// This number includes repeated requests for the same texture at different resolutions (which we don't 52 /// We will allow the client to request the same texture n times before dropping further requests
53 /// currently handle properly as far as I know). However, this situation should be handled in a more 53 ///
54 /// sophisticated way. 54 /// This number includes repeated requests for the same texture at different resolutions (which we don't
55 /// </summary> 55 /// currently handle properly as far as I know). However, this situation should be handled in a more
56 private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5; 56 /// sophisticated way.
57 57 /// </summary>
58 /// <summary> 58 private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
59 /// We're going to limit requests for the same missing texture. 59
60 /// XXX This is really a temporary solution to deal with the situation where a client continually requests 60 /// <summary>
61 /// the same missing textures 61 /// We're going to limit requests for the same missing texture.
62 /// </summary> 62 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
63 private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy 63 /// the same missing textures
64 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); 64 /// </summary>
65 65 private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy
66 /// <summary> 66 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
67 /// XXX Also going to limit requests for found textures. 67
68 /// </summary> 68 /// <summary>
69 private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy 69 /// XXX Also going to limit requests for found textures.
70 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); 70 /// </summary>
71 71 private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy
72 /// <summary> 72 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
73 /// Holds texture senders before they have received the appropriate texture from the asset cache. 73
74 /// </summary> 74 /// <summary>
75 private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>(); 75 /// Holds texture senders before they have received the appropriate texture from the asset cache.
76 76 /// </summary>
77 /// <summary> 77 private readonly Dictionary<LLUUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender.TextureSender>();
78 /// Texture Senders are placed in this queue once they have received their texture from the asset 78
79 /// cache. Another module actually invokes the send. 79 /// <summary>
80 /// </summary> 80 /// Texture Senders are placed in this queue once they have received their texture from the asset
81 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue; 81 /// cache. Another module actually invokes the send.
82 82 /// </summary>
83 private readonly Scene m_scene; 83 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue;
84 84
85 private readonly IClientAPI m_client; 85 private readonly Scene m_scene;
86 86
87 public UserTextureDownloadService( 87 private readonly IClientAPI m_client;
88 IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue) 88
89 { 89 public UserTextureDownloadService(
90 m_client = client; 90 IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue)
91 m_scene = scene; 91 {
92 m_sharedSendersQueue = sharedQueue; 92 m_client = client;
93 } 93 m_scene = scene;
94 94 m_sharedSendersQueue = sharedQueue;
95 /// <summary> 95 }
96 /// Handle a texture request. This involves creating a texture sender and placing it on the 96
97 /// previously passed in shared queue. 97 /// <summary>
98 /// </summary> 98 /// Handle a texture request. This involves creating a texture sender and placing it on the
99 /// <param name="e"></param> 99 /// previously passed in shared queue.
100 public void HandleTextureRequest(TextureRequestArgs e) 100 /// </summary>
101 { 101 /// <param name="e"></param>
102 TextureSender textureSender; 102 public void HandleTextureRequest(TextureRequestArgs e)
103 103 {
104 //TODO: should be working out the data size/ number of packets to be sent for each discard level 104 TextureSender.TextureSender textureSender;
105 if ((e.DiscardLevel >= 0) || (e.Priority != 0)) 105
106 { 106 //TODO: should be working out the data size/ number of packets to be sent for each discard level
107 lock (m_textureSenders) 107 if ((e.DiscardLevel >= 0) || (e.Priority != 0))
108 { 108 {
109 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) 109 lock (m_textureSenders)
110 { 110 {
111 // If we've received new non UUID information for this request and it hasn't dispatched 111 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
112 // yet, then update the request accordingly. 112 {
113 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); 113 // If we've received new non UUID information for this request and it hasn't dispatched
114 } 114 // yet, then update the request accordingly.
115 else 115 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
116 { 116 }
117 if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) 117 else
118 { 118 {
119// m_log.DebugFormat( 119 if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
120// "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}", 120 {
121// e.RequestedAssetID, m_client.AgentId); 121// m_log.DebugFormat(
122 122// "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}",
123 return; 123// e.RequestedAssetID, m_client.AgentId);
124 } 124
125 else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) 125 return;
126 { 126 }
127 if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID)) 127 else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
128 { 128 {
129 // Commenting out this message for now as it causes too much noise with other 129 if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
130 // debug messages. 130 {
131 // TODO: possibly record this as a statistic in the future 131 // Commenting out this message for now as it causes too much noise with other
132 // 132 // debug messages.
133// m_log.DebugFormat( 133 // TODO: possibly record this as a statistic in the future
134// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests", 134 //
135// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS); 135// m_log.DebugFormat(
136 } 136// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
137 137// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
138 return; 138 }
139 } 139
140 140 return;
141 m_scene.AddPendingDownloads(1); 141 }
142 142
143 TextureSender requestHandler = new TextureSender(m_client, e.DiscardLevel, e.PacketNumber); 143 m_scene.AddPendingDownloads(1);
144 m_textureSenders.Add(e.RequestedAssetID, requestHandler); 144
145 145 TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
146 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true); 146 m_textureSenders.Add(e.RequestedAssetID, requestHandler);
147 } 147
148 } 148 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true);
149 } 149 }
150 else 150 }
151 { 151 }
152 lock (m_textureSenders) 152 else
153 { 153 {
154 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) 154 lock (m_textureSenders)
155 { 155 {
156 textureSender.Cancel = true; 156 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
157 } 157 {
158 } 158 textureSender.Cancel = true;
159 } 159 }
160 } 160 }
161 161 }
162 /// <summary> 162 }
163 /// The callback for the asset cache when a texture has been retrieved. This method queues the 163
164 /// texture sender for processing. 164 /// <summary>
165 /// </summary> 165 /// The callback for the asset cache when a texture has been retrieved. This method queues the
166 /// <param name="textureID"></param> 166 /// texture sender for processing.
167 /// <param name="texture"></param> 167 /// </summary>
168 public void TextureCallback(LLUUID textureID, AssetBase texture) 168 /// <param name="textureID"></param>
169 { 169 /// <param name="texture"></param>
170 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false)); 170 public void TextureCallback(LLUUID textureID, AssetBase texture)
171 171 {
172 lock (m_textureSenders) 172 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
173 { 173
174 TextureSender textureSender; 174 lock (m_textureSenders)
175 175 {
176 if (m_textureSenders.TryGetValue(textureID, out textureSender)) 176 TextureSender.TextureSender textureSender;
177 { 177
178 // XXX It may be perfectly valid for a texture to have no data... but if we pass 178 if (m_textureSenders.TryGetValue(textureID, out textureSender))
179 // this on to the TextureSender it will blow up, so just discard for now. 179 {
180 // Needs investigation. 180 // XXX It may be perfectly valid for a texture to have no data... but if we pass
181 if (texture == null || texture.Data == null) 181 // this on to the TextureSender it will blow up, so just discard for now.
182 { 182 // Needs investigation.
183 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID)) 183 if (texture == null || texture.Data == null)
184 { 184 {
185 missingTextureLimitStrategy.MonitorRequests(textureID); 185 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
186 186 {
187 m_log.DebugFormat( 187 missingTextureLimitStrategy.MonitorRequests(textureID);
188 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}", 188
189 textureID, m_client.AgentId); 189 m_log.DebugFormat(
190 } 190 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}",
191 191 textureID, m_client.AgentId);
192 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID); 192 }
193 EnqueueTextureSender(textureNotFoundSender); 193
194 } 194 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
195 else 195 EnqueueTextureSender(textureNotFoundSender);
196 { 196 }
197 if (!textureSender.ImageLoaded) 197 else
198 { 198 {
199 textureSender.TextureReceived(texture); 199 if (!textureSender.ImageLoaded)
200 EnqueueTextureSender(textureSender); 200 {
201 201 textureSender.TextureReceived(texture);
202 foundTextureLimitStrategy.MonitorRequests(textureID); 202 EnqueueTextureSender(textureSender);
203 } 203
204 } 204 foundTextureLimitStrategy.MonitorRequests(textureID);
205 205 }
206 //m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID); 206 }
207 m_textureSenders.Remove(textureID); 207
208 //m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count); 208 //m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID);
209 } 209 m_textureSenders.Remove(textureID);
210 else 210 //m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count);
211 { 211 }
212 m_log.WarnFormat( 212 else
213 "Got a texture uuid {0} with no sender object to handle it, this shouldn't happen", 213 {
214 textureID); 214 m_log.WarnFormat(
215 } 215 "Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
216 } 216 textureID);
217 } 217 }
218 218 }
219 /// <summary> 219 }
220 /// Place a ready texture sender on the processing queue. 220
221 /// </summary> 221 /// <summary>
222 /// <param name="textureSender"></param> 222 /// Place a ready texture sender on the processing queue.
223 private void EnqueueTextureSender(ITextureSender textureSender) 223 /// </summary>
224 { 224 /// <param name="textureSender"></param>
225 textureSender.Cancel = false; 225 private void EnqueueTextureSender(ITextureSender textureSender)
226 textureSender.Sending = true; 226 {
227 227 textureSender.Cancel = false;
228 if (!m_sharedSendersQueue.Contains(textureSender)) 228 textureSender.Sending = true;
229 { 229
230 m_sharedSendersQueue.Enqueue(textureSender); 230 if (!m_sharedSendersQueue.Contains(textureSender))
231 } 231 {
232 } 232 m_sharedSendersQueue.Enqueue(textureSender);
233 233 }
234 /// <summary> 234 }
235 /// Close this module. 235
236 /// </summary> 236 /// <summary>
237 internal void Close() 237 /// Close this module.
238 { 238 /// </summary>
239 lock (m_textureSenders) 239 internal void Close()
240 { 240 {
241 foreach( TextureSender textureSender in m_textureSenders.Values ) 241 lock (m_textureSenders)
242 { 242 {
243 textureSender.Cancel = true; 243 foreach( TextureSender.TextureSender textureSender in m_textureSenders.Values )
244 } 244 {
245 245 textureSender.Cancel = true;
246 m_textureSenders.Clear(); 246 }
247 } 247
248 } 248 m_textureSenders.Clear();
249 } 249 }
250} 250 }
251 }
252} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/TextureSender.cs b/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs
index e54a1a2..37b0652 100644
--- a/OpenSim/Region/Environment/Modules/TextureSender.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.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
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife.Packets; 30using libsecondlife.Packets;
31using log4net; 31using log4net;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34 34
35namespace OpenSim.Region.Environment.Modules 35namespace 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 /// <summary> 51 /// <summary>
52 /// Holds the texture asset to send. 52 /// Holds the texture asset to send.
53 /// </summary> 53 /// </summary>
54 private AssetBase m_asset; 54 private AssetBase m_asset;
55 55
56 //public LLUUID assetID { get { return m_asset.FullID; } } 56 //public LLUUID assetID { get { return m_asset.FullID; } }
57 57
58 /// <summary> 58 /// <summary>
59 /// This is actually the number of extra packets required to send the texture data! We always assume 59 /// This is actually the number of extra packets required to send the texture data! We always assume
60 /// at least one is required. 60 /// at least one is required.
61 /// </summary> 61 /// </summary>
62 private int NumPackets = 0; 62 private int NumPackets = 0;
63 63
64 /// <summary> 64 /// <summary>
65 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts 65 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
66 /// at the 600th byte (0th indexed). 66 /// at the 600th byte (0th indexed).
67 /// </summary> 67 /// </summary>
68 private int PacketCounter = 0; 68 private int PacketCounter = 0;
69 69
70 // See ITextureSender 70 // See ITextureSender
71 public bool Cancel 71 public bool Cancel
72 { 72 {
73 get { return false; } 73 get { return false; }
74 set { m_cancel = value; } 74 set { m_cancel = value; }
75 } 75 }
76 76
77 private bool m_cancel = false; 77 private bool m_cancel = false;
78 78
79 // See ITextureSender 79 // See ITextureSender
80 public bool Sending 80 public bool Sending
81 { 81 {
82 get { return false; } 82 get { return false; }
83 set { m_sending = value; } 83 set { m_sending = value; }
84 } 84 }
85 85
86 private bool m_sending = false; 86 private bool m_sending = false;
87 87
88 public bool ImageLoaded = false; 88 public bool ImageLoaded = false;
89 89
90 private IClientAPI RequestUser; 90 private IClientAPI RequestUser;
91 91
92 private int RequestedDiscardLevel = -1; 92 private int RequestedDiscardLevel = -1;
93 private uint StartPacketNumber = 0; 93 private uint StartPacketNumber = 0;
94 94
95 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) 95 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
96 { 96 {
97 RequestUser = client; 97 RequestUser = client;
98 RequestedDiscardLevel = discardLevel; 98 RequestedDiscardLevel = discardLevel;
99 StartPacketNumber = packetNumber; 99 StartPacketNumber = packetNumber;
100 } 100 }
101 101
102 /// <summary> 102 /// <summary>
103 /// Load up the texture data to send. 103 /// Load up the texture data to send.
104 /// </summary> 104 /// </summary>
105 /// <param name="asset"> 105 /// <param name="asset">
106 /// A <see cref="AssetBase"/> 106 /// A <see cref="AssetBase"/>
107 /// </param> 107 /// </param>
108 public void TextureReceived(AssetBase asset) 108 public void TextureReceived(AssetBase asset)
109 { 109 {
110 m_asset = asset; 110 m_asset = asset;
111 NumPackets = CalculateNumPackets(asset.Data.Length); 111 NumPackets = CalculateNumPackets(asset.Data.Length);
112 PacketCounter = (int) StartPacketNumber; 112 PacketCounter = (int) StartPacketNumber;
113 ImageLoaded = true; 113 ImageLoaded = true;
114 } 114 }
115 115
116 // See ITextureSender 116 // See ITextureSender
117 public void UpdateRequest(int discardLevel, uint packetNumber) 117 public void UpdateRequest(int discardLevel, uint packetNumber)
118 { 118 {
119 RequestedDiscardLevel = discardLevel; 119 RequestedDiscardLevel = discardLevel;
120 StartPacketNumber = packetNumber; 120 StartPacketNumber = packetNumber;
121 PacketCounter = (int) StartPacketNumber; 121 PacketCounter = (int) StartPacketNumber;
122 } 122 }
123 123
124 // See ITextureSender 124 // See ITextureSender
125 public bool SendTexturePacket() 125 public bool SendTexturePacket()
126 { 126 {
127 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID); 127 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
128 128
129 SendPacket(); 129 SendPacket();
130 counter++; 130 counter++;
131 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || 131 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
132 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1))))) 132 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1)))))
133 { 133 {
134 return true; 134 return true;
135 } 135 }
136 return false; 136 return false;
137 } 137 }
138 138
139 /// <summary> 139 /// <summary>
140 /// Sends a texture packet to the client. 140 /// Sends a texture packet to the client.
141 /// </summary> 141 /// </summary>
142 private void SendPacket() 142 private void SendPacket()
143 { 143 {
144 if (PacketCounter <= NumPackets) 144 if (PacketCounter <= NumPackets)
145 { 145 {
146 if (PacketCounter == 0) 146 if (PacketCounter == 0)
147 { 147 {
148 if (NumPackets == 0) 148 if (NumPackets == 0)
149 { 149 {
150 ImageDataPacket im = new ImageDataPacket(); 150 ImageDataPacket im = new ImageDataPacket();
151 im.Header.Reliable = false; 151 im.Header.Reliable = false;
152 im.ImageID.Packets = 1; 152 im.ImageID.Packets = 1;
153 im.ImageID.ID = m_asset.FullID; 153 im.ImageID.ID = m_asset.FullID;
154 im.ImageID.Size = (uint) m_asset.Data.Length; 154 im.ImageID.Size = (uint) m_asset.Data.Length;
155 im.ImageData.Data = m_asset.Data; 155 im.ImageData.Data = m_asset.Data;
156 im.ImageID.Codec = 2; 156 im.ImageID.Codec = 2;
157 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); 157 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
158 PacketCounter++; 158 PacketCounter++;
159 } 159 }
160 else 160 else
161 { 161 {
162 ImageDataPacket im = new ImageDataPacket(); 162 ImageDataPacket im = new ImageDataPacket();
163 im.Header.Reliable = false; 163 im.Header.Reliable = false;
164 im.ImageID.Packets = (ushort) (NumPackets); 164 im.ImageID.Packets = (ushort) (NumPackets);
165 im.ImageID.ID = m_asset.FullID; 165 im.ImageID.ID = m_asset.FullID;
166 im.ImageID.Size = (uint) m_asset.Data.Length; 166 im.ImageID.Size = (uint) m_asset.Data.Length;
167 im.ImageData.Data = new byte[600]; 167 im.ImageData.Data = new byte[600];
168 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); 168 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
169 im.ImageID.Codec = 2; 169 im.ImageID.Codec = 2;
170 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); 170 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
171 PacketCounter++; 171 PacketCounter++;
172 } 172 }
173 } 173 }
174 else 174 else
175 { 175 {
176 ImagePacketPacket im = new ImagePacketPacket(); 176 ImagePacketPacket im = new ImagePacketPacket();
177 im.Header.Reliable = false; 177 im.Header.Reliable = false;
178 im.ImageID.Packet = (ushort) (PacketCounter); 178 im.ImageID.Packet = (ushort) (PacketCounter);
179 im.ImageID.ID = m_asset.FullID; 179 im.ImageID.ID = m_asset.FullID;
180 int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1)); 180 int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1));
181 if (size > 1000) size = 1000; 181 if (size > 1000) size = 1000;
182 im.ImageData.Data = new byte[size]; 182 im.ImageData.Data = new byte[size];
183 try 183 try
184 { 184 {
185 Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size); 185 Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size);
186 } 186 }
187 catch (ArgumentOutOfRangeException) 187 catch (ArgumentOutOfRangeException)
188 { 188 {
189 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" + 189 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
190 m_asset.FullID.ToString() ); 190 m_asset.FullID.ToString() );
191 return; 191 return;
192 } 192 }
193 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); 193 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
194 PacketCounter++; 194 PacketCounter++;
195 } 195 }
196 } 196 }
197 } 197 }
198 198
199 /// <summary> 199 /// <summary>
200 /// Calculate the number of packets that will be required to send the texture loaded into this sender 200 /// Calculate the number of packets that will be required to send the texture loaded into this sender
201 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... 201 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
202 /// </summary> 202 /// </summary>
203 /// <param name="length"></param> 203 /// <param name="length"></param>
204 /// <returns></returns> 204 /// <returns></returns>
205 private int CalculateNumPackets(int length) 205 private int CalculateNumPackets(int length)
206 { 206 {
207 int numPackets = 0; 207 int numPackets = 0;
208 208
209 if (length > 600) 209 if (length > 600)
210 { 210 {
211 //over 600 bytes so split up file 211 //over 600 bytes so split up file
212 int restData = (length - 600); 212 int restData = (length - 600);
213 int restPackets = ((restData + 999)/1000); 213 int restPackets = ((restData + 999)/1000);
214 numPackets = restPackets; 214 numPackets = restPackets;
215 } 215 }
216 216
217 return numPackets; 217 return numPackets;
218 } 218 }
219 } 219 }
220} 220} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/XferModule.cs b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs
index 87bc1c5..b609f93 100644
--- a/OpenSim/Region/Environment/Modules/XferModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using libsecondlife; 30using libsecondlife;
31using Nini.Config; 31using Nini.Config;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35 35
36namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules.Agent.Xfer
37{ 37{
38 public class XferModule : IRegionModule, IXfer 38 public class XferModule : IRegionModule, IXfer
39 { 39 {
40 public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>(); 40 public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>();
41 public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); 41 public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
42 42
43 private Scene m_scene; 43 private Scene m_scene;
44 44
45 public XferModule() 45 public XferModule()
46 { 46 {
47 } 47 }
48 48
49 public void Initialise(Scene scene, IConfigSource config) 49 public void Initialise(Scene scene, IConfigSource config)
50 { 50 {
51 m_scene = scene; 51 m_scene = scene;
52 m_scene.EventManager.OnNewClient += NewClient; 52 m_scene.EventManager.OnNewClient += NewClient;
53 53
54 m_scene.RegisterModuleInterface<IXfer>(this); 54 m_scene.RegisterModuleInterface<IXfer>(this);
55 } 55 }
56 56
57 public void PostInitialise() 57 public void PostInitialise()
58 { 58 {
59 } 59 }
60 60
61 public void Close() 61 public void Close()
62 { 62 {
63 } 63 }
64 64
65 public string Name 65 public string Name
66 { 66 {
67 get { return "XferModule"; } 67 get { return "XferModule"; }
68 } 68 }
69 69
70 public bool IsSharedModule 70 public bool IsSharedModule
71 { 71 {
72 get { return false; } 72 get { return false; }
73 } 73 }
74 74
75 public void NewClient(IClientAPI client) 75 public void NewClient(IClientAPI client)
76 { 76 {
77 client.OnRequestXfer += RequestXfer; 77 client.OnRequestXfer += RequestXfer;
78 client.OnConfirmXfer += AckPacket; 78 client.OnConfirmXfer += AckPacket;
79 } 79 }
80 80
81 /// <summary> 81 /// <summary>
82 /// 82 ///
83 /// </summary> 83 /// </summary>
84 /// <param name="remoteClient"></param> 84 /// <param name="remoteClient"></param>
85 /// <param name="xferID"></param> 85 /// <param name="xferID"></param>
86 /// <param name="fileName"></param> 86 /// <param name="fileName"></param>
87 public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName) 87 public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
88 { 88 {
89 lock (NewFiles) 89 lock (NewFiles)
90 { 90 {
91 if (NewFiles.ContainsKey(fileName)) 91 if (NewFiles.ContainsKey(fileName))
92 { 92 {
93 if (!Transfers.ContainsKey(xferID)) 93 if (!Transfers.ContainsKey(xferID))
94 { 94 {
95 byte[] fileData = NewFiles[fileName]; 95 byte[] fileData = NewFiles[fileName];
96 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); 96 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
97 Transfers.Add(xferID, transaction); 97 Transfers.Add(xferID, transaction);
98 NewFiles.Remove(fileName); 98 NewFiles.Remove(fileName);
99 99
100 if (transaction.StartSend()) 100 if (transaction.StartSend())
101 { 101 {
102 Transfers.Remove(xferID); 102 Transfers.Remove(xferID);
103 } 103 }
104 } 104 }
105 } 105 }
106 } 106 }
107 } 107 }
108 108
109 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) 109 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
110 { 110 {
111 if (Transfers.ContainsKey(xferID)) 111 if (Transfers.ContainsKey(xferID))
112 { 112 {
113 if (Transfers[xferID].AckPacket(packet)) 113 if (Transfers[xferID].AckPacket(packet))
114 { 114 {
115 { 115 {
116 Transfers.Remove(xferID); 116 Transfers.Remove(xferID);
117 } 117 }
118 } 118 }
119 } 119 }
120 } 120 }
121 121
122 public bool AddNewFile(string fileName, byte[] data) 122 public bool AddNewFile(string fileName, byte[] data)
123 { 123 {
124 lock (NewFiles) 124 lock (NewFiles)
125 { 125 {
126 if (NewFiles.ContainsKey(fileName)) 126 if (NewFiles.ContainsKey(fileName))
127 { 127 {
128 NewFiles[fileName] = data; 128 NewFiles[fileName] = data;
129 } 129 }
130 else 130 else
131 { 131 {
132 NewFiles.Add(fileName, data); 132 NewFiles.Add(fileName, data);
133 } 133 }
134 } 134 }
135 return true; 135 return true;
136 } 136 }
137 137
138 138
139 public class XferDownLoad 139 public class XferDownLoad
140 { 140 {
141 public byte[] Data = new byte[0]; 141 public byte[] Data = new byte[0];
142 public string FileName = String.Empty; 142 public string FileName = String.Empty;
143 public ulong XferID = 0; 143 public ulong XferID = 0;
144 public int DataPointer = 0; 144 public int DataPointer = 0;
145 public uint Packet = 0; 145 public uint Packet = 0;
146 public IClientAPI Client; 146 public IClientAPI Client;
147 public uint Serial = 1; 147 public uint Serial = 1;
148 private bool complete; 148 private bool complete;
149 149
150 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) 150 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
151 { 151 {
152 FileName = fileName; 152 FileName = fileName;
153 Data = data; 153 Data = data;
154 XferID = xferID; 154 XferID = xferID;
155 Client = client; 155 Client = client;
156 } 156 }
157 157
158 public XferDownLoad() 158 public XferDownLoad()
159 { 159 {
160 } 160 }
161 161
162 /// <summary> 162 /// <summary>
163 /// Start a transfer 163 /// Start a transfer
164 /// </summary> 164 /// </summary>
165 /// <returns>True if the transfer is complete, false if not</returns> 165 /// <returns>True if the transfer is complete, false if not</returns>
166 public bool StartSend() 166 public bool StartSend()
167 { 167 {
168 if (Data.Length < 1000) 168 if (Data.Length < 1000)
169 { 169 {
170 // for now (testing ) we only support files under 1000 bytes 170 // for now (testing ) we only support files under 1000 bytes
171 byte[] transferData = new byte[Data.Length + 4]; 171 byte[] transferData = new byte[Data.Length + 4];
172 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); 172 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
173 Array.Copy(Data, 0, transferData, 4, Data.Length); 173 Array.Copy(Data, 0, transferData, 4, Data.Length);
174 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData); 174 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
175 175
176 complete = true; 176 complete = true;
177 } 177 }
178 else 178 else
179 { 179 {
180 byte[] transferData = new byte[1000 + 4]; 180 byte[] transferData = new byte[1000 + 4];
181 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); 181 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
182 Array.Copy(Data, 0, transferData, 4, 1000); 182 Array.Copy(Data, 0, transferData, 4, 1000);
183 Client.SendXferPacket(XferID, 0, transferData); 183 Client.SendXferPacket(XferID, 0, transferData);
184 Packet++; 184 Packet++;
185 DataPointer = 1000; 185 DataPointer = 1000;
186 } 186 }
187 187
188 return complete; 188 return complete;
189 } 189 }
190 190
191 /// <summary> 191 /// <summary>
192 /// Respond to an ack packet from the client 192 /// Respond to an ack packet from the client
193 /// </summary> 193 /// </summary>
194 /// <param name="packet"></param> 194 /// <param name="packet"></param>
195 /// <returns>True if the transfer is complete, false otherwise</returns> 195 /// <returns>True if the transfer is complete, false otherwise</returns>
196 public bool AckPacket(uint packet) 196 public bool AckPacket(uint packet)
197 { 197 {
198 if (!complete) 198 if (!complete)
199 { 199 {
200 if ((Data.Length - DataPointer) > 1000) 200 if ((Data.Length - DataPointer) > 1000)
201 { 201 {
202 byte[] transferData = new byte[1000]; 202 byte[] transferData = new byte[1000];
203 Array.Copy(Data, DataPointer, transferData, 0, 1000); 203 Array.Copy(Data, DataPointer, transferData, 0, 1000);
204 Client.SendXferPacket(XferID, Packet, transferData); 204 Client.SendXferPacket(XferID, Packet, transferData);
205 Packet++; 205 Packet++;
206 DataPointer += 1000; 206 DataPointer += 1000;
207 } 207 }
208 else 208 else
209 { 209 {
210 byte[] transferData = new byte[Data.Length - DataPointer]; 210 byte[] transferData = new byte[Data.Length - DataPointer];
211 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); 211 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
212 uint endPacket = Packet |= (uint) 0x80000000; 212 uint endPacket = Packet |= (uint) 0x80000000;
213 Client.SendXferPacket(XferID, endPacket, transferData); 213 Client.SendXferPacket(XferID, endPacket, transferData);
214 Packet++; 214 Packet++;
215 DataPointer += (Data.Length - DataPointer); 215 DataPointer += (Data.Length - DataPointer);
216 216
217 complete = true; 217 complete = true;
218 } 218 }
219 } 219 }
220 220
221 return complete; 221 return complete;
222 } 222 }
223 } 223 }
224 } 224 }
225} 225} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs b/OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs
deleted file mode 100644
index 5353952..0000000
--- a/OpenSim/Region/Environment/Modules/AppearanceTableMapper.cs
+++ /dev/null
@@ -1,244 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenSim.Region.Environment.Scenes;
32using OpenSim.Framework;
33using OpenSim.Data.Base;
34
35namespace OpenSim.Region.Environment.Modules
36{
37
38 public class AppearanceRowMapper : BaseRowMapper<AvatarAppearance>
39 {
40 public AppearanceRowMapper(BaseSchema schema, AvatarAppearance obj)
41 : base(schema, obj)
42 {
43 }
44 }
45
46 public class AppearanceTableMapper : BaseTableMapper<AppearanceRowMapper, Guid>
47 {
48 public AppearanceTableMapper(BaseDatabaseConnector database, string tableName)
49 : base(database, tableName)
50 {
51 BaseSchema<AppearanceRowMapper> rowMapperSchema = new BaseSchema<AppearanceRowMapper>(this);
52 m_schema = rowMapperSchema;
53
54 m_keyFieldMapper = rowMapperSchema.AddMapping<Guid>("UUID",
55 delegate(AppearanceRowMapper mapper) { return mapper.Object.ScenePresenceID.UUID; },
56 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.ScenePresenceID = new libsecondlife.LLUUID(value.ToString()); });
57
58 rowMapperSchema.AddMapping<uint>("Serial",
59 delegate(AppearanceRowMapper mapper) { return (uint)mapper.Object.WearablesSerial; },
60 delegate(AppearanceRowMapper mapper, uint value) { mapper.Object.WearablesSerial = (int)value; });
61
62 rowMapperSchema.AddMapping<Guid>("WearableItem0",
63 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[0].ItemID.UUID; },
64 delegate(AppearanceRowMapper mapper, Guid value)
65 {
66 if (mapper.Object.Wearables == null)
67 {
68 mapper.Object.Wearables = new OpenSim.Framework.AvatarWearable[13];
69 for (int i = 0; i < 13; i++)
70 {
71 mapper.Object.Wearables[i] = new AvatarWearable();
72 }
73 }
74 mapper.Object.Wearables[0].ItemID = new libsecondlife.LLUUID(value.ToString());
75 });
76
77 rowMapperSchema.AddMapping<Guid>("WearableAsset0",
78 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[0].AssetID.UUID; },
79 delegate(AppearanceRowMapper mapper, Guid value)
80 { mapper.Object.Wearables[0].AssetID = new libsecondlife.LLUUID(value.ToString()); });
81
82 rowMapperSchema.AddMapping<Guid>("WearableItem1",
83 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[1].ItemID.UUID; },
84 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[1].ItemID = new libsecondlife.LLUUID(value.ToString()); });
85
86 rowMapperSchema.AddMapping<Guid>("WearableAsset1",
87 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[1].AssetID.UUID; },
88 delegate(AppearanceRowMapper mapper, Guid value)
89 { mapper.Object.Wearables[1].AssetID = new libsecondlife.LLUUID(value.ToString()); });
90
91 rowMapperSchema.AddMapping<Guid>("WearableItem2",
92 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[2].ItemID.UUID; },
93 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[2].ItemID = new libsecondlife.LLUUID(value.ToString()); });
94
95 rowMapperSchema.AddMapping<Guid>("WearableAsset2",
96 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[2].AssetID.UUID; },
97 delegate(AppearanceRowMapper mapper, Guid value)
98 { mapper.Object.Wearables[2].AssetID = new libsecondlife.LLUUID(value.ToString()); });
99
100 rowMapperSchema.AddMapping<Guid>("WearableItem3",
101 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[3].ItemID.UUID; },
102 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[3].ItemID = new libsecondlife.LLUUID(value.ToString()); });
103
104 rowMapperSchema.AddMapping<Guid>("WearableAsset3",
105 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[3].AssetID.UUID; },
106 delegate(AppearanceRowMapper mapper, Guid value)
107 { mapper.Object.Wearables[3].AssetID = new libsecondlife.LLUUID(value.ToString()); });
108
109 rowMapperSchema.AddMapping<Guid>("WearableItem4",
110 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[4].ItemID.UUID; },
111 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[4].ItemID = new libsecondlife.LLUUID(value.ToString()); });
112
113 rowMapperSchema.AddMapping<Guid>("WearableAsset4",
114 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[4].AssetID.UUID; },
115 delegate(AppearanceRowMapper mapper, Guid value)
116 { mapper.Object.Wearables[4].AssetID = new libsecondlife.LLUUID(value.ToString()); });
117
118 rowMapperSchema.AddMapping<Guid>("WearableItem5",
119 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[5].ItemID.UUID; },
120 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[5].ItemID = new libsecondlife.LLUUID(value.ToString()); });
121
122 rowMapperSchema.AddMapping<Guid>("WearableAsset5",
123 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[5].AssetID.UUID; },
124 delegate(AppearanceRowMapper mapper, Guid value)
125 { mapper.Object.Wearables[5].AssetID = new libsecondlife.LLUUID(value.ToString()); });
126
127 rowMapperSchema.AddMapping<Guid>("WearableItem6",
128 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[6].ItemID.UUID; },
129 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[6].ItemID = new libsecondlife.LLUUID(value.ToString()); });
130
131 rowMapperSchema.AddMapping<Guid>("WearableAsset6",
132 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[6].AssetID.UUID; },
133 delegate(AppearanceRowMapper mapper, Guid value)
134 { mapper.Object.Wearables[6].AssetID = new libsecondlife.LLUUID(value.ToString()); });
135
136 rowMapperSchema.AddMapping<Guid>("WearableItem7",
137 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[7].ItemID.UUID; },
138 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[7].ItemID = new libsecondlife.LLUUID(value.ToString()); });
139
140 rowMapperSchema.AddMapping<Guid>("WearableAsset7",
141 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[7].AssetID.UUID; },
142 delegate(AppearanceRowMapper mapper, Guid value)
143 { mapper.Object.Wearables[7].AssetID = new libsecondlife.LLUUID(value.ToString()); });
144
145 rowMapperSchema.AddMapping<Guid>("WearableItem8",
146 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[8].ItemID.UUID; },
147 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[8].ItemID = new libsecondlife.LLUUID(value.ToString()); });
148
149 rowMapperSchema.AddMapping<Guid>("WearableAsset8",
150 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[8].AssetID.UUID; },
151 delegate(AppearanceRowMapper mapper, Guid value)
152 { mapper.Object.Wearables[8].AssetID = new libsecondlife.LLUUID(value.ToString()); });
153
154 rowMapperSchema.AddMapping<Guid>("WearableItem9",
155 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[9].ItemID.UUID; },
156 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[9].ItemID = new libsecondlife.LLUUID(value.ToString()); });
157
158 rowMapperSchema.AddMapping<Guid>("WearableAsset9",
159 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[9].AssetID.UUID; },
160 delegate(AppearanceRowMapper mapper, Guid value)
161 { mapper.Object.Wearables[9].AssetID = new libsecondlife.LLUUID(value.ToString()); });
162
163 rowMapperSchema.AddMapping<Guid>("WearableItem10",
164 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[10].ItemID.UUID; },
165 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[10].ItemID = new libsecondlife.LLUUID(value.ToString()); });
166
167 rowMapperSchema.AddMapping<Guid>("WearableAsset10",
168 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[10].AssetID.UUID; },
169 delegate(AppearanceRowMapper mapper, Guid value)
170 { mapper.Object.Wearables[10].AssetID = new libsecondlife.LLUUID(value.ToString()); });
171
172 rowMapperSchema.AddMapping<Guid>("WearableItem11",
173 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[11].ItemID.UUID; },
174 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[11].ItemID = new libsecondlife.LLUUID(value.ToString()); });
175
176 rowMapperSchema.AddMapping<Guid>("WearableAsset11",
177 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[11].AssetID.UUID; },
178 delegate(AppearanceRowMapper mapper, Guid value)
179 { mapper.Object.Wearables[11].AssetID = new libsecondlife.LLUUID(value.ToString()); });
180
181 rowMapperSchema.AddMapping<Guid>("WearableItem12",
182 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[12].ItemID.UUID; },
183 delegate(AppearanceRowMapper mapper, Guid value) { mapper.Object.Wearables[12].ItemID = new libsecondlife.LLUUID(value.ToString()); });
184
185 rowMapperSchema.AddMapping<Guid>("WearableAsset12",
186 delegate(AppearanceRowMapper mapper) { return mapper.Object.Wearables[12].AssetID.UUID; },
187 delegate(AppearanceRowMapper mapper, Guid value)
188 { mapper.Object.Wearables[12].AssetID = new libsecondlife.LLUUID(value.ToString()); });
189
190 }
191
192 public bool Add(Guid userID, AvatarAppearance appearance)
193 {
194 AppearanceRowMapper mapper = CreateRowMapper(appearance);
195 return Add(mapper);
196 }
197
198 public bool Update(Guid userID, AvatarAppearance appearance)
199 {
200 AppearanceRowMapper mapper = CreateRowMapper(appearance);
201 return Update(appearance.ScenePresenceID.UUID, mapper);
202 }
203
204 protected AppearanceRowMapper CreateRowMapper(AvatarAppearance appearance)
205 {
206 return new AppearanceRowMapper(m_schema, appearance);
207 }
208
209 protected AppearanceRowMapper CreateRowMapper()
210 {
211 return CreateRowMapper(new AvatarAppearance());
212 }
213
214 protected AppearanceRowMapper FromReader(BaseDataReader reader, AvatarAppearance appearance)
215 {
216 AppearanceRowMapper mapper = CreateRowMapper(appearance);
217 mapper.FillObject(reader);
218 return mapper;
219 }
220
221 public override AppearanceRowMapper FromReader(BaseDataReader reader)
222 {
223 AppearanceRowMapper mapper = CreateRowMapper();
224 mapper.FillObject(reader);
225 return mapper;
226 }
227
228 public bool TryGetValue(Guid presenceID, out AvatarAppearance val)
229 {
230 AppearanceRowMapper mapper;
231 if (TryGetValue(presenceID, out mapper))
232 {
233 val = mapper.Object;
234 return true;
235 }
236 else
237 {
238 val = null;
239 return false;
240 }
241 }
242 }
243
244}*/
diff --git a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index cb94021..3614686 100644
--- a/OpenSim/Region/Environment/Modules/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/*
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Threading; 31using System.Threading;
32using libsecondlife; 32using libsecondlife;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications.Cache; 35using OpenSim.Framework.Communications.Cache;
36using OpenSim.Data.MySQLMapper; 36using OpenSim.Data.MySQLMapper;
37using OpenSim.Region.Environment.Interfaces; 37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
39using OpenSim.Data.Base; 39using OpenSim.Data.Base;
40 40
41namespace OpenSim.Region.Environment.Modules 41namespace 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/ChatModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
index 30c1397..1281873 100644
--- a/OpenSim/Region/Environment/Modules/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs
@@ -1,831 +1,831 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Net.Sockets; 31using System.Net.Sockets;
32using System.Reflection; 32using System.Reflection;
33using System.Text.RegularExpressions; 33using System.Text.RegularExpressions;
34using System.Threading; 34using System.Threading;
35using libsecondlife; 35using libsecondlife;
36using log4net; 36using log4net;
37using Nini.Config; 37using Nini.Config;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Region.Environment.Interfaces; 39using OpenSim.Region.Environment.Interfaces;
40using OpenSim.Region.Environment.Scenes; 40using OpenSim.Region.Environment.Scenes;
41 41
42namespace OpenSim.Region.Environment.Modules 42namespace 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 47
48 private List<Scene> m_scenes = new List<Scene>(); 48 private List<Scene> m_scenes = new List<Scene>();
49 49
50 private int m_whisperdistance = 10; 50 private int m_whisperdistance = 10;
51 private int m_saydistance = 30; 51 private int m_saydistance = 30;
52 private int m_shoutdistance = 100; 52 private int m_shoutdistance = 100;
53 53
54 private IRCChatModule m_irc = null; 54 private IRCChatModule m_irc = null;
55 55
56 private string m_last_new_user = null; 56 private string m_last_new_user = null;
57 private string m_last_leaving_user = null; 57 private string m_last_leaving_user = null;
58 private string m_defaultzone = null; 58 private string m_defaultzone = null;
59 internal object m_syncInit = new object(); 59 internal object m_syncInit = new object();
60 internal object m_syncLogout = new object(); 60 internal object m_syncLogout = new object();
61 private Thread m_irc_connector=null; 61 private Thread m_irc_connector=null;
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) { m_irc = new IRCChatModule(config); } 95 if (m_irc == null) { m_irc = new IRCChatModule(config); }
96 if (m_irc_connector == null) 96 if (m_irc_connector == null)
97 { 97 {
98 m_irc_connector = new Thread(IRCConnectRun); 98 m_irc_connector = new Thread(IRCConnectRun);
99 m_irc_connector.Name = "IRCConnectorThread"; 99 m_irc_connector.Name = "IRCConnectorThread";
100 m_irc_connector.IsBackground = true; 100 m_irc_connector.IsBackground = true;
101 } 101 }
102 } 102 }
103 } 103 }
104 104
105 public void PostInitialise() 105 public void PostInitialise()
106 { 106 {
107 if (m_irc.Enabled) 107 if (m_irc.Enabled)
108 { 108 {
109 try 109 try
110 { 110 {
111 //m_irc.Connect(m_scenes); 111 //m_irc.Connect(m_scenes);
112 if (m_irc_connector == null) 112 if (m_irc_connector == null)
113 { 113 {
114 m_irc_connector = new Thread(IRCConnectRun); 114 m_irc_connector = new Thread(IRCConnectRun);
115 m_irc_connector.Name = "IRCConnectorThread"; 115 m_irc_connector.Name = "IRCConnectorThread";
116 m_irc_connector.IsBackground = true; 116 m_irc_connector.IsBackground = true;
117 } 117 }
118 if (!m_irc_connector.IsAlive) 118 if (!m_irc_connector.IsAlive)
119 { 119 {
120 m_irc_connector.Start(); 120 m_irc_connector.Start();
121 ThreadTracker.Add(m_irc_connector); 121 ThreadTracker.Add(m_irc_connector);
122 } 122 }
123 } 123 }
124 catch (Exception) 124 catch (Exception)
125 { 125 {
126 } 126 }
127 } 127 }
128 } 128 }
129 129
130 public void Close() 130 public void Close()
131 { 131 {
132 m_irc.Close(); 132 m_irc.Close();
133 } 133 }
134 134
135 public string Name 135 public string Name
136 { 136 {
137 get { return "ChatModule"; } 137 get { return "ChatModule"; }
138 } 138 }
139 139
140 public bool IsSharedModule 140 public bool IsSharedModule
141 { 141 {
142 get { return true; } 142 get { return true; }
143 } 143 }
144 144
145 public void NewClient(IClientAPI client) 145 public void NewClient(IClientAPI client)
146 { 146 {
147 try 147 try
148 { 148 {
149 client.OnChatFromViewer += SimChat; 149 client.OnChatFromViewer += SimChat;
150 150
151 if ((m_irc.Enabled) && (m_irc.Connected)) 151 if ((m_irc.Enabled) && (m_irc.Connected))
152 { 152 {
153 string clientName = client.FirstName + " " + client.LastName; 153 string clientName = client.FirstName + " " + client.LastName;
154 // handles simple case. May not work for hundred connecting in per second. 154 // handles simple case. May not work for hundred connecting in per second.
155 // and the NewClients calles getting interleved 155 // and the NewClients calles getting interleved
156 // but filters out multiple reports 156 // but filters out multiple reports
157 if (clientName != m_last_new_user) 157 if (clientName != m_last_new_user)
158 { 158 {
159 m_last_new_user = clientName; 159 m_last_new_user = clientName;
160 string clientRegion = FindClientRegion(client.FirstName, client.LastName); 160 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
161 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion); 161 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion);
162 } 162 }
163 } 163 }
164 client.OnLogout += ClientLoggedOut; 164 client.OnLogout += ClientLoggedOut;
165 client.OnConnectionClosed += ClientLoggedOut; 165 client.OnConnectionClosed += ClientLoggedOut;
166 client.OnLogout += ClientLoggedOut; 166 client.OnLogout += ClientLoggedOut;
167 } 167 }
168 catch (Exception ex) 168 catch (Exception ex)
169 { 169 {
170 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); 170 m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString());
171 } 171 }
172 } 172 }
173 173
174 public void ClientLoggedOut(IClientAPI client) 174 public void ClientLoggedOut(IClientAPI client)
175 { 175 {
176 lock (m_syncLogout) 176 lock (m_syncLogout)
177 { 177 {
178 try 178 try
179 { 179 {
180 if ((m_irc.Enabled) && (m_irc.Connected)) 180 if ((m_irc.Enabled) && (m_irc.Connected))
181 { 181 {
182 string clientName = client.FirstName + " " + client.LastName; 182 string clientName = client.FirstName + " " + client.LastName;
183 string clientRegion = FindClientRegion(client.FirstName, client.LastName); 183 string clientRegion = FindClientRegion(client.FirstName, client.LastName);
184 // handles simple case. May not work for hundred connecting in per second. 184 // handles simple case. May not work for hundred connecting in per second.
185 // and the NewClients calles getting interleved 185 // and the NewClients calles getting interleved
186 // but filters out multiple reports 186 // but filters out multiple reports
187 if (clientName != m_last_leaving_user) 187 if (clientName != m_last_leaving_user)
188 { 188 {
189 m_last_leaving_user = clientName; 189 m_last_leaving_user = clientName;
190 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); 190 m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion);
191 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); 191 m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion);
192 } 192 }
193 } 193 }
194 } 194 }
195 catch (Exception ex) 195 catch (Exception ex)
196 { 196 {
197 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); 197 m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString());
198 } 198 }
199 } 199 }
200 } 200 }
201 201
202 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, 202 private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos,
203 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) 203 LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message)
204 { 204 {
205 if (!presence.IsChildAgent) 205 if (!presence.IsChildAgent)
206 { 206 {
207 LLVector3 fromRegionPos = fromPos + regionPos; 207 LLVector3 fromRegionPos = fromPos + regionPos;
208 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; 208 LLVector3 toRegionPos = presence.AbsolutePosition + regionPos;
209 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); 209 int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos));
210 210
211 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 211 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
212 type == ChatTypeEnum.Say && dis > m_saydistance || 212 type == ChatTypeEnum.Say && dis > m_saydistance ||
213 type == ChatTypeEnum.Shout && dis > m_shoutdistance) 213 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
214 { 214 {
215 return; 215 return;
216 } 216 }
217 217
218 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 218 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
219 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); 219 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID);
220 } 220 }
221 } 221 }
222 222
223 public void SimChat(Object sender, ChatFromViewerArgs e) 223 public void SimChat(Object sender, ChatFromViewerArgs e)
224 { 224 {
225 // FROM: Sim TO: IRC 225 // FROM: Sim TO: IRC
226 226
227 ScenePresence avatar = null; 227 ScenePresence avatar = null;
228 228
229 //TODO: Move ForEachScenePresence and others into IScene. 229 //TODO: Move ForEachScenePresence and others into IScene.
230 Scene scene = (Scene) e.Scene; 230 Scene scene = (Scene) e.Scene;
231 231
232 //TODO: Remove the need for this check 232 //TODO: Remove the need for this check
233 if (scene == null) 233 if (scene == null)
234 scene = m_scenes[0]; 234 scene = m_scenes[0];
235 235
236 // Filled in since it's easier than rewriting right now. 236 // Filled in since it's easier than rewriting right now.
237 LLVector3 fromPos = e.Position; 237 LLVector3 fromPos = e.Position;
238 LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 238 LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
239 239
240 string fromName = e.From; 240 string fromName = e.From;
241 string message = e.Message; 241 string message = e.Message;
242 LLUUID fromAgentID = LLUUID.Zero; 242 LLUUID fromAgentID = LLUUID.Zero;
243 243
244 if (e.Sender != null) 244 if (e.Sender != null)
245 { 245 {
246 avatar = scene.GetScenePresence(e.Sender.AgentId); 246 avatar = scene.GetScenePresence(e.Sender.AgentId);
247 } 247 }
248 248
249 if (avatar != null) 249 if (avatar != null)
250 { 250 {
251 fromPos = avatar.AbsolutePosition; 251 fromPos = avatar.AbsolutePosition;
252 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 252 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
253 fromName = avatar.Firstname + " " + avatar.Lastname; 253 fromName = avatar.Firstname + " " + avatar.Lastname;
254 fromAgentID = e.Sender.AgentId; 254 fromAgentID = e.Sender.AgentId;
255 } 255 }
256 256
257 // Try to reconnect to server if not connected 257 // Try to reconnect to server if not connected
258 if (m_irc.Enabled && !m_irc.Connected) 258 if (m_irc.Enabled && !m_irc.Connected)
259 { 259 {
260 // In a non-blocking way. Eventually the connector will get it started 260 // In a non-blocking way. Eventually the connector will get it started
261 try 261 try
262 { 262 {
263 if (m_irc_connector == null) 263 if (m_irc_connector == null)
264 { 264 {
265 m_irc_connector = new Thread(IRCConnectRun); 265 m_irc_connector = new Thread(IRCConnectRun);
266 m_irc_connector.Name = "IRCConnectorThread"; 266 m_irc_connector.Name = "IRCConnectorThread";
267 m_irc_connector.IsBackground = true; 267 m_irc_connector.IsBackground = true;
268 } 268 }
269 if (!m_irc_connector.IsAlive) 269 if (!m_irc_connector.IsAlive)
270 { 270 {
271 m_irc_connector.Start(); 271 m_irc_connector.Start();
272 ThreadTracker.Add(m_irc_connector); 272 ThreadTracker.Add(m_irc_connector);
273 } 273 }
274 } 274 }
275 catch (Exception) 275 catch (Exception)
276 { 276 {
277 } 277 }
278 } 278 }
279 279
280 280
281 // We only want to relay stuff on channel 0 281 // We only want to relay stuff on channel 0
282 if (e.Channel == 0) 282 if (e.Channel == 0)
283 { 283 {
284 // IRC stuff 284 // IRC stuff
285 if (e.Message.Length > 0) 285 if (e.Message.Length > 0)
286 { 286 {
287 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC 287 if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC
288 { 288 {
289 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); 289 m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
290 } 290 }
291 } 291 }
292 292
293 foreach (Scene s in m_scenes) 293 foreach (Scene s in m_scenes)
294 { 294 {
295 s.ForEachScenePresence(delegate(ScenePresence presence) 295 s.ForEachScenePresence(delegate(ScenePresence presence)
296 { 296 {
297 TrySendChatMessage(presence, fromPos, regionPos, 297 TrySendChatMessage(presence, fromPos, regionPos,
298 fromAgentID, fromName, e.Type, message); 298 fromAgentID, fromName, e.Type, message);
299 }); 299 });
300 } 300 }
301 } 301 }
302 } 302 }
303 303
304 // if IRC is enabled then just keep trying using a monitor thread 304 // if IRC is enabled then just keep trying using a monitor thread
305 public void IRCConnectRun() 305 public void IRCConnectRun()
306 { 306 {
307 while(true) 307 while(true)
308 { 308 {
309 if ((m_irc.Enabled)&&(!m_irc.Connected)) 309 if ((m_irc.Enabled)&&(!m_irc.Connected))
310 { 310 {
311 m_irc.Connect(m_scenes); 311 m_irc.Connect(m_scenes);
312 } 312 }
313 Thread.Sleep(15000); 313 Thread.Sleep(15000);
314 } 314 }
315 } 315 }
316 316
317 public string FindClientRegion(string client_FirstName,string client_LastName) 317 public string FindClientRegion(string client_FirstName,string client_LastName)
318 { 318 {
319 string sourceRegion = null; 319 string sourceRegion = null;
320 foreach (Scene s in m_scenes) 320 foreach (Scene s in m_scenes)
321 { 321 {
322 s.ForEachScenePresence(delegate(ScenePresence presence) 322 s.ForEachScenePresence(delegate(ScenePresence presence)
323 { 323 {
324 if ((presence.IsChildAgent==false) 324 if ((presence.IsChildAgent==false)
325 &&(presence.Firstname==client_FirstName) 325 &&(presence.Firstname==client_FirstName)
326 &&(presence.Lastname==client_LastName)) 326 &&(presence.Lastname==client_LastName))
327 { 327 {
328 sourceRegion = presence.Scene.RegionInfo.RegionName; 328 sourceRegion = presence.Scene.RegionInfo.RegionName;
329 //sourceRegion= s.RegionInfo.RegionName; 329 //sourceRegion= s.RegionInfo.RegionName;
330 } 330 }
331 }); 331 });
332 if (sourceRegion != null) return sourceRegion; 332 if (sourceRegion != null) return sourceRegion;
333 } 333 }
334 if (m_defaultzone == null) { m_defaultzone = "Sim"; } 334 if (m_defaultzone == null) { m_defaultzone = "Sim"; }
335 return m_defaultzone; 335 return m_defaultzone;
336 } 336 }
337 } 337 }
338 338
339 internal class IRCChatModule 339 internal class IRCChatModule
340 { 340 {
341 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 341 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
342 342
343 private string m_server = null; 343 private string m_server = null;
344 private uint m_port = 6668; 344 private uint m_port = 6668;
345 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; 345 private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
346 private string m_nick = null; 346 private string m_nick = null;
347 private string m_basenick = null; 347 private string m_basenick = null;
348 private string m_channel = null; 348 private string m_channel = null;
349 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; 349 private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}";
350 350
351 private NetworkStream m_stream; 351 private NetworkStream m_stream;
352 private TcpClient m_tcp; 352 private TcpClient m_tcp;
353 private StreamWriter m_writer; 353 private StreamWriter m_writer;
354 private StreamReader m_reader; 354 private StreamReader m_reader;
355 355
356 private Thread pingSender; 356 private Thread pingSender;
357 private Thread listener; 357 private Thread listener;
358 internal object m_syncConnect = new object(); 358 internal object m_syncConnect = new object();
359 359
360 private bool m_enabled = false; 360 private bool m_enabled = false;
361 private bool m_connected = false; 361 private bool m_connected = false;
362 362
363 private List<Scene> m_scenes = null; 363 private List<Scene> m_scenes = null;
364 private List<Scene> m_last_scenes = null; 364 private List<Scene> m_last_scenes = null;
365 365
366 public IRCChatModule(IConfigSource config) 366 public IRCChatModule(IConfigSource config)
367 { 367 {
368 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); 368 m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
369 m_tcp = null; 369 m_tcp = null;
370 m_writer = null; 370 m_writer = null;
371 m_reader = null; 371 m_reader = null;
372 372
373 // configuration in OpenSim.ini 373 // configuration in OpenSim.ini
374 // [IRC] 374 // [IRC]
375 // server = chat.freenode.net 375 // server = chat.freenode.net
376 // nick = OSimBot_mysim 376 // nick = OSimBot_mysim
377 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot 377 // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot
378 // ; username is the IRC command line sent 378 // ; username is the IRC command line sent
379 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> 379 // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname>
380 // channel = #opensim-regions 380 // channel = #opensim-regions
381 // port = 6667 381 // port = 6667
382 // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message 382 // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message
383 // ;for <bot>:<user in region> :<message> 383 // ;for <bot>:<user in region> :<message>
384 // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" 384 // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"
385 // ;for <bot>:<message> - <user of region> : 385 // ;for <bot>:<message> - <user of region> :
386 // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" 386 // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}"
387 // ;for <bot>:<message> - from <user> : 387 // ;for <bot>:<message> - from <user> :
388 // ;msgformat = "PRIVMSG {0} : {3} - from {1}" 388 // ;msgformat = "PRIVMSG {0} : {3} - from {1}"
389 // Traps I/O disconnects so it does not crash the sim 389 // Traps I/O disconnects so it does not crash the sim
390 // Trys to reconnect if disconnected and someone says something 390 // Trys to reconnect if disconnected and someone says something
391 // Tells IRC server "QUIT" when doing a close (just to be nice) 391 // Tells IRC server "QUIT" when doing a close (just to be nice)
392 // Default port back to 6667 392 // Default port back to 6667
393 393
394 try 394 try
395 { 395 {
396 m_server = config.Configs["IRC"].GetString("server"); 396 m_server = config.Configs["IRC"].GetString("server");
397 m_nick = config.Configs["IRC"].GetString("nick"); 397 m_nick = config.Configs["IRC"].GetString("nick");
398 m_basenick = m_nick; 398 m_basenick = m_nick;
399 m_channel = config.Configs["IRC"].GetString("channel"); 399 m_channel = config.Configs["IRC"].GetString("channel");
400 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); 400 m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port);
401 m_user = config.Configs["IRC"].GetString("username", m_user); 401 m_user = config.Configs["IRC"].GetString("username", m_user);
402 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); 402 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat);
403 if (m_server != null && m_nick != null && m_channel != null) 403 if (m_server != null && m_nick != null && m_channel != null)
404 { 404 {
405 m_nick = m_nick + Util.RandomClass.Next(1, 99); 405 m_nick = m_nick + Util.RandomClass.Next(1, 99);
406 m_enabled = true; 406 m_enabled = true;
407 } 407 }
408 } 408 }
409 catch (Exception) 409 catch (Exception)
410 { 410 {
411 m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); 411 m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration");
412 } 412 }
413 } 413 }
414 414
415 public bool Connect(List<Scene> scenes) 415 public bool Connect(List<Scene> scenes)
416 { 416 {
417 lock (m_syncConnect) 417 lock (m_syncConnect)
418 { 418 {
419 try 419 try
420 { 420 {
421 if (m_connected) return true; 421 if (m_connected) return true;
422 m_scenes = scenes; 422 m_scenes = scenes;
423 if (m_last_scenes == null) { m_last_scenes = scenes; } 423 if (m_last_scenes == null) { m_last_scenes = scenes; }
424 424
425 m_tcp = new TcpClient(m_server, (int)m_port); 425 m_tcp = new TcpClient(m_server, (int)m_port);
426 m_log.Info("[IRC]: Connecting..."); 426 m_log.Info("[IRC]: Connecting...");
427 m_stream = m_tcp.GetStream(); 427 m_stream = m_tcp.GetStream();
428 m_log.Info("[IRC]: Connected to " + m_server); 428 m_log.Info("[IRC]: Connected to " + m_server);
429 m_reader = new StreamReader(m_stream); 429 m_reader = new StreamReader(m_stream);
430 m_writer = new StreamWriter(m_stream); 430 m_writer = new StreamWriter(m_stream);
431 431
432 pingSender = new Thread(new ThreadStart(PingRun)); 432 pingSender = new Thread(new ThreadStart(PingRun));
433 pingSender.Name = "PingSenderThread"; 433 pingSender.Name = "PingSenderThread";
434 pingSender.IsBackground = true; 434 pingSender.IsBackground = true;
435 pingSender.Start(); 435 pingSender.Start();
436 ThreadTracker.Add(pingSender); 436 ThreadTracker.Add(pingSender);
437 437
438 listener = new Thread(new ThreadStart(ListenerRun)); 438 listener = new Thread(new ThreadStart(ListenerRun));
439 listener.Name = "IRCChatModuleListenerThread"; 439 listener.Name = "IRCChatModuleListenerThread";
440 listener.IsBackground = true; 440 listener.IsBackground = true;
441 listener.Start(); 441 listener.Start();
442 ThreadTracker.Add(listener); 442 ThreadTracker.Add(listener);
443 443
444 m_writer.WriteLine(m_user); 444 m_writer.WriteLine(m_user);
445 m_writer.Flush(); 445 m_writer.Flush();
446 m_writer.WriteLine("NICK " + m_nick); 446 m_writer.WriteLine("NICK " + m_nick);
447 m_writer.Flush(); 447 m_writer.Flush();
448 m_writer.WriteLine("JOIN " + m_channel); 448 m_writer.WriteLine("JOIN " + m_channel);
449 m_writer.Flush(); 449 m_writer.Flush();
450 m_log.Info("[IRC]: Connection fully established"); 450 m_log.Info("[IRC]: Connection fully established");
451 m_connected = true; 451 m_connected = true;
452 } 452 }
453 catch (Exception e) 453 catch (Exception e)
454 { 454 {
455 Console.WriteLine(e.ToString()); 455 Console.WriteLine(e.ToString());
456 } 456 }
457 return m_connected; 457 return m_connected;
458 } 458 }
459 } 459 }
460 460
461 public bool Enabled 461 public bool Enabled
462 { 462 {
463 get { return m_enabled; } 463 get { return m_enabled; }
464 } 464 }
465 465
466 public bool Connected 466 public bool Connected
467 { 467 {
468 get { return m_connected; } 468 get { return m_connected; }
469 } 469 }
470 470
471 public string Nick 471 public string Nick
472 { 472 {
473 get { return m_nick; } 473 get { return m_nick; }
474 } 474 }
475 475
476 public void Reconnect() 476 public void Reconnect()
477 { 477 {
478 m_connected = false; 478 m_connected = false;
479 listener.Abort(); 479 listener.Abort();
480 pingSender.Abort(); 480 pingSender.Abort();
481 m_writer.Close(); 481 m_writer.Close();
482 m_reader.Close(); 482 m_reader.Close();
483 m_tcp.Close(); 483 m_tcp.Close();
484 if (m_enabled) { Connect(m_last_scenes); } 484 if (m_enabled) { Connect(m_last_scenes); }
485 } 485 }
486 486
487 public void PrivMsg(string from, string region, string msg) 487 public void PrivMsg(string from, string region, string msg)
488 { 488 {
489 // One message to the IRC server 489 // One message to the IRC server
490 490
491 try 491 try
492 { 492 {
493 if (m_privmsgformat == null) 493 if (m_privmsgformat == null)
494 { 494 {
495 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); 495 m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
496 } 496 }
497 else 497 else
498 { 498 {
499 m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); 499 m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg);
500 } 500 }
501 m_writer.Flush(); 501 m_writer.Flush();
502 m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); 502 m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg);
503 } 503 }
504 catch (IOException) 504 catch (IOException)
505 { 505 {
506 m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); 506 m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)");
507 Reconnect(); 507 Reconnect();
508 } 508 }
509 catch (Exception ex) 509 catch (Exception ex)
510 { 510 {
511 m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); 511 m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString());
512 } 512 }
513 } 513 }
514 514
515 private Dictionary<string, string> ExtractMsg(string input) 515 private Dictionary<string, string> ExtractMsg(string input)
516 { 516 {
517 //examines IRC commands and extracts any private messages 517 //examines IRC commands and extracts any private messages
518 // which will then be reboadcast in the Sim 518 // which will then be reboadcast in the Sim
519 519
520 m_log.Info("[IRC]: ExtractMsg: " + input); 520 m_log.Info("[IRC]: ExtractMsg: " + input);
521 Dictionary<string, string> result = null; 521 Dictionary<string, string> result = null;
522 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 522 //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
523 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; 523 string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
524 Regex RE = new Regex(regex, RegexOptions.Multiline); 524 Regex RE = new Regex(regex, RegexOptions.Multiline);
525 MatchCollection matches = RE.Matches(input); 525 MatchCollection matches = RE.Matches(input);
526 // Get some direct matches $1 $4 is a 526 // Get some direct matches $1 $4 is a
527 if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) 527 if ((matches.Count == 1) && (matches[0].Groups.Count == 5))
528 { 528 {
529 result = new Dictionary<string, string>(); 529 result = new Dictionary<string, string>();
530 result.Add("nick", matches[0].Groups[1].Value); 530 result.Add("nick", matches[0].Groups[1].Value);
531 result.Add("user", matches[0].Groups[2].Value); 531 result.Add("user", matches[0].Groups[2].Value);
532 result.Add("channel", matches[0].Groups[3].Value); 532 result.Add("channel", matches[0].Groups[3].Value);
533 result.Add("msg", matches[0].Groups[4].Value); 533 result.Add("msg", matches[0].Groups[4].Value);
534 } 534 }
535 else 535 else
536 { 536 {
537 m_log.Info("[IRC]: Number of matches: " + matches.Count); 537 m_log.Info("[IRC]: Number of matches: " + matches.Count);
538 if (matches.Count > 0) 538 if (matches.Count > 0)
539 { 539 {
540 m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); 540 m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count);
541 } 541 }
542 } 542 }
543 return result; 543 return result;
544 } 544 }
545 545
546 public void PingRun() 546 public void PingRun()
547 { 547 {
548 // IRC keep alive thread 548 // IRC keep alive thread
549 // send PING ever 15 seconds 549 // send PING ever 15 seconds
550 while (true) 550 while (true)
551 { 551 {
552 try 552 try
553 { 553 {
554 if (m_connected == true) 554 if (m_connected == true)
555 { 555 {
556 m_writer.WriteLine("PING :" + m_server); 556 m_writer.WriteLine("PING :" + m_server);
557 m_writer.Flush(); 557 m_writer.Flush();
558 Thread.Sleep(15000); 558 Thread.Sleep(15000);
559 } 559 }
560 } 560 }
561 catch (IOException) 561 catch (IOException)
562 { 562 {
563 m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); 563 m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)");
564 Reconnect(); 564 Reconnect();
565 } 565 }
566 catch (Exception ex) 566 catch (Exception ex)
567 { 567 {
568 m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); 568 m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
569 } 569 }
570 } 570 }
571 } 571 }
572 572
573 public void ListenerRun() 573 public void ListenerRun()
574 { 574 {
575 string inputLine; 575 string inputLine;
576 LLVector3 pos = new LLVector3(128, 128, 20); 576 LLVector3 pos = new LLVector3(128, 128, 20);
577 while (true) 577 while (true)
578 { 578 {
579 try 579 try
580 { 580 {
581 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) 581 while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null))
582 { 582 {
583 // Console.WriteLine(inputLine); 583 // Console.WriteLine(inputLine);
584 if (inputLine.Contains(m_channel)) 584 if (inputLine.Contains(m_channel))
585 { 585 {
586 Dictionary<string, string> data = ExtractMsg(inputLine); 586 Dictionary<string, string> data = ExtractMsg(inputLine);
587 // Any chat ??? 587 // Any chat ???
588 if (data != null) 588 if (data != null)
589 { 589 {
590 foreach (Scene m_scene in m_scenes) 590 foreach (Scene m_scene in m_scenes)
591 { 591 {
592 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 592 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
593 { 593 {
594 if (!avatar.IsChildAgent) 594 if (!avatar.IsChildAgent)
595 { 595 {
596 avatar.ControllingClient.SendChatMessage( 596 avatar.ControllingClient.SendChatMessage(
597 Helpers.StringToField(data["msg"]), 255, 597 Helpers.StringToField(data["msg"]), 255,
598 pos, data["nick"], 598 pos, data["nick"],
599 LLUUID.Zero); 599 LLUUID.Zero);
600 } 600 }
601 }); 601 });
602 } 602 }
603 } 603 }
604 else 604 else
605 { 605 {
606 // Was an command from the IRC server 606 // Was an command from the IRC server
607 ProcessIRCCommand(inputLine); 607 ProcessIRCCommand(inputLine);
608 } 608 }
609 } 609 }
610 else 610 else
611 { 611 {
612 // Was an command from the IRC server 612 // Was an command from the IRC server
613 ProcessIRCCommand(inputLine); 613 ProcessIRCCommand(inputLine);
614 } 614 }
615 Thread.Sleep(150); 615 Thread.Sleep(150);
616 } 616 }
617 } 617 }
618 catch (IOException) 618 catch (IOException)
619 { 619 {
620 m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); 620 m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)");
621 Reconnect(); 621 Reconnect();
622 } 622 }
623 catch (Exception ex) 623 catch (Exception ex)
624 { 624 {
625 m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); 625 m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace);
626 } 626 }
627 } 627 }
628 } 628 }
629 629
630 public void BroadcastSim(string message,string sender) 630 public void BroadcastSim(string message,string sender)
631 { 631 {
632 LLVector3 pos = new LLVector3(128, 128, 20); 632 LLVector3 pos = new LLVector3(128, 128, 20);
633 try 633 try
634 { 634 {
635 foreach (Scene m_scene in m_scenes) 635 foreach (Scene m_scene in m_scenes)
636 { 636 {
637 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 637 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
638 { 638 {
639 if (!avatar.IsChildAgent) 639 if (!avatar.IsChildAgent)
640 { 640 {
641 avatar.ControllingClient.SendChatMessage( 641 avatar.ControllingClient.SendChatMessage(
642 Helpers.StringToField(message), 255, 642 Helpers.StringToField(message), 255,
643 pos, sender, 643 pos, sender,
644 LLUUID.Zero); 644 LLUUID.Zero);
645 } 645 }
646 }); 646 });
647 } 647 }
648 } 648 }
649 catch (Exception ex) // IRC gate should not crash Sim 649 catch (Exception ex) // IRC gate should not crash Sim
650 { 650 {
651 m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); 651 m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace);
652 } 652 }
653 } 653 }
654 654
655 public enum ErrorReplies 655 public enum ErrorReplies
656 { 656 {
657 NotRegistered = 451, // ":You have not registered" 657 NotRegistered = 451, // ":You have not registered"
658 NicknameInUse = 433 // "<nick> :Nickname is already in use" 658 NicknameInUse = 433 // "<nick> :Nickname is already in use"
659 } 659 }
660 660
661 public enum Replies 661 public enum Replies
662 { 662 {
663 MotdStart = 375, // ":- <server> Message of the day - " 663 MotdStart = 375, // ":- <server> Message of the day - "
664 Motd = 372, // ":- <text>" 664 Motd = 372, // ":- <text>"
665 EndOfMotd = 376 // ":End of /MOTD command" 665 EndOfMotd = 376 // ":End of /MOTD command"
666 } 666 }
667 667
668 public void ProcessIRCCommand(string command) 668 public void ProcessIRCCommand(string command)
669 { 669 {
670 //m_log.Info("[IRC]: ProcessIRCCommand:" + command); 670 //m_log.Info("[IRC]: ProcessIRCCommand:" + command);
671 671
672 string[] commArgs = new string[command.Split(' ').Length]; 672 string[] commArgs = new string[command.Split(' ').Length];
673 string c_server = m_server; 673 string c_server = m_server;
674 674
675 commArgs = command.Split(' '); 675 commArgs = command.Split(' ');
676 if (commArgs[0].Substring(0, 1) == ":") 676 if (commArgs[0].Substring(0, 1) == ":")
677 { 677 {
678 commArgs[0] = commArgs[0].Remove(0, 1); 678 commArgs[0] = commArgs[0].Remove(0, 1);
679 } 679 }
680 680
681 if (commArgs[1] == "002") 681 if (commArgs[1] == "002")
682 { 682 {
683 // fetch the correct servername 683 // fetch the correct servername
684 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... 684 // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/...
685 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch 685 // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch
686 686
687 c_server = (commArgs[6].Split('['))[0]; 687 c_server = (commArgs[6].Split('['))[0];
688 m_server = c_server; 688 m_server = c_server;
689 } 689 }
690 690
691 if (commArgs[0] == "ERROR") 691 if (commArgs[0] == "ERROR")
692 { 692 {
693 m_log.Error("[IRC]: IRC SERVER ERROR:" + command); 693 m_log.Error("[IRC]: IRC SERVER ERROR:" + command);
694 } 694 }
695 695
696 if (commArgs[0] == "PING") 696 if (commArgs[0] == "PING")
697 { 697 {
698 string p_reply = ""; 698 string p_reply = "";
699 699
700 for (int i = 1; i < commArgs.Length; i++) 700 for (int i = 1; i < commArgs.Length; i++)
701 { 701 {
702 p_reply += commArgs[i] + " "; 702 p_reply += commArgs[i] + " ";
703 } 703 }
704 704
705 m_writer.WriteLine("PONG " + p_reply); 705 m_writer.WriteLine("PONG " + p_reply);
706 m_writer.Flush(); 706 m_writer.Flush();
707 } 707 }
708 else if (commArgs[0] == c_server) 708 else if (commArgs[0] == c_server)
709 { 709 {
710 // server message 710 // server message
711 try 711 try
712 { 712 {
713 Int32 commandCode = Int32.Parse(commArgs[1]); 713 Int32 commandCode = Int32.Parse(commArgs[1]);
714 switch (commandCode) 714 switch (commandCode)
715 { 715 {
716 case (int)ErrorReplies.NicknameInUse: 716 case (int)ErrorReplies.NicknameInUse:
717 // Gen a new name 717 // Gen a new name
718 m_nick = m_basenick + Util.RandomClass.Next(1, 99); 718 m_nick = m_basenick + Util.RandomClass.Next(1, 99);
719 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); 719 m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick);
720 // Retry 720 // Retry
721 m_writer.WriteLine("NICK " + m_nick); 721 m_writer.WriteLine("NICK " + m_nick);
722 m_writer.Flush(); 722 m_writer.Flush();
723 m_writer.WriteLine("JOIN " + m_channel); 723 m_writer.WriteLine("JOIN " + m_channel);
724 m_writer.Flush(); 724 m_writer.Flush();
725 break; 725 break;
726 case (int)ErrorReplies.NotRegistered: 726 case (int)ErrorReplies.NotRegistered:
727 break; 727 break;
728 case (int)Replies.EndOfMotd: 728 case (int)Replies.EndOfMotd:
729 break; 729 break;
730 } 730 }
731 } 731 }
732 catch (Exception) 732 catch (Exception)
733 { 733 {
734 } 734 }
735 } 735 }
736 else 736 else
737 { 737 {
738 // Normal message 738 // Normal message
739 string commAct = commArgs[1]; 739 string commAct = commArgs[1];
740 switch (commAct) 740 switch (commAct)
741 { 741 {
742 case "JOIN": eventIrcJoin(commArgs); break; 742 case "JOIN": eventIrcJoin(commArgs); break;
743 case "PART": eventIrcPart(commArgs); break; 743 case "PART": eventIrcPart(commArgs); break;
744 case "MODE": eventIrcMode(commArgs); break; 744 case "MODE": eventIrcMode(commArgs); break;
745 case "NICK": eventIrcNickChange(commArgs); break; 745 case "NICK": eventIrcNickChange(commArgs); break;
746 case "KICK": eventIrcKick(commArgs); break; 746 case "KICK": eventIrcKick(commArgs); break;
747 case "QUIT": eventIrcQuit(commArgs); break; 747 case "QUIT": eventIrcQuit(commArgs); break;
748 case "PONG": break; // that's nice 748 case "PONG": break; // that's nice
749 } 749 }
750 } 750 }
751 } 751 }
752 752
753 public void eventIrcJoin(string[] commArgs) 753 public void eventIrcJoin(string[] commArgs)
754 { 754 {
755 string IrcChannel = commArgs[2]; 755 string IrcChannel = commArgs[2];
756 string IrcUser = commArgs[0].Split('!')[0]; 756 string IrcUser = commArgs[0].Split('!')[0];
757 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); 757 BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick);
758 } 758 }
759 759
760 public void eventIrcPart(string[] commArgs) 760 public void eventIrcPart(string[] commArgs)
761 { 761 {
762 string IrcChannel = commArgs[2]; 762 string IrcChannel = commArgs[2];
763 string IrcUser = commArgs[0].Split('!')[0]; 763 string IrcUser = commArgs[0].Split('!')[0];
764 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); 764 BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick);
765 } 765 }
766 766
767 public void eventIrcMode(string[] commArgs) 767 public void eventIrcMode(string[] commArgs)
768 { 768 {
769 string IrcChannel = commArgs[2]; 769 string IrcChannel = commArgs[2];
770 string IrcUser = commArgs[0].Split('!')[0]; 770 string IrcUser = commArgs[0].Split('!')[0];
771 string UserMode = ""; 771 string UserMode = "";
772 for (int i = 3; i < commArgs.Length; i++) 772 for (int i = 3; i < commArgs.Length; i++)
773 { 773 {
774 UserMode += commArgs[i] + " "; 774 UserMode += commArgs[i] + " ";
775 } 775 }
776 776
777 if (UserMode.Substring(0, 1) == ":") 777 if (UserMode.Substring(0, 1) == ":")
778 { 778 {
779 UserMode = UserMode.Remove(0, 1); 779 UserMode = UserMode.Remove(0, 1);
780 } 780 }
781 } 781 }
782 782
783 public void eventIrcNickChange(string[] commArgs) 783 public void eventIrcNickChange(string[] commArgs)
784 { 784 {
785 string UserOldNick = commArgs[0].Split('!')[0]; 785 string UserOldNick = commArgs[0].Split('!')[0];
786 string UserNewNick = commArgs[2].Remove(0, 1); 786 string UserNewNick = commArgs[2].Remove(0, 1);
787 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); 787 BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick);
788 } 788 }
789 789
790 public void eventIrcKick(string[] commArgs) 790 public void eventIrcKick(string[] commArgs)
791 { 791 {
792 string UserKicker = commArgs[0].Split('!')[0]; 792 string UserKicker = commArgs[0].Split('!')[0];
793 string UserKicked = commArgs[3]; 793 string UserKicked = commArgs[3];
794 string IrcChannel = commArgs[2]; 794 string IrcChannel = commArgs[2];
795 string KickMessage = ""; 795 string KickMessage = "";
796 for (int i = 4; i < commArgs.Length; i++) 796 for (int i = 4; i < commArgs.Length; i++)
797 { 797 {
798 KickMessage += commArgs[i] + " "; 798 KickMessage += commArgs[i] + " ";
799 } 799 }
800 BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick); 800 BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick);
801 if (UserKicked == m_nick) 801 if (UserKicked == m_nick)
802 { 802 {
803 BroadcastSim("Hey, that was me!!!", m_nick); 803 BroadcastSim("Hey, that was me!!!", m_nick);
804 } 804 }
805 } 805 }
806 806
807 public void eventIrcQuit(string[] commArgs) 807 public void eventIrcQuit(string[] commArgs)
808 { 808 {
809 string IrcUser = commArgs[0].Split('!')[0]; 809 string IrcUser = commArgs[0].Split('!')[0];
810 string QuitMessage = ""; 810 string QuitMessage = "";
811 811
812 for (int i = 2; i < commArgs.Length; i++) 812 for (int i = 2; i < commArgs.Length; i++)
813 { 813 {
814 QuitMessage += commArgs[i] + " "; 814 QuitMessage += commArgs[i] + " ";
815 } 815 }
816 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); 816 BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick);
817 } 817 }
818 818
819 public void Close() 819 public void Close()
820 { 820 {
821 m_connected = false; 821 m_connected = false;
822 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); 822 m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing");
823 m_writer.Flush(); 823 m_writer.Flush();
824 listener.Abort(); 824 listener.Abort();
825 pingSender.Abort(); 825 pingSender.Abort();
826 m_writer.Close(); 826 m_writer.Close();
827 m_reader.Close(); 827 m_reader.Close();
828 m_tcp.Close(); 828 m_tcp.Close();
829 } 829 }
830 } 830 }
831} 831} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs
index 3a8906e..0e058ec 100644
--- a/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs
@@ -1,1490 +1,1491 @@
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
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Net.Sockets; 32using System.Net.Sockets;
33using System.Reflection; 33using System.Reflection;
34using System.Xml; 34using System.Xml;
35using libsecondlife; 35using libsecondlife;
36using log4net; 36using log4net;
37using Nini.Config; 37using Nini.Config;
38using Nwc.XmlRpc; 38using Nwc.XmlRpc;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Region.Environment.Interfaces; 40using OpenSim.Region.Environment.Interfaces;
41using OpenSim.Region.Environment.Scenes; 41using OpenSim.Region.Environment.Scenes;
42 42
43namespace OpenSim.Region.Environment.Modules 43namespace 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 56
57 public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount); 57 public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount);
58 58
59 public interface IMoneyModule : IRegionModule 59 public interface IMoneyModule : IRegionModule
60 { 60 {
61 bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount); 61 bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount);
62 62
63 event ObjectPaid OnObjectPaid; 63 event ObjectPaid OnObjectPaid;
64 } 64 }
65 65
66 public class BetaGridLikeMoneyModule: IMoneyModule 66 public class SampleMoneyModule : IMoneyModule
67 { 67 {
68 public event ObjectPaid OnObjectPaid; 68 public event ObjectPaid OnObjectPaid;
69 69
70 private ObjectPaid handerOnObjectPaid; 70 private ObjectPaid handerOnObjectPaid;
71 71
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
73 73
74 /// <summary> 74 /// <summary>
75 /// Region UUIDS indexed by AgentID 75 /// Region UUIDS indexed by AgentID
76 /// </summary> 76 /// </summary>
77 Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>(); 77 Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>();
78 78
79 /// <summary> 79 /// <summary>
80 /// Scenes by Region Handle 80 /// Scenes by Region Handle
81 /// </summary> 81 /// </summary>
82 private Dictionary<ulong,Scene> m_scenel = new Dictionary<ulong,Scene>(); 82 private Dictionary<ulong,Scene> m_scenel = new Dictionary<ulong,Scene>();
83 83
84 private IConfigSource m_gConfig; 84 private IConfigSource m_gConfig;
85 85
86 private bool m_keepMoneyAcrossLogins = true; 86 private bool m_keepMoneyAcrossLogins = true;
87 87
88 private int m_minFundsBeforeRefresh = 100; 88 private int m_minFundsBeforeRefresh = 100;
89 89
90 private int m_stipend = 1000; 90 private int m_stipend = 1000;
91 91
92 private bool m_enabled = true; 92 private bool m_enabled = true;
93 93
94 private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>(); 94 private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>();
95 95
96 private bool gridmode = false; 96 private bool gridmode = false;
97 private Scene XMLRPCHandler; 97 private Scene XMLRPCHandler;
98 private float EnergyEfficiency = 0f; 98 private float EnergyEfficiency = 0f;
99 private int ObjectCapacity = 45000; 99 private int ObjectCapacity = 45000;
100 private int ObjectCount = 0; 100 private int ObjectCount = 0;
101 private int PriceEnergyUnit = 0; 101 private int PriceEnergyUnit = 0;
102 private int PriceGroupCreate = 0; 102 private int PriceGroupCreate = 0;
103 private int PriceObjectClaim = 0; 103 private int PriceObjectClaim = 0;
104 private float PriceObjectRent = 0f; 104 private float PriceObjectRent = 0f;
105 private float PriceObjectScaleFactor = 0f; 105 private float PriceObjectScaleFactor = 0f;
106 private int PriceParcelClaim = 0; 106 private int PriceParcelClaim = 0;
107 private float PriceParcelClaimFactor = 0f; 107 private float PriceParcelClaimFactor = 0f;
108 private int PriceParcelRent = 0; 108 private int PriceParcelRent = 0;
109 private int PricePublicObjectDecay = 0; 109 private int PricePublicObjectDecay = 0;
110 private int PricePublicObjectDelete = 0; 110 private int PricePublicObjectDelete = 0;
111 private int PriceRentLight = 0; 111 private int PriceRentLight = 0;
112 private int PriceUpload = 0; 112 private int PriceUpload = 0;
113 private int TeleportMinPrice = 0; 113 private int TeleportMinPrice = 0;
114 private int UserLevelPaysFees = 2; 114 private int UserLevelPaysFees = 2;
115 private string m_MoneyAddress = String.Empty; 115 private string m_MoneyAddress = String.Empty;
116 private string m_LandAddress = String.Empty; 116 private string m_LandAddress = String.Empty;
117 117
118 float TeleportPriceExponent = 0f; 118 float TeleportPriceExponent = 0f;
119 119
120 /// <summary> 120 /// <summary>
121 /// Where Stipends come from and Fees go to. 121 /// Where Stipends come from and Fees go to.
122 /// </summary> 122 /// </summary>
123 LLUUID EconomyBaseAccount = LLUUID.Zero; 123 LLUUID EconomyBaseAccount = LLUUID.Zero;
124 124
125 /// <summary> 125 /// <summary>
126 /// Startup 126 /// Startup
127 /// </summary> 127 /// </summary>
128 /// <param name="scene"></param> 128 /// <param name="scene"></param>
129 /// <param name="config"></param> 129 /// <param name="config"></param>
130 public void Initialise(Scene scene, IConfigSource config) 130 public void Initialise(Scene scene, IConfigSource config)
131 { 131 {
132 m_gConfig = config; 132 m_gConfig = config;
133 133
134 IConfig startupConfig = m_gConfig.Configs["Startup"]; 134 IConfig startupConfig = m_gConfig.Configs["Startup"];
135 IConfig economyConfig = m_gConfig.Configs["Economy"]; 135 IConfig economyConfig = m_gConfig.Configs["Economy"];
136 136
137 scene.RegisterModuleInterface<IMoneyModule>(this); 137 scene.RegisterModuleInterface<IMoneyModule>(this);
138 138
139 ReadConfigAndPopulate(scene, startupConfig, "Startup"); 139 ReadConfigAndPopulate(scene, startupConfig, "Startup");
140 ReadConfigAndPopulate(scene, economyConfig, "Economy"); 140 ReadConfigAndPopulate(scene, economyConfig, "Economy");
141 141
142 if (m_enabled) 142 if (m_enabled)
143 { 143 {
144 lock (m_scenel) 144 lock (m_scenel)
145 { 145 {
146 if (m_scenel.Count == 0) 146 if (m_scenel.Count == 0)
147 { 147 {
148 XMLRPCHandler = scene; 148 XMLRPCHandler = scene;
149 149
150 // To use the following you need to add: 150 // To use the following you need to add:
151 // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> 151 // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER>
152 // to the command line parameters you use to start up your client 152 // to the command line parameters you use to start up your client
153 // This commonly looks like -helperuri http://127.0.0.1:9000/ 153 // This commonly looks like -helperuri http://127.0.0.1:9000/
154 154
155 if (m_MoneyAddress.Length > 0) 155 if (m_MoneyAddress.Length > 0)
156 { 156 {
157 // Centralized grid structure using OpenSimWi Redux revision 9+ 157 // Centralized grid structure using OpenSimWi Redux revision 9+
158 // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux 158 // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux
159 scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate); 159 scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate);
160 scene.AddXmlRPCHandler("userAlert", UserAlert); 160 scene.AddXmlRPCHandler("userAlert", UserAlert);
161 } 161 }
162 else 162 else
163 { 163 {
164 // Local Server.. enables functionality only. 164 // Local Server.. enables functionality only.
165 scene.AddXmlRPCHandler("getCurrencyQuote", quote_func); 165 scene.AddXmlRPCHandler("getCurrencyQuote", quote_func);
166 scene.AddXmlRPCHandler("buyCurrency", buy_func); 166 scene.AddXmlRPCHandler("buyCurrency", buy_func);
167 scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); 167 scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func);
168 scene.AddXmlRPCHandler("buyLandPrep", landBuy_func); 168 scene.AddXmlRPCHandler("buyLandPrep", landBuy_func);
169 } 169 }
170 170
171 171
172 } 172 }
173 173
174 if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) 174 if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle))
175 { 175 {
176 m_scenel[scene.RegionInfo.RegionHandle] = scene; 176 m_scenel[scene.RegionInfo.RegionHandle] = scene;
177 } 177 }
178 else 178 else
179 { 179 {
180 m_scenel.Add(scene.RegionInfo.RegionHandle, scene); 180 m_scenel.Add(scene.RegionInfo.RegionHandle, scene);
181 } 181 }
182 } 182 }
183 183
184 scene.EventManager.OnNewClient += OnNewClient; 184 scene.EventManager.OnNewClient += OnNewClient;
185 scene.EventManager.OnMoneyTransfer += MoneyTransferAction; 185 scene.EventManager.OnMoneyTransfer += MoneyTransferAction;
186 scene.EventManager.OnClientClosed += ClientClosed; 186 scene.EventManager.OnClientClosed += ClientClosed;
187 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; 187 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
188 scene.EventManager.OnMakeChildAgent += MakeChildAgent; 188 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
189 scene.EventManager.OnClientClosed += ClientLoggedOut; 189 scene.EventManager.OnClientClosed += ClientLoggedOut;
190 scene.EventManager.OnValidateLandBuy += ValidateLandBuy; 190 scene.EventManager.OnValidateLandBuy += ValidateLandBuy;
191 scene.EventManager.OnLandBuy += processLandBuy; 191 scene.EventManager.OnLandBuy += processLandBuy;
192 192
193 } 193 }
194 } 194 }
195 /// <summary> 195 /// <summary>
196 /// Parse Configuration 196 /// Parse Configuration
197 /// </summary> 197 /// </summary>
198 /// <param name="scene"></param> 198 /// <param name="scene"></param>
199 /// <param name="startupConfig"></param> 199 /// <param name="startupConfig"></param>
200 /// <param name="config"></param> 200 /// <param name="config"></param>
201 private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config) 201 private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config)
202 { 202 {
203 if (config == "Startup" && startupConfig != null) 203 if (config == "Startup" && startupConfig != null)
204 { 204 {
205 gridmode = startupConfig.GetBoolean("gridmode", false); 205 gridmode = startupConfig.GetBoolean("gridmode", false);
206 m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); 206 m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule");
207 } 207 }
208 208
209 if (config == "Economy" && startupConfig != null) 209 if (config == "Economy" && startupConfig != null)
210 { 210 {
211 ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000); 211 ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000);
212 PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); 212 PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100);
213 PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); 213 PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10);
214 PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); 214 PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4);
215 PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4); 215 PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4);
216 PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1); 216 PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1);
217 PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f); 217 PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f);
218 PriceUpload = startupConfig.GetInt("PriceUpload", 0); 218 PriceUpload = startupConfig.GetInt("PriceUpload", 0);
219 PriceRentLight = startupConfig.GetInt("PriceRentLight", 5); 219 PriceRentLight = startupConfig.GetInt("PriceRentLight", 5);
220 TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2); 220 TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2);
221 TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f); 221 TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f);
222 EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1); 222 EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1);
223 PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1); 223 PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1);
224 PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10); 224 PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10);
225 PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1); 225 PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1);
226 PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1); 226 PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1);
227 string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString()); 227 string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString());
228 Helpers.TryParse(EBA,out EconomyBaseAccount); 228 Helpers.TryParse(EBA,out EconomyBaseAccount);
229 229
230 UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1); 230 UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1);
231 m_stipend = startupConfig.GetInt("UserStipend", 500); 231 m_stipend = startupConfig.GetInt("UserStipend", 500);
232 m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10); 232 m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10);
233 m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true); 233 m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true);
234 m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty); 234 m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty);
235 m_LandAddress = startupConfig.GetString("LandServer", String.Empty); 235 m_LandAddress = startupConfig.GetString("LandServer", String.Empty);
236 } 236 }
237 237
238 // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter. 238 // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter.
239 scene.SetObjectCapacity(ObjectCapacity); 239 scene.SetObjectCapacity(ObjectCapacity);
240 } 240 }
241 241
242 /// <summary> 242 /// <summary>
243 /// New Client Event Handler 243 /// New Client Event Handler
244 /// </summary> 244 /// </summary>
245 /// <param name="client"></param> 245 /// <param name="client"></param>
246 private void OnNewClient(IClientAPI client) 246 private void OnNewClient(IClientAPI client)
247 { 247 {
248 // Here we check if we're in grid mode 248 // Here we check if we're in grid mode
249 // I imagine that the 'check balance' 249 // I imagine that the 'check balance'
250 // function for the client should be here or shortly after 250 // function for the client should be here or shortly after
251 251
252 if (gridmode) 252 if (gridmode)
253 { 253 {
254 if (m_MoneyAddress.Length == 0) 254 if (m_MoneyAddress.Length == 0)
255 { 255 {
256 256
257 CheckExistAndRefreshFunds(client.AgentId); 257 CheckExistAndRefreshFunds(client.AgentId);
258 } 258 }
259 else 259 else
260 { 260 {
261 bool childYN = true; 261 bool childYN = true;
262 ScenePresence agent = null; 262 ScenePresence agent = null;
263 //client.SecureSessionId; 263 //client.SecureSessionId;
264 Scene s = LocateSceneClientIn(client.AgentId); 264 Scene s = LocateSceneClientIn(client.AgentId);
265 if (s != null) 265 if (s != null)
266 { 266 {
267 agent = s.GetScenePresence(client.AgentId); 267 agent = s.GetScenePresence(client.AgentId);
268 if (agent != null) 268 if (agent != null)
269 childYN = agent.IsChildAgent; 269 childYN = agent.IsChildAgent;
270 } 270 }
271 if (s != null && agent != null && childYN == false) 271 if (s != null && agent != null && childYN == false)
272 { 272 {
273 //s.RegionInfo.RegionHandle; 273 //s.RegionInfo.RegionHandle;
274 LLUUID agentID = LLUUID.Zero; 274 LLUUID agentID = LLUUID.Zero;
275 int funds = 0; 275 int funds = 0;
276 276
277 Hashtable hbinfo = GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret); 277 Hashtable hbinfo = GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret);
278 if ((bool)hbinfo["success"] == true) 278 if ((bool)hbinfo["success"] == true)
279 { 279 {
280 280
281 Helpers.TryParse((string)hbinfo["agentId"], out agentID); 281 Helpers.TryParse((string)hbinfo["agentId"], out agentID);
282 try 282 try
283 { 283 {
284 funds = (Int32)hbinfo["funds"]; 284 funds = (Int32)hbinfo["funds"];
285 } 285 }
286 catch (ArgumentException) 286 catch (ArgumentException)
287 { 287 {
288 } 288 }
289 catch (FormatException) 289 catch (FormatException)
290 { 290 {
291 } 291 }
292 catch (OverflowException) 292 catch (OverflowException)
293 { 293 {
294 m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID); 294 m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID);
295 client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); 295 client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable");
296 } 296 }
297 catch (InvalidCastException) 297 catch (InvalidCastException)
298 { 298 {
299 funds = 0; 299 funds = 0;
300 } 300 }
301 301
302 m_KnownClientFunds[agentID] = funds; 302 m_KnownClientFunds[agentID] = funds;
303 } 303 }
304 else 304 else
305 { 305 {
306 m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, (string)hbinfo["errorMessage"]); 306 m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, (string)hbinfo["errorMessage"]);
307 client.SendAlertMessage((string)hbinfo["errorMessage"]); 307 client.SendAlertMessage((string)hbinfo["errorMessage"]);
308 } 308 }
309 SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero); 309 SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero);
310 310
311 } 311 }
312 } 312 }
313 313
314 } 314 }
315 else 315 else
316 { 316 {
317 CheckExistAndRefreshFunds(client.AgentId); 317 CheckExistAndRefreshFunds(client.AgentId);
318 } 318 }
319 319
320 // Subscribe to Money messages 320 // Subscribe to Money messages
321 client.OnEconomyDataRequest += EconomyDataRequestHandler; 321 client.OnEconomyDataRequest += EconomyDataRequestHandler;
322 client.OnMoneyBalanceRequest += SendMoneyBalance; 322 client.OnMoneyBalanceRequest += SendMoneyBalance;
323 client.OnRequestPayPrice += requestPayPrice; 323 client.OnRequestPayPrice += requestPayPrice;
324 client.OnLogout += ClientClosed; 324 client.OnLogout += ClientClosed;
325 325
326 326
327 } 327 }
328 328
329 #region event Handlers 329 #region event Handlers
330 330
331 public void requestPayPrice(IClientAPI client, LLUUID objectID) 331 public void requestPayPrice(IClientAPI client, LLUUID objectID)
332 { 332 {
333 Scene scene=LocateSceneClientIn(client.AgentId); 333 Scene scene=LocateSceneClientIn(client.AgentId);
334 if(scene == null) 334 if(scene == null)
335 return; 335 return;
336 336
337 SceneObjectPart task=scene.GetSceneObjectPart(objectID); 337 SceneObjectPart task=scene.GetSceneObjectPart(objectID);
338 if(task == null) 338 if(task == null)
339 return; 339 return;
340 SceneObjectGroup group=task.ParentGroup; 340 SceneObjectGroup group=task.ParentGroup;
341 SceneObjectPart root=group.RootPart; 341 SceneObjectPart root=group.RootPart;
342 342
343 client.SendPayPrice(objectID, root.PayPrice); 343 client.SendPayPrice(objectID, root.PayPrice);
344 } 344 }
345 345
346 /// <summary> 346 /// <summary>
347 /// When the client closes the connection we remove their accounting info from memory to free up resources. 347 /// When the client closes the connection we remove their accounting info from memory to free up resources.
348 /// </summary> 348 /// </summary>
349 /// <param name="AgentID"></param> 349 /// <param name="AgentID"></param>
350 public void ClientClosed(LLUUID AgentID) 350 public void ClientClosed(LLUUID AgentID)
351 { 351 {
352 lock (m_KnownClientFunds) 352 lock (m_KnownClientFunds)
353 { 353 {
354 if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0) 354 if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0)
355 { 355 {
356 } 356 }
357 else 357 else
358 { 358 {
359 m_KnownClientFunds.Remove(AgentID); 359 m_KnownClientFunds.Remove(AgentID);
360 } 360 }
361 } 361 }
362 } 362 }
363 363
364 /// <summary> 364 /// <summary>
365 /// Event called Economy Data Request handler. 365 /// Event called Economy Data Request handler.
366 /// </summary> 366 /// </summary>
367 /// <param name="agentId"></param> 367 /// <param name="agentId"></param>
368 public void EconomyDataRequestHandler(LLUUID agentId) 368 public void EconomyDataRequestHandler(LLUUID agentId)
369 { 369 {
370 IClientAPI user = LocateClientObject(agentId); 370 IClientAPI user = LocateClientObject(agentId);
371 371
372 if (user != null) 372 if (user != null)
373 { 373 {
374 user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, 374 user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate,
375 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, 375 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor,
376 PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, 376 PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload,
377 TeleportMinPrice, TeleportPriceExponent); 377 TeleportMinPrice, TeleportPriceExponent);
378 } 378 }
379 } 379 }
380 380
381 private void ValidateLandBuy (Object osender, EventManager.LandBuyArgs e) 381 private void ValidateLandBuy (Object osender, EventManager.LandBuyArgs e)
382 { 382 {
383 if (m_MoneyAddress.Length == 0) 383 if (m_MoneyAddress.Length == 0)
384 { 384 {
385 lock (m_KnownClientFunds) 385 lock (m_KnownClientFunds)
386 { 386 {
387 if (m_KnownClientFunds.ContainsKey(e.agentId)) 387 if (m_KnownClientFunds.ContainsKey(e.agentId))
388 { 388 {
389 // Does the sender have enough funds to give? 389 // Does the sender have enough funds to give?
390 if (m_KnownClientFunds[e.agentId] >= e.parcelPrice) 390 if (m_KnownClientFunds[e.agentId] >= e.parcelPrice)
391 { 391 {
392 lock(e) 392 lock(e)
393 { 393 {
394 e.economyValidated=true; 394 e.economyValidated=true;
395 } 395 }
396 } 396 }
397 } 397 }
398 } 398 }
399 } 399 }
400 else 400 else
401 { 401 {
402 if(GetRemoteBalance(e.agentId) >= e.parcelPrice) 402 if(GetRemoteBalance(e.agentId) >= e.parcelPrice)
403 { 403 {
404 lock(e) 404 lock(e)
405 { 405 {
406 e.economyValidated=true; 406 e.economyValidated=true;
407 } 407 }
408 } 408 }
409 } 409 }
410 } 410 }
411 411
412 private void processLandBuy(Object osender, EventManager.LandBuyArgs e) 412 private void processLandBuy(Object osender, EventManager.LandBuyArgs e)
413 { 413 {
414 lock(e) 414 lock(e)
415 { 415 {
416 if(e.economyValidated == true && e.transactionID == 0) 416 if(e.economyValidated == true && e.transactionID == 0)
417 { 417 {
418 e.transactionID=Util.UnixTimeSinceEpoch(); 418 e.transactionID=Util.UnixTimeSinceEpoch();
419 419
420 if(doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase")) 420 if(doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase"))
421 { 421 {
422 lock (e) 422 lock (e)
423 { 423 {
424 e.amountDebited = e.parcelPrice; 424 e.amountDebited = e.parcelPrice;
425 } 425 }
426 } 426 }
427 } 427 }
428 } 428 }
429 } 429 }
430 430
431 /// <summary> 431 /// <summary>
432 /// THis method gets called when someone pays someone else as a gift. 432 /// THis method gets called when someone pays someone else as a gift.
433 /// </summary> 433 /// </summary>
434 /// <param name="osender"></param> 434 /// <param name="osender"></param>
435 /// <param name="e"></param> 435 /// <param name="e"></param>
436 private void MoneyTransferAction (Object osender, EventManager.MoneyTransferArgs e) 436 private void MoneyTransferAction (Object osender, EventManager.MoneyTransferArgs e)
437 { 437 {
438 IClientAPI sender = null; 438 IClientAPI sender = null;
439 IClientAPI receiver = null; 439 IClientAPI receiver = null;
440 440
441 if(m_MoneyAddress.Length > 0) // Handled on server 441 if(m_MoneyAddress.Length > 0) // Handled on server
442 e.description=String.Empty; 442 e.description=String.Empty;
443 443
444 if(e.transactiontype == 5008) // Object gets paid 444 if(e.transactiontype == 5008) // Object gets paid
445 { 445 {
446 sender = LocateClientObject(e.sender); 446 sender = LocateClientObject(e.sender);
447 if (sender != null) 447 if (sender != null)
448 { 448 {
449 SceneObjectPart part=findPrim(e.receiver); 449 SceneObjectPart part=findPrim(e.receiver);
450 if(part == null) 450 if(part == null)
451 return; 451 return;
452 452
453 string name=resolveAgentName(part.OwnerID); 453 string name=resolveAgentName(part.OwnerID);
454 if(name == String.Empty) 454 if(name == String.Empty)
455 name="(hippos)"; 455 name="(hippos)";
456 456
457 receiver = LocateClientObject(part.OwnerID); 457 receiver = LocateClientObject(part.OwnerID);
458 458
459 string description=String.Format("Paid {0} via object {1}", name, e.description); 459 string description=String.Format("Paid {0} via object {1}", name, e.description);
460 bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description); 460 bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description);
461 461
462 if(transactionresult) 462 if(transactionresult)
463 { 463 {
464 ObjectPaid handlerOnObjectPaid = OnObjectPaid; 464 ObjectPaid handlerOnObjectPaid = OnObjectPaid;
465 if(handlerOnObjectPaid != null) 465 if(handlerOnObjectPaid != null)
466 { 466 {
467 handlerOnObjectPaid(e.receiver, e.sender, e.amount); 467 handlerOnObjectPaid(e.receiver, e.sender, e.amount);
468 } 468 }
469 } 469 }
470 470
471 if (e.sender != e.receiver) 471 if (e.sender != e.receiver)
472 { 472 {
473 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); 473 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender));
474 } 474 }
475 if(receiver != null) 475 if(receiver != null)
476 { 476 {
477 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID)); 477 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID));
478 } 478 }
479 } 479 }
480 return; 480 return;
481 } 481 }
482 482
483 sender = LocateClientObject(e.sender); 483 sender = LocateClientObject(e.sender);
484 if (sender != null) 484 if (sender != null)
485 { 485 {
486 receiver = LocateClientObject(e.receiver); 486 receiver = LocateClientObject(e.receiver);
487 487
488 bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description); 488 bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description);
489 489
490 if (e.sender != e.receiver) 490 if (e.sender != e.receiver)
491 { 491 {
492 if (sender != null) 492 if (sender != null)
493 { 493 {
494 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); 494 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender));
495 } 495 }
496 } 496 }
497 497
498 if (receiver != null) 498 if (receiver != null)
499 { 499 {
500 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver)); 500 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver));
501 } 501 }
502 } 502 }
503 else 503 else
504 { 504 {
505 m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString()); 505 m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString());
506 } 506 }
507 } 507 }
508 508
509 /// <summary> 509 /// <summary>
510 /// Event Handler for when a root agent becomes a child agent 510 /// Event Handler for when a root agent becomes a child agent
511 /// </summary> 511 /// </summary>
512 /// <param name="avatar"></param> 512 /// <param name="avatar"></param>
513 private void MakeChildAgent(ScenePresence avatar) 513 private void MakeChildAgent(ScenePresence avatar)
514 { 514 {
515 lock (m_rootAgents) 515 lock (m_rootAgents)
516 { 516 {
517 if (m_rootAgents.ContainsKey(avatar.UUID)) 517 if (m_rootAgents.ContainsKey(avatar.UUID))
518 { 518 {
519 if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID) 519 if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID)
520 { 520 {
521 m_rootAgents.Remove(avatar.UUID); 521 m_rootAgents.Remove(avatar.UUID);
522 m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); 522 m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent");
523 } 523 }
524 524
525 } 525 }
526 } 526 }
527 527
528 } 528 }
529 529
530 /// <summary> 530 /// <summary>
531 /// Event Handler for when the client logs out. 531 /// Event Handler for when the client logs out.
532 /// </summary> 532 /// </summary>
533 /// <param name="AgentId"></param> 533 /// <param name="AgentId"></param>
534 private void ClientLoggedOut(LLUUID AgentId) 534 private void ClientLoggedOut(LLUUID AgentId)
535 { 535 {
536 lock (m_rootAgents) 536 lock (m_rootAgents)
537 { 537 {
538 if (m_rootAgents.ContainsKey(AgentId)) 538 if (m_rootAgents.ContainsKey(AgentId))
539 { 539 {
540 m_rootAgents.Remove(AgentId); 540 m_rootAgents.Remove(AgentId);
541 //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out."); 541 //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out.");
542 } 542 }
543 } 543 }
544 } 544 }
545 545
546 /// <summary> 546 /// <summary>
547 /// Call this when the client disconnects. 547 /// Call this when the client disconnects.
548 /// </summary> 548 /// </summary>
549 /// <param name="client"></param> 549 /// <param name="client"></param>
550 public void ClientClosed(IClientAPI client) 550 public void ClientClosed(IClientAPI client)
551 { 551 {
552 ClientClosed(client.AgentId); 552 ClientClosed(client.AgentId);
553 } 553 }
554 554
555 /// <summary> 555 /// <summary>
556 /// Event Handler for when an Avatar enters one of the parcels in the simulator. 556 /// Event Handler for when an Avatar enters one of the parcels in the simulator.
557 /// </summary> 557 /// </summary>
558 /// <param name="avatar"></param> 558 /// <param name="avatar"></param>
559 /// <param name="localLandID"></param> 559 /// <param name="localLandID"></param>
560 /// <param name="regionID"></param> 560 /// <param name="regionID"></param>
561 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) 561 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
562 { 562 {
563 lock (m_rootAgents) 563 lock (m_rootAgents)
564 { 564 {
565 if (m_rootAgents.ContainsKey(avatar.UUID)) 565 if (m_rootAgents.ContainsKey(avatar.UUID))
566 { 566 {
567 if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID]) 567 if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID])
568 { 568 {
569 m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID; 569 m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID;
570 //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); 570 //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
571 // Claim User! my user! Mine mine mine! 571 // Claim User! my user! Mine mine mine!
572 if (m_MoneyAddress.Length > 0) 572 if (m_MoneyAddress.Length > 0)
573 { 573 {
574 Scene RegionItem = GetSceneByUUID(regionID); 574 Scene RegionItem = GetSceneByUUID(regionID);
575 if (RegionItem != null) 575 if (RegionItem != null)
576 { 576 {
577 Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); 577 Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret);
578 if ((bool)hresult["success"] == true) 578 if ((bool)hresult["success"] == true)
579 { 579 {
580 int funds = 0; 580 int funds = 0;
581 try 581 try
582 { 582 {
583 funds = (Int32)hresult["funds"]; 583 funds = (Int32)hresult["funds"];
584 } 584 }
585 catch (InvalidCastException) 585 catch (InvalidCastException)
586 { 586 {
587 587
588 } 588 }
589 SetLocalFundsForAgentID(avatar.UUID, funds); 589 SetLocalFundsForAgentID(avatar.UUID, funds);
590 } 590 }
591 else 591 else
592 { 592 {
593 avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true); 593 avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true);
594 } 594 }
595 } 595 }
596 } 596 }
597 } 597 }
598 } 598 }
599 else 599 else
600 { 600 {
601 lock (m_rootAgents) 601 lock (m_rootAgents)
602 { 602 {
603 m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID); 603 m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID);
604 } 604 }
605 if (m_MoneyAddress.Length > 0) 605 if (m_MoneyAddress.Length > 0)
606 { 606 {
607 Scene RegionItem = GetSceneByUUID(regionID); 607 Scene RegionItem = GetSceneByUUID(regionID);
608 if (RegionItem != null) 608 if (RegionItem != null)
609 { 609 {
610 Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); 610 Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret);
611 if ((bool)hresult["success"] == true) 611 if ((bool)hresult["success"] == true)
612 { 612 {
613 int funds = 0; 613 int funds = 0;
614 try 614 try
615 { 615 {
616 funds = (Int32)hresult["funds"]; 616 funds = (Int32)hresult["funds"];
617 } 617 }
618 catch (InvalidCastException) 618 catch (InvalidCastException)
619 { 619 {
620 620
621 } 621 }
622 SetLocalFundsForAgentID(avatar.UUID, funds); 622 SetLocalFundsForAgentID(avatar.UUID, funds);
623 } 623 }
624 else 624 else
625 { 625 {
626 avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true); 626 avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true);
627 } 627 }
628 } 628 }
629 } 629 }
630 630
631 //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); 631 //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
632 } 632 }
633 } 633 }
634 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); 634 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString());
635 } 635 }
636 636
637 #endregion 637 #endregion
638 638
639 /// <summary> 639 /// <summary>
640 /// Transfer money 640 /// Transfer money
641 /// </summary> 641 /// </summary>
642 /// <param name="Sender"></param> 642 /// <param name="Sender"></param>
643 /// <param name="Receiver"></param> 643 /// <param name="Receiver"></param>
644 /// <param name="amount"></param> 644 /// <param name="amount"></param>
645 /// <returns></returns> 645 /// <returns></returns>
646 private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description) 646 private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description)
647 { 647 {
648 bool result = false; 648 bool result = false;
649 if (amount >= 0) 649 if (amount >= 0)
650 { 650 {
651 lock (m_KnownClientFunds) 651 lock (m_KnownClientFunds)
652 { 652 {
653 // If we don't know about the sender, then the sender can't 653 // If we don't know about the sender, then the sender can't
654 // actually be here and therefore this is likely fraud or outdated. 654 // actually be here and therefore this is likely fraud or outdated.
655 if (m_MoneyAddress.Length == 0) 655 if (m_MoneyAddress.Length == 0)
656 { 656 {
657 if (m_KnownClientFunds.ContainsKey(Sender)) 657 if (m_KnownClientFunds.ContainsKey(Sender))
658 { 658 {
659 // Does the sender have enough funds to give? 659 // Does the sender have enough funds to give?
660 if (m_KnownClientFunds[Sender] >= amount) 660 if (m_KnownClientFunds[Sender] >= amount)
661 { 661 {
662 // Subtract the funds from the senders account 662 // Subtract the funds from the senders account
663 m_KnownClientFunds[Sender] -= amount; 663 m_KnownClientFunds[Sender] -= amount;
664 664
665 // do we know about the receiver? 665 // do we know about the receiver?
666 if (!m_KnownClientFunds.ContainsKey(Receiver)) 666 if (!m_KnownClientFunds.ContainsKey(Receiver))
667 { 667 {
668 // Make a record for them so they get the updated balance when they login 668 // Make a record for them so they get the updated balance when they login
669 CheckExistAndRefreshFunds(Receiver); 669 CheckExistAndRefreshFunds(Receiver);
670 } 670 }
671 if (m_enabled) 671 if (m_enabled)
672 { 672 {
673 //Add the amount to the Receiver's funds 673 //Add the amount to the Receiver's funds
674 m_KnownClientFunds[Receiver] += amount; 674 m_KnownClientFunds[Receiver] += amount;
675 result = true; 675 result = true;
676 } 676 }
677 } 677 }
678 else 678 else
679 { 679 {
680 // These below are redundant to make this clearer to read 680 // These below are redundant to make this clearer to read
681 result = false; 681 result = false;
682 } 682 }
683 } 683 }
684 else 684 else
685 { 685 {
686 result = false; 686 result = false;
687 } 687 }
688 } 688 }
689 else 689 else
690 { 690 {
691 result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description); 691 result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description);
692 } 692 }
693 } 693 }
694 } 694 }
695 return result; 695 return result;
696 } 696 }
697 697
698 #region Utility Helpers 698 #region Utility Helpers
699 /// <summary> 699 /// <summary>
700 /// Locates a IClientAPI for the client specified 700 /// Locates a IClientAPI for the client specified
701 /// </summary> 701 /// </summary>
702 /// <param name="AgentID"></param> 702 /// <param name="AgentID"></param>
703 /// <returns></returns> 703 /// <returns></returns>
704 private IClientAPI LocateClientObject(LLUUID AgentID) 704 private IClientAPI LocateClientObject(LLUUID AgentID)
705 { 705 {
706 ScenePresence tPresence = null; 706 ScenePresence tPresence = null;
707 IClientAPI rclient = null; 707 IClientAPI rclient = null;
708 708
709 lock (m_scenel) 709 lock (m_scenel)
710 { 710 {
711 foreach (Scene _scene in m_scenel.Values) 711 foreach (Scene _scene in m_scenel.Values)
712 { 712 {
713 tPresence = _scene.GetScenePresence(AgentID); 713 tPresence = _scene.GetScenePresence(AgentID);
714 if (tPresence != null) 714 if (tPresence != null)
715 { 715 {
716 if (!tPresence.IsChildAgent) 716 if (!tPresence.IsChildAgent)
717 { 717 {
718 rclient = tPresence.ControllingClient; 718 rclient = tPresence.ControllingClient;
719 } 719 }
720 } 720 }
721 if (rclient != null) 721 if (rclient != null)
722 { 722 {
723 return rclient; 723 return rclient;
724 } 724 }
725 } 725 }
726 726
727 } 727 }
728 return null; 728 return null;
729 } 729 }
730 730
731 private Scene LocateSceneClientIn(LLUUID AgentId) 731 private Scene LocateSceneClientIn(LLUUID AgentId)
732 { 732 {
733 lock (m_scenel) 733 lock (m_scenel)
734 { 734 {
735 foreach (Scene _scene in m_scenel.Values) 735 foreach (Scene _scene in m_scenel.Values)
736 { 736 {
737 ScenePresence tPresence = _scene.GetScenePresence(AgentId); 737 ScenePresence tPresence = _scene.GetScenePresence(AgentId);
738 if (tPresence != null) 738 if (tPresence != null)
739 { 739 {
740 if (!tPresence.IsChildAgent) 740 if (!tPresence.IsChildAgent)
741 { 741 {
742 return _scene; 742 return _scene;
743 } 743 }
744 } 744 }
745 745
746 } 746 }
747 747
748 } 748 }
749 return null; 749 return null;
750 } 750 }
751 751
752 /// <summary> 752 /// <summary>
753 /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter 753 /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter
754 /// </summary> 754 /// </summary>
755 /// <returns></returns> 755 /// <returns></returns>
756 public Scene GetRandomScene() 756 public Scene GetRandomScene()
757 { 757 {
758 lock (m_scenel) 758 lock (m_scenel)
759 { 759 {
760 foreach (Scene rs in m_scenel.Values) 760 foreach (Scene rs in m_scenel.Values)
761 return rs; 761 return rs;
762 } 762 }
763 return null; 763 return null;
764 764
765 } 765 }
766 /// <summary> 766 /// <summary>
767 /// Utility function to get a Scene by RegionID in a module 767 /// Utility function to get a Scene by RegionID in a module
768 /// </summary> 768 /// </summary>
769 /// <param name="RegionID"></param> 769 /// <param name="RegionID"></param>
770 /// <returns></returns> 770 /// <returns></returns>
771 public Scene GetSceneByUUID(LLUUID RegionID) 771 public Scene GetSceneByUUID(LLUUID RegionID)
772 { 772 {
773 lock (m_scenel) 773 lock (m_scenel)
774 { 774 {
775 foreach (Scene rs in m_scenel.Values) 775 foreach (Scene rs in m_scenel.Values)
776 { 776 {
777 if (rs.RegionInfo.originRegionID == RegionID) 777 if (rs.RegionInfo.originRegionID == RegionID)
778 { 778 {
779 return rs; 779 return rs;
780 } 780 }
781 } 781 }
782 } 782 }
783 return null; 783 return null;
784 } 784 }
785 #endregion 785 #endregion
786 786
787 787
788 788
789 /// <summary> 789 /// <summary>
790 /// Sends the the stored money balance to the client 790 /// Sends the the stored money balance to the client
791 /// </summary> 791 /// </summary>
792 /// <param name="client"></param> 792 /// <param name="client"></param>
793 /// <param name="agentID"></param> 793 /// <param name="agentID"></param>
794 /// <param name="SessionID"></param> 794 /// <param name="SessionID"></param>
795 /// <param name="TransactionID"></param> 795 /// <param name="TransactionID"></param>
796 public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID) 796 public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID)
797 { 797 {
798 if (client.AgentId == agentID && client.SessionId == SessionID) 798 if (client.AgentId == agentID && client.SessionId == SessionID)
799 { 799 {
800 int returnfunds = 0; 800 int returnfunds = 0;
801 801
802 try 802 try
803 { 803 {
804 returnfunds = GetFundsForAgentID(agentID); 804 returnfunds = GetFundsForAgentID(agentID);
805 } 805 }
806 catch (Exception e) 806 catch (Exception e)
807 { 807 {
808 client.SendAlertMessage(e.Message + " "); 808 client.SendAlertMessage(e.Message + " ");
809 } 809 }
810 810
811 client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); 811 client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds);
812 } 812 }
813 else 813 else
814 { 814 {
815 client.SendAlertMessage("Unable to send your money balance to you!"); 815 client.SendAlertMessage("Unable to send your money balance to you!");
816 } 816 }
817 } 817 }
818 818
819 #region local Fund Management 819 #region local Fund Management
820 /// <summary> 820 /// <summary>
821 /// Ensures that the agent accounting data is set up in this instance. 821 /// Ensures that the agent accounting data is set up in this instance.
822 /// </summary> 822 /// </summary>
823 /// <param name="agentID"></param> 823 /// <param name="agentID"></param>
824 private void CheckExistAndRefreshFunds(LLUUID agentID) 824 private void CheckExistAndRefreshFunds(LLUUID agentID)
825 { 825 {
826 lock (m_KnownClientFunds) 826 lock (m_KnownClientFunds)
827 { 827 {
828 if (!m_KnownClientFunds.ContainsKey(agentID)) 828 if (!m_KnownClientFunds.ContainsKey(agentID))
829 { 829 {
830 m_KnownClientFunds.Add(agentID, m_stipend); 830 m_KnownClientFunds.Add(agentID, m_stipend);
831 } 831 }
832 else 832 else
833 { 833 {
834 if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh) 834 if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh)
835 { 835 {
836 m_KnownClientFunds[agentID] = m_stipend; 836 m_KnownClientFunds[agentID] = m_stipend;
837 } 837 }
838 } 838 }
839 } 839 }
840 } 840 }
841 /// <summary> 841 /// <summary>
842 /// Gets the amount of Funds for an agent 842 /// Gets the amount of Funds for an agent
843 /// </summary> 843 /// </summary>
844 /// <param name="AgentID"></param> 844 /// <param name="AgentID"></param>
845 /// <returns></returns> 845 /// <returns></returns>
846 private int GetFundsForAgentID(LLUUID AgentID) 846 private int GetFundsForAgentID(LLUUID AgentID)
847 { 847 {
848 int returnfunds = 0; 848 int returnfunds = 0;
849 lock (m_KnownClientFunds) 849 lock (m_KnownClientFunds)
850 { 850 {
851 if (m_KnownClientFunds.ContainsKey(AgentID)) 851 if (m_KnownClientFunds.ContainsKey(AgentID))
852 { 852 {
853 returnfunds = m_KnownClientFunds[AgentID]; 853 returnfunds = m_KnownClientFunds[AgentID];
854 } 854 }
855 else 855 else
856 { 856 {
857 //throw new Exception("Unable to get funds."); 857 //throw new Exception("Unable to get funds.");
858 } 858 }
859 } 859 }
860 return returnfunds; 860 return returnfunds;
861 } 861 }
862 private void SetLocalFundsForAgentID(LLUUID AgentID, int amount) 862 private void SetLocalFundsForAgentID(LLUUID AgentID, int amount)
863 { 863 {
864 lock (m_KnownClientFunds) 864 lock (m_KnownClientFunds)
865 { 865 {
866 if (m_KnownClientFunds.ContainsKey(AgentID)) 866 if (m_KnownClientFunds.ContainsKey(AgentID))
867 { 867 {
868 m_KnownClientFunds[AgentID] = amount; 868 m_KnownClientFunds[AgentID] = amount;
869 } 869 }
870 else 870 else
871 { 871 {
872 m_KnownClientFunds.Add(AgentID, amount); 872 m_KnownClientFunds.Add(AgentID, amount);
873 } 873 }
874 } 874 }
875 875
876 } 876 }
877 877
878 #endregion 878 #endregion
879 879
880 /// <summary> 880 /// <summary>
881 /// Gets the current balance for the user from the Grid Money Server 881 /// Gets the current balance for the user from the Grid Money Server
882 /// </summary> 882 /// </summary>
883 /// <param name="agentId"></param> 883 /// <param name="agentId"></param>
884 /// <param name="secureSessionID"></param> 884 /// <param name="secureSessionID"></param>
885 /// <param name="regionId"></param> 885 /// <param name="regionId"></param>
886 /// <param name="regionSecret"></param> 886 /// <param name="regionSecret"></param>
887 /// <returns></returns> 887 /// <returns></returns>
888 public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) 888 public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret)
889 { 889 {
890 890
891 Hashtable MoneyBalanceRequestParams = new Hashtable(); 891 Hashtable MoneyBalanceRequestParams = new Hashtable();
892 MoneyBalanceRequestParams["agentId"] = agentId.ToString(); 892 MoneyBalanceRequestParams["agentId"] = agentId.ToString();
893 MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); 893 MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString();
894 MoneyBalanceRequestParams["regionId"] = regionId.ToString(); 894 MoneyBalanceRequestParams["regionId"] = regionId.ToString();
895 MoneyBalanceRequestParams["secret"] = regionSecret; 895 MoneyBalanceRequestParams["secret"] = regionSecret;
896 MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system 896 MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system
897 897
898 Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest"); 898 Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest");
899 899
900 return MoneyRespData; 900 return MoneyRespData;
901 } 901 }
902 902
903 903
904 904
905 /// <summary> 905 /// <summary>
906 /// Generic XMLRPC client abstraction 906 /// Generic XMLRPC client abstraction
907 /// </summary> 907 /// </summary>
908 /// <param name="ReqParams">Hashtable containing parameters to the method</param> 908 /// <param name="ReqParams">Hashtable containing parameters to the method</param>
909 /// <param name="method">Method to invoke</param> 909 /// <param name="method">Method to invoke</param>
910 /// <returns>Hashtable with success=>bool and other values</returns> 910 /// <returns>Hashtable with success=>bool and other values</returns>
911 public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method) 911 public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method)
912 { 912 {
913 ArrayList SendParams = new ArrayList(); 913 ArrayList SendParams = new ArrayList();
914 SendParams.Add(ReqParams); 914 SendParams.Add(ReqParams);
915 // Send Request 915 // Send Request
916 XmlRpcResponse MoneyResp; 916 XmlRpcResponse MoneyResp;
917 try 917 try
918 { 918 {
919 XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams); 919 XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams);
920 MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000); 920 MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000);
921 } 921 }
922 catch (WebException ex) 922 catch (WebException ex)
923 { 923 {
924 924
925 m_log.ErrorFormat( 925 m_log.ErrorFormat(
926 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", 926 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}",
927 m_MoneyAddress, ex); 927 m_MoneyAddress, ex);
928 928
929 Hashtable ErrorHash = new Hashtable(); 929 Hashtable ErrorHash = new Hashtable();
930 ErrorHash["success"] = false; 930 ErrorHash["success"] = false;
931 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; 931 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
932 ErrorHash["errorURI"] = ""; 932 ErrorHash["errorURI"] = "";
933 933
934 return ErrorHash; 934 return ErrorHash;
935 //throw (ex); 935 //throw (ex);
936 } 936 }
937 catch (SocketException ex) 937 catch (SocketException ex)
938 { 938 {
939 939
940 m_log.ErrorFormat( 940 m_log.ErrorFormat(
941 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", 941 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}",
942 m_MoneyAddress, ex); 942 m_MoneyAddress, ex);
943 943
944 Hashtable ErrorHash = new Hashtable(); 944 Hashtable ErrorHash = new Hashtable();
945 ErrorHash["success"] = false; 945 ErrorHash["success"] = false;
946 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; 946 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
947 ErrorHash["errorURI"] = ""; 947 ErrorHash["errorURI"] = "";
948 948
949 return ErrorHash; 949 return ErrorHash;
950 //throw (ex); 950 //throw (ex);
951 } 951 }
952 catch (XmlException ex) 952 catch (XmlException ex)
953 { 953 {
954 m_log.ErrorFormat( 954 m_log.ErrorFormat(
955 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", 955 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}",
956 m_MoneyAddress, ex); 956 m_MoneyAddress, ex);
957 957
958 Hashtable ErrorHash = new Hashtable(); 958 Hashtable ErrorHash = new Hashtable();
959 ErrorHash["success"] = false; 959 ErrorHash["success"] = false;
960 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; 960 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
961 ErrorHash["errorURI"] = ""; 961 ErrorHash["errorURI"] = "";
962 962
963 return ErrorHash; 963 return ErrorHash;
964 964
965 } 965 }
966 if (MoneyResp.IsFault) 966 if (MoneyResp.IsFault)
967 { 967 {
968 Hashtable ErrorHash = new Hashtable(); 968 Hashtable ErrorHash = new Hashtable();
969 ErrorHash["success"] = false; 969 ErrorHash["success"] = false;
970 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; 970 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
971 ErrorHash["errorURI"] = ""; 971 ErrorHash["errorURI"] = "";
972 972
973 return ErrorHash; 973 return ErrorHash;
974 974
975 } 975 }
976 Hashtable MoneyRespData = (Hashtable)MoneyResp.Value; 976 Hashtable MoneyRespData = (Hashtable)MoneyResp.Value;
977 977
978 return MoneyRespData; 978 return MoneyRespData;
979 } 979 }
980 /// <summary> 980 /// <summary>
981 /// This informs the Money Grid Server that the avatar is in this simulator 981 /// This informs the Money Grid Server that the avatar is in this simulator
982 /// </summary> 982 /// </summary>
983 /// <param name="agentId"></param> 983 /// <param name="agentId"></param>
984 /// <param name="secureSessionID"></param> 984 /// <param name="secureSessionID"></param>
985 /// <param name="regionId"></param> 985 /// <param name="regionId"></param>
986 /// <param name="regionSecret"></param> 986 /// <param name="regionSecret"></param>
987 /// <returns></returns> 987 /// <returns></returns>
988 public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) 988 public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret)
989 { 989 {
990 990
991 Hashtable MoneyBalanceRequestParams = new Hashtable(); 991 Hashtable MoneyBalanceRequestParams = new Hashtable();
992 MoneyBalanceRequestParams["agentId"] = agentId.ToString(); 992 MoneyBalanceRequestParams["agentId"] = agentId.ToString();
993 MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); 993 MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString();
994 MoneyBalanceRequestParams["regionId"] = regionId.ToString(); 994 MoneyBalanceRequestParams["regionId"] = regionId.ToString();
995 MoneyBalanceRequestParams["secret"] = regionSecret; 995 MoneyBalanceRequestParams["secret"] = regionSecret;
996 996
997 Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest"); 997 Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest");
998 IClientAPI sendMoneyBal = LocateClientObject(agentId); 998 IClientAPI sendMoneyBal = LocateClientObject(agentId);
999 if (sendMoneyBal != null) 999 if (sendMoneyBal != null)
1000 { 1000 {
1001 SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero); 1001 SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero);
1002 } 1002 }
1003 return MoneyRespData; 1003 return MoneyRespData;
1004 } 1004 }
1005 1005
1006 private SceneObjectPart findPrim(LLUUID objectID) 1006 private SceneObjectPart findPrim(LLUUID objectID)
1007 { 1007 {
1008 lock (m_scenel) 1008 lock (m_scenel)
1009 { 1009 {
1010 foreach (Scene s in m_scenel.Values) 1010 foreach (Scene s in m_scenel.Values)
1011 { 1011 {
1012 SceneObjectPart part=s.GetSceneObjectPart(objectID); 1012 SceneObjectPart part=s.GetSceneObjectPart(objectID);
1013 if(part != null) 1013 if(part != null)
1014 { 1014 {
1015 return part; 1015 return part;
1016 } 1016 }
1017 } 1017 }
1018 } 1018 }
1019 return null; 1019 return null;
1020 } 1020 }
1021 1021
1022 private string resolveObjectName(LLUUID objectID) 1022 private string resolveObjectName(LLUUID objectID)
1023 { 1023 {
1024 SceneObjectPart part=findPrim(objectID); 1024 SceneObjectPart part=findPrim(objectID);
1025 if(part != null) 1025 if(part != null)
1026 { 1026 {
1027 return part.Name; 1027 return part.Name;
1028 } 1028 }
1029 return String.Empty; 1029 return String.Empty;
1030 } 1030 }
1031 1031
1032 private string resolveAgentName(LLUUID agentID) 1032 private string resolveAgentName(LLUUID agentID)
1033 { 1033 {
1034 // try avatar username surname 1034 // try avatar username surname
1035 Scene scene=GetRandomScene(); 1035 Scene scene=GetRandomScene();
1036 UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID); 1036 UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID);
1037 if (profile != null) 1037 if (profile != null)
1038 { 1038 {
1039 string avatarname = profile.FirstName + " " + profile.SurName; 1039 string avatarname = profile.FirstName + " " + profile.SurName;
1040 return avatarname; 1040 return avatarname;
1041 } 1041 }
1042 return String.Empty; 1042 return String.Empty;
1043 } 1043 }
1044 1044
1045 public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount) 1045 public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount)
1046 { 1046 {
1047 string description=String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID)); 1047 string description=String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID));
1048 1048
1049 bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description); 1049 bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description);
1050 1050
1051 if (m_MoneyAddress.Length == 0) 1051 if (m_MoneyAddress.Length == 0)
1052 BalanceUpdate(fromID, toID, give_result, description); 1052 BalanceUpdate(fromID, toID, give_result, description);
1053 1053
1054 return give_result; 1054 return give_result;
1055 1055
1056 1056
1057 } 1057 }
1058 private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description) 1058 private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description)
1059 { 1059 {
1060 IClientAPI sender = LocateClientObject(senderID); 1060 IClientAPI sender = LocateClientObject(senderID);
1061 IClientAPI receiver = LocateClientObject(receiverID); 1061 IClientAPI receiver = LocateClientObject(receiverID);
1062 1062
1063 if (senderID != receiverID) 1063 if (senderID != receiverID)
1064 { 1064 {
1065 if (sender != null) 1065 if (sender != null)
1066 { 1066 {
1067 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID)); 1067 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID));
1068 } 1068 }
1069 1069
1070 if (receiver != null) 1070 if (receiver != null)
1071 { 1071 {
1072 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID)); 1072 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID));
1073 } 1073 }
1074 } 1074 }
1075 } 1075 }
1076 1076
1077 /// <summary> 1077 /// <summary>
1078 /// Informs the Money Grid Server of a transfer. 1078 /// Informs the Money Grid Server of a transfer.
1079 /// </summary> 1079 /// </summary>
1080 /// <param name="sourceId"></param> 1080 /// <param name="sourceId"></param>
1081 /// <param name="destId"></param> 1081 /// <param name="destId"></param>
1082 /// <param name="amount"></param> 1082 /// <param name="amount"></param>
1083 /// <returns></returns> 1083 /// <returns></returns>
1084 public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description) 1084 public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description)
1085 { 1085 {
1086 int aggregatePermInventory = 0; 1086 int aggregatePermInventory = 0;
1087 int aggregatePermNextOwner = 0; 1087 int aggregatePermNextOwner = 0;
1088 int flags = 0; 1088 int flags = 0;
1089 bool rvalue = false; 1089 bool rvalue = false;
1090 1090
1091 IClientAPI cli = LocateClientObject(sourceId); 1091 IClientAPI cli = LocateClientObject(sourceId);
1092 if (cli != null) 1092 if (cli != null)
1093 { 1093 {
1094 1094
1095 Scene userScene = null; 1095 Scene userScene = null;
1096 lock (m_rootAgents) 1096 lock (m_rootAgents)
1097 { 1097 {
1098 userScene = GetSceneByUUID(m_rootAgents[sourceId]); 1098 userScene = GetSceneByUUID(m_rootAgents[sourceId]);
1099 } 1099 }
1100 if (userScene != null) 1100 if (userScene != null)
1101 { 1101 {
1102 Hashtable ht = new Hashtable(); 1102 Hashtable ht = new Hashtable();
1103 ht["agentId"] = sourceId.ToString(); 1103 ht["agentId"] = sourceId.ToString();
1104 ht["secureSessionId"] = cli.SecureSessionId.ToString(); 1104 ht["secureSessionId"] = cli.SecureSessionId.ToString();
1105 ht["regionId"] = userScene.RegionInfo.originRegionID.ToString(); 1105 ht["regionId"] = userScene.RegionInfo.originRegionID.ToString();
1106 ht["secret"] = userScene.RegionInfo.regionSecret; 1106 ht["secret"] = userScene.RegionInfo.regionSecret;
1107 ht["currencySecret"] = " "; 1107 ht["currencySecret"] = " ";
1108 ht["destId"] = destId.ToString(); 1108 ht["destId"] = destId.ToString();
1109 ht["cash"] = amount; 1109 ht["cash"] = amount;
1110 ht["aggregatePermInventory"] = aggregatePermInventory; 1110 ht["aggregatePermInventory"] = aggregatePermInventory;
1111 ht["aggregatePermNextOwner"] = aggregatePermNextOwner; 1111 ht["aggregatePermNextOwner"] = aggregatePermNextOwner;
1112 ht["flags"] = flags; 1112 ht["flags"] = flags;
1113 ht["transactionType"] = transactiontype; 1113 ht["transactionType"] = transactiontype;
1114 ht["description"] = description; 1114 ht["description"] = description;
1115 1115
1116 Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney"); 1116 Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney");
1117 1117
1118 if ((bool)hresult["success"] == true) 1118 if ((bool)hresult["success"] == true)
1119 { 1119 {
1120 int funds1 = 0; 1120 int funds1 = 0;
1121 int funds2 = 0; 1121 int funds2 = 0;
1122 try 1122 try
1123 { 1123 {
1124 funds1 = (Int32)hresult["funds"]; 1124 funds1 = (Int32)hresult["funds"];
1125 } 1125 }
1126 catch(InvalidCastException) 1126 catch(InvalidCastException)
1127 { 1127 {
1128 funds1 = 0; 1128 funds1 = 0;
1129 } 1129 }
1130 SetLocalFundsForAgentID(sourceId, funds1); 1130 SetLocalFundsForAgentID(sourceId, funds1);
1131 if (m_KnownClientFunds.ContainsKey(destId)) 1131 if (m_KnownClientFunds.ContainsKey(destId))
1132 { 1132 {
1133 try 1133 try
1134 { 1134 {
1135 funds2 = (Int32)hresult["funds2"]; 1135 funds2 = (Int32)hresult["funds2"];
1136 } 1136 }
1137 catch (InvalidCastException) 1137 catch (InvalidCastException)
1138 { 1138 {
1139 funds2 = 0; 1139 funds2 = 0;
1140 } 1140 }
1141 SetLocalFundsForAgentID(destId, funds2); 1141 SetLocalFundsForAgentID(destId, funds2);
1142 } 1142 }
1143 1143
1144 1144
1145 rvalue = true; 1145 rvalue = true;
1146 } 1146 }
1147 else 1147 else
1148 { 1148 {
1149 cli.SendAgentAlertMessage((string)hresult["errorMessage"], true); 1149 cli.SendAgentAlertMessage((string)hresult["errorMessage"], true);
1150 } 1150 }
1151 1151
1152 } 1152 }
1153 } 1153 }
1154 else 1154 else
1155 { 1155 {
1156 m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString()); 1156 m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString());
1157 } 1157 }
1158 1158
1159 return rvalue; 1159 return rvalue;
1160 1160
1161 } 1161 }
1162 1162
1163 public int GetRemoteBalance(LLUUID agentId) 1163 public int GetRemoteBalance(LLUUID agentId)
1164 { 1164 {
1165 int funds = 0; 1165 int funds = 0;
1166 1166
1167 IClientAPI aClient = LocateClientObject(agentId); 1167 IClientAPI aClient = LocateClientObject(agentId);
1168 if (aClient != null) 1168 if (aClient != null)
1169 { 1169 {
1170 Scene s = LocateSceneClientIn(agentId); 1170 Scene s = LocateSceneClientIn(agentId);
1171 if (s != null) 1171 if (s != null)
1172 { 1172 {
1173 if (m_MoneyAddress.Length > 0) 1173 if (m_MoneyAddress.Length > 0)
1174 { 1174 {
1175 Hashtable hbinfo = GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret); 1175 Hashtable hbinfo = GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret);
1176 if ((bool)hbinfo["success"] == true) 1176 if ((bool)hbinfo["success"] == true)
1177 { 1177 {
1178 try 1178 try
1179 { 1179 {
1180 funds = (Int32)hbinfo["funds"]; 1180 funds = (Int32)hbinfo["funds"];
1181 } 1181 }
1182 catch (ArgumentException) 1182 catch (ArgumentException)
1183 { 1183 {
1184 } 1184 }
1185 catch (FormatException) 1185 catch (FormatException)
1186 { 1186 {
1187 } 1187 }
1188 catch (OverflowException) 1188 catch (OverflowException)
1189 { 1189 {
1190 m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId); 1190 m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId);
1191 aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); 1191 aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable");
1192 } 1192 }
1193 catch (InvalidCastException) 1193 catch (InvalidCastException)
1194 { 1194 {
1195 funds = 0; 1195 funds = 0;
1196 } 1196 }
1197 1197
1198 } 1198 }
1199 else 1199 else
1200 { 1200 {
1201 m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, (string)hbinfo["errorMessage"]); 1201 m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, (string)hbinfo["errorMessage"]);
1202 aClient.SendAlertMessage((string)hbinfo["errorMessage"]); 1202 aClient.SendAlertMessage((string)hbinfo["errorMessage"]);
1203 } 1203 }
1204 } 1204 }
1205 1205
1206 SetLocalFundsForAgentID(agentId, funds); 1206 SetLocalFundsForAgentID(agentId, funds);
1207 SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero); 1207 SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero);
1208 } 1208 }
1209 else 1209 else
1210 { 1210 {
1211 m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene."); 1211 m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene.");
1212 } 1212 }
1213 } 1213 }
1214 else 1214 else
1215 { 1215 {
1216 m_log.Debug("[MONEY]: Got balance request update for agent that isn't here."); 1216 m_log.Debug("[MONEY]: Got balance request update for agent that isn't here.");
1217 } 1217 }
1218 return funds; 1218 return funds;
1219 } 1219 }
1220 1220
1221 public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request) 1221 public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request)
1222 { 1222 {
1223 m_log.Debug("[MONEY]: Dynamic balance update called."); 1223 m_log.Debug("[MONEY]: Dynamic balance update called.");
1224 Hashtable requestData = (Hashtable)request.Params[0]; 1224 Hashtable requestData = (Hashtable)request.Params[0];
1225 1225
1226 if (requestData.ContainsKey("agentId")) 1226 if (requestData.ContainsKey("agentId"))
1227 { 1227 {
1228 LLUUID agentId = LLUUID.Zero; 1228 LLUUID agentId = LLUUID.Zero;
1229 1229
1230 Helpers.TryParse((string)requestData["agentId"], out agentId); 1230 Helpers.TryParse((string)requestData["agentId"], out agentId);
1231 if (agentId != LLUUID.Zero) 1231 if (agentId != LLUUID.Zero)
1232 { 1232 {
1233 GetRemoteBalance(agentId); 1233 GetRemoteBalance(agentId);
1234 1234
1235 } 1235 }
1236 else 1236 else
1237 { 1237 {
1238 m_log.Debug("[MONEY]: invalid agentId specified, dropping."); 1238 m_log.Debug("[MONEY]: invalid agentId specified, dropping.");
1239 } 1239 }
1240 } 1240 }
1241 else 1241 else
1242 { 1242 {
1243 m_log.Debug("[MONEY]: no agentId specified, dropping."); 1243 m_log.Debug("[MONEY]: no agentId specified, dropping.");
1244 } 1244 }
1245 XmlRpcResponse r = new XmlRpcResponse(); 1245 XmlRpcResponse r = new XmlRpcResponse();
1246 Hashtable rparms = new Hashtable(); 1246 Hashtable rparms = new Hashtable();
1247 rparms["success"] = true; 1247 rparms["success"] = true;
1248 1248
1249 r.Value = rparms; 1249 r.Value = rparms;
1250 return r; 1250 return r;
1251 } 1251 }
1252 1252
1253 /// <summary> 1253 /// <summary>
1254 /// XMLRPC handler to send alert message and sound to client 1254 /// XMLRPC handler to send alert message and sound to client
1255 /// </summary> 1255 /// </summary>
1256 public XmlRpcResponse UserAlert(XmlRpcRequest request) 1256 public XmlRpcResponse UserAlert(XmlRpcRequest request)
1257 { 1257 {
1258 XmlRpcResponse ret = new XmlRpcResponse(); 1258 XmlRpcResponse ret = new XmlRpcResponse();
1259 Hashtable retparam = new Hashtable(); 1259 Hashtable retparam = new Hashtable();
1260 Hashtable requestData = (Hashtable)request.Params[0]; 1260 Hashtable requestData = (Hashtable)request.Params[0];
1261 1261
1262 LLUUID agentId = LLUUID.Zero; 1262 LLUUID agentId = LLUUID.Zero;
1263 LLUUID soundId = LLUUID.Zero; 1263 LLUUID soundId = LLUUID.Zero;
1264 1264
1265 Helpers.TryParse((string)requestData["agentId"], out agentId); 1265 Helpers.TryParse((string)requestData["agentId"], out agentId);
1266 Helpers.TryParse((string)requestData["soundId"], out soundId); 1266 Helpers.TryParse((string)requestData["soundId"], out soundId);
1267 string text=(string)requestData["text"]; 1267 string text=(string)requestData["text"];
1268 string secret=(string)requestData["secret"]; 1268 string secret=(string)requestData["secret"];
1269 1269
1270 Scene userScene = GetRandomScene(); 1270 Scene userScene = GetRandomScene();
1271 if(userScene.RegionInfo.regionSecret.ToString() == secret) 1271 if(userScene.RegionInfo.regionSecret.ToString() == secret)
1272 { 1272 {
1273 IClientAPI client = LocateClientObject(agentId); 1273 IClientAPI client = LocateClientObject(agentId);
1274 1274
1275 if (client != null) 1275 if (client != null)
1276 { 1276 {
1277 if(soundId != LLUUID.Zero) 1277 if(soundId != LLUUID.Zero)
1278 client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0); 1278 client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0);
1279 client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text); 1279 client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text);
1280 retparam.Add("success", true); 1280 retparam.Add("success", true);
1281 } 1281 }
1282 else 1282 else
1283 { 1283 {
1284 retparam.Add("success", false); 1284 retparam.Add("success", false);
1285 } 1285 }
1286 } 1286 }
1287 else 1287 else
1288 { 1288 {
1289 retparam.Add("success", false); 1289 retparam.Add("success", false);
1290 } 1290 }
1291 ret.Value = retparam; 1291 ret.Value = retparam;
1292 1292
1293 return ret; 1293 return ret;
1294 } 1294 }
1295 1295
1296 1296
1297# region Standalone box enablers only 1297 # region Standalone box enablers only
1298 1298
1299 public XmlRpcResponse quote_func(XmlRpcRequest request) 1299 public XmlRpcResponse quote_func(XmlRpcRequest request)
1300 { 1300 {
1301 Hashtable requestData = (Hashtable)request.Params[0]; 1301 Hashtable requestData = (Hashtable)request.Params[0];
1302 LLUUID agentId = LLUUID.Zero; 1302 LLUUID agentId = LLUUID.Zero;
1303 int amount = 0; 1303 int amount = 0;
1304 Hashtable quoteResponse = new Hashtable(); 1304 Hashtable quoteResponse = new Hashtable();
1305 XmlRpcResponse returnval = new XmlRpcResponse(); 1305 XmlRpcResponse returnval = new XmlRpcResponse();
1306 1306
1307 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) 1307 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy"))
1308 { 1308 {
1309 Helpers.TryParse((string)requestData["agentId"], out agentId); 1309 Helpers.TryParse((string)requestData["agentId"], out agentId);
1310 try 1310 try
1311 { 1311 {
1312 amount = (Int32)requestData["currencyBuy"]; 1312 amount = (Int32)requestData["currencyBuy"];
1313 } 1313 }
1314 catch (InvalidCastException) 1314 catch (InvalidCastException)
1315 { 1315 {
1316 1316
1317 } 1317 }
1318 Hashtable currencyResponse = new Hashtable(); 1318 Hashtable currencyResponse = new Hashtable();
1319 currencyResponse.Add("estimatedCost", 0); 1319 currencyResponse.Add("estimatedCost", 0);
1320 currencyResponse.Add("currencyBuy", amount); 1320 currencyResponse.Add("currencyBuy", amount);
1321 1321
1322 quoteResponse.Add("success", true); 1322 quoteResponse.Add("success", true);
1323 quoteResponse.Add("currency", currencyResponse); 1323 quoteResponse.Add("currency", currencyResponse);
1324 quoteResponse.Add("confirm", "asdfad9fj39ma9fj"); 1324 quoteResponse.Add("confirm", "asdfad9fj39ma9fj");
1325 1325
1326 returnval.Value = quoteResponse; 1326 returnval.Value = quoteResponse;
1327 return returnval; 1327 return returnval;
1328 } 1328 }
1329 1329
1330 1330
1331 1331
1332 quoteResponse.Add("success", false); 1332 quoteResponse.Add("success", false);
1333 quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box"); 1333 quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box");
1334 quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki"); 1334 quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki");
1335 returnval.Value = quoteResponse; 1335 returnval.Value = quoteResponse;
1336 return returnval; 1336 return returnval;
1337 } 1337 }
1338 public XmlRpcResponse buy_func(XmlRpcRequest request) 1338 public XmlRpcResponse buy_func(XmlRpcRequest request)
1339 { 1339 {
1340 1340
1341 Hashtable requestData = (Hashtable)request.Params[0]; 1341 Hashtable requestData = (Hashtable)request.Params[0];
1342 LLUUID agentId = LLUUID.Zero; 1342 LLUUID agentId = LLUUID.Zero;
1343 int amount = 0; 1343 int amount = 0;
1344 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) 1344 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy"))
1345 { 1345 {
1346 Helpers.TryParse((string)requestData["agentId"], out agentId); 1346 Helpers.TryParse((string)requestData["agentId"], out agentId);
1347 try 1347 try
1348 { 1348 {
1349 amount = (Int32)requestData["currencyBuy"]; 1349 amount = (Int32)requestData["currencyBuy"];
1350 } 1350 }
1351 catch (InvalidCastException) 1351 catch (InvalidCastException)
1352 { 1352 {
1353 1353
1354 } 1354 }
1355 if (agentId != LLUUID.Zero) 1355 if (agentId != LLUUID.Zero)
1356 { 1356 {
1357 lock (m_KnownClientFunds) 1357 lock (m_KnownClientFunds)
1358 { 1358 {
1359 if (m_KnownClientFunds.ContainsKey(agentId)) 1359 if (m_KnownClientFunds.ContainsKey(agentId))
1360 { 1360 {
1361 m_KnownClientFunds[agentId] += amount; 1361 m_KnownClientFunds[agentId] += amount;
1362 } 1362 }
1363 else 1363 else
1364 { 1364 {
1365 m_KnownClientFunds.Add(agentId, amount); 1365 m_KnownClientFunds.Add(agentId, amount);
1366 } 1366 }
1367 } 1367 }
1368 IClientAPI client = LocateClientObject(agentId); 1368 IClientAPI client = LocateClientObject(agentId);
1369 if (client != null) 1369 if (client != null)
1370 { 1370 {
1371 SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); 1371 SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero);
1372 } 1372 }
1373 } 1373 }
1374 } 1374 }
1375 XmlRpcResponse returnval = new XmlRpcResponse(); 1375 XmlRpcResponse returnval = new XmlRpcResponse();
1376 Hashtable returnresp = new Hashtable(); 1376 Hashtable returnresp = new Hashtable();
1377 returnresp.Add("success", true); 1377 returnresp.Add("success", true);
1378 returnval.Value = returnresp; 1378 returnval.Value = returnresp;
1379 return returnval; 1379 return returnval;
1380 } 1380 }
1381 1381
1382 public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request) 1382 public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request)
1383 { 1383 {
1384 XmlRpcResponse ret = new XmlRpcResponse(); 1384 XmlRpcResponse ret = new XmlRpcResponse();
1385 Hashtable retparam = new Hashtable(); 1385 Hashtable retparam = new Hashtable();
1386 Hashtable membershiplevels = new Hashtable(); 1386 Hashtable membershiplevels = new Hashtable();
1387 ArrayList levels = new ArrayList(); 1387 ArrayList levels = new ArrayList();
1388 Hashtable level = new Hashtable(); 1388 Hashtable level = new Hashtable();
1389 level.Add("id", "00000000-0000-0000-0000-000000000000"); 1389 level.Add("id", "00000000-0000-0000-0000-000000000000");
1390 level.Add("description", "some level"); 1390 level.Add("description", "some level");
1391 levels.Add(level); 1391 levels.Add(level);
1392 //membershiplevels.Add("levels",levels); 1392 //membershiplevels.Add("levels",levels);
1393 1393
1394 Hashtable landuse = new Hashtable(); 1394 Hashtable landuse = new Hashtable();
1395 landuse.Add("upgrade", false); 1395 landuse.Add("upgrade", false);
1396 landuse.Add("action", "http://invaliddomaininvalid.com/"); 1396 landuse.Add("action", "http://invaliddomaininvalid.com/");
1397 1397
1398 Hashtable currency = new Hashtable(); 1398 Hashtable currency = new Hashtable();
1399 currency.Add("estimatedCost", 0); 1399 currency.Add("estimatedCost", 0);
1400 1400
1401 Hashtable membership = new Hashtable(); 1401 Hashtable membership = new Hashtable();
1402 membershiplevels.Add("upgrade", false); 1402 membershiplevels.Add("upgrade", false);
1403 membershiplevels.Add("action", "http://invaliddomaininvalid.com/"); 1403 membershiplevels.Add("action", "http://invaliddomaininvalid.com/");
1404 membershiplevels.Add("levels", membershiplevels); 1404 membershiplevels.Add("levels", membershiplevels);
1405 1405
1406 retparam.Add("success", true); 1406 retparam.Add("success", true);
1407 retparam.Add("currency", currency); 1407 retparam.Add("currency", currency);
1408 retparam.Add("membership", membership); 1408 retparam.Add("membership", membership);
1409 retparam.Add("landuse", landuse); 1409 retparam.Add("landuse", landuse);
1410 retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf"); 1410 retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf");
1411 1411
1412 ret.Value = retparam; 1412 ret.Value = retparam;
1413 1413
1414 return ret; 1414 return ret;
1415 1415
1416 } 1416 }
1417 public XmlRpcResponse landBuy_func(XmlRpcRequest request) 1417 public XmlRpcResponse landBuy_func(XmlRpcRequest request)
1418 { 1418 {
1419 XmlRpcResponse ret = new XmlRpcResponse(); 1419 XmlRpcResponse ret = new XmlRpcResponse();
1420 Hashtable retparam = new Hashtable(); 1420 Hashtable retparam = new Hashtable();
1421 Hashtable requestData = (Hashtable)request.Params[0]; 1421 Hashtable requestData = (Hashtable)request.Params[0];
1422 1422
1423 LLUUID agentId = LLUUID.Zero; 1423 LLUUID agentId = LLUUID.Zero;
1424 int amount = 0; 1424 int amount = 0;
1425 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) 1425 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy"))
1426 { 1426 {
1427 Helpers.TryParse((string)requestData["agentId"], out agentId); 1427 Helpers.TryParse((string)requestData["agentId"], out agentId);
1428 try 1428 try
1429 { 1429 {
1430 amount = (Int32)requestData["currencyBuy"]; 1430 amount = (Int32)requestData["currencyBuy"];
1431 } 1431 }
1432 catch (InvalidCastException) 1432 catch (InvalidCastException)
1433 { 1433 {
1434 1434
1435 } 1435 }
1436 if (agentId != LLUUID.Zero) 1436 if (agentId != LLUUID.Zero)
1437 { 1437 {
1438 lock (m_KnownClientFunds) 1438 lock (m_KnownClientFunds)
1439 { 1439 {
1440 if (m_KnownClientFunds.ContainsKey(agentId)) 1440 if (m_KnownClientFunds.ContainsKey(agentId))
1441 { 1441 {
1442 m_KnownClientFunds[agentId] += amount; 1442 m_KnownClientFunds[agentId] += amount;
1443 } 1443 }
1444 else 1444 else
1445 { 1445 {
1446 m_KnownClientFunds.Add(agentId, amount); 1446 m_KnownClientFunds.Add(agentId, amount);
1447 } 1447 }
1448 } 1448 }
1449 IClientAPI client = LocateClientObject(agentId); 1449 IClientAPI client = LocateClientObject(agentId);
1450 if (client != null) 1450 if (client != null)
1451 { 1451 {
1452 SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); 1452 SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero);
1453 } 1453 }
1454 } 1454 }
1455 } 1455 }
1456 retparam.Add("success", true); 1456 retparam.Add("success", true);
1457 ret.Value = retparam; 1457 ret.Value = retparam;
1458 1458
1459 return ret; 1459 return ret;
1460 1460
1461 } 1461 }
1462#endregion 1462 #endregion
1463 1463
1464 public void PostInitialise() 1464 public void PostInitialise()
1465 { 1465 {
1466 } 1466 }
1467 1467
1468 public void Close() 1468 public void Close()
1469 { 1469 {
1470 } 1470 }
1471 1471
1472 public string Name 1472 public string Name
1473 { 1473 {
1474 get { return "BetaGridLikeMoneyModule"; } 1474 get { return "BetaGridLikeMoneyModule"; }
1475 } 1475 }
1476 1476
1477 public bool IsSharedModule 1477 public bool IsSharedModule
1478 { 1478 {
1479 get { return true; } 1479 get { return true; }
1480 } 1480 }
1481 } 1481 }
1482 public enum TransactionType : int 1482
1483 { 1483 public enum TransactionType : int
1484 SystemGenerated=0, 1484 {
1485 RegionMoneyRequest=1, 1485 SystemGenerated=0,
1486 Gift=2, 1486 RegionMoneyRequest=1,
1487 Purchase=3 1487 Gift=2,
1488 1488 Purchase=3
1489 } 1489
1490} 1490 }
1491} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/FriendsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
index 7078906..3b0cc4c 100644
--- a/OpenSim/Region/Environment/Modules/FriendsModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
@@ -1,504 +1,504 @@
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 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife; 30using libsecondlife;
31using libsecondlife.Packets; 31using libsecondlife.Packets;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using Nwc.XmlRpc; 34using Nwc.XmlRpc;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
38 38
39namespace OpenSim.Region.Environment.Modules 39namespace 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 List<Scene> m_scene = new List<Scene>(); 45 private List<Scene> m_scene = new List<Scene>();
46 46
47 Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); 47 Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>();
48 48
49 Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); 49 Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>();
50 50
51 Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>(); 51 Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>();
52 52
53 public void Initialise(Scene scene, IConfigSource config) 53 public void Initialise(Scene scene, IConfigSource config)
54 { 54 {
55 lock (m_scene) 55 lock (m_scene)
56 { 56 {
57 if (m_scene.Count == 0) 57 if (m_scene.Count == 0)
58 { 58 {
59 scene.AddXmlRPCHandler("presence_update", processPresenceUpdate); 59 scene.AddXmlRPCHandler("presence_update", processPresenceUpdate);
60 } 60 }
61 61
62 if (!m_scene.Contains(scene)) 62 if (!m_scene.Contains(scene))
63 m_scene.Add(scene); 63 m_scene.Add(scene);
64 } 64 }
65 scene.EventManager.OnNewClient += OnNewClient; 65 scene.EventManager.OnNewClient += OnNewClient;
66 scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; 66 scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage;
67 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; 67 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
68 scene.EventManager.OnMakeChildAgent += MakeChildAgent; 68 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
69 scene.EventManager.OnClientClosed += ClientLoggedOut; 69 scene.EventManager.OnClientClosed += ClientLoggedOut;
70 } 70 }
71 public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) 71 public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req)
72 { 72 {
73 m_log.Info("[FRIENDS]: Got Notification about a user! OMG"); 73 m_log.Info("[FRIENDS]: Got Notification about a user! OMG");
74 return new XmlRpcResponse(); 74 return new XmlRpcResponse();
75 } 75 }
76 private void OnNewClient(IClientAPI client) 76 private void OnNewClient(IClientAPI client)
77 { 77 {
78 // All friends establishment protocol goes over instant message 78 // All friends establishment protocol goes over instant message
79 // There's no way to send a message from the sim 79 // There's no way to send a message from the sim
80 // to a user to 'add a friend' without causing dialog box spam 80 // to a user to 'add a friend' without causing dialog box spam
81 // 81 //
82 // The base set of friends are added when the user signs on in their XMLRPC response 82 // The base set of friends are added when the user signs on in their XMLRPC response
83 // Generated by LoginService. The friends are retreived from the database by the UserManager 83 // Generated by LoginService. The friends are retreived from the database by the UserManager
84 84
85 // Subscribe to instant messages 85 // Subscribe to instant messages
86 86
87 client.OnInstantMessage += OnInstantMessage; 87 client.OnInstantMessage += OnInstantMessage;
88 client.OnApproveFriendRequest += OnApprovedFriendRequest; 88 client.OnApproveFriendRequest += OnApprovedFriendRequest;
89 client.OnDenyFriendRequest += OnDenyFriendRequest; 89 client.OnDenyFriendRequest += OnDenyFriendRequest;
90 client.OnTerminateFriendship += OnTerminateFriendship; 90 client.OnTerminateFriendship += OnTerminateFriendship;
91 91
92 List<FriendListItem> fl = new List<FriendListItem>(); 92 List<FriendListItem> fl = new List<FriendListItem>();
93 93
94 //bool addFLback = false; 94 //bool addFLback = false;
95 95
96 lock (FriendLists) 96 lock (FriendLists)
97 { 97 {
98 if (FriendLists.ContainsKey(client.AgentId)) 98 if (FriendLists.ContainsKey(client.AgentId))
99 { 99 {
100 fl = FriendLists[client.AgentId]; 100 fl = FriendLists[client.AgentId];
101 } 101 }
102 else 102 else
103 { 103 {
104 fl = m_scene[0].GetFriendList(client.AgentId); 104 fl = m_scene[0].GetFriendList(client.AgentId);
105 105
106 //lock (FriendLists) 106 //lock (FriendLists)
107 //{ 107 //{
108 if (!FriendLists.ContainsKey(client.AgentId)) 108 if (!FriendLists.ContainsKey(client.AgentId))
109 FriendLists.Add(client.AgentId, fl); 109 FriendLists.Add(client.AgentId, fl);
110 //} 110 //}
111 } 111 }
112 } 112 }
113 113
114 List<LLUUID> UpdateUsers = new List<LLUUID>(); 114 List<LLUUID> UpdateUsers = new List<LLUUID>();
115 115
116 foreach (FriendListItem f in fl) 116 foreach (FriendListItem f in fl)
117 { 117 {
118 if (m_rootAgents.ContainsKey(f.Friend)) 118 if (m_rootAgents.ContainsKey(f.Friend))
119 { 119 {
120 if (f.onlinestatus == false) 120 if (f.onlinestatus == false)
121 { 121 {
122 UpdateUsers.Add(f.Friend); 122 UpdateUsers.Add(f.Friend);
123 f.onlinestatus = true; 123 f.onlinestatus = true;
124 } 124 }
125 } 125 }
126 } 126 }
127 foreach (LLUUID user in UpdateUsers) 127 foreach (LLUUID user in UpdateUsers)
128 { 128 {
129 ScenePresence av = GetPresenceFromAgentID(user); 129 ScenePresence av = GetPresenceFromAgentID(user);
130 if (av != null) 130 if (av != null)
131 { 131 {
132 List<FriendListItem> usrfl = new List<FriendListItem>(); 132 List<FriendListItem> usrfl = new List<FriendListItem>();
133 133
134 lock (FriendLists) 134 lock (FriendLists)
135 { 135 {
136 usrfl = FriendLists[user]; 136 usrfl = FriendLists[user];
137 } 137 }
138 138
139 lock (usrfl) 139 lock (usrfl)
140 { 140 {
141 foreach (FriendListItem fli in usrfl) 141 foreach (FriendListItem fli in usrfl)
142 { 142 {
143 if (fli.Friend == client.AgentId) 143 if (fli.Friend == client.AgentId)
144 { 144 {
145 fli.onlinestatus = true; 145 fli.onlinestatus = true;
146 OnlineNotificationPacket onp = new OnlineNotificationPacket(); 146 OnlineNotificationPacket onp = new OnlineNotificationPacket();
147 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1]; 147 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1];
148 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); 148 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock();
149 onpbl.AgentID = client.AgentId; 149 onpbl.AgentID = client.AgentId;
150 onpb[0] = onpbl; 150 onpb[0] = onpbl;
151 onp.AgentBlock = onpb; 151 onp.AgentBlock = onpb;
152 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); 152 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task);
153 } 153 }
154 } 154 }
155 } 155 }
156 } 156 }
157 } 157 }
158 158
159 if (UpdateUsers.Count > 0) 159 if (UpdateUsers.Count > 0)
160 { 160 {
161 OnlineNotificationPacket onp = new OnlineNotificationPacket(); 161 OnlineNotificationPacket onp = new OnlineNotificationPacket();
162 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count]; 162 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count];
163 for (int i = 0; i < UpdateUsers.Count; i++) 163 for (int i = 0; i < UpdateUsers.Count; i++)
164 { 164 {
165 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); 165 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock();
166 onpbl.AgentID = UpdateUsers[i]; 166 onpbl.AgentID = UpdateUsers[i];
167 onpb[i] = onpbl; 167 onpb[i] = onpbl;
168 } 168 }
169 onp.AgentBlock = onpb; 169 onp.AgentBlock = onpb;
170 client.OutPacket(onp, ThrottleOutPacketType.Task); 170 client.OutPacket(onp, ThrottleOutPacketType.Task);
171 } 171 }
172 172
173 173
174 174
175 175
176 } 176 }
177 177
178 private void ClientLoggedOut(LLUUID AgentId) 178 private void ClientLoggedOut(LLUUID AgentId)
179 { 179 {
180 lock (m_rootAgents) 180 lock (m_rootAgents)
181 { 181 {
182 if (m_rootAgents.ContainsKey(AgentId)) 182 if (m_rootAgents.ContainsKey(AgentId))
183 { 183 {
184 m_rootAgents.Remove(AgentId); 184 m_rootAgents.Remove(AgentId);
185 m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out."); 185 m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out.");
186 } 186 }
187 } 187 }
188 List<FriendListItem> lfli = new List<FriendListItem>(); 188 List<FriendListItem> lfli = new List<FriendListItem>();
189 lock (FriendLists) 189 lock (FriendLists)
190 { 190 {
191 if (FriendLists.ContainsKey(AgentId)) 191 if (FriendLists.ContainsKey(AgentId))
192 { 192 {
193 lfli = FriendLists[AgentId]; 193 lfli = FriendLists[AgentId];
194 } 194 }
195 } 195 }
196 List<LLUUID> updateUsers = new List<LLUUID>(); 196 List<LLUUID> updateUsers = new List<LLUUID>();
197 foreach (FriendListItem fli in lfli) 197 foreach (FriendListItem fli in lfli)
198 { 198 {
199 if (fli.onlinestatus == true) 199 if (fli.onlinestatus == true)
200 { 200 {
201 updateUsers.Add(fli.Friend); 201 updateUsers.Add(fli.Friend);
202 } 202 }
203 } 203 }
204 lock (updateUsers) 204 lock (updateUsers)
205 { 205 {
206 for (int i = 0; i < updateUsers.Count; i++) 206 for (int i = 0; i < updateUsers.Count; i++)
207 { 207 {
208 List<FriendListItem> flfli = new List<FriendListItem>(); 208 List<FriendListItem> flfli = new List<FriendListItem>();
209 try 209 try
210 { 210 {
211 211
212 lock (FriendLists) 212 lock (FriendLists)
213 { 213 {
214 if (FriendLists.ContainsKey(updateUsers[i])) 214 if (FriendLists.ContainsKey(updateUsers[i]))
215 flfli = FriendLists[updateUsers[i]]; 215 flfli = FriendLists[updateUsers[i]];
216 } 216 }
217 } 217 }
218 catch (IndexOutOfRangeException) 218 catch (IndexOutOfRangeException)
219 { 219 {
220 // Ignore the index out of range exception. 220 // Ignore the index out of range exception.
221 // This causes friend lists to get out of sync slightly.. however 221 // This causes friend lists to get out of sync slightly.. however
222 // prevents a sim crash. 222 // prevents a sim crash.
223 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); 223 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off");
224 } 224 }
225 225
226 for (int j = 0; j < flfli.Count; j++) 226 for (int j = 0; j < flfli.Count; j++)
227 { 227 {
228 try 228 try
229 { 229 {
230 if (flfli[i].Friend == AgentId) 230 if (flfli[i].Friend == AgentId)
231 { 231 {
232 flfli[i].onlinestatus = false; 232 flfli[i].onlinestatus = false;
233 } 233 }
234 234
235 } 235 }
236 236
237 catch (IndexOutOfRangeException) 237 catch (IndexOutOfRangeException)
238 { 238 {
239 // Ignore the index out of range exception. 239 // Ignore the index out of range exception.
240 // This causes friend lists to get out of sync slightly.. however 240 // This causes friend lists to get out of sync slightly.. however
241 // prevents a sim crash. 241 // prevents a sim crash.
242 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); 242 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off");
243 } 243 }
244 } 244 }
245 245
246 } 246 }
247 247
248 for (int i = 0; i < updateUsers.Count; i++) 248 for (int i = 0; i < updateUsers.Count; i++)
249 { 249 {
250 ScenePresence av = GetPresenceFromAgentID(updateUsers[i]); 250 ScenePresence av = GetPresenceFromAgentID(updateUsers[i]);
251 if (av != null) 251 if (av != null)
252 { 252 {
253 253
254 OfflineNotificationPacket onp = new OfflineNotificationPacket(); 254 OfflineNotificationPacket onp = new OfflineNotificationPacket();
255 OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1]; 255 OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1];
256 OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); 256 OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock();
257 onpbl.AgentID = AgentId; 257 onpbl.AgentID = AgentId;
258 onpb[0] = onpbl; 258 onpb[0] = onpbl;
259 onp.AgentBlock = onpb; 259 onp.AgentBlock = onpb;
260 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); 260 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task);
261 } 261 }
262 } 262 }
263 } 263 }
264 lock (FriendLists) 264 lock (FriendLists)
265 { 265 {
266 FriendLists.Remove(AgentId); 266 FriendLists.Remove(AgentId);
267 } 267 }
268 268
269 } 269 }
270 270
271 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) 271 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
272 { 272 {
273 lock (m_rootAgents) 273 lock (m_rootAgents)
274 { 274 {
275 if (m_rootAgents.ContainsKey(avatar.UUID)) 275 if (m_rootAgents.ContainsKey(avatar.UUID))
276 { 276 {
277 if (avatar.RegionHandle != m_rootAgents[avatar.UUID]) 277 if (avatar.RegionHandle != m_rootAgents[avatar.UUID])
278 { 278 {
279 m_rootAgents[avatar.UUID] = avatar.RegionHandle; 279 m_rootAgents[avatar.UUID] = avatar.RegionHandle;
280 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); 280 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
281 if (avatar.JID.Length > 0) 281 if (avatar.JID.Length > 0)
282 { 282 {
283 JId avatarID = new JId(avatar.JID); 283 JId avatarID = new JId(avatar.JID);
284 // REST Post XMPP Stanzas! 284 // REST Post XMPP Stanzas!
285 285
286 } 286 }
287 // Claim User! my user! Mine mine mine! 287 // Claim User! my user! Mine mine mine!
288 } 288 }
289 } 289 }
290 else 290 else
291 { 291 {
292 m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); 292 m_rootAgents.Add(avatar.UUID, avatar.RegionHandle);
293 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); 293 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
294 } 294 }
295 } 295 }
296 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); 296 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString());
297 } 297 }
298 private void MakeChildAgent(ScenePresence avatar) 298 private void MakeChildAgent(ScenePresence avatar)
299 { 299 {
300 300
301 lock (m_rootAgents) 301 lock (m_rootAgents)
302 { 302 {
303 if (m_rootAgents.ContainsKey(avatar.UUID)) 303 if (m_rootAgents.ContainsKey(avatar.UUID))
304 { 304 {
305 if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) 305 if (m_rootAgents[avatar.UUID] == avatar.RegionHandle)
306 { 306 {
307 m_rootAgents.Remove(avatar.UUID); 307 m_rootAgents.Remove(avatar.UUID);
308 m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); 308 m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent");
309 } 309 }
310 310
311 } 311 }
312 } 312 }
313 313
314 } 314 }
315 #region FriendRequestHandling 315 #region FriendRequestHandling
316 private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, 316 private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID,
317 LLUUID fromAgentSession, LLUUID toAgentID, 317 LLUUID fromAgentSession, LLUUID toAgentID,
318 LLUUID imSessionID, uint timestamp, string fromAgentName, 318 LLUUID imSessionID, uint timestamp, string fromAgentName,
319 string message, byte dialog, bool fromGroup, byte offline, 319 string message, byte dialog, bool fromGroup, byte offline,
320 uint ParentEstateID, LLVector3 Position, LLUUID RegionID, 320 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
321 byte[] binaryBucket) 321 byte[] binaryBucket)
322 { 322 {
323 // Friend Requests go by Instant Message.. using the dialog param 323 // Friend Requests go by Instant Message.. using the dialog param
324 // https://wiki.secondlife.com/wiki/ImprovedInstantMessage 324 // https://wiki.secondlife.com/wiki/ImprovedInstantMessage
325 325
326 // 38 == Offer friendship 326 // 38 == Offer friendship
327 if (dialog == (byte)38) 327 if (dialog == (byte)38)
328 { 328 {
329 LLUUID friendTransactionID = LLUUID.Random(); 329 LLUUID friendTransactionID = LLUUID.Random();
330 330
331 m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 331 m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
332 332
333 m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); 333 m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message);
334 GridInstantMessage msg = new GridInstantMessage(); 334 GridInstantMessage msg = new GridInstantMessage();
335 msg.fromAgentID = fromAgentID.UUID; 335 msg.fromAgentID = fromAgentID.UUID;
336 msg.fromAgentSession = fromAgentSession.UUID; 336 msg.fromAgentSession = fromAgentSession.UUID;
337 msg.toAgentID = toAgentID.UUID; 337 msg.toAgentID = toAgentID.UUID;
338 msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here 338 msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here
339 m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString()); 339 m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString());
340 msg.timestamp = timestamp; 340 msg.timestamp = timestamp;
341 if (client != null) 341 if (client != null)
342 { 342 {
343 msg.fromAgentName = client.FirstName + " " + client.LastName;// fromAgentName; 343 msg.fromAgentName = client.FirstName + " " + client.LastName;// fromAgentName;
344 } 344 }
345 else 345 else
346 { 346 {
347 msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it 347 msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it
348 } 348 }
349 msg.message = message; 349 msg.message = message;
350 msg.dialog = dialog; 350 msg.dialog = dialog;
351 msg.fromGroup = fromGroup; 351 msg.fromGroup = fromGroup;
352 msg.offline = offline; 352 msg.offline = offline;
353 msg.ParentEstateID = ParentEstateID; 353 msg.ParentEstateID = ParentEstateID;
354 msg.Position = new sLLVector3(Position); 354 msg.Position = new sLLVector3(Position);
355 msg.RegionID = RegionID.UUID; 355 msg.RegionID = RegionID.UUID;
356 msg.binaryBucket = binaryBucket; 356 msg.binaryBucket = binaryBucket;
357 // We don't really care which scene we pipe it through. 357 // We don't really care which scene we pipe it through.
358 m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); 358 m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
359 } 359 }
360 360
361 // 39 == Accept Friendship 361 // 39 == Accept Friendship
362 if (dialog == (byte)39) 362 if (dialog == (byte)39)
363 { 363 {
364 m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); 364 m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message);
365 } 365 }
366 366
367 // 40 == Decline Friendship 367 // 40 == Decline Friendship
368 if (dialog == (byte)40) 368 if (dialog == (byte)40)
369 { 369 {
370 m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); 370 m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message);
371 } 371 }
372 } 372 }
373 373
374 private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) 374 private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders)
375 { 375 {
376 if (m_pendingFriendRequests.ContainsKey(transactionID)) 376 if (m_pendingFriendRequests.ContainsKey(transactionID))
377 { 377 {
378 // Found Pending Friend Request with that Transaction.. 378 // Found Pending Friend Request with that Transaction..
379 Scene SceneAgentIn = m_scene[0]; 379 Scene SceneAgentIn = m_scene[0];
380 380
381 // Found Pending Friend Request with that Transaction.. 381 // Found Pending Friend Request with that Transaction..
382 ScenePresence agentpresence = GetPresenceFromAgentID(agentID); 382 ScenePresence agentpresence = GetPresenceFromAgentID(agentID);
383 if (agentpresence != null) 383 if (agentpresence != null)
384 { 384 {
385 SceneAgentIn = agentpresence.Scene; 385 SceneAgentIn = agentpresence.Scene;
386 } 386 }
387 387
388 // Compose response to other agent. 388 // Compose response to other agent.
389 GridInstantMessage msg = new GridInstantMessage(); 389 GridInstantMessage msg = new GridInstantMessage();
390 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; 390 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID;
391 msg.fromAgentID = agentID.UUID; 391 msg.fromAgentID = agentID.UUID;
392 msg.fromAgentName = client.FirstName + " " + client.LastName; 392 msg.fromAgentName = client.FirstName + " " + client.LastName;
393 msg.fromAgentSession = client.SessionId.UUID; 393 msg.fromAgentSession = client.SessionId.UUID;
394 msg.fromGroup = false; 394 msg.fromGroup = false;
395 msg.imSessionID = transactionID.UUID; 395 msg.imSessionID = transactionID.UUID;
396 msg.message = agentID.UUID.ToString(); 396 msg.message = agentID.UUID.ToString();
397 msg.ParentEstateID = 0; 397 msg.ParentEstateID = 0;
398 msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); 398 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
399 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; 399 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID;
400 msg.dialog = (byte)39;// Approved friend request 400 msg.dialog = (byte)39;// Approved friend request
401 msg.Position = new sLLVector3(); 401 msg.Position = new sLLVector3();
402 msg.offline = (byte)0; 402 msg.offline = (byte)0;
403 msg.binaryBucket = new byte[0]; 403 msg.binaryBucket = new byte[0];
404 // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database 404 // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database
405 405
406 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); 406 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
407 SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint)1); 407 SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint)1);
408 m_pendingFriendRequests.Remove(transactionID); 408 m_pendingFriendRequests.Remove(transactionID);
409 409
410 // TODO: Inform agent that the friend is online 410 // TODO: Inform agent that the friend is online
411 } 411 }
412 } 412 }
413 413
414 private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) 414 private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders)
415 { 415 {
416 if (m_pendingFriendRequests.ContainsKey(transactionID)) 416 if (m_pendingFriendRequests.ContainsKey(transactionID))
417 { 417 {
418 Scene SceneAgentIn = m_scene[0]; 418 Scene SceneAgentIn = m_scene[0];
419 419
420 // Found Pending Friend Request with that Transaction.. 420 // Found Pending Friend Request with that Transaction..
421 ScenePresence agentpresence = GetPresenceFromAgentID(agentID); 421 ScenePresence agentpresence = GetPresenceFromAgentID(agentID);
422 if (agentpresence != null) 422 if (agentpresence != null)
423 { 423 {
424 SceneAgentIn = agentpresence.Scene; 424 SceneAgentIn = agentpresence.Scene;
425 } 425 }
426 // Compose response to other agent. 426 // Compose response to other agent.
427 GridInstantMessage msg = new GridInstantMessage(); 427 GridInstantMessage msg = new GridInstantMessage();
428 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; 428 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID;
429 msg.fromAgentID = agentID.UUID; 429 msg.fromAgentID = agentID.UUID;
430 msg.fromAgentName = client.FirstName + " " + client.LastName; 430 msg.fromAgentName = client.FirstName + " " + client.LastName;
431 msg.fromAgentSession = client.SessionId.UUID; 431 msg.fromAgentSession = client.SessionId.UUID;
432 msg.fromGroup = false; 432 msg.fromGroup = false;
433 msg.imSessionID = transactionID.UUID; 433 msg.imSessionID = transactionID.UUID;
434 msg.message = agentID.UUID.ToString(); 434 msg.message = agentID.UUID.ToString();
435 msg.ParentEstateID = 0; 435 msg.ParentEstateID = 0;
436 msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); 436 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
437 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; 437 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID;
438 msg.dialog = (byte)40;// Deny friend request 438 msg.dialog = (byte)40;// Deny friend request
439 msg.Position = new sLLVector3(); 439 msg.Position = new sLLVector3();
440 msg.offline = (byte)0; 440 msg.offline = (byte)0;
441 msg.binaryBucket = new byte[0]; 441 msg.binaryBucket = new byte[0];
442 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); 442 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
443 m_pendingFriendRequests.Remove(transactionID); 443 m_pendingFriendRequests.Remove(transactionID);
444 } 444 }
445 } 445 }
446 446
447 private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID) 447 private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID)
448 { 448 {
449 m_scene[0].StoreRemoveFriendship(agent, exfriendID); 449 m_scene[0].StoreRemoveFriendship(agent, exfriendID);
450 // TODO: Inform the client that the ExFriend is offline 450 // TODO: Inform the client that the ExFriend is offline
451 } 451 }
452 452
453 private void OnGridInstantMessage(GridInstantMessage msg) 453 private void OnGridInstantMessage(GridInstantMessage msg)
454 { 454 {
455 // Trigger the above event handler 455 // Trigger the above event handler
456 OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), 456 OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
457 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, 457 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
458 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, 458 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
459 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), 459 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
460 msg.binaryBucket); 460 msg.binaryBucket);
461 } 461 }
462 #endregion 462 #endregion
463 private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) 463 private ScenePresence GetPresenceFromAgentID(LLUUID AgentID)
464 { 464 {
465 ScenePresence returnAgent = null; 465 ScenePresence returnAgent = null;
466 lock (m_scene) 466 lock (m_scene)
467 { 467 {
468 ScenePresence queryagent = null; 468 ScenePresence queryagent = null;
469 for (int i = 0; i < m_scene.Count; i++) 469 for (int i = 0; i < m_scene.Count; i++)
470 { 470 {
471 queryagent = m_scene[i].GetScenePresence(AgentID); 471 queryagent = m_scene[i].GetScenePresence(AgentID);
472 if (queryagent != null) 472 if (queryagent != null)
473 { 473 {
474 if (!queryagent.IsChildAgent) 474 if (!queryagent.IsChildAgent)
475 { 475 {
476 returnAgent = queryagent; 476 returnAgent = queryagent;
477 break; 477 break;
478 } 478 }
479 } 479 }
480 } 480 }
481 } 481 }
482 return returnAgent; 482 return returnAgent;
483 483
484 } 484 }
485 485
486 public void PostInitialise() 486 public void PostInitialise()
487 { 487 {
488 } 488 }
489 489
490 public void Close() 490 public void Close()
491 { 491 {
492 } 492 }
493 493
494 public string Name 494 public string Name
495 { 495 {
496 get { return "FriendsModule"; } 496 get { return "FriendsModule"; }
497 } 497 }
498 498
499 public bool IsSharedModule 499 public bool IsSharedModule
500 { 500 {
501 get { return true; } 501 get { return true; }
502 } 502 }
503 } 503 }
504} 504} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/GroupsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs
index b23bb91..4b28ad7 100644
--- a/OpenSim/Region/Environment/Modules/GroupsModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs
@@ -1,278 +1,278 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using libsecondlife; 31using libsecondlife;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Scenes; 36using OpenSim.Region.Environment.Scenes;
37 37
38namespace OpenSim.Region.Environment.Modules 38namespace 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 List<Scene> m_scene = new List<Scene>(); 44 private List<Scene> m_scene = new List<Scene>();
45 private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>(); 45 private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>();
46 private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>(); 46 private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>();
47 private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>(); 47 private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>();
48 48
49 public void Initialise(Scene scene, IConfigSource config) 49 public void Initialise(Scene scene, IConfigSource config)
50 { 50 {
51 lock (m_scene) 51 lock (m_scene)
52 { 52 {
53 m_scene.Add(scene); 53 m_scene.Add(scene);
54 } 54 }
55 scene.EventManager.OnNewClient += OnNewClient; 55 scene.EventManager.OnNewClient += OnNewClient;
56 scene.EventManager.OnClientClosed += OnClientClosed; 56 scene.EventManager.OnClientClosed += OnClientClosed;
57 scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage; 57 scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage;
58 //scene.EventManager. 58 //scene.EventManager.
59 } 59 }
60 60
61 private void OnNewClient(IClientAPI client) 61 private void OnNewClient(IClientAPI client)
62 { 62 {
63 // All friends establishment protocol goes over instant message 63 // All friends establishment protocol goes over instant message
64 // There's no way to send a message from the sim 64 // There's no way to send a message from the sim
65 // to a user to 'add a friend' without causing dialog box spam 65 // to a user to 'add a friend' without causing dialog box spam
66 // 66 //
67 // The base set of friends are added when the user signs on in their XMLRPC response 67 // The base set of friends are added when the user signs on in their XMLRPC response
68 // Generated by LoginService. The friends are retreived from the database by the UserManager 68 // Generated by LoginService. The friends are retreived from the database by the UserManager
69 69
70 // Subscribe to instant messages 70 // Subscribe to instant messages
71 client.OnInstantMessage += OnInstantMessage; 71 client.OnInstantMessage += OnInstantMessage;
72 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 72 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
73 lock (m_iclientmap) 73 lock (m_iclientmap)
74 { 74 {
75 if (!m_iclientmap.ContainsKey(client.AgentId)) 75 if (!m_iclientmap.ContainsKey(client.AgentId))
76 { 76 {
77 m_iclientmap.Add(client.AgentId, client); 77 m_iclientmap.Add(client.AgentId, client);
78 } 78 }
79 } 79 }
80 GroupData OpenSimulatorGroup = new GroupData(); 80 GroupData OpenSimulatorGroup = new GroupData();
81 OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester"; 81 OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester";
82 OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120"); 82 OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120");
83 OpenSimulatorGroup.GroupMembers.Add(client.AgentId); 83 OpenSimulatorGroup.GroupMembers.Add(client.AgentId);
84 OpenSimulatorGroup.groupName = "OpenSimulator Testing"; 84 OpenSimulatorGroup.groupName = "OpenSimulator Testing";
85 OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome; 85 OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome;
86 OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester"); 86 OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester");
87 lock (m_groupmap) 87 lock (m_groupmap)
88 { 88 {
89 if (!m_groupmap.ContainsKey(client.AgentId)) 89 if (!m_groupmap.ContainsKey(client.AgentId))
90 { 90 {
91 m_groupmap.Add(client.AgentId, OpenSimulatorGroup); 91 m_groupmap.Add(client.AgentId, OpenSimulatorGroup);
92 } 92 }
93 } 93 }
94 GroupList testGroupList = new GroupList(); 94 GroupList testGroupList = new GroupList();
95 testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120")); 95 testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120"));
96 96
97 lock (m_grouplistmap) 97 lock (m_grouplistmap)
98 { 98 {
99 if (!m_grouplistmap.ContainsKey(client.AgentId)) 99 if (!m_grouplistmap.ContainsKey(client.AgentId))
100 { 100 {
101 m_grouplistmap.Add(client.AgentId, testGroupList); 101 m_grouplistmap.Add(client.AgentId, testGroupList);
102 } 102 }
103 } 103 }
104 m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group"); 104 m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group");
105 } 105 }
106 106
107 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID) 107 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID)
108 { 108 {
109 string firstname = remoteClient.FirstName; 109 string firstname = remoteClient.FirstName;
110 string lastname = remoteClient.LastName; 110 string lastname = remoteClient.LastName;
111 111
112 LLUUID ActiveGroupID = LLUUID.Zero; 112 LLUUID ActiveGroupID = LLUUID.Zero;
113 uint ActiveGroupPowers = 0; 113 uint ActiveGroupPowers = 0;
114 string ActiveGroupName = ""; 114 string ActiveGroupName = "";
115 string ActiveGroupTitle = ""; 115 string ActiveGroupTitle = "";
116 116
117 bool foundUser = false; 117 bool foundUser = false;
118 118
119 lock (m_iclientmap) 119 lock (m_iclientmap)
120 { 120 {
121 if (m_iclientmap.ContainsKey(remoteClient.AgentId)) 121 if (m_iclientmap.ContainsKey(remoteClient.AgentId))
122 { 122 {
123 foundUser = true; 123 foundUser = true;
124 } 124 }
125 } 125 }
126 if (foundUser) 126 if (foundUser)
127 { 127 {
128 lock (m_groupmap) 128 lock (m_groupmap)
129 { 129 {
130 if (m_groupmap.ContainsKey(remoteClient.AgentId)) 130 if (m_groupmap.ContainsKey(remoteClient.AgentId))
131 { 131 {
132 GroupData grp = m_groupmap[remoteClient.AgentId]; 132 GroupData grp = m_groupmap[remoteClient.AgentId];
133 if (grp != null) 133 if (grp != null)
134 { 134 {
135 ActiveGroupID = grp.GroupID; 135 ActiveGroupID = grp.GroupID;
136 ActiveGroupName = grp.groupName; 136 ActiveGroupName = grp.groupName;
137 ActiveGroupPowers = grp.groupPowers; 137 ActiveGroupPowers = grp.groupPowers;
138 ActiveGroupTitle = grp.ActiveGroupTitle; 138 ActiveGroupTitle = grp.ActiveGroupTitle;
139 } 139 }
140 140
141 //remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle); 141 //remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle);
142 142
143 } 143 }
144 } 144 }
145 } 145 }
146 146
147 } 147 }
148 148
149 private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, 149 private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
150 LLUUID fromAgentSession, LLUUID toAgentID, 150 LLUUID fromAgentSession, LLUUID toAgentID,
151 LLUUID imSessionID, uint timestamp, string fromAgentName, 151 LLUUID imSessionID, uint timestamp, string fromAgentName,
152 string message, byte dialog, bool fromGroup, byte offline, 152 string message, byte dialog, bool fromGroup, byte offline,
153 uint ParentEstateID, LLVector3 Position, LLUUID RegionID, 153 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
154 byte[] binaryBucket) 154 byte[] binaryBucket)
155 { 155 {
156 } 156 }
157 157
158 private void OnGridInstantMessage(GridInstantMessage msg) 158 private void OnGridInstantMessage(GridInstantMessage msg)
159 { 159 {
160 // Trigger the above event handler 160 // Trigger the above event handler
161 OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), 161 OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
162 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, 162 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
163 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, 163 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
164 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), 164 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
165 msg.binaryBucket); 165 msg.binaryBucket);
166 } 166 }
167 167
168 private void OnClientClosed(LLUUID agentID) 168 private void OnClientClosed(LLUUID agentID)
169 { 169 {
170 lock (m_iclientmap) 170 lock (m_iclientmap)
171 { 171 {
172 if (m_iclientmap.ContainsKey(agentID)) 172 if (m_iclientmap.ContainsKey(agentID))
173 { 173 {
174 IClientAPI cli = m_iclientmap[agentID]; 174 IClientAPI cli = m_iclientmap[agentID];
175 if (cli != null) 175 if (cli != null)
176 { 176 {
177 m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName); 177 m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName);
178 } 178 }
179 else 179 else
180 { 180 {
181 m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString()); 181 m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString());
182 } 182 }
183 m_iclientmap.Remove(agentID); 183 m_iclientmap.Remove(agentID);
184 } 184 }
185 } 185 }
186 186
187 lock (m_groupmap) 187 lock (m_groupmap)
188 { 188 {
189 if (m_groupmap.ContainsKey(agentID)) 189 if (m_groupmap.ContainsKey(agentID))
190 { 190 {
191 m_groupmap.Remove(agentID); 191 m_groupmap.Remove(agentID);
192 } 192 }
193 } 193 }
194 194
195 lock (m_grouplistmap) 195 lock (m_grouplistmap)
196 { 196 {
197 if (m_grouplistmap.ContainsKey(agentID)) 197 if (m_grouplistmap.ContainsKey(agentID))
198 { 198 {
199 m_grouplistmap.Remove(agentID); 199 m_grouplistmap.Remove(agentID);
200 } 200 }
201 } 201 }
202 GC.Collect(); 202 GC.Collect();
203 } 203 }
204 204
205 public void PostInitialise() 205 public void PostInitialise()
206 { 206 {
207 } 207 }
208 208
209 public void Close() 209 public void Close()
210 { 210 {
211 m_log.Info("[GROUP]: Shutting down group module."); 211 m_log.Info("[GROUP]: Shutting down group module.");
212 lock (m_iclientmap) 212 lock (m_iclientmap)
213 { 213 {
214 m_iclientmap.Clear(); 214 m_iclientmap.Clear();
215 } 215 }
216 216
217 lock (m_groupmap) 217 lock (m_groupmap)
218 { 218 {
219 m_groupmap.Clear(); 219 m_groupmap.Clear();
220 } 220 }
221 221
222 lock (m_grouplistmap) 222 lock (m_grouplistmap)
223 { 223 {
224 m_grouplistmap.Clear(); 224 m_grouplistmap.Clear();
225 } 225 }
226 GC.Collect(); 226 GC.Collect();
227 } 227 }
228 228
229 public string Name 229 public string Name
230 { 230 {
231 get { return "GroupsModule"; } 231 get { return "GroupsModule"; }
232 } 232 }
233 233
234 public bool IsSharedModule 234 public bool IsSharedModule
235 { 235 {
236 get { return true; } 236 get { return true; }
237 } 237 }
238 238
239 } 239 }
240 240
241 public class GroupData 241 public class GroupData
242 { 242 {
243 public LLUUID GroupID; 243 public LLUUID GroupID;
244 public string groupName; 244 public string groupName;
245 public string ActiveGroupTitle; 245 public string ActiveGroupTitle;
246 public List<string> GroupTitles; 246 public List<string> GroupTitles;
247 public List<LLUUID> GroupMembers; 247 public List<LLUUID> GroupMembers;
248 public uint groupPowers = (uint)(GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome); 248 public uint groupPowers = (uint)(GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome);
249 249
250 public GroupPowers ActiveGroupPowers 250 public GroupPowers ActiveGroupPowers
251 { 251 {
252 set 252 set
253 { 253 {
254 groupPowers = (uint) value; 254 groupPowers = (uint) value;
255 } 255 }
256 get 256 get
257 { 257 {
258 return (GroupPowers)groupPowers; 258 return (GroupPowers)groupPowers;
259 } 259 }
260 } 260 }
261 261
262 public GroupData() 262 public GroupData()
263 { 263 {
264 GroupTitles = new List<string>(); 264 GroupTitles = new List<string>();
265 GroupMembers = new List<LLUUID>(); 265 GroupMembers = new List<LLUUID>();
266 } 266 }
267 267
268 } 268 }
269 269
270 public class GroupList 270 public class GroupList
271 { 271 {
272 public List<LLUUID> m_GroupList; 272 public List<LLUUID> m_GroupList;
273 public GroupList() 273 public GroupList()
274 { 274 {
275 m_GroupList = new List<LLUUID>(); 275 m_GroupList = new List<LLUUID>();
276 } 276 }
277 } 277 }
278} 278} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs
index 6e13b73..1b82837 100644
--- a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -1,159 +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
28using System.Collections; 28using System.Collections.Generic;
29using System.Collections.Generic; 29using libsecondlife;
30using libsecondlife; 30using Nini.Config;
31using Nini.Config; 31using OpenSim.Framework;
32using OpenSim.Framework; 32using OpenSim.Region.Environment.Interfaces;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Scenes;
34using OpenSim.Region.Environment.Scenes; 34
35 35namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
36namespace OpenSim.Region.Environment.Modules 36{
37{ 37 public class InstantMessageModule : IRegionModule
38 public class InstantMessageModule : IRegionModule 38 {
39 { 39 private readonly List<Scene> m_scenes = new List<Scene>();
40 private List<Scene> m_scenes = new List<Scene>(); 40
41 private Hashtable m_RegionInfoCache = new Hashtable(); 41 public void Initialise(Scene scene, IConfigSource config)
42 42 {
43 public void Initialise(Scene scene, IConfigSource config) 43 lock (m_scenes)
44 { 44 {
45 lock (m_scenes) 45 if (m_scenes.Count == 0)
46 { 46 {
47 if (m_scenes.Count == 0) 47 //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate);
48 { 48 }
49 //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate); 49
50 } 50 if (!m_scenes.Contains(scene))
51 51 {
52 if (!m_scenes.Contains(scene)) 52 m_scenes.Add(scene);
53 { 53 scene.EventManager.OnNewClient += OnNewClient;
54 m_scenes.Add(scene); 54 scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage;
55 scene.EventManager.OnNewClient += OnNewClient; 55 }
56 scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; 56 }
57 } 57 }
58 } 58
59 } 59 private void OnNewClient(IClientAPI client)
60 60 {
61 private void OnNewClient(IClientAPI client) 61 client.OnInstantMessage += OnInstantMessage;
62 { 62 }
63 client.OnInstantMessage += OnInstantMessage; 63
64 } 64 private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID,
65 65 LLUUID fromAgentSession, LLUUID toAgentID,
66 private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, 66 LLUUID imSessionID, uint timestamp, string fromAgentName,
67 LLUUID fromAgentSession, LLUUID toAgentID, 67 string message, byte dialog, bool fromGroup, byte offline,
68 LLUUID imSessionID, uint timestamp, string fromAgentName, 68 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
69 string message, byte dialog, bool fromGroup, byte offline, 69 byte[] binaryBucket)
70 uint ParentEstateID, LLVector3 Position, LLUUID RegionID, 70 {
71 byte[] binaryBucket) 71 bool dialogHandledElsewhere
72 { 72 = ((dialog == 38) || (dialog == 39) || (dialog == 40)
73 bool dialogHandledElsewhere 73 || dialog == (byte)InstantMessageDialog.InventoryOffered
74 = ((dialog == (byte)38) || (dialog == (byte)39) || (dialog == (byte)40) 74 || dialog == (byte)InstantMessageDialog.InventoryAccepted
75 || dialog == (byte)InstantMessageDialog.InventoryOffered 75 || dialog == (byte)InstantMessageDialog.InventoryDeclined);
76 || dialog == (byte)InstantMessageDialog.InventoryAccepted 76
77 || dialog == (byte)InstantMessageDialog.InventoryDeclined); 77 // IM dialogs need to be pre-processed and have their sessionID filled by the server
78 78 // so the sim can match the transaction on the return packet.
79 // IM dialogs need to be pre-processed and have their sessionID filled by the server 79
80 // so the sim can match the transaction on the return packet. 80 // Don't send a Friend Dialog IM with a LLUUID.Zero session.
81 81 if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero))
82 // Don't send a Friend Dialog IM with a LLUUID.Zero session. 82 {
83 if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero)) 83 // Try root avatar only first
84 { 84 foreach (Scene scene in m_scenes)
85 // Try root avatar only first 85 {
86 foreach (Scene scene in m_scenes) 86 if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
87 { 87 {
88 if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) 88 // Local message
89 { 89 ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
90 // Local message 90 if (!user.IsChildAgent)
91 ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; 91 {
92 if (!user.IsChildAgent) 92 user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
93 { 93 toAgentID, imSessionID, fromAgentName, dialog,
94 user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, 94 timestamp);
95 toAgentID, imSessionID, fromAgentName, dialog, 95 // Message sent
96 timestamp); 96 return;
97 // Message sent 97 }
98 return; 98 }
99 } 99 }
100 } 100
101 } 101 // try child avatar second
102 102 foreach (Scene scene in m_scenes)
103 // try child avatar second 103 {
104 foreach (Scene scene in m_scenes) 104 if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
105 { 105 {
106 if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) 106 // Local message
107 { 107 ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
108 // Local message 108
109 ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; 109 user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
110 110 toAgentID, imSessionID, fromAgentName, dialog,
111 user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, 111 timestamp);
112 toAgentID, imSessionID, fromAgentName, dialog, 112 // Message sent
113 timestamp); 113 return;
114 // Message sent 114
115 return; 115 }
116 116 }
117 } 117
118 } 118 }
119 119
120 } 120
121 121 // Still here, try send via Grid
122 122 // TODO
123 // Still here, try send via Grid 123 }
124 // TODO 124
125 } 125 // Trusty OSG1 called method. This method also gets called from the FriendsModule
126 126 // Turns out the sim has to send an instant message to the user to get it to show an accepted friend.
127 // Trusty OSG1 called method. This method also gets called from the FriendsModule 127
128 // Turns out the sim has to send an instant message to the user to get it to show an accepted friend. 128 private void OnGridInstantMessage(GridInstantMessage msg)
129 129 {
130 private void OnGridInstantMessage(GridInstantMessage msg) 130 // Trigger the above event handler
131 { 131 OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
132 // Trigger the above event handler 132 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
133 OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), 133 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
134 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, 134 new LLVector3(msg.Position.x,msg.Position.y,msg.Position.z), new LLUUID(msg.RegionID),
135 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, 135 msg.binaryBucket);
136 new LLVector3(msg.Position.x,msg.Position.y,msg.Position.z), new LLUUID(msg.RegionID), 136
137 msg.binaryBucket); 137 }
138 138
139 } 139 public void PostInitialise()
140 140 {
141 public void PostInitialise() 141 }
142 { 142
143 } 143 public void Close()
144 144 {
145 public void Close() 145 }
146 { 146
147 } 147 public string Name
148 148 {
149 public string Name 149 get { return "InstantMessageModule"; }
150 { 150 }
151 get { return "InstantMessageModule"; } 151
152 } 152 public bool IsSharedModule
153 153 {
154 public bool IsSharedModule 154 get { return true; }
155 { 155 }
156 get { return true; } 156 }
157 } 157} \ No newline at end of file
158 }
159}
diff --git a/OpenSim/Region/Environment/Modules/InventoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs
index ff5a02c..42c6238 100644
--- a/OpenSim/Region/Environment/Modules/InventoryModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs
@@ -1,216 +1,216 @@
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
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife; 30using libsecondlife;
31using log4net; 31using log4net;
32using Nini.Config; 32using Nini.Config;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Scenes;
36 36
37namespace OpenSim.Region.Environment.Modules 37namespace 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 private Scene m_scene; 44 private Scene m_scene;
45 45
46 /// <summary> 46 /// <summary>
47 /// We need to keep track of the pending item offers between clients since the itemId offered only 47 /// We need to keep track of the pending item offers between clients since the itemId offered only
48 /// occurs in the initial offer message, not the accept message. So this dictionary links 48 /// occurs in the initial offer message, not the accept message. So this dictionary links
49 /// IM Session Ids to ItemIds 49 /// IM Session Ids to ItemIds
50 /// </summary> 50 /// </summary>
51 private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>(); 51 private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>();
52 52
53 public void Initialise(Scene scene, IConfigSource config) 53 public void Initialise(Scene scene, IConfigSource config)
54 { 54 {
55 m_scene = scene; 55 m_scene = scene;
56 scene.EventManager.OnNewClient += OnNewClient; 56 scene.EventManager.OnNewClient += OnNewClient;
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 "InventoryModule"; } 69 get { return "InventoryModule"; }
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 private void OnNewClient(IClientAPI client) 77 private void OnNewClient(IClientAPI client)
78 { 78 {
79 // Inventory giving is conducted via instant message 79 // Inventory giving is conducted via instant message
80 client.OnInstantMessage += OnInstantMessage; 80 client.OnInstantMessage += OnInstantMessage;
81 } 81 }
82 82
83 private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, 83 private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
84 LLUUID fromAgentSession, LLUUID toAgentID, 84 LLUUID fromAgentSession, LLUUID toAgentID,
85 LLUUID imSessionID, uint timestamp, string fromAgentName, 85 LLUUID imSessionID, uint timestamp, string fromAgentName,
86 string message, byte dialog, bool fromGroup, byte offline, 86 string message, byte dialog, bool fromGroup, byte offline,
87 uint ParentEstateID, LLVector3 Position, LLUUID RegionID, 87 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
88 byte[] binaryBucket) 88 byte[] binaryBucket)
89 { 89 {
90 if (dialog == (byte)InstantMessageDialog.InventoryOffered) 90 if (dialog == (byte)InstantMessageDialog.InventoryOffered)
91 { 91 {
92 m_log.DebugFormat( 92 m_log.DebugFormat(
93 "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", 93 "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}",
94 client.AgentId, client.Name, toAgentID); 94 client.AgentId, client.Name, toAgentID);
95 95
96 if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) 96 if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
97 { 97 {
98 ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; 98 ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID];
99 99
100 if (!user.IsChildAgent) 100 if (!user.IsChildAgent)
101 { 101 {
102 //byte[] rawId = new byte[16]; 102 //byte[] rawId = new byte[16];
103 103
104 // First byte of the array is probably the item type 104 // First byte of the array is probably the item type
105 // Next 16 bytes are the UUID 105 // Next 16 bytes are the UUID
106 //Array.Copy(binaryBucket, 1, rawId, 0, 16); 106 //Array.Copy(binaryBucket, 1, rawId, 0, 16);
107 107
108 //LLUUID itemId = new LLUUID(new Guid(rawId)); 108 //LLUUID itemId = new LLUUID(new Guid(rawId));
109 LLUUID itemId = new LLUUID(binaryBucket, 1); 109 LLUUID itemId = new LLUUID(binaryBucket, 1);
110 110
111 m_log.DebugFormat( 111 m_log.DebugFormat(
112 "[AGENT INVENTORY]: ItemId for giving is {0}", itemId); 112 "[AGENT INVENTORY]: ItemId for giving is {0}", itemId);
113 113
114 m_pendingOffers[imSessionID] = itemId; 114 m_pendingOffers[imSessionID] = itemId;
115 115
116 user.ControllingClient.SendInstantMessage( 116 user.ControllingClient.SendInstantMessage(
117 fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, 117 fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
118 dialog, timestamp, binaryBucket); 118 dialog, timestamp, binaryBucket);
119 119
120 return; 120 return;
121 } 121 }
122 else 122 else
123 { 123 {
124 m_log.WarnFormat( 124 m_log.WarnFormat(
125 "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", 125 "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
126 toAgentID, client.AgentId, client.Name, message); 126 toAgentID, client.AgentId, client.Name, message);
127 } 127 }
128 } 128 }
129 else 129 else
130 { 130 {
131 m_log.WarnFormat( 131 m_log.WarnFormat(
132 "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", 132 "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}",
133 toAgentID, client.AgentId, client.Name, message); 133 toAgentID, client.AgentId, client.Name, message);
134 } 134 }
135 } 135 }
136 else if (dialog == (byte)InstantMessageDialog.InventoryAccepted) 136 else if (dialog == (byte)InstantMessageDialog.InventoryAccepted)
137 { 137 {
138 m_log.DebugFormat( 138 m_log.DebugFormat(
139 "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}", 139 "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}",
140 client.AgentId, client.Name, toAgentID); 140 client.AgentId, client.Name, toAgentID);
141 141
142 if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) 142 if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
143 { 143 {
144 ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; 144 ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID];
145 145
146 if (!user.IsChildAgent) 146 if (!user.IsChildAgent)
147 { 147 {
148 user.ControllingClient.SendInstantMessage( 148 user.ControllingClient.SendInstantMessage(
149 fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, 149 fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
150 dialog, timestamp, binaryBucket); 150 dialog, timestamp, binaryBucket);
151 151
152 if (m_pendingOffers.ContainsKey(imSessionID)) 152 if (m_pendingOffers.ContainsKey(imSessionID))
153 { 153 {
154 m_log.DebugFormat( 154 m_log.DebugFormat(
155 "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]); 155 "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]);
156 156
157 // Since the message originates from the accepting client, the toAgentID is 157 // Since the message originates from the accepting client, the toAgentID is
158 // the agent giving the item. 158 // the agent giving the item.
159 m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]); 159 m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]);
160 160
161 m_pendingOffers.Remove(imSessionID); 161 m_pendingOffers.Remove(imSessionID);
162 } 162 }
163 else 163 else
164 { 164 {
165 m_log.ErrorFormat( 165 m_log.ErrorFormat(
166 "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept", 166 "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept",
167 imSessionID); 167 imSessionID);
168 } 168 }
169 169
170 return; 170 return;
171 } 171 }
172 else 172 else
173 { 173 {
174 m_log.WarnFormat( 174 m_log.WarnFormat(
175 "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", 175 "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
176 toAgentID, client.AgentId, client.Name, message); 176 toAgentID, client.AgentId, client.Name, message);
177 } 177 }
178 } 178 }
179 else 179 else
180 { 180 {
181 m_log.WarnFormat( 181 m_log.WarnFormat(
182 "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", 182 "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}",
183 toAgentID, client.AgentId, client.Name, message); 183 toAgentID, client.AgentId, client.Name, message);
184 } 184 }
185 } 185 }
186 else if (dialog == (byte)InstantMessageDialog.InventoryDeclined) 186 else if (dialog == (byte)InstantMessageDialog.InventoryDeclined)
187 { 187 {
188 if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) 188 if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
189 { 189 {
190 ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; 190 ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID];
191 191
192 if (!user.IsChildAgent) 192 if (!user.IsChildAgent)
193 { 193 {
194 user.ControllingClient.SendInstantMessage( 194 user.ControllingClient.SendInstantMessage(
195 fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, 195 fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
196 dialog, timestamp, binaryBucket); 196 dialog, timestamp, binaryBucket);
197 197
198 if (m_pendingOffers.ContainsKey(imSessionID)) 198 if (m_pendingOffers.ContainsKey(imSessionID))
199 { 199 {
200 m_log.DebugFormat( 200 m_log.DebugFormat(
201 "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]); 201 "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]);
202 202
203 m_pendingOffers.Remove(imSessionID); 203 m_pendingOffers.Remove(imSessionID);
204 } 204 }
205 else 205 else
206 { 206 {
207 m_log.ErrorFormat( 207 m_log.ErrorFormat(
208 "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", 208 "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline",
209 imSessionID); 209 imSessionID);
210 } 210 }
211 } 211 }
212 } 212 }
213 } 213 }
214 } 214 }
215 } 215 }
216} 216} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs
index 44b3f8b..f8b14d3 100644
--- a/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs
@@ -1,129 +1,129 @@
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
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife; 30using libsecondlife;
31using log4net; 31using log4net;
32using Nini.Config; 32using Nini.Config;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Scenes;
36 36
37namespace OpenSim.Region.Environment.Modules 37namespace 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 public void Initialise(Scene scene, IConfigSource config) 48 public void Initialise(Scene scene, IConfigSource config)
49 { 49 {
50 m_scene = scene; 50 m_scene = scene;
51 m_scene.EventManager.OnNewClient += NewClient; 51 m_scene.EventManager.OnNewClient += NewClient;
52 } 52 }
53 53
54 public void PostInitialise() 54 public void PostInitialise()
55 { 55 {
56 } 56 }
57 57
58 public void Close() 58 public void Close()
59 { 59 {
60 } 60 }
61 61
62 public string Name 62 public string Name
63 { 63 {
64 get { return "AvatarProfilesModule"; } 64 get { return "AvatarProfilesModule"; }
65 } 65 }
66 66
67 public bool IsSharedModule 67 public bool IsSharedModule
68 { 68 {
69 get { return false; } 69 get { return false; }
70 } 70 }
71 71
72 public void NewClient(IClientAPI client) 72 public void NewClient(IClientAPI client)
73 { 73 {
74 client.OnRequestAvatarProperties += RequestAvatarProperty; 74 client.OnRequestAvatarProperties += RequestAvatarProperty;
75 client.OnUpdateAvatarProperties += UpdateAvatarProperties; 75 client.OnUpdateAvatarProperties += UpdateAvatarProperties;
76 } 76 }
77 77
78 public void RemoveClient(IClientAPI client) 78 public void RemoveClient(IClientAPI client)
79 { 79 {
80 client.OnRequestAvatarProperties -= RequestAvatarProperty; 80 client.OnRequestAvatarProperties -= RequestAvatarProperty;
81 client.OnUpdateAvatarProperties -= UpdateAvatarProperties; 81 client.OnUpdateAvatarProperties -= UpdateAvatarProperties;
82 } 82 }
83 83
84 /// <summary> 84 /// <summary>
85 /// 85 ///
86 /// </summary> 86 /// </summary>
87 /// <param name="remoteClient"></param> 87 /// <param name="remoteClient"></param>
88 /// <param name="avatarID"></param> 88 /// <param name="avatarID"></param>
89 public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID) 89 public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID)
90 { 90 {
91 // FIXME: finish adding fields such as url, masking, etc. 91 // FIXME: finish adding fields such as url, masking, etc.
92 LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000"); 92 LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000");
93 UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID); 93 UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID);
94 if (null != profile) 94 if (null != profile)
95 { 95 {
96 remoteClient.SendAvatarProperties(profile.ID, profile.AboutText, 96 remoteClient.SendAvatarProperties(profile.ID, profile.AboutText,
97 Util.ToDateTime(profile.Created).ToString(), 97 Util.ToDateTime(profile.Created).ToString(),
98 String.Empty, profile.FirstLifeAboutText, profile.CanDoMask, 98 String.Empty, profile.FirstLifeAboutText, profile.CanDoMask,
99 profile.FirstLifeImage, profile.Image, String.Empty, partner); 99 profile.FirstLifeImage, profile.Image, String.Empty, partner);
100 } 100 }
101 else 101 else
102 { 102 {
103 m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString()); 103 m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString());
104 } 104 }
105 } 105 }
106 106
107 public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile) 107 public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile)
108 { 108 {
109 UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID); 109 UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID);
110 110
111 // if it's the profile of the user requesting the update, then we change only a few things. 111 // if it's the profile of the user requesting the update, then we change only a few things.
112 if (remoteClient.AgentId.CompareTo(Profile.ID) == 0) 112 if (remoteClient.AgentId.CompareTo(Profile.ID) == 0)
113 { 113 {
114 Profile.Image = newProfile.Image; 114 Profile.Image = newProfile.Image;
115 Profile.FirstLifeImage = newProfile.FirstLifeImage; 115 Profile.FirstLifeImage = newProfile.FirstLifeImage;
116 Profile.AboutText = newProfile.AboutText; 116 Profile.AboutText = newProfile.AboutText;
117 Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText; 117 Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText;
118 } 118 }
119 else 119 else
120 { 120 {
121 return; 121 return;
122 } 122 }
123 if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile)) 123 if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile))
124 { 124 {
125 RequestAvatarProperty(remoteClient, newProfile.ID); 125 RequestAvatarProperty(remoteClient, newProfile.ID);
126 } 126 }
127 } 127 }
128 } 128 }
129} 129} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/AsteriskVoiceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs
index 38c0c1d..0d7de78 100644
--- a/OpenSim/Region/Environment/Modules/AsteriskVoiceModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs
@@ -1,285 +1,285 @@
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
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Reflection; 30using System.Reflection;
31using libsecondlife; 31using libsecondlife;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using Nwc.XmlRpc; 34using Nwc.XmlRpc;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Communications.Cache; 36using OpenSim.Framework.Communications.Cache;
37using OpenSim.Framework.Servers; 37using OpenSim.Framework.Servers;
38using OpenSim.Region.Capabilities; 38using OpenSim.Region.Capabilities;
39using OpenSim.Region.Environment.Interfaces; 39using OpenSim.Region.Environment.Interfaces;
40using OpenSim.Region.Environment.Scenes; 40using OpenSim.Region.Environment.Scenes;
41using Caps=OpenSim.Region.Capabilities.Caps; 41using Caps=OpenSim.Region.Capabilities.Caps;
42 42
43namespace OpenSim.Region.Environment.Modules 43namespace 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 Scene m_scene; 50 private Scene m_scene;
51 private IConfig m_config; 51 private IConfig m_config;
52 private string m_asterisk; 52 private string m_asterisk;
53 private string m_asterisk_password; 53 private string m_asterisk_password;
54 private string m_asterisk_salt; 54 private string m_asterisk_salt;
55 private int m_asterisk_timeout; 55 private int m_asterisk_timeout;
56 private string m_sipDomain; 56 private string m_sipDomain;
57 private string m_confDomain; 57 private string m_confDomain;
58 58
59 private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; 59 private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
60 private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; 60 private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
61 61
62 public void Initialise(Scene scene, IConfigSource config) 62 public void Initialise(Scene scene, IConfigSource config)
63 { 63 {
64 m_scene = scene; 64 m_scene = scene;
65 m_config = config.Configs["AsteriskVoice"]; 65 m_config = config.Configs["AsteriskVoice"];
66 66
67 if (null == m_config) 67 if (null == m_config)
68 { 68 {
69 m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); 69 m_log.Info("[ASTERISKVOICE] no config found, plugin disabled");
70 return; 70 return;
71 } 71 }
72 72
73 if (!m_config.GetBoolean("enabled", false)) 73 if (!m_config.GetBoolean("enabled", false))
74 { 74 {
75 m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); 75 m_log.Info("[ASTERISKVOICE] plugin disabled by configuration");
76 return; 76 return;
77 } 77 }
78 m_log.Info("[ASTERISKVOICE] plugin enabled"); 78 m_log.Info("[ASTERISKVOICE] plugin enabled");
79 79
80 try { 80 try {
81 m_sipDomain = m_config.GetString("sip_domain", String.Empty); 81 m_sipDomain = m_config.GetString("sip_domain", String.Empty);
82 m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); 82 m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain);
83 83
84 m_confDomain = m_config.GetString("conf_domain", String.Empty); 84 m_confDomain = m_config.GetString("conf_domain", String.Empty);
85 m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); 85 m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain);
86 86
87 m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); 87 m_asterisk = m_config.GetString("asterisk_frontend", String.Empty);
88 m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); 88 m_asterisk_password = m_config.GetString("asterisk_password", String.Empty);
89 m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); 89 m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000);
90 m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); 90 m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff");
91 if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); 91 if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter");
92 if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); 92 if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter");
93 m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); 93 m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk);
94 94
95 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 95 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
96 } 96 }
97 catch (Exception e) 97 catch (Exception e)
98 { 98 {
99 m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); 99 m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message);
100 m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); 100 m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString());
101 return; 101 return;
102 } 102 }
103 } 103 }
104 104
105 public void PostInitialise() 105 public void PostInitialise()
106 { 106 {
107 } 107 }
108 108
109 public void Close() 109 public void Close()
110 { 110 {
111 } 111 }
112 112
113 public string Name 113 public string Name
114 { 114 {
115 get { return "AsteriskVoiceModule"; } 115 get { return "AsteriskVoiceModule"; }
116 } 116 }
117 117
118 public bool IsSharedModule 118 public bool IsSharedModule
119 { 119 {
120 get { return false; } 120 get { return false; }
121 } 121 }
122 122
123 public void OnRegisterCaps(LLUUID agentID, Caps caps) 123 public void OnRegisterCaps(LLUUID agentID, Caps caps)
124 { 124 {
125 m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); 125 m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
126 string capsBase = "/CAPS/" + caps.CapsObjectPath; 126 string capsBase = "/CAPS/" + caps.CapsObjectPath;
127 caps.RegisterHandler("ParcelVoiceInfoRequest", 127 caps.RegisterHandler("ParcelVoiceInfoRequest",
128 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, 128 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
129 delegate(string request, string path, string param) 129 delegate(string request, string path, string param)
130 { 130 {
131 return ParcelVoiceInfoRequest(request, path, param, 131 return ParcelVoiceInfoRequest(request, path, param,
132 agentID, caps); 132 agentID, caps);
133 })); 133 }));
134 caps.RegisterHandler("ProvisionVoiceAccountRequest", 134 caps.RegisterHandler("ProvisionVoiceAccountRequest",
135 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, 135 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
136 delegate(string request, string path, string param) 136 delegate(string request, string path, string param)
137 { 137 {
138 return ProvisionVoiceAccountRequest(request, path, param, 138 return ProvisionVoiceAccountRequest(request, path, param,
139 agentID, caps); 139 agentID, caps);
140 })); 140 }));
141 } 141 }
142 142
143 /// <summary> 143 /// <summary>
144 /// Callback for a client request for ParcelVoiceInfo 144 /// Callback for a client request for ParcelVoiceInfo
145 /// </summary> 145 /// </summary>
146 /// <param name="request"></param> 146 /// <param name="request"></param>
147 /// <param name="path"></param> 147 /// <param name="path"></param>
148 /// <param name="param"></param> 148 /// <param name="param"></param>
149 /// <param name="agentID"></param> 149 /// <param name="agentID"></param>
150 /// <param name="caps"></param> 150 /// <param name="caps"></param>
151 /// <returns></returns> 151 /// <returns></returns>
152 public string ParcelVoiceInfoRequest(string request, string path, string param, 152 public string ParcelVoiceInfoRequest(string request, string path, string param,
153 LLUUID agentID, Caps caps) 153 LLUUID agentID, Caps caps)
154 { 154 {
155 // we need to do: 155 // we need to do:
156 // - send channel_uri: as "sip:regionID@m_sipDomain" 156 // - send channel_uri: as "sip:regionID@m_sipDomain"
157 try 157 try
158 { 158 {
159 m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", 159 m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}",
160 request, path, param); 160 request, path, param);
161 161
162 162
163 // setup response to client 163 // setup response to client
164 Hashtable creds = new Hashtable(); 164 Hashtable creds = new Hashtable();
165 creds["channel_uri"] = String.Format("sip:{0}@{1}", 165 creds["channel_uri"] = String.Format("sip:{0}@{1}",
166 m_scene.RegionInfo.RegionID, m_sipDomain); 166 m_scene.RegionInfo.RegionID, m_sipDomain);
167 167
168 string regionName = m_scene.RegionInfo.RegionName; 168 string regionName = m_scene.RegionInfo.RegionName;
169 ScenePresence avatar = m_scene.GetScenePresence(agentID); 169 ScenePresence avatar = m_scene.GetScenePresence(agentID);
170 if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); 170 if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
171 LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 171 LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
172 172
173 LLSDParcelVoiceInfoResponse parcelVoiceInfo = 173 LLSDParcelVoiceInfoResponse parcelVoiceInfo =
174 new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); 174 new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
175 175
176 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); 176 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
177 177
178 178
179 // update region on asterisk-opensim frontend 179 // update region on asterisk-opensim frontend
180 Hashtable requestData = new Hashtable(); 180 Hashtable requestData = new Hashtable();
181 requestData["admin_password"] = m_asterisk_password; 181 requestData["admin_password"] = m_asterisk_password;
182 requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); 182 requestData["region"] = m_scene.RegionInfo.RegionID.ToString();
183 if (!String.IsNullOrEmpty(m_confDomain)) 183 if (!String.IsNullOrEmpty(m_confDomain))
184 { 184 {
185 requestData["region"] += String.Format("@{0}", m_confDomain); 185 requestData["region"] += String.Format("@{0}", m_confDomain);
186 } 186 }
187 187
188 ArrayList SendParams = new ArrayList(); 188 ArrayList SendParams = new ArrayList();
189 SendParams.Add(requestData); 189 SendParams.Add(requestData);
190 XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); 190 XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams);
191 XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); 191 XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout);
192 Hashtable responseData = (Hashtable)updateAccountResponse.Value; 192 Hashtable responseData = (Hashtable)updateAccountResponse.Value;
193 193
194 if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); 194 if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed");
195 195
196 bool success = Convert.ToBoolean((string)responseData["success"]); 196 bool success = Convert.ToBoolean((string)responseData["success"]);
197 if (!success) throw new Exception("region_update failed"); 197 if (!success) throw new Exception("region_update failed");
198 198
199 199
200 m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); 200 m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r);
201 return r; 201 return r;
202 } 202 }
203 catch (Exception e) 203 catch (Exception e)
204 { 204 {
205 m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); 205 m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message);
206 m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); 206 m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString());
207 207
208 return "<llsd>undef</llsd>"; 208 return "<llsd>undef</llsd>";
209 } 209 }
210 } 210 }
211 211
212 /// <summary> 212 /// <summary>
213 /// Callback for a client request for Voice Account Details 213 /// Callback for a client request for Voice Account Details
214 /// </summary> 214 /// </summary>
215 /// <param name="request"></param> 215 /// <param name="request"></param>
216 /// <param name="path"></param> 216 /// <param name="path"></param>
217 /// <param name="param"></param> 217 /// <param name="param"></param>
218 /// <param name="agentID"></param> 218 /// <param name="agentID"></param>
219 /// <param name="caps"></param> 219 /// <param name="caps"></param>
220 /// <returns></returns> 220 /// <returns></returns>
221 public string ProvisionVoiceAccountRequest(string request, string path, string param, 221 public string ProvisionVoiceAccountRequest(string request, string path, string param,
222 LLUUID agentID, Caps caps) 222 LLUUID agentID, Caps caps)
223 { 223 {
224 // we need to 224 // we need to
225 // - get user data from UserProfileCacheService 225 // - get user data from UserProfileCacheService
226 // - generate nonce for user voice account password 226 // - generate nonce for user voice account password
227 // - issue XmlRpc request to asterisk opensim front end: 227 // - issue XmlRpc request to asterisk opensim front end:
228 // + user: base 64 encoded user name (otherwise SL 228 // + user: base 64 encoded user name (otherwise SL
229 // client is unhappy) 229 // client is unhappy)
230 // + password: nonce 230 // + password: nonce
231 // - the XmlRpc call to asteris-opensim was successful: 231 // - the XmlRpc call to asteris-opensim was successful:
232 // send account details back to client 232 // send account details back to client
233 try 233 try
234 { 234 {
235 m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", 235 m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
236 request, path, param); 236 request, path, param);
237 237
238 // get user data & prepare voice account response 238 // get user data & prepare voice account response
239 string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); 239 string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
240 voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); 240 voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
241 241
242 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); 242 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
243 if (null == userInfo) throw new Exception("cannot get user details"); 243 if (null == userInfo) throw new Exception("cannot get user details");
244 244
245 // we generate a nonce everytime 245 // we generate a nonce everytime
246 string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); 246 string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt);
247 LLSDVoiceAccountResponse voiceAccountResponse = 247 LLSDVoiceAccountResponse voiceAccountResponse =
248 new LLSDVoiceAccountResponse(voiceUser, voicePassword); 248 new LLSDVoiceAccountResponse(voiceUser, voicePassword);
249 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); 249 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
250 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); 250 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
251 251
252 252
253 // update user account on asterisk frontend 253 // update user account on asterisk frontend
254 Hashtable requestData = new Hashtable(); 254 Hashtable requestData = new Hashtable();
255 requestData["admin_password"] = m_asterisk_password; 255 requestData["admin_password"] = m_asterisk_password;
256 requestData["username"] = voiceUser; 256 requestData["username"] = voiceUser;
257 if (!String.IsNullOrEmpty(m_sipDomain)) 257 if (!String.IsNullOrEmpty(m_sipDomain))
258 { 258 {
259 requestData["username"] += String.Format("@{0}", m_sipDomain); 259 requestData["username"] += String.Format("@{0}", m_sipDomain);
260 } 260 }
261 requestData["password"] = voicePassword; 261 requestData["password"] = voicePassword;
262 262
263 ArrayList SendParams = new ArrayList(); 263 ArrayList SendParams = new ArrayList();
264 SendParams.Add(requestData); 264 SendParams.Add(requestData);
265 XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); 265 XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams);
266 XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); 266 XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout);
267 Hashtable responseData = (Hashtable)updateAccountResponse.Value; 267 Hashtable responseData = (Hashtable)updateAccountResponse.Value;
268 268
269 if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); 269 if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed");
270 270
271 bool success = Convert.ToBoolean((string)responseData["success"]); 271 bool success = Convert.ToBoolean((string)responseData["success"]);
272 if (!success) throw new Exception("account_update failed"); 272 if (!success) throw new Exception("account_update failed");
273 273
274 return r; 274 return r;
275 } 275 }
276 catch (Exception e) 276 catch (Exception e)
277 { 277 {
278 m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); 278 m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
279 m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); 279 m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString());
280 280
281 return "<llsd>undef</llsd>"; 281 return "<llsd>undef</llsd>";
282 } 282 }
283 } 283 }
284 } 284 }
285} 285} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/VoiceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs
index 106becd..8b7c3d0 100644
--- a/OpenSim/Region/Environment/Modules/VoiceModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs
@@ -1,197 +1,197 @@
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
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Reflection; 30using System.Reflection;
31using libsecondlife; 31using libsecondlife;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications.Cache; 35using OpenSim.Framework.Communications.Cache;
36using OpenSim.Framework.Servers; 36using OpenSim.Framework.Servers;
37using OpenSim.Region.Capabilities; 37using OpenSim.Region.Capabilities;
38using OpenSim.Region.Environment.Interfaces; 38using OpenSim.Region.Environment.Interfaces;
39using OpenSim.Region.Environment.Scenes; 39using OpenSim.Region.Environment.Scenes;
40using Caps=OpenSim.Region.Capabilities.Caps; 40using Caps=OpenSim.Region.Capabilities.Caps;
41 41
42namespace OpenSim.Region.Environment.Modules 42namespace OpenSim.Region.Environment.Modules.Avatar.Voice.SIPVoice
43{ 43{
44 public class VoiceModule : 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 Scene m_scene; 49 private Scene m_scene;
50 private IConfig m_config; 50 private IConfig m_config;
51 private string m_sipDomain; 51 private string m_sipDomain;
52 52
53 private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; 53 private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
54 private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; 54 private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
55 55
56 public void Initialise(Scene scene, IConfigSource config) 56 public void Initialise(Scene scene, IConfigSource config)
57 { 57 {
58 m_scene = scene; 58 m_scene = scene;
59 m_config = config.Configs["Voice"]; 59 m_config = config.Configs["Voice"];
60 60
61 if (null == m_config || !m_config.GetBoolean("enabled", false)) 61 if (null == m_config || !m_config.GetBoolean("enabled", false))
62 { 62 {
63 m_log.Info("[VOICE] plugin disabled"); 63 m_log.Info("[VOICE] plugin disabled");
64 return; 64 return;
65 } 65 }
66 m_log.Info("[VOICE] plugin enabled"); 66 m_log.Info("[VOICE] plugin enabled");
67 67
68 m_sipDomain = m_config.GetString("sip_domain", String.Empty); 68 m_sipDomain = m_config.GetString("sip_domain", String.Empty);
69 if (String.IsNullOrEmpty(m_sipDomain)) 69 if (String.IsNullOrEmpty(m_sipDomain))
70 { 70 {
71 m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); 71 m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration");
72 m_log.Info("[VOICE] plugin disabled"); 72 m_log.Info("[VOICE] plugin disabled");
73 return; 73 return;
74 } 74 }
75 m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); 75 m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain);
76 76
77 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 77 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
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 "VoiceModule"; } 90 get { return "VoiceModule"; }
91 } 91 }
92 92
93 public bool IsSharedModule 93 public bool IsSharedModule
94 { 94 {
95 get { return false; } 95 get { return false; }
96 } 96 }
97 97
98 public void OnRegisterCaps(LLUUID agentID, Caps caps) 98 public void OnRegisterCaps(LLUUID agentID, Caps caps)
99 { 99 {
100 m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); 100 m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
101 string capsBase = "/CAPS/" + caps.CapsObjectPath; 101 string capsBase = "/CAPS/" + caps.CapsObjectPath;
102 caps.RegisterHandler("ParcelVoiceInfoRequest", 102 caps.RegisterHandler("ParcelVoiceInfoRequest",
103 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, 103 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
104 delegate(string request, string path, string param) 104 delegate(string request, string path, string param)
105 { 105 {
106 return ParcelVoiceInfoRequest(request, path, param, 106 return ParcelVoiceInfoRequest(request, path, param,
107 agentID, caps); 107 agentID, caps);
108 })); 108 }));
109 caps.RegisterHandler("ProvisionVoiceAccountRequest", 109 caps.RegisterHandler("ProvisionVoiceAccountRequest",
110 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, 110 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
111 delegate(string request, string path, string param) 111 delegate(string request, string path, string param)
112 { 112 {
113 return ProvisionVoiceAccountRequest(request, path, param, 113 return ProvisionVoiceAccountRequest(request, path, param,
114 agentID, caps); 114 agentID, caps);
115 })); 115 }));
116 } 116 }
117 117
118 /// <summary> 118 /// <summary>
119 /// Callback for a client request for ParcelVoiceInfo 119 /// Callback for a client request for ParcelVoiceInfo
120 /// </summary> 120 /// </summary>
121 /// <param name="request"></param> 121 /// <param name="request"></param>
122 /// <param name="path"></param> 122 /// <param name="path"></param>
123 /// <param name="param"></param> 123 /// <param name="param"></param>
124 /// <param name="agentID"></param> 124 /// <param name="agentID"></param>
125 /// <param name="caps"></param> 125 /// <param name="caps"></param>
126 /// <returns></returns> 126 /// <returns></returns>
127 public string ParcelVoiceInfoRequest(string request, string path, string param, 127 public string ParcelVoiceInfoRequest(string request, string path, string param,
128 LLUUID agentID, Caps caps) 128 LLUUID agentID, Caps caps)
129 { 129 {
130 try 130 try
131 { 131 {
132 m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); 132 m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param);
133 133
134 // FIXME: get the creds from region file or from config 134 // FIXME: get the creds from region file or from config
135 Hashtable creds = new Hashtable(); 135 Hashtable creds = new Hashtable();
136 136
137 creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID.ToString(), m_sipDomain); 137 creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain);
138 138
139 string regionName = m_scene.RegionInfo.RegionName; 139 string regionName = m_scene.RegionInfo.RegionName;
140 ScenePresence avatar = m_scene.GetScenePresence(agentID); 140 ScenePresence avatar = m_scene.GetScenePresence(agentID);
141 if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); 141 if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
142 LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 142 LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
143 143
144 LLSDParcelVoiceInfoResponse parcelVoiceInfo = 144 LLSDParcelVoiceInfoResponse parcelVoiceInfo =
145 new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); 145 new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
146 146
147 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); 147 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
148 m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); 148 m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r);
149 149
150 return r; 150 return r;
151 } 151 }
152 catch (Exception e) 152 catch (Exception e)
153 { 153 {
154 m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); 154 m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString());
155 } 155 }
156 156
157 return null; 157 return null;
158 } 158 }
159 159
160 /// <summary> 160 /// <summary>
161 /// Callback for a client request for Voice Account Details 161 /// Callback for a client request for Voice Account Details
162 /// </summary> 162 /// </summary>
163 /// <param name="request"></param> 163 /// <param name="request"></param>
164 /// <param name="path"></param> 164 /// <param name="path"></param>
165 /// <param name="param"></param> 165 /// <param name="param"></param>
166 /// <param name="agentID"></param> 166 /// <param name="agentID"></param>
167 /// <param name="caps"></param> 167 /// <param name="caps"></param>
168 /// <returns></returns> 168 /// <returns></returns>
169 public string ProvisionVoiceAccountRequest(string request, string path, string param, 169 public string ProvisionVoiceAccountRequest(string request, string path, string param,
170 LLUUID agentID, Caps caps) 170 LLUUID agentID, Caps caps)
171 { 171 {
172 try 172 try
173 { 173 {
174 m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", 174 m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
175 request, path, param); 175 request, path, param);
176 176
177 string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); 177 string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
178 voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); 178 voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
179 179
180 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); 180 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
181 if (null == userInfo) throw new Exception("cannot get user details"); 181 if (null == userInfo) throw new Exception("cannot get user details");
182 182
183 LLSDVoiceAccountResponse voiceAccountResponse = 183 LLSDVoiceAccountResponse voiceAccountResponse =
184 new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); 184 new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash);
185 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); 185 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
186 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); 186 m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
187 return r; 187 return r;
188 } 188 }
189 catch (Exception e) 189 catch (Exception e)
190 { 190 {
191 m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); 191 m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
192 } 192 }
193 193
194 return null; 194 return null;
195 } 195 }
196 } 196 }
197} 197} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/CommanderTestModule.cs b/OpenSim/Region/Environment/Modules/CommanderTestModule.cs
deleted file mode 100644
index a30de73..0000000
--- a/OpenSim/Region/Environment/Modules/CommanderTestModule.cs
+++ /dev/null
@@ -1,89 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Region.Environment.Interfaces;
31using OpenSim.Region.Environment.Modules.ModuleFramework;
32using OpenSim.Region.Environment.Scenes;
33
34namespace OpenSim.Region.Environment.Modules
35{
36 public class CommanderTestModule : IRegionModule, ICommandableModule
37 {
38 Commander m_commander = new Commander("CommanderTest");
39 Scene m_scene;
40
41 #region IRegionModule Members
42
43 public void Initialise(Scene scene, IConfigSource source)
44 {
45 m_scene = scene;
46 }
47
48 private void InterfaceHelloWorld(Object[] args)
49 {
50 Console.WriteLine("Hello World");
51 }
52
53 public void PostInitialise()
54 {
55 Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string");
56 testCommand.AddArgument("world", "Write world here", "string");
57
58 m_commander.RegisterCommand("hello", testCommand);
59
60 // Register me
61 m_scene.RegisterModuleCommander("commandertest", m_commander);
62 }
63
64 public void Close()
65 {
66 }
67
68 public string Name
69 {
70 get { return "CommanderTestModule"; }
71 }
72
73 public bool IsSharedModule
74 {
75 get { return false; }
76 }
77
78 #endregion
79
80 #region ICommandableModule Members
81
82 public ICommander CommandInterface
83 {
84 get { throw new NotImplementedException(); }
85 }
86
87 #endregion
88 }
89}
diff --git a/OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs b/OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs
deleted file mode 100644
index 713b46a..0000000
--- a/OpenSim/Region/Environment/Modules/Communications/Interregion/IInterregionModule.cs
+++ /dev/null
@@ -1,15 +0,0 @@
1using OpenSim.Framework;
2using OpenSim.Region.Environment.Scenes;
3
4namespace OpenSim.Region.Environment.Modules.Communications.Interregion
5{
6 public interface IInterregionModule
7 {
8 void RegisterMethod<T>(T e);
9 bool HasInterface<T>(Location loc);
10 T RequestInterface<T>(Location loc);
11 T[] RequestInterface<T>();
12 Location GetLocationByDirection(Scene scene, InterregionModule.Direction dir);
13 void internal_CreateRemotingObjects();
14 }
15} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs b/OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs
deleted file mode 100644
index 8d040c4..0000000
--- a/OpenSim/Region/Environment/Modules/Communications/Interregion/InterregionModule.cs
+++ /dev/null
@@ -1,174 +0,0 @@
1using System;
2using System.Collections.Generic;
3using System.Runtime.Remoting;
4using System.Runtime.Remoting.Channels;
5using System.Runtime.Remoting.Channels.Tcp;
6using Nini.Config;
7using OpenSim.Framework;
8using OpenSim.Region.Environment.Interfaces;
9using OpenSim.Region.Environment.Scenes;
10
11namespace OpenSim.Region.Environment.Modules.Communications.Interregion
12{
13 public class InterregionModule : IInterregionModule, IRegionModule
14 {
15 #region Direction enum
16
17 public enum Direction
18 {
19 North,
20 NorthEast,
21 East,
22 SouthEast,
23 South,
24 SouthWest,
25 West,
26 NorthWest
27 }
28
29 #endregion
30
31 private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
32 private readonly List<Location> m_myLocations = new List<Location>();
33
34 private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>();
35 private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>();
36 private IConfigSource m_config;
37 private RemotingObject m_myRemote;
38
39 private Object m_lockObject = new object();
40 private TcpChannel m_tcpChannel;
41 private int m_tcpPort = 10101;
42 private bool m_enabled = false;
43
44 #region IRegionModule Members
45
46 //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
47 public void Initialise(Scene scene, IConfigSource source)
48 {
49 if (m_enabled)
50 {
51 m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX,
52 (int) scene.RegionInfo.RegionLocY));
53 m_config = source;
54
55 scene.RegisterModuleInterface<IInterregionModule>(this);
56 }
57 }
58
59 //TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
60 public void PostInitialise()
61 {
62 if (m_enabled)
63 {
64 try
65 {
66 m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort);
67 }
68 catch
69 {
70 }
71
72 internal_CreateRemotingObjects();
73 }
74 }
75
76 public void Close()
77 {
78 ChannelServices.UnregisterChannel(m_tcpChannel);
79 }
80
81 public string Name
82 {
83 get { return "InterregionModule"; }
84 }
85
86 public bool IsSharedModule
87 {
88 get { return true; }
89 }
90
91 #endregion
92
93 public void internal_CreateRemotingObjects()
94 {
95 lock (m_lockObject)
96 {
97 if (m_tcpChannel == null)
98 {
99 m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray());
100 m_tcpChannel = new TcpChannel(m_tcpPort);
101
102 ChannelServices.RegisterChannel(m_tcpChannel, false);
103 RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject));
104 }
105 }
106 }
107
108 public void RegisterRemoteRegion(string uri)
109 {
110 RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri));
111 }
112
113 private void RegisterRemotingInterface(RemotingObject remote)
114 {
115 Location[] locs = remote.GetLocations();
116 string[] interfaces = remote.GetInterfaces();
117 foreach (Location loc in locs)
118 {
119 m_neighbourInterfaces[loc] = interfaces;
120 m_neighbourRemote[loc] = remote;
121 }
122 }
123
124 public void RegisterMethod<T>(T e)
125 {
126 m_interfaces[typeof (T)] = e;
127 }
128
129 public bool HasInterface<T>(Location loc)
130 {
131 foreach (string val in m_neighbourInterfaces[loc])
132 {
133 if (val == typeof (T).FullName)
134 {
135 return true;
136 }
137 }
138 return false;
139 }
140
141 public T RequestInterface<T>(Location loc)
142 {
143 if (m_neighbourRemote.ContainsKey(loc))
144 {
145 return m_neighbourRemote[loc].RequestInterface<T>();
146 }
147 else
148 {
149 throw new IndexOutOfRangeException("No neighbour availible at that location");
150 }
151 }
152
153 public T[] RequestInterface<T>()
154 {
155 List<T> m_t = new List<T>();
156 foreach (RemotingObject remote in m_neighbourRemote.Values)
157 {
158 try
159 {
160 m_t.Add(remote.RequestInterface<T>());
161 }
162 catch (NotSupportedException)
163 {
164 }
165 }
166 return m_t.ToArray();
167 }
168
169 public Location GetLocationByDirection(Scene scene, Direction dir)
170 {
171 return new Location(0, 0);
172 }
173 }
174} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs b/OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs
deleted file mode 100644
index a735677..0000000
--- a/OpenSim/Region/Environment/Modules/Communications/Interregion/RemotingObject.cs
+++ /dev/null
@@ -1,50 +0,0 @@
1using System;
2using System.Collections.Generic;
3using OpenSim.Framework;
4
5namespace OpenSim.Region.Environment.Modules.Communications.Interregion
6{
7 public class RemotingObject : MarshalByRefObject
8 {
9 private readonly Location[] m_coords;
10 private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
11
12 public RemotingObject(Dictionary<Type, Object> myInterfaces, Location[] coords)
13 {
14 m_interfaces = myInterfaces;
15 m_coords = coords;
16 }
17
18 public Location[] GetLocations()
19 {
20 return (Location[]) m_coords.Clone();
21 }
22
23 public string[] GetInterfaces()
24 {
25 string[] interfaces = new string[m_interfaces.Count];
26 int i = 0;
27
28 foreach (KeyValuePair<Type, object> pair in m_interfaces)
29 {
30 interfaces[i++] = pair.Key.FullName;
31 }
32
33 return interfaces;
34 }
35
36 /// <summary>
37 /// Returns a registered interface availible to neighbouring regions.
38 /// </summary>
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>
41 /// <remarks>All registered interfaces <b>MUST</b> inherit from MarshalByRefObject and use only serialisable types.</remarks>
42 public T RequestInterface<T>()
43 {
44 if (m_interfaces.ContainsKey(typeof (T)))
45 return (T) m_interfaces[typeof (T)];
46
47 throw new NotSupportedException("No such interface registered.");
48 }
49 }
50} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/EmailModule.cs b/OpenSim/Region/Environment/Modules/EmailModule.cs
deleted file mode 100644
index b629f4c..0000000
--- a/OpenSim/Region/Environment/Modules/EmailModule.cs
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Region.Environment.Modules
29{
30 internal class EmailModule
31 {
32 }
33}
diff --git a/OpenSim/Region/Environment/Modules/ExportSerialiser/ExportSerialisationModule.cs b/OpenSim/Region/Environment/Modules/ExportSerialiser/ExportSerialisationModule.cs
deleted file mode 100644
index 91770af..0000000
--- a/OpenSim/Region/Environment/Modules/ExportSerialiser/ExportSerialisationModule.cs
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using Nini.Config;
32using OpenSim.Region.Environment.Interfaces;
33using OpenSim.Region.Environment.Modules.ModuleFramework;
34using OpenSim.Region.Environment.Scenes;
35
36namespace OpenSim.Region.Environment.Modules.ExportSerialiser
37{
38 public class ExportSerialisationModule : IRegionModule, IRegionSerialiser
39 {
40 private Commander m_commander = new Commander("Export");
41 private List<Scene> m_regions = new List<Scene>();
42 private string m_savedir = "exports" + "/";
43 private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>();
44
45 #region IRegionModule Members
46
47 public void Initialise(Scene scene, IConfigSource source)
48 {
49 scene.RegisterModuleCommander("Export", m_commander);
50 scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
51 scene.RegisterModuleInterface<IRegionSerialiser>(this);
52
53 lock (m_regions)
54 {
55 m_regions.Add(scene);
56 }
57 }
58
59 public void PostInitialise()
60 {
61 lock (m_serialisers)
62 {
63 m_serialisers.Add(new SerialiseTerrain());
64 m_serialisers.Add(new SerialiseObjects());
65 }
66
67 LoadCommanderCommands();
68 }
69
70 public void Close()
71 {
72 m_regions.Clear();
73 }
74
75 public string Name
76 {
77 get { return "ExportSerialisationModule"; }
78 }
79
80 public bool IsSharedModule
81 {
82 get { return true; }
83 }
84
85 #endregion
86
87 #region IRegionSerialiser Members
88
89 public List<string> SerialiseRegion(Scene scene, string saveDir)
90 {
91 List<string> results = new List<string>();
92
93 if (!Directory.Exists(saveDir))
94 {
95 Directory.CreateDirectory(saveDir);
96 }
97
98 lock (m_serialisers)
99 {
100 foreach (IFileSerialiser serialiser in m_serialisers)
101 {
102 results.Add(serialiser.WriteToFile(scene, saveDir));
103 }
104 }
105
106 TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT");
107 regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName);
108 regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString());
109 regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString());
110 regionInfoWriter.WriteLine("Serialise Version: 0.1");
111 regionInfoWriter.Close();
112
113 TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest");
114 foreach (string line in results)
115 {
116 manifestWriter.WriteLine(line);
117 }
118 manifestWriter.Close();
119
120 return results;
121 }
122
123 #endregion
124
125 private void EventManager_OnPluginConsole(string[] args)
126 {
127 if (args[0] == "export")
128 {
129 string[] tmpArgs = new string[args.Length - 2];
130 int i = 0;
131 for (i = 2; i < args.Length; i++)
132 tmpArgs[i - 2] = args[i];
133
134 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
135 }
136 }
137
138 private void InterfaceSaveRegion(Object[] args)
139 {
140 foreach (Scene region in m_regions)
141 {
142 if (region.RegionInfo.RegionName == (string) args[0])
143 {
144 List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
145 }
146 }
147 }
148
149 private void InterfaceSaveAllRegions(Object[] args)
150 {
151 foreach (Scene region in m_regions)
152 {
153 List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
154 }
155 }
156
157 private void LoadCommanderCommands()
158 {
159 Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory.");
160 serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String");
161
162 Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory.");
163
164 m_commander.RegisterCommand("save", serialiseSceneCommand);
165 m_commander.RegisterCommand("save-all", serialiseAllScenesCommand);
166 }
167 }
168} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ExportSerialiser/IFileSerialiser.cs b/OpenSim/Region/Environment/Modules/ExportSerialiser/IFileSerialiser.cs
deleted file mode 100644
index 77a418f..0000000
--- a/OpenSim/Region/Environment/Modules/ExportSerialiser/IFileSerialiser.cs
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Scenes;
29
30namespace OpenSim.Region.Environment.Modules.ExportSerialiser
31{
32 internal interface IFileSerialiser
33 {
34 string WriteToFile(Scene scene, string dir);
35 }
36} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ExportSerialiser/IRegionSerialiser.cs b/OpenSim/Region/Environment/Modules/ExportSerialiser/IRegionSerialiser.cs
deleted file mode 100644
index e1721ff..0000000
--- a/OpenSim/Region/Environment/Modules/ExportSerialiser/IRegionSerialiser.cs
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using OpenSim.Region.Environment.Scenes;
30
31namespace OpenSim.Region.Environment.Modules.ExportSerialiser
32{
33 public interface IRegionSerialiser
34 {
35 List<string> SerialiseRegion(Scene scene, string saveDir);
36 }
37} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseObjects.cs b/OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseObjects.cs
deleted file mode 100644
index 277370d..0000000
--- a/OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseObjects.cs
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using System.IO;
30using System.IO.Compression;
31using System.Text;
32using System.Xml;
33using OpenSim.Region.Environment.Scenes;
34
35namespace OpenSim.Region.Environment.Modules.ExportSerialiser
36{
37 internal class SerialiseObjects : IFileSerialiser
38 {
39 #region IFileSerialiser Members
40
41 public string WriteToFile(Scene scene, string dir)
42 {
43 string targetFileName = dir + "objects.xml";
44
45 SaveSerialisedToFile(targetFileName, scene);
46
47 return "objects.xml";
48 }
49
50 #endregion
51
52 public void SaveSerialisedToFile(string fileName, Scene scene)
53 {
54 string xmlstream = GetObjectXml(scene);
55
56 MemoryStream stream = ReformatXmlString(xmlstream);
57
58 stream.Seek(0, SeekOrigin.Begin);
59 CreateXmlFile(stream, fileName);
60
61 stream.Seek(0, SeekOrigin.Begin);
62 CreateCompressedXmlFile(stream, fileName);
63 }
64
65 private static MemoryStream ReformatXmlString(string xmlstream)
66 {
67 MemoryStream stream = new MemoryStream();
68 XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8);
69 XmlDocument doc = new XmlDocument();
70
71 doc.LoadXml(xmlstream);
72 formatter.Formatting = Formatting.Indented;
73 doc.WriteContentTo(formatter);
74 formatter.Flush();
75 return stream;
76 }
77
78 private static string GetObjectXml(Scene scene)
79 {
80 string xmlstream = "<scene>";
81
82 List<EntityBase> EntityList = scene.GetEntities();
83 List<string> EntityXml = new List<string>();
84
85 foreach (EntityBase ent in EntityList)
86 {
87 if (ent is SceneObjectGroup)
88 {
89 EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2());
90 }
91 }
92 EntityXml.Sort();
93
94 foreach (string xml in EntityXml)
95 xmlstream += xml;
96
97 xmlstream += "</scene>";
98 return xmlstream;
99 }
100
101 private static void CreateXmlFile(MemoryStream xmlStream, string fileName)
102 {
103 FileStream objectsFile = new FileStream(fileName, FileMode.Create);
104
105 xmlStream.WriteTo(objectsFile);
106 objectsFile.Flush();
107 objectsFile.Close();
108 }
109
110 private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName)
111 {
112 #region GZip Compressed Version
113 FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create);
114 MemoryStream gzipMSStream = new MemoryStream();
115 GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress);
116 xmlStream.WriteTo(gzipStream);
117 gzipMSStream.WriteTo(objectsFileCompressed);
118 objectsFileCompressed.Flush();
119 objectsFileCompressed.Close();
120 #endregion
121 }
122 }
123} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseTerrain.cs b/OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseTerrain.cs
deleted file mode 100644
index c4790c2..0000000
--- a/OpenSim/Region/Environment/Modules/ExportSerialiser/SerialiseTerrain.cs
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Modules.Terrain;
29using OpenSim.Region.Environment.Modules.Terrain.FileLoaders;
30using OpenSim.Region.Environment.Scenes;
31
32namespace OpenSim.Region.Environment.Modules.ExportSerialiser
33{
34 internal class SerialiseTerrain : IFileSerialiser
35 {
36 #region IFileSerialiser Members
37
38 public string WriteToFile(Scene scene, string dir)
39 {
40 ITerrainLoader fileSystemExporter = new RAW32();
41 string targetFileName = dir + "heightmap.r32";
42
43 lock (scene.Heightmap)
44 {
45 fileSystemExporter.SaveFile(targetFileName, scene.Heightmap);
46 }
47
48 return "heightmap.r32";
49 }
50
51 #endregion
52 }
53} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/LandManagement/LandChannel.cs b/OpenSim/Region/Environment/Modules/LandManagement/LandChannel.cs
deleted file mode 100644
index e2414b0..0000000
--- a/OpenSim/Region/Environment/Modules/LandManagement/LandChannel.cs
+++ /dev/null
@@ -1,1008 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using Axiom.Math;
31using libsecondlife;
32using libsecondlife.Packets;
33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Physics.Manager;
37
38namespace OpenSim.Region.Environment.Modules.LandManagement
39{
40 public class LandChannel : ILandChannel
41 {
42 #region Constants
43
44 //Land types set with flags in ParcelOverlay.
45 //Only one of these can be used.
46 public const byte LAND_TYPE_PUBLIC = (byte)0; //Equals 00000000
47 public const byte LAND_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001
48 public const byte LAND_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010
49 public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011
50 public const byte LAND_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100
51 public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101
52
53 //Flags that when set, a border on the given side will be placed
54 //NOTE: North and East is assumable by the west and south sides (if land to east has a west border, then I have an east border; etc)
55 //This took forever to figure out -- jeesh. /blame LL for even having to send these
56 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000
57 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000
58
59 //RequestResults (I think these are right, they seem to work):
60 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
61 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
62
63 //ParcelSelectObjects
64 public const int LAND_SELECT_OBJECTS_OWNER = 2;
65 public const int LAND_SELECT_OBJECTS_GROUP = 4;
66 public const int LAND_SELECT_OBJECTS_OTHER = 8;
67
68 //These are other constants. Yay!
69 public const int START_LAND_LOCAL_ID = 1;
70
71 public const float BAN_LINE_SAFETY_HIEGHT = 100;
72
73 #endregion
74
75 private Scene m_scene;
76
77 private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>();
78 private int lastLandLocalID = START_LAND_LOCAL_ID - 1;
79 private int[,] landIDList = new int[64, 64];
80
81 private bool landPrimCountTainted = false;
82
83 private bool m_allowedForcefulBans = true;
84 public bool allowedForcefulBans
85 {
86 get
87 {
88 return m_allowedForcefulBans;
89 }
90 set
91 {
92 m_allowedForcefulBans = value;
93 }
94 }
95
96 public LandChannel(Scene scene)
97 {
98 m_scene = scene;
99 landIDList.Initialize();
100 }
101 #region Land Object From Storage Functions
102
103 public void IncomingLandObjectsFromStorage(List<LandData> data)
104 {
105 for (int i = 0; i < data.Count; i++)
106 {
107 //try
108 //{
109 IncomingLandObjectFromStorage(data[i]);
110 //}
111 //catch (Exception ex)
112 //{
113 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString());
114 //throw ex;
115 //}
116 }
117 //foreach (LandData parcel in data)
118 //{
119 // IncomingLandObjectFromStorage(parcel);
120 //}
121 }
122
123 public void IncomingLandObjectFromStorage(LandData data)
124 {
125 ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene);
126 new_land.landData = data.Copy();
127 new_land.setLandBitmapFromByteArray();
128 addLandObject(new_land);
129 }
130
131 public void NoLandDataFromStorage()
132 {
133 resetSimLandObjects();
134 }
135
136 #endregion
137
138 #region Parcel Add/Remove/Get/Create
139
140 /// <summary>
141 /// Creates a basic Parcel object without an owner (a zeroed key)
142 /// </summary>
143 /// <returns></returns>
144 public ILandObject createBaseLand()
145 {
146 return new LandObject(LLUUID.Zero, false, m_scene);
147 }
148
149 /// <summary>
150 /// Adds a land object to the stored list and adds them to the landIDList to what they own
151 /// </summary>
152 /// <param name="new_land">The land object being added</param>
153 public ILandObject addLandObject(ILandObject new_land)
154 {
155 lastLandLocalID++;
156 new_land.landData.localID = lastLandLocalID;
157 landList.Add(lastLandLocalID, (LandObject)new_land.Copy());
158
159
160 bool[,] landBitmap = new_land.getLandBitmap();
161 int x, y;
162 for (x = 0; x < 64; x++)
163 {
164 for (y = 0; y < 64; y++)
165 {
166 if (landBitmap[x, y])
167 {
168 landIDList[x, y] = lastLandLocalID;
169 }
170 }
171 }
172 landList[lastLandLocalID].forceUpdateLandInfo();
173 m_scene.EventManager.TriggerLandObjectAdded(new_land);
174 return new_land;
175 }
176
177 /// <summary>
178 /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList
179 /// </summary>
180 /// <param name="local_id">Land.localID of the peice of land to remove.</param>
181 public void removeLandObject(int local_id)
182 {
183 int x, y;
184 for (x = 0; x < 64; x++)
185 {
186 for (y = 0; y < 64; y++)
187 {
188 if (landIDList[x, y] == local_id)
189 {
190 return;
191 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y);
192 }
193 }
194 }
195
196 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID);
197 landList.Remove(local_id);
198 }
199
200 public void updateLandObject(int local_id, LandData newData)
201 {
202 if (landList.ContainsKey(local_id))
203 {
204 landList[local_id].landData = newData.Copy();
205 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landList[local_id]);
206 }
207 }
208
209 private void performFinalLandJoin(ILandObject master, ILandObject slave)
210 {
211 int x, y;
212 bool[,] landBitmapSlave = slave.getLandBitmap();
213 for (x = 0; x < 64; x++)
214 {
215 for (y = 0; y < 64; y++)
216 {
217 if (landBitmapSlave[x, y])
218 {
219 landIDList[x, y] = master.landData.localID;
220 }
221 }
222 }
223
224 removeLandObject(slave.landData.localID);
225 updateLandObject(master.landData.localID, master.landData);
226 }
227
228 /// <summary>
229 /// Get the land object at the specified point
230 /// </summary>
231 /// <param name="x">Value between 0 - 256 on the x axis of the point</param>
232 /// <param name="y">Value between 0 - 256 on the y axis of the point</param>
233 /// <returns>Land object at the point supplied</returns>
234 public ILandObject getLandObject(float x_float, float y_float)
235 {
236 int x;
237 int y;
238
239 try
240 {
241 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0)));
242 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0)));
243 }
244 catch (OverflowException)
245 {
246 return null;
247 }
248
249 if (x >= 64 || y >= 64 || x < 0 || y < 0)
250 {
251 return null;
252 }
253 else
254 {
255 return landList[landIDList[x, y]];
256 }
257 }
258
259 public ILandObject getLandObject(int parcelLocalID)
260 {
261 lock (landList)
262 {
263 if (landList.ContainsKey(parcelLocalID))
264 {
265 return landList[parcelLocalID];
266 }
267 }
268 return null;
269 }
270
271 public ILandObject getLandObject(int x, int y)
272 {
273 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
274 {
275 // These exceptions here will cause a lot of complaints from the users specifically because
276 // they happen every time at border crossings
277 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
278 }
279 else
280 {
281 return landList[landIDList[x / 4, y / 4]];
282 }
283 }
284
285 #endregion
286
287 #region Parcel Modification
288
289 /// <summary>
290 /// Subdivides a piece of land
291 /// </summary>
292 /// <param name="start_x">West Point</param>
293 /// <param name="start_y">South Point</param>
294 /// <param name="end_x">East Point</param>
295 /// <param name="end_y">North Point</param>
296 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param>
297 /// <returns>Returns true if successful</returns>
298 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
299 {
300 //First, lets loop through the points and make sure they are all in the same peice of land
301 //Get the land object at start
302 ILandObject startLandObject = null;
303 try
304 {
305 startLandObject = getLandObject(start_x, start_y);
306 }
307 catch (Exception)
308 {
309 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y);
310 }
311 if (startLandObject == null) return false; //No such land object at the beginning
312
313 //Loop through the points
314 try
315 {
316 int totalX = end_x - start_x;
317 int totalY = end_y - start_y;
318 int x, y;
319 for (y = 0; y < totalY; y++)
320 {
321 for (x = 0; x < totalX; x++)
322 {
323 ILandObject tempLandObject = getLandObject(start_x + x, start_y + y);
324 if (tempLandObject == null) return false; //No such land object at that point
325 if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no
326 }
327 }
328 }
329 catch (Exception)
330 {
331 return false; //Exception. For now, lets skip subdivision
332 }
333
334 //If we are still here, then they are subdividing within one piece of land
335 //Check owner
336 if (startLandObject.landData.ownerID != attempting_user_id)
337 {
338 return false; //They cant do this!
339 }
340
341 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
342 ILandObject newLand = startLandObject.Copy();
343 newLand.landData.landName = "Subdivision of " + newLand.landData.landName;
344 newLand.landData.globalID = LLUUID.Random();
345
346 newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y));
347
348 //Now, lets set the subdivision area of the original to false
349 int startLandObjectIndex = startLandObject.landData.localID;
350 landList[startLandObjectIndex].setLandBitmap(
351 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false));
352 landList[startLandObjectIndex].forceUpdateLandInfo();
353
354 setPrimsTainted();
355
356 //Now add the new land object
357 ILandObject result = addLandObject(newLand);
358 updateLandObject(startLandObject.landData.localID, startLandObject.landData);
359 result.sendLandUpdateToAvatarsOverMe();
360
361
362 return true;
363 }
364
365 /// <summary>
366 /// Join 2 land objects together
367 /// </summary>
368 /// <param name="start_x">x value in first piece of land</param>
369 /// <param name="start_y">y value in first piece of land</param>
370 /// <param name="end_x">x value in second peice of land</param>
371 /// <param name="end_y">y value in second peice of land</param>
372 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param>
373 /// <returns>Returns true if successful</returns>
374 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
375 {
376 end_x -= 4;
377 end_y -= 4;
378
379 List<ILandObject> selectedLandObjects = new List<ILandObject>();
380 int stepXSelected = 0;
381 int stepYSelected = 0;
382 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
383 {
384 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
385 {
386 ILandObject p = null;
387 try
388 {
389 p = getLandObject(stepXSelected, stepYSelected);
390 }
391 catch (Exception)
392 {
393 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected);
394 }
395 if (p != null)
396 {
397 if (!selectedLandObjects.Contains(p))
398 {
399 selectedLandObjects.Add(p);
400 }
401 }
402 }
403 }
404 ILandObject masterLandObject = selectedLandObjects[0];
405 selectedLandObjects.RemoveAt(0);
406
407
408 if (selectedLandObjects.Count < 1)
409 {
410 return false; //Only one piece of land selected
411 }
412 if (masterLandObject.landData.ownerID != attempting_user_id)
413 {
414 return false; //Not the same owner
415 }
416 foreach (ILandObject p in selectedLandObjects)
417 {
418 if (p.landData.ownerID != masterLandObject.landData.ownerID)
419 {
420 return false; //Over multiple users. TODO: make this just ignore this piece of land?
421 }
422 }
423 foreach (ILandObject slaveLandObject in selectedLandObjects)
424 {
425 landList[masterLandObject.landData.localID].setLandBitmap(
426 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap()));
427 performFinalLandJoin(masterLandObject, slaveLandObject);
428 }
429
430
431 setPrimsTainted();
432
433 masterLandObject.sendLandUpdateToAvatarsOverMe();
434
435 return true;
436 }
437
438 public void resetAllLandPrimCounts()
439 {
440 foreach (LandObject p in landList.Values)
441 {
442 p.resetLandPrimCounts();
443 }
444 }
445
446 public void setPrimsTainted()
447 {
448 landPrimCountTainted = true;
449 }
450
451 public bool isLandPrimCountTainted()
452 {
453 return landPrimCountTainted;
454 }
455
456 public void addPrimToLandPrimCounts(SceneObjectGroup obj)
457 {
458 LLVector3 position = obj.AbsolutePosition;
459 ILandObject landUnderPrim = getLandObject(position.X, position.Y);
460 if (landUnderPrim != null)
461 {
462 landUnderPrim.addPrimToCount(obj);
463 }
464 }
465
466 public void removePrimFromLandPrimCounts(SceneObjectGroup obj)
467 {
468 foreach (LandObject p in landList.Values)
469 {
470 p.removePrimFromCount(obj);
471 }
472 }
473
474 public void finalizeLandPrimCountUpdate()
475 {
476 //Get Simwide prim count for owner
477 Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>();
478 foreach (LandObject p in landList.Values)
479 {
480 if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID))
481 {
482 List<LandObject> tempList = new List<LandObject>();
483 tempList.Add(p);
484 landOwnersAndParcels.Add(p.landData.ownerID, tempList);
485 }
486 else
487 {
488 landOwnersAndParcels[p.landData.ownerID].Add(p);
489 }
490 }
491
492 foreach (LLUUID owner in landOwnersAndParcels.Keys)
493 {
494 int simArea = 0;
495 int simPrims = 0;
496 foreach (LandObject p in landOwnersAndParcels[owner])
497 {
498 simArea += p.landData.area;
499 simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims +
500 p.landData.selectedPrims;
501 }
502
503 foreach (LandObject p in landOwnersAndParcels[owner])
504 {
505 p.landData.simwideArea = simArea;
506 p.landData.simwidePrims = simPrims;
507 }
508 }
509 }
510
511 public void updateLandPrimCounts()
512 {
513 foreach (EntityBase obj in m_scene.Entities.Values)
514 {
515 if (obj is SceneObjectGroup)
516 {
517 m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup)obj);
518 }
519 }
520 }
521
522 public void performParcelPrimCountUpdate()
523 {
524 resetAllLandPrimCounts();
525 m_scene.EventManager.TriggerParcelPrimCountUpdate();
526 finalizeLandPrimCountUpdate();
527 landPrimCountTainted = false;
528 }
529 #endregion
530
531 #region Parcel Updating
532
533 /// <summary>
534 /// Where we send the ParcelOverlay packet to the client
535 /// </summary>
536 /// <param name="remote_client">The object representing the client</param>
537 public void sendParcelOverlay(IClientAPI remote_client)
538 {
539 const int LAND_BLOCKS_PER_PACKET = 1024;
540 int x, y = 0;
541 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
542 int byteArrayCount = 0;
543 int sequenceID = 0;
544 ParcelOverlayPacket packet;
545
546 for (y = 0; y < 64; y++)
547 {
548 for (x = 0; x < 64; x++)
549 {
550 byte tempByte = (byte)0; //This represents the byte for the current 4x4
551 ILandObject currentParcelBlock = null;
552
553 try
554 {
555 currentParcelBlock = getLandObject(x * 4, y * 4);
556 }
557 catch (Exception)
558 {
559 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4));
560 }
561
562
563 if (currentParcelBlock != null)
564 {
565 if (currentParcelBlock.landData.ownerID == remote_client.AgentId)
566 {
567 //Owner Flag
568 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER);
569 }
570 else if (currentParcelBlock.landData.salePrice > 0 &&
571 (currentParcelBlock.landData.authBuyerID == LLUUID.Zero ||
572 currentParcelBlock.landData.authBuyerID == remote_client.AgentId))
573 {
574 //Sale Flag
575 tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE);
576 }
577 else if (currentParcelBlock.landData.ownerID == LLUUID.Zero)
578 {
579 //Public Flag
580 tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC);
581 }
582 else
583 {
584 //Other Flag
585 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER);
586 }
587
588
589 //Now for border control
590 try
591 {
592 ILandObject westParcel = null;
593 ILandObject southParcel = null;
594 if (x > 0)
595 {
596 westParcel = getLandObject((x - 1) * 4, y * 4);
597 }
598 if (y > 0)
599 {
600 southParcel = getLandObject(x * 4, (y - 1) * 4);
601 }
602
603 if (x == 0)
604 {
605 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
606 }
607 else if (westParcel != null && westParcel != currentParcelBlock)
608 {
609 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
610 }
611
612 if (y == 0)
613 {
614 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
615 }
616 else if (southParcel != null && southParcel != currentParcelBlock)
617 {
618 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
619 }
620
621 byteArray[byteArrayCount] = tempByte;
622 byteArrayCount++;
623 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
624 {
625 byteArrayCount = 0;
626 packet = (ParcelOverlayPacket)PacketPool.Instance.GetPacket(PacketType.ParcelOverlay);
627 packet.ParcelData.Data = byteArray;
628 packet.ParcelData.SequenceID = sequenceID;
629 remote_client.OutPacket((Packet)packet, ThrottleOutPacketType.Task);
630 sequenceID++;
631 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
632 }
633 }
634 catch (Exception)
635 {
636 //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message);
637 }
638 }
639 }
640 }
641 }
642
643 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
644 bool snap_selection, IClientAPI remote_client)
645 {
646 //Get the land objects within the bounds
647 List<ILandObject> temp = new List<ILandObject>();
648 int x, y, i;
649 int inc_x = end_x - start_x;
650 int inc_y = end_y - start_y;
651 for (x = 0; x < inc_x; x++)
652 {
653 for (y = 0; y < inc_y; y++)
654 {
655
656 ILandObject currentParcel = null;
657 try
658 {
659 currentParcel = getLandObject(start_x + x, start_y + y);
660 }
661 catch (Exception)
662 {
663 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y));
664 }
665 if (currentParcel != null)
666 {
667 if (!temp.Contains(currentParcel))
668 {
669 currentParcel.forceUpdateLandInfo();
670 temp.Add(currentParcel);
671 }
672 }
673 }
674 }
675
676 int requestResult = LAND_RESULT_SINGLE;
677 if (temp.Count > 1)
678 {
679 requestResult = LAND_RESULT_MULTIPLE;
680 }
681
682 for (i = 0; i < temp.Count; i++)
683 {
684 temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
685 }
686
687
688 sendParcelOverlay(remote_client);
689 }
690
691 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
692 {
693 if (landList.ContainsKey(packet.ParcelData.LocalID))
694 {
695 landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client);
696
697 }
698 }
699
700 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
701 {
702 subdivide(west, south, east, north, remote_client.AgentId);
703 }
704
705 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
706 {
707 join(west, south, east, north, remote_client.AgentId);
708 }
709
710 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client)
711 {
712 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client);
713 }
714
715 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client)
716 {
717 landList[local_id].sendLandObjectOwners(remote_client);
718 }
719
720 #endregion
721
722 /// <summary>
723 /// Resets the sim to the default land object (full sim piece of land owned by the default user)
724 /// </summary>
725 public void resetSimLandObjects()
726 {
727 //Remove all the land objects in the sim and add a blank, full sim land object set to public
728 landList.Clear();
729 lastLandLocalID = START_LAND_LOCAL_ID - 1;
730 landIDList.Initialize();
731
732 ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene);
733
734 fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
735 fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
736
737 addLandObject(fullSimParcel);
738 }
739
740 public List<ILandObject> parcelsNearPoint(LLVector3 position)
741 {
742 List<ILandObject> parcelsNear = new List<ILandObject>();
743 int x, y;
744 for (x = -4; x <= 4; x += 4)
745 {
746 for (y = -4; y <= 4; y += 4)
747 {
748 ILandObject check = getLandObject(position.X + x, position.Y + y);
749 if (check != null)
750 {
751 if (!parcelsNear.Contains(check))
752 {
753 parcelsNear.Add(check);
754 }
755 }
756 }
757 }
758
759 return parcelsNear;
760 }
761
762 public void sendYouAreBannedNotice(ScenePresence avatar)
763 {
764 if (allowedForcefulBans)
765 {
766 avatar.ControllingClient.SendAlertMessage(
767 "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers");
768
769 avatar.PhysicsActor.Position =
770 new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y,
771 avatar.lastKnownAllowedPosition.z);
772 avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0);
773 }
774 else
775 {
776 avatar.ControllingClient.SendAlertMessage(
777 "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");
778 }
779 }
780
781 public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
782 {
783 if (m_scene.RegionInfo.RegionID == regionID)
784 {
785 if (landList[localLandID] != null)
786 {
787 ILandObject parcelAvatarIsEntering = landList[localLandID];
788 if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT)
789 {
790 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID))
791 {
792 sendYouAreBannedNotice(avatar);
793 }
794 else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID))
795 {
796 avatar.ControllingClient.SendAlertMessage(
797 "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");
798 }
799 else
800 {
801 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
802 }
803 }
804 else
805 {
806 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
807 }
808 }
809 }
810 }
811
812 public void sendOutNearestBanLine(IClientAPI avatar)
813 {
814 List<ScenePresence> avatars = m_scene.GetAvatars();
815 foreach (ScenePresence presence in avatars)
816 {
817 if (presence.UUID == avatar.AgentId)
818 {
819
820 List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition);
821 foreach (ILandObject checkBan in checkLandParcels)
822 {
823 if (checkBan.isBannedFromLand(avatar.AgentId))
824 {
825 checkBan.sendLandProperties(-30000, false, (int)ParcelManager.ParcelResult.Single, avatar);
826 return; //Only send one
827 }
828 else if (checkBan.isRestrictedFromLand(avatar.AgentId))
829 {
830 checkBan.sendLandProperties(-40000, false, (int)ParcelManager.ParcelResult.Single, avatar);
831 return; //Only send one
832 }
833 }
834 return;
835 }
836 }
837 }
838
839 public void sendLandUpdate(ScenePresence avatar, bool force)
840 {
841 ILandObject over = null;
842 try
843 {
844 over = getLandObject((int)Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
845 (int)Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
846 }
847 catch (Exception)
848 {
849 //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y));
850 }
851
852 if (over != null)
853 {
854 if (force)
855 {
856 if (!avatar.IsChildAgent)
857 {
858 over.sendLandUpdateToClient(avatar.ControllingClient);
859 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
860 m_scene.RegionInfo.RegionID);
861 }
862 }
863
864 if (avatar.currentParcelUUID != over.landData.globalID)
865 {
866 if (!avatar.IsChildAgent)
867 {
868 over.sendLandUpdateToClient(avatar.ControllingClient);
869 avatar.currentParcelUUID = over.landData.globalID;
870 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
871 m_scene.RegionInfo.RegionID);
872 }
873 }
874 }
875 }
876 public void sendLandUpdate(ScenePresence avatar)
877 {
878 sendLandUpdate(avatar, false);
879
880 }
881 public void handleSignificantClientMovement(IClientAPI remote_client)
882 {
883 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId);
884
885 if (clientAvatar != null)
886 {
887 sendLandUpdate(clientAvatar);
888 sendOutNearestBanLine(remote_client);
889 ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
890 if (parcel != null)
891 {
892 if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
893 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
894 {
895 handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID);
896 //They are going below the safety line!
897 if (!parcel.isBannedFromLand(clientAvatar.UUID))
898 {
899 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
900 }
901 }
902 else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
903 parcel.isBannedFromLand(clientAvatar.UUID))
904 {
905 sendYouAreBannedNotice(clientAvatar);
906 }
907 }
908 }
909 }
910
911 public void handleAnyClientMovement(ScenePresence avatar)
912 //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance.
913 {
914 ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
915 if (over != null)
916 {
917 if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT)
918 {
919 avatar.lastKnownAllowedPosition =
920 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
921 }
922 }
923 }
924
925
926 public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
927 int landLocalID, IClientAPI remote_client)
928 {
929 if (landList.ContainsKey(landLocalID))
930 {
931 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client);
932 }
933 }
934
935 public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID,
936 List<ParcelManager.ParcelAccessEntry> entries,
937 IClientAPI remote_client)
938 {
939 if (landList.ContainsKey(landLocalID))
940 {
941 if (agentID == landList[landLocalID].landData.ownerID)
942 {
943 landList[landLocalID].updateAccessList(flags, entries, remote_client);
944 }
945 }
946 else
947 {
948 Console.WriteLine("INVALID LOCAL LAND ID");
949 }
950 }
951
952 // If the economy has been validated by the economy module,
953 // and land has been validated as well, this method transfers
954 // the land ownership
955
956 public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e)
957 {
958 if (e.economyValidated && e.landValidated)
959 {
960 lock (landList)
961 {
962 if (landList.ContainsKey(e.parcelLocalID))
963 {
964 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint)e.transactionID, e.parcelPrice, e.parcelArea);
965 return;
966 }
967 }
968 }
969 }
970
971 // After receiving a land buy packet, first the data needs to
972 // be validated. This method validates the right to buy the
973 // parcel
974
975 public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e)
976 {
977 if (e.landValidated == false)
978 {
979 ILandObject lob = null;
980 lock (landList)
981 {
982 if (landList.ContainsKey(e.parcelLocalID))
983 {
984 lob = landList[e.parcelLocalID];
985 }
986 }
987 if (lob != null)
988 {
989 LLUUID AuthorizedID = lob.landData.authBuyerID;
990 int saleprice = lob.landData.salePrice;
991 LLUUID pOwnerID = lob.landData.ownerID;
992
993 bool landforsale = ((lob.landData.landFlags & (uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0);
994 if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale)
995 {
996 lock (e)
997 {
998 e.parcelOwnerID = pOwnerID;
999 e.landValidated = true;
1000
1001 }
1002
1003 }
1004 }
1005 }
1006 }
1007 }
1008}
diff --git a/OpenSim/Region/Environment/Modules/LandManagement/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/LandManagement/LandManagementModule.cs
deleted file mode 100644
index 1c36c0c..0000000
--- a/OpenSim/Region/Environment/Modules/LandManagement/LandManagementModule.cs
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using Nini.Config;
29using OpenSim.Region.Environment.Interfaces;
30using OpenSim.Region.Environment.Scenes;
31
32namespace OpenSim.Region.Environment.Modules.LandManagement
33{
34 public class LandManagementModule : IRegionModule
35 {
36 private LandChannel landChannel;
37 private Scene m_scene;
38
39 #region IRegionModule Members
40
41 public void Initialise(Scene scene, IConfigSource source)
42 {
43 m_scene = scene;
44 landChannel = new LandChannel(scene);
45
46 m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts;
47 m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts;
48 m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel);
49 m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement);
50 m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest;
51 m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest;
52
53 lock (m_scene)
54 {
55 m_scene.LandChannel = (ILandChannel)landChannel;
56 }
57 }
58
59 public void PostInitialise()
60 {
61
62 }
63
64 public void Close()
65 {
66
67 }
68
69 public string Name
70 {
71 get { return "LandManagementModule"; }
72 }
73
74 public bool IsSharedModule
75 {
76 get { return false; }
77 }
78
79
80
81
82
83 #endregion
84 }
85}
diff --git a/OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs b/OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs
deleted file mode 100644
index da42c21..0000000
--- a/OpenSim/Region/Environment/Modules/LandManagement/LandObject.cs
+++ /dev/null
@@ -1,947 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using libsecondlife;
32using libsecondlife.Packets;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Scenes;
37
38namespace OpenSim.Region.Environment.Modules.LandManagement
39{
40
41 #region LandObject Class
42
43 /// <summary>
44 /// Keeps track of a specific piece of land's information
45 /// </summary>
46 public class LandObject : ILandObject
47 {
48 #region Member Variables
49
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 protected LandData m_landData = new LandData();
53 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
54 protected Scene m_scene;
55
56 private bool[,] m_landBitmap = new bool[64,64];
57
58 public bool[,] landBitmap
59 {
60 get
61 {
62 return m_landBitmap;
63 }
64 set
65 {
66 m_landBitmap = value;
67 }
68 }
69
70 #endregion
71
72 #region ILandObject Members
73
74 public LandData landData
75 {
76 get
77 {
78 return m_landData;
79 }
80
81 set
82 {
83 m_landData = value;
84 }
85 }
86
87 public LLUUID regionUUID
88 {
89 get { return m_scene.RegionInfo.RegionID; }
90 }
91
92 #endregion
93
94
95 #region Constructors
96
97 public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene)
98 {
99 m_scene = scene;
100 landData.ownerID = owner_id;
101 landData.isGroupOwned = is_group_owned;
102 }
103
104 #endregion
105
106 #region Member Functions
107
108 #region General Functions
109
110 /// <summary>
111 /// Checks to see if this land object contains a point
112 /// </summary>
113 /// <param name="x"></param>
114 /// <param name="y"></param>
115 /// <returns>Returns true if the piece of land contains the specified point</returns>
116 public bool containsPoint(int x, int y)
117 {
118 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize)
119 {
120 return (landBitmap[x/4, y/4] == true);
121 }
122 else
123 {
124 return false;
125 }
126 }
127
128 public ILandObject Copy()
129 {
130 ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene);
131
132 //Place all new variables here!
133 newLand.landBitmap = (bool[,]) (landBitmap.Clone());
134 newLand.landData = landData.Copy();
135
136 return newLand;
137 }
138
139 #endregion
140
141 #region Packet Request Handling
142
143 /// <summary>
144 /// Sends land properties as requested
145 /// </summary>
146 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
147 /// <param name="snap_selection">Bool sent by client for them to use</param>
148 /// <param name="remote_client">Object representing the client</param>
149 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result,
150 IClientAPI remote_client)
151 {
152 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties);
153 // TODO: don't create new blocks if recycling an old packet
154
155 updatePacket.ParcelData.AABBMax = landData.AABBMax;
156 updatePacket.ParcelData.AABBMin = landData.AABBMin;
157 updatePacket.ParcelData.Area = landData.area;
158 updatePacket.ParcelData.AuctionID = landData.auctionID;
159 updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented
160
161 updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray;
162
163 updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc);
164 updatePacket.ParcelData.Category = (byte) landData.category;
165 updatePacket.ParcelData.ClaimDate = landData.claimDate;
166 updatePacket.ParcelData.ClaimPrice = landData.claimPrice;
167 updatePacket.ParcelData.GroupID = landData.groupID;
168 updatePacket.ParcelData.GroupPrims = landData.groupPrims;
169 updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned;
170 updatePacket.ParcelData.LandingType = (byte) landData.landingType;
171 updatePacket.ParcelData.LocalID = landData.localID;
172 if (landData.area > 0)
173 {
174 updatePacket.ParcelData.MaxPrims =
175 Convert.ToInt32(
176 Math.Round((Convert.ToDecimal(landData.area)/Convert.ToDecimal(65536))*m_scene.objectCapacity*
177 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
178 }
179 else
180 {
181 updatePacket.ParcelData.MaxPrims = 0;
182 }
183 updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale;
184 updatePacket.ParcelData.MediaID = landData.mediaID;
185 updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL);
186 updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL);
187 updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName);
188 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
189 updatePacket.ParcelData.OtherCount = 0; //unemplemented
190 updatePacket.ParcelData.OtherPrims = landData.otherPrims;
191 updatePacket.ParcelData.OwnerID = landData.ownerID;
192 updatePacket.ParcelData.OwnerPrims = landData.ownerPrims;
193 updatePacket.ParcelData.ParcelFlags = landData.landFlags;
194 updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor;
195 updatePacket.ParcelData.PassHours = landData.passHours;
196 updatePacket.ParcelData.PassPrice = landData.passPrice;
197 updatePacket.ParcelData.PublicCount = 0; //unemplemented
198
199 uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags;
200 updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) >
201 0);
202 updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) >
203 0);
204 updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) >
205 0);
206 updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) >
207 0);
208
209 updatePacket.ParcelData.RentPrice = 0;
210 updatePacket.ParcelData.RequestResult = request_result;
211 updatePacket.ParcelData.SalePrice = landData.salePrice;
212 updatePacket.ParcelData.SelectedPrims = landData.selectedPrims;
213 updatePacket.ParcelData.SelfCount = 0; //unemplemented
214 updatePacket.ParcelData.SequenceID = sequence_id;
215 if (landData.simwideArea > 0)
216 {
217 updatePacket.ParcelData.SimWideMaxPrims =
218 Convert.ToInt32(
219 Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
220 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
221 }
222 else
223 {
224 updatePacket.ParcelData.SimWideMaxPrims = 0;
225 }
226 updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims;
227 updatePacket.ParcelData.SnapSelection = snap_selection;
228 updatePacket.ParcelData.SnapshotID = landData.snapshotID;
229 updatePacket.ParcelData.Status = (byte) landData.landStatus;
230 updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims +
231 landData.selectedPrims;
232 updatePacket.ParcelData.UserLocation = landData.userLocation;
233 updatePacket.ParcelData.UserLookAt = landData.userLookAt;
234 remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task);
235 }
236
237 public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
238 {
239 if (remote_client.AgentId == landData.ownerID)
240 {
241 //Needs later group support
242 LandData newData = landData.Copy();
243 newData.authBuyerID = packet.ParcelData.AuthBuyerID;
244 newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category;
245 newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
246 newData.groupID = packet.ParcelData.GroupID;
247 newData.landingType = packet.ParcelData.LandingType;
248 newData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
249 newData.mediaID = packet.ParcelData.MediaID;
250 newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
251 newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
252 newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
253 newData.landFlags = packet.ParcelData.ParcelFlags;
254 newData.passHours = packet.ParcelData.PassHours;
255 newData.passPrice = packet.ParcelData.PassPrice;
256 newData.salePrice = packet.ParcelData.SalePrice;
257 newData.snapshotID = packet.ParcelData.SnapshotID;
258 newData.userLocation = packet.ParcelData.UserLocation;
259 newData.userLookAt = packet.ParcelData.UserLookAt;
260
261 m_scene.LandChannel.updateLandObject(landData.localID, newData);
262
263 sendLandUpdateToAvatarsOverMe();
264 }
265 }
266 public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
267 {
268 LandData newData = landData.Copy();
269 newData.ownerID = avatarID;
270 newData.groupID = groupID;
271 newData.isGroupOwned = groupOwned;
272 //newData.auctionID = AuctionID;
273 newData.claimDate = Util.UnixTimeSinceEpoch();
274 newData.claimPrice = claimprice;
275 newData.salePrice = 0;
276 newData.authBuyerID = LLUUID.Zero;
277 newData.landFlags &= ~(uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects);
278 m_scene.LandChannel.updateLandObject(landData.localID, newData);
279
280 sendLandUpdateToAvatarsOverMe();
281 }
282
283 public bool isEitherBannedOrRestricted(LLUUID avatar)
284 {
285 if (isBannedFromLand(avatar))
286 {
287 return true;
288 }
289 else if (isRestrictedFromLand(avatar))
290 {
291 return true;
292 }
293 return false;
294 }
295
296 public bool isBannedFromLand(LLUUID avatar)
297 {
298 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0)
299 {
300 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
301 entry.AgentID = avatar;
302 entry.Flags = ParcelManager.AccessList.Ban;
303 entry.Time = new DateTime();
304 if (landData.parcelAccessList.Contains(entry))
305 {
306 //They are banned, so lets send them a notice about this parcel
307 return true;
308 }
309 }
310 return false;
311 }
312
313 public bool isRestrictedFromLand(LLUUID avatar)
314 {
315 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0)
316 {
317 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
318 entry.AgentID = avatar;
319 entry.Flags = ParcelManager.AccessList.Access;
320 entry.Time = new DateTime();
321 if (!landData.parcelAccessList.Contains(entry))
322 {
323 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
324 return true;
325 }
326 }
327 return false;
328 }
329
330 public void sendLandUpdateToClient(IClientAPI remote_client)
331 {
332 sendLandProperties(0, false, 0, remote_client);
333 }
334
335 public void sendLandUpdateToAvatarsOverMe()
336 {
337 List<ScenePresence> avatars = m_scene.GetAvatars();
338 ILandObject over = null;
339 for (int i = 0; i < avatars.Count; i++)
340 {
341 try
342 {
343 over =
344 m_scene.LandChannel.getLandObject((int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.X))),
345 (int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.Y))));
346 }
347 catch (Exception)
348 {
349 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + Math.Round(avatars[i].AbsolutePosition.Y));
350 }
351
352 if (over != null)
353 {
354 if (over.landData.localID == landData.localID)
355 {
356 sendLandUpdateToClient(avatars[i].ControllingClient);
357 }
358 }
359 }
360 }
361
362 #endregion
363
364 #region AccessList Functions
365
366 public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag)
367 {
368 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
369 foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList)
370 {
371 if (entry.Flags == flag)
372 {
373 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
374
375 listBlock.Flags = (uint) 0;
376 listBlock.ID = entry.AgentID;
377 listBlock.Time = 0;
378
379 list.Add(listBlock);
380 }
381 }
382
383 if (list.Count == 0)
384 {
385 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
386
387 listBlock.Flags = (uint) 0;
388 listBlock.ID = LLUUID.Zero;
389 listBlock.Time = 0;
390
391 list.Add(listBlock);
392 }
393 return list.ToArray();
394 }
395
396 public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
397 IClientAPI remote_client)
398 {
399 ParcelAccessListReplyPacket replyPacket;
400
401 if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both)
402 {
403 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
404 replyPacket.Data.AgentID = agentID;
405 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access;
406 replyPacket.Data.LocalID = landData.localID;
407 replyPacket.Data.SequenceID = 0;
408
409 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access);
410 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
411 }
412
413 if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both)
414 {
415 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
416 replyPacket.Data.AgentID = agentID;
417 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban;
418 replyPacket.Data.LocalID = landData.localID;
419 replyPacket.Data.SequenceID = 0;
420
421 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban);
422 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
423 }
424 }
425
426 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
427 {
428 LandData newData = landData.Copy();
429
430 if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero)
431 {
432 entries.Clear();
433 }
434
435 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
436 foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList)
437 {
438 if (entry.Flags == (ParcelManager.AccessList) flags)
439 {
440 toRemove.Add(entry);
441 }
442 }
443
444 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
445 {
446 newData.parcelAccessList.Remove(entry);
447 }
448 foreach (ParcelManager.ParcelAccessEntry entry in entries)
449 {
450 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
451 temp.AgentID = entry.AgentID;
452 temp.Time = new DateTime(); //Pointless? Yes.
453 temp.Flags = (ParcelManager.AccessList) flags;
454
455 if (!newData.parcelAccessList.Contains(temp))
456 {
457 newData.parcelAccessList.Add(temp);
458 }
459 }
460
461 m_scene.LandChannel.updateLandObject(landData.localID, newData);
462 }
463
464 #endregion
465
466 #region Update Functions
467
468 /// <summary>
469 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
470 /// </summary>
471 private void updateAABBAndAreaValues()
472 {
473 int min_x = 64;
474 int min_y = 64;
475 int max_x = 0;
476 int max_y = 0;
477 int tempArea = 0;
478 int x, y;
479 for (x = 0; x < 64; x++)
480 {
481 for (y = 0; y < 64; y++)
482 {
483 if (landBitmap[x, y] == true)
484 {
485 if (min_x > x) min_x = x;
486 if (min_y > y) min_y = y;
487 if (max_x < x) max_x = x;
488 if (max_y < y) max_y = y;
489 tempArea += 16; //16sqm peice of land
490 }
491 }
492 }
493 int tx = min_x * 4;
494 if (tx > 255)
495 tx = 255;
496 int ty = min_y * 4;
497 if (ty > 255)
498 ty = 255;
499 landData.AABBMin =
500 new LLVector3((float)(min_x * 4), (float)(min_y * 4),
501 (float)m_scene.Heightmap[tx, ty]);
502
503 tx = max_x * 4;
504 if (tx > 255)
505 tx = 255;
506 ty = max_y * 4;
507 if (ty > 255)
508 ty = 255;
509 landData.AABBMax =
510 new LLVector3((float)(max_x * 4), (float)(max_y * 4),
511 (float)m_scene.Heightmap[tx, ty]);
512 landData.area = tempArea;
513 }
514
515 public void updateLandBitmapByteArray()
516 {
517 landData.landBitmapByteArray = convertLandBitmapToBytes();
518 }
519
520 /// <summary>
521 /// Update all settings in land such as area, bitmap byte array, etc
522 /// </summary>
523 public void forceUpdateLandInfo()
524 {
525 updateAABBAndAreaValues();
526 updateLandBitmapByteArray();
527 }
528
529 public void setLandBitmapFromByteArray()
530 {
531 landBitmap = convertBytesToLandBitmap();
532 }
533
534 #endregion
535
536 #region Land Bitmap Functions
537
538 /// <summary>
539 /// Sets the land's bitmap manually
540 /// </summary>
541 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
542 public void setLandBitmap(bool[,] bitmap)
543 {
544 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
545 {
546 //Throw an exception - The bitmap is not 64x64
547 //throw new Exception("Error: Invalid Parcel Bitmap");
548 }
549 else
550 {
551 //Valid: Lets set it
552 landBitmap = bitmap;
553 forceUpdateLandInfo();
554 }
555 }
556
557 /// <summary>
558 /// Gets the land's bitmap manually
559 /// </summary>
560 /// <returns></returns>
561 public bool[,] getLandBitmap()
562 {
563 return landBitmap;
564 }
565
566 /// <summary>
567 /// Converts the land bitmap to a packet friendly byte array
568 /// </summary>
569 /// <returns></returns>
570 private byte[] convertLandBitmapToBytes()
571 {
572 byte[] tempConvertArr = new byte[512];
573 byte tempByte = 0;
574 int x, y, i, byteNum = 0;
575 i = 0;
576 for (y = 0; y < 64; y++)
577 {
578 for (x = 0; x < 64; x++)
579 {
580 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++%8));
581 if (i%8 == 0)
582 {
583 tempConvertArr[byteNum] = tempByte;
584 tempByte = (byte) 0;
585 i = 0;
586 byteNum++;
587 }
588 }
589 }
590 return tempConvertArr;
591 }
592
593 private bool[,] convertBytesToLandBitmap()
594 {
595 bool[,] tempConvertMap = new bool[64,64];
596 tempConvertMap.Initialize();
597 byte tempByte = 0;
598 int x = 0, y = 0, i = 0, bitNum = 0;
599 for (i = 0; i < 512; i++)
600 {
601 tempByte = landData.landBitmapByteArray[i];
602 for (bitNum = 0; bitNum < 8; bitNum++)
603 {
604 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
605 tempConvertMap[x, y] = bit;
606 x++;
607 if (x > 63)
608 {
609 x = 0;
610 y++;
611 }
612 }
613 }
614 return tempConvertMap;
615 }
616
617 /// <summary>
618 /// Full sim land object creation
619 /// </summary>
620 /// <returns></returns>
621 public bool[,] basicFullRegionLandBitmap()
622 {
623 return getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize);
624 }
625
626 /// <summary>
627 /// Used to modify the bitmap between the x and y points. Points use 64 scale
628 /// </summary>
629 /// <param name="start_x"></param>
630 /// <param name="start_y"></param>
631 /// <param name="end_x"></param>
632 /// <param name="end_y"></param>
633 /// <returns></returns>
634 public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
635 {
636 bool[,] tempBitmap = new bool[64,64];
637 tempBitmap.Initialize();
638
639 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
640 return tempBitmap;
641 }
642
643 /// <summary>
644 /// Change a land bitmap at within a square and set those points to a specific value
645 /// </summary>
646 /// <param name="land_bitmap"></param>
647 /// <param name="start_x"></param>
648 /// <param name="start_y"></param>
649 /// <param name="end_x"></param>
650 /// <param name="end_y"></param>
651 /// <param name="set_value"></param>
652 /// <returns></returns>
653 public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
654 bool set_value)
655 {
656 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
657 {
658 //Throw an exception - The bitmap is not 64x64
659 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
660 }
661
662 int x, y;
663 for (y = 0; y < 64; y++)
664 {
665 for (x = 0; x < 64; x++)
666 {
667 if (x >= start_x/4 && x < end_x/4
668 && y >= start_y/4 && y < end_y/4)
669 {
670 land_bitmap[x, y] = set_value;
671 }
672 }
673 }
674 return land_bitmap;
675 }
676
677 /// <summary>
678 /// Join the true values of 2 bitmaps together
679 /// </summary>
680 /// <param name="bitmap_base"></param>
681 /// <param name="bitmap_add"></param>
682 /// <returns></returns>
683 public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
684 {
685 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
686 {
687 //Throw an exception - The bitmap is not 64x64
688 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
689 }
690 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
691 {
692 //Throw an exception - The bitmap is not 64x64
693 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
694 }
695
696 int x, y;
697 for (y = 0; y < 64; y++)
698 {
699 for (x = 0; x < 64; x++)
700 {
701 if (bitmap_add[x, y])
702 {
703 bitmap_base[x, y] = true;
704 }
705 }
706 }
707 return bitmap_base;
708 }
709
710 #endregion
711
712 #region Object Select and Object Owner Listing
713
714 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
715 {
716 List<uint> resultLocalIDs = new List<uint>();
717 foreach (SceneObjectGroup obj in primsOverMe)
718 {
719 if (obj.LocalId > 0)
720 {
721 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID)
722 {
723 resultLocalIDs.Add(obj.LocalId);
724 }
725 // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support
726 // {
727 // }
728 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
729 obj.OwnerID != remote_client.AgentId)
730 {
731 resultLocalIDs.Add(obj.LocalId);
732 }
733 }
734 }
735
736
737 bool firstCall = true;
738 int MAX_OBJECTS_PER_PACKET = 251;
739 ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
740 // TODO: don't create new blocks if recycling an old packet
741 ForceObjectSelectPacket.DataBlock[] data;
742 while (resultLocalIDs.Count > 0)
743 {
744 if (firstCall)
745 {
746 pack._Header.ResetList = true;
747 firstCall = false;
748 }
749 else
750 {
751 pack._Header.ResetList = false;
752 }
753
754 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
755 {
756 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
757 }
758 else
759 {
760 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
761 }
762
763 int i;
764 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
765 {
766 data[i] = new ForceObjectSelectPacket.DataBlock();
767 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
768 resultLocalIDs.RemoveAt(0);
769 }
770 pack.Data = data;
771 remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task);
772 }
773 }
774
775 /// <summary>
776 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
777 /// aggreagete details such as the number of prims.
778 ///
779 /// </summary>
780 /// <param name="remote_client">
781 /// A <see cref="IClientAPI"/>
782 /// </param>
783 public void sendLandObjectOwners(IClientAPI remote_client)
784 {
785 Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>();
786 ParcelObjectOwnersReplyPacket pack
787 = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
788 // TODO: don't create new blocks if recycling an old packet
789
790 foreach (SceneObjectGroup obj in primsOverMe)
791 {
792 try
793 {
794 if (!primCount.ContainsKey(obj.OwnerID))
795 {
796 primCount.Add(obj.OwnerID, 0);
797 }
798 }
799 catch (NullReferenceException)
800 {
801 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
802 }
803 try
804 {
805 primCount[obj.OwnerID] += obj.PrimCount;
806 }
807 catch (KeyNotFoundException)
808 {
809 m_log.Error("[LAND]: Unable to match a prim with it's owner.");
810 }
811 }
812
813 int notifyCount = primCount.Count;
814
815 if (notifyCount > 0)
816 {
817 if (notifyCount > 32)
818 {
819 m_log.InfoFormat(
820 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
821 + " - a developer might want to investigate whether this is a hard limit", 32);
822
823 notifyCount = 32;
824 }
825
826 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
827 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
828
829 int num = 0;
830 foreach (LLUUID owner in primCount.Keys)
831 {
832 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
833 dataBlock[num].Count = primCount[owner];
834 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
835 dataBlock[num].OnlineStatus = true; //TODO: fix me later
836 dataBlock[num].OwnerID = owner;
837
838 num++;
839
840 if (num >= notifyCount)
841 {
842 break;
843 }
844 }
845
846 pack.Data = dataBlock;
847 }
848
849 remote_client.OutPacket(pack, ThrottleOutPacketType.Task);
850 }
851
852 public Dictionary<LLUUID, int> getLandObjectOwners()
853 {
854 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>();
855 foreach (SceneObjectGroup obj in primsOverMe)
856 {
857 if (!ownersAndCount.ContainsKey(obj.OwnerID))
858 {
859 ownersAndCount.Add(obj.OwnerID, 0);
860 }
861 ownersAndCount[obj.OwnerID] += obj.PrimCount;
862 }
863 return ownersAndCount;
864 }
865
866 #endregion
867
868 #region Object Returning
869
870 public void returnObject(SceneObjectGroup obj)
871 {
872 }
873
874 public void returnLandObjects(int type, LLUUID owner)
875 {
876 }
877
878 #endregion
879
880 #region Object Adding/Removing from Parcel
881
882 public void resetLandPrimCounts()
883 {
884 landData.groupPrims = 0;
885 landData.ownerPrims = 0;
886 landData.otherPrims = 0;
887 landData.selectedPrims = 0;
888 primsOverMe.Clear();
889 }
890
891 public void addPrimToCount(SceneObjectGroup obj)
892 {
893 LLUUID prim_owner = obj.OwnerID;
894 int prim_count = obj.PrimCount;
895
896 if (obj.IsSelected)
897 {
898 landData.selectedPrims += prim_count;
899 }
900 else
901 {
902 if (prim_owner == landData.ownerID)
903 {
904 landData.ownerPrims += prim_count;
905 }
906 else
907 {
908 landData.otherPrims += prim_count;
909 }
910 }
911
912 primsOverMe.Add(obj);
913 }
914
915 public void removePrimFromCount(SceneObjectGroup obj)
916 {
917 if (primsOverMe.Contains(obj))
918 {
919 LLUUID prim_owner = obj.OwnerID;
920 int prim_count = obj.PrimCount;
921
922 if (prim_owner == landData.ownerID)
923 {
924 landData.ownerPrims -= prim_count;
925 }
926 else if (prim_owner == landData.groupID)
927 {
928 landData.groupPrims -= prim_count;
929 }
930 else
931 {
932 landData.otherPrims -= prim_count;
933 }
934
935 primsOverMe.Remove(obj);
936 }
937 }
938
939 #endregion
940
941 #endregion
942
943
944}
945
946 #endregion
947}
diff --git a/OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs b/OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs
deleted file mode 100644
index 7ef087d..0000000
--- a/OpenSim/Region/Environment/Modules/ModuleFramework/Commander.cs
+++ /dev/null
@@ -1,308 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces;
35
36namespace OpenSim.Region.Environment.Modules.ModuleFramework
37{
38 /// <summary>
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
41 /// </summary>
42 public class Command : ICommand
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private List<CommandArgument> m_args = new List<CommandArgument>();
46
47 private Action<object[]> m_command;
48 private string m_help;
49 private string m_name;
50
51 public Command(string name, Action<Object[]> command, string help)
52 {
53 m_name = name;
54 m_command = command;
55 m_help = help;
56 }
57
58 #region ICommand Members
59
60 public void AddArgument(string name, string helptext, string type)
61 {
62 m_args.Add(new CommandArgument(name, helptext, type));
63 }
64
65 public string Name
66 {
67 get { return m_name; }
68 }
69
70 public string Help
71 {
72 get { return m_help; }
73 }
74
75 public Dictionary<string, string> Arguments
76 {
77 get
78 {
79 Dictionary<string, string> tmp = new Dictionary<string, string>();
80 foreach (CommandArgument arg in m_args)
81 {
82 tmp.Add(arg.Name, arg.ArgumentType);
83 }
84 return tmp;
85 }
86 }
87
88 public void ShowConsoleHelp()
89 {
90 m_log.Info("== " + Name + " ==");
91 m_log.Info(m_help);
92 m_log.Info("= Parameters =");
93 foreach (CommandArgument arg in m_args)
94 {
95 m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")");
96 m_log.Info("\t" + arg.HelpText);
97 }
98 }
99
100 public void Run(Object[] args)
101 {
102 Object[] cleanArgs = new Object[m_args.Count];
103
104 if (args.Length < cleanArgs.Length)
105 {
106 m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)");
107 ShowConsoleHelp();
108 return;
109 }
110 if (args.Length > cleanArgs.Length)
111 {
112 m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help.");
113 return;
114 }
115
116 int i = 0;
117 foreach (Object arg in args)
118 {
119 if (string.IsNullOrEmpty(arg.ToString()))
120 {
121 m_log.Error("Empty arguments are not allowed");
122 return;
123 }
124 try
125 {
126 switch (m_args[i].ArgumentType)
127 {
128 case "String":
129 m_args[i].ArgumentValue = arg.ToString();
130 break;
131 case "Integer":
132 m_args[i].ArgumentValue = Int32.Parse(arg.ToString());
133 break;
134 case "Double":
135 m_args[i].ArgumentValue = Double.Parse(arg.ToString());
136 break;
137 case "Boolean":
138 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
139 break;
140 default:
141 m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
142 break;
143 }
144 }
145 catch (FormatException)
146 {
147 m_log.Error("Argument number " + (i + 1) +
148 " (" + m_args[i].Name + ") must be a valid " +
149 m_args[i].ArgumentType.ToLower() + ".");
150 }
151 cleanArgs[i] = m_args[i].ArgumentValue;
152
153 i++;
154 }
155
156 m_command.Invoke(cleanArgs);
157 }
158
159 #endregion
160 }
161
162 /// <summary>
163 /// A single command argument, contains name, type and at runtime, value.
164 /// </summary>
165 public class CommandArgument
166 {
167 private string m_help;
168 private string m_name;
169 private string m_type;
170 private Object m_val;
171
172 public CommandArgument(string name, string help, string type)
173 {
174 m_name = name;
175 m_help = help;
176 m_type = type;
177 }
178
179 public string Name
180 {
181 get { return m_name; }
182 }
183
184 public string HelpText
185 {
186 get { return m_help; }
187 }
188
189 public string ArgumentType
190 {
191 get { return m_type; }
192 }
193
194 public Object ArgumentValue
195 {
196 get { return m_val; }
197 set { m_val = value; }
198 }
199 }
200
201 /// <summary>
202 /// A class to enable modules to register console and script commands, which enforces typing and valid input.
203 /// </summary>
204 public class Commander : ICommander
205 {
206 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
207 private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
208 private string m_name;
209
210 public Commander(string name)
211 {
212 m_name = name;
213 }
214
215 #region ICommander Members
216
217 public void RegisterCommand(string commandName, ICommand command)
218 {
219 m_commands[commandName] = command;
220 }
221
222 /// <summary>
223 /// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands
224 /// </summary>
225 /// <returns>Returns C# source code to create a binding</returns>
226 public string GenerateRuntimeAPI()
227 {
228 string classSrc = "\n\tpublic class " + m_name + " {\n";
229 foreach (ICommand com in m_commands.Values)
230 {
231 classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( ";
232 foreach (KeyValuePair<string, string> arg in com.Arguments)
233 {
234 classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ",";
235 }
236 classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma
237 classSrc += " )\n\t{\n";
238 classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n";
239 int i = 0;
240 foreach (KeyValuePair<string, string> arg in com.Arguments)
241 {
242 classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n";
243 i++;
244 }
245 classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n";
246 classSrc += "\t}\n";
247 }
248 classSrc += "}\n";
249
250 return classSrc;
251 }
252
253 /// <summary>
254 /// Runs a specified function with attached arguments
255 /// *** <b>DO NOT CALL DIRECTLY.</b> ***
256 /// Call ProcessConsoleCommand instead if handling human input.
257 /// </summary>
258 /// <param name="function">The function name to call</param>
259 /// <param name="args">The function parameters</param>
260 public void Run(string function, object[] args)
261 {
262 m_commands[function].Run(args);
263 }
264
265 public void ProcessConsoleCommand(string function, string[] args)
266 {
267 if (m_commands.ContainsKey(function))
268 {
269 if (args.Length > 0 && args[0] == "help")
270 {
271 m_commands[function].ShowConsoleHelp();
272 }
273 else
274 {
275 m_commands[function].Run(args);
276 }
277 }
278 else
279 {
280 if (function != "help")
281 m_log.Error("Invalid command - No such command exists");
282 if (function == "api")
283 m_log.Info(GenerateRuntimeAPI());
284 ShowConsoleHelp();
285 }
286 }
287
288 #endregion
289
290 private void ShowConsoleHelp()
291 {
292 m_log.Info("===" + m_name + "===");
293 foreach (ICommand com in m_commands.Values)
294 {
295 m_log.Info("* " + com.Name + " - " + com.Help);
296 }
297 }
298
299 private string EscapeRuntimeAPICommand(string command)
300 {
301 command = command.Replace('-', '_');
302 StringBuilder tmp = new StringBuilder(command);
303 tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0];
304
305 return tmp.ToString();
306 }
307 }
308} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs b/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 02354f1..63eee97 100644
--- a/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -1,277 +1,277 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Drawing; 30using System.Drawing;
31using System.Drawing.Imaging; 31using System.Drawing.Imaging;
32using libsecondlife; 32using libsecondlife;
33using Nini.Config; 33using Nini.Config;
34using OpenJPEGNet; 34using OpenJPEGNet;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
38 38
39namespace OpenSim.Region.Environment.Modules 39namespace 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 public void Initialise(Scene scene, IConfigSource config) 50 public void Initialise(Scene scene, IConfigSource config)
51 { 51 {
52 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 52 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
53 { 53 {
54 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 54 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
55 scene.RegisterModuleInterface<IDynamicTextureManager>(this); 55 scene.RegisterModuleInterface<IDynamicTextureManager>(this);
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 "DynamicTextureModule"; } 69 get { return "DynamicTextureModule"; }
70 } 70 }
71 71
72 public bool IsSharedModule 72 public bool IsSharedModule
73 { 73 {
74 get { return true; } 74 get { return true; }
75 } 75 }
76 76
77 public void RegisterRender(string handleType, IDynamicTextureRender render) 77 public void RegisterRender(string handleType, IDynamicTextureRender render)
78 { 78 {
79 if (!RenderPlugins.ContainsKey(handleType)) 79 if (!RenderPlugins.ContainsKey(handleType))
80 { 80 {
81 RenderPlugins.Add(handleType, render); 81 RenderPlugins.Add(handleType, render);
82 } 82 }
83 } 83 }
84 84
85 public void ReturnData(LLUUID id, byte[] data) 85 public void ReturnData(LLUUID id, byte[] data)
86 { 86 {
87 if (Updaters.ContainsKey(id)) 87 if (Updaters.ContainsKey(id))
88 { 88 {
89 DynamicTextureUpdater updater = Updaters[id]; 89 DynamicTextureUpdater updater = Updaters[id];
90 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 90 if (RegisteredScenes.ContainsKey(updater.SimUUID))
91 { 91 {
92 Scene scene = RegisteredScenes[updater.SimUUID]; 92 Scene scene = RegisteredScenes[updater.SimUUID];
93 updater.DataReceived(data, scene); 93 updater.DataReceived(data, scene);
94 } 94 }
95 } 95 }
96 } 96 }
97 97
98 98
99 public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, 99 public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url,
100 string extraParams, int updateTimer) 100 string extraParams, int updateTimer)
101 { 101 {
102 return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); 102 return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255);
103 } 103 }
104 104
105 public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, 105 public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url,
106 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) 106 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
107 { 107 {
108 if (RenderPlugins.ContainsKey(contentType)) 108 if (RenderPlugins.ContainsKey(contentType))
109 { 109 {
110 //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType); 110 //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType);
111 111
112 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 112 DynamicTextureUpdater updater = new DynamicTextureUpdater();
113 updater.SimUUID = simID; 113 updater.SimUUID = simID;
114 updater.PrimID = primID; 114 updater.PrimID = primID;
115 updater.ContentType = contentType; 115 updater.ContentType = contentType;
116 updater.Url = url; 116 updater.Url = url;
117 updater.UpdateTimer = updateTimer; 117 updater.UpdateTimer = updateTimer;
118 updater.UpdaterID = LLUUID.Random(); 118 updater.UpdaterID = LLUUID.Random();
119 updater.Params = extraParams; 119 updater.Params = extraParams;
120 updater.BlendWithOldTexture = SetBlending; 120 updater.BlendWithOldTexture = SetBlending;
121 updater.FrontAlpha = AlphaValue; 121 updater.FrontAlpha = AlphaValue;
122 122
123 if (!Updaters.ContainsKey(updater.UpdaterID)) 123 if (!Updaters.ContainsKey(updater.UpdaterID))
124 { 124 {
125 Updaters.Add(updater.UpdaterID, updater); 125 Updaters.Add(updater.UpdaterID, updater);
126 } 126 }
127 127
128 RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); 128 RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
129 return updater.UpdaterID; 129 return updater.UpdaterID;
130 } 130 }
131 return LLUUID.Zero; 131 return LLUUID.Zero;
132 } 132 }
133 133
134 public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, 134 public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data,
135 string extraParams, int updateTimer) 135 string extraParams, int updateTimer)
136 { 136 {
137 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); 137 return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255);
138 } 138 }
139 139
140 public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, 140 public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data,
141 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) 141 string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
142 { 142 {
143 if (RenderPlugins.ContainsKey(contentType)) 143 if (RenderPlugins.ContainsKey(contentType))
144 { 144 {
145 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 145 DynamicTextureUpdater updater = new DynamicTextureUpdater();
146 updater.SimUUID = simID; 146 updater.SimUUID = simID;
147 updater.PrimID = primID; 147 updater.PrimID = primID;
148 updater.ContentType = contentType; 148 updater.ContentType = contentType;
149 updater.BodyData = data; 149 updater.BodyData = data;
150 updater.UpdateTimer = updateTimer; 150 updater.UpdateTimer = updateTimer;
151 updater.UpdaterID = LLUUID.Random(); 151 updater.UpdaterID = LLUUID.Random();
152 updater.Params = extraParams; 152 updater.Params = extraParams;
153 updater.BlendWithOldTexture = SetBlending; 153 updater.BlendWithOldTexture = SetBlending;
154 updater.FrontAlpha = AlphaValue; 154 updater.FrontAlpha = AlphaValue;
155 155
156 if (!Updaters.ContainsKey(updater.UpdaterID)) 156 if (!Updaters.ContainsKey(updater.UpdaterID))
157 { 157 {
158 Updaters.Add(updater.UpdaterID, updater); 158 Updaters.Add(updater.UpdaterID, updater);
159 } 159 }
160 160
161 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); 161 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
162 return updater.UpdaterID; 162 return updater.UpdaterID;
163 } 163 }
164 return LLUUID.Zero; 164 return LLUUID.Zero;
165 } 165 }
166 166
167 public class DynamicTextureUpdater 167 public class DynamicTextureUpdater
168 { 168 {
169 public LLUUID SimUUID; 169 public LLUUID SimUUID;
170 public LLUUID UpdaterID; 170 public LLUUID UpdaterID;
171 public string ContentType; 171 public string ContentType;
172 public string Url; 172 public string Url;
173 public string BodyData; 173 public string BodyData;
174 public LLUUID PrimID; 174 public LLUUID PrimID;
175 public int UpdateTimer; 175 public int UpdateTimer;
176 public LLUUID LastAssetID; 176 public LLUUID LastAssetID;
177 public string Params; 177 public string Params;
178 public bool BlendWithOldTexture = false; 178 public bool BlendWithOldTexture = false;
179 public bool SetNewFrontAlpha = false; 179 public bool SetNewFrontAlpha = false;
180 public byte FrontAlpha = 255; 180 public byte FrontAlpha = 255;
181 181
182 public DynamicTextureUpdater() 182 public DynamicTextureUpdater()
183 { 183 {
184 LastAssetID = LLUUID.Zero; 184 LastAssetID = LLUUID.Zero;
185 UpdateTimer = 0; 185 UpdateTimer = 0;
186 BodyData = null; 186 BodyData = null;
187 } 187 }
188 188
189 public void DataReceived(byte[] data, Scene scene) 189 public void DataReceived(byte[] data, Scene scene)
190 { 190 {
191 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 191 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
192 byte[] assetData; 192 byte[] assetData;
193 AssetBase oldAsset = null; 193 AssetBase oldAsset = null;
194 if (BlendWithOldTexture) 194 if (BlendWithOldTexture)
195 { 195 {
196 LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; 196 LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID;
197 oldAsset = scene.AssetCache.GetAsset(lastTextureID, true); 197 oldAsset = scene.AssetCache.GetAsset(lastTextureID, true);
198 if (oldAsset != null) 198 if (oldAsset != null)
199 { 199 {
200 assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); 200 assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha);
201 } 201 }
202 else 202 else
203 { 203 {
204 assetData = new byte[data.Length]; 204 assetData = new byte[data.Length];
205 Array.Copy(data, assetData, data.Length); 205 Array.Copy(data, assetData, data.Length);
206 } 206 }
207 } 207 }
208 else 208 else
209 { 209 {
210 assetData = new byte[data.Length]; 210 assetData = new byte[data.Length];
211 Array.Copy(data, assetData, data.Length); 211 Array.Copy(data, assetData, data.Length);
212 } 212 }
213 213
214 //TODO delete the last asset(data), if it was a dynamic texture 214 //TODO delete the last asset(data), if it was a dynamic texture
215 AssetBase asset = new AssetBase(); 215 AssetBase asset = new AssetBase();
216 asset.FullID = LLUUID.Random(); 216 asset.FullID = LLUUID.Random();
217 asset.Data = assetData; 217 asset.Data = assetData;
218 asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); 218 asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000);
219 asset.Type = 0; 219 asset.Type = 0;
220 asset.Description = "dynamic image"; 220 asset.Description = "dynamic image";
221 asset.Local = false; 221 asset.Local = false;
222 asset.Temporary = true; 222 asset.Temporary = true;
223 scene.AssetCache.AddAsset(asset); 223 scene.AssetCache.AddAsset(asset);
224 224
225 LastAssetID = asset.FullID; 225 LastAssetID = asset.FullID;
226 226
227 227
228 part.Shape.Textures = new LLObject.TextureEntry(asset.FullID); 228 part.Shape.Textures = new LLObject.TextureEntry(asset.FullID);
229 part.ScheduleFullUpdate(); 229 part.ScheduleFullUpdate();
230 } 230 }
231 231
232// TODO: unused 232// TODO: unused
233// private byte[] BlendTextures(byte[] frontImage, byte[] backImage) 233// private byte[] BlendTextures(byte[] frontImage, byte[] backImage)
234// { 234// {
235// return BlendTextures(frontImage, backImage, false, 0); 235// return BlendTextures(frontImage, backImage, false, 0);
236// } 236// }
237 237
238 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 238 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
239 { 239 {
240 Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage)); 240 Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage));
241 Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage)); 241 Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage));
242 if (setNewAlpha) 242 if (setNewAlpha)
243 { 243 {
244 SetAlpha(ref image1, newAlpha); 244 SetAlpha(ref image1, newAlpha);
245 } 245 }
246 Bitmap joint = MergeBitMaps(image1, image2); 246 Bitmap joint = MergeBitMaps(image1, image2);
247 247
248 return OpenJPEG.EncodeFromImage(joint, true); 248 return OpenJPEG.EncodeFromImage(joint, true);
249 } 249 }
250 250
251 public Bitmap MergeBitMaps(Bitmap front, Bitmap back) 251 public Bitmap MergeBitMaps(Bitmap front, Bitmap back)
252 { 252 {
253 Bitmap joint; 253 Bitmap joint;
254 Graphics jG; 254 Graphics jG;
255 255
256 joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb); 256 joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb);
257 jG = Graphics.FromImage(joint); 257 jG = Graphics.FromImage(joint);
258 258
259 jG.DrawImage(back, 0, 0, back.Width, back.Height); 259 jG.DrawImage(back, 0, 0, back.Width, back.Height);
260 jG.DrawImage(front, 0, 0, back.Width, back.Height); 260 jG.DrawImage(front, 0, 0, back.Width, back.Height);
261 261
262 return joint; 262 return joint;
263 } 263 }
264 264
265 private void SetAlpha(ref Bitmap b, byte alpha) 265 private void SetAlpha(ref Bitmap b, byte alpha)
266 { 266 {
267 for (int w = 0; w < b.Width; w++) 267 for (int w = 0; w < b.Width; w++)
268 { 268 {
269 for (int h = 0; h < b.Height; h++) 269 for (int h = 0; h < b.Height; h++)
270 { 270 {
271 b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h))); 271 b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h)));
272 } 272 }
273 } 273 }
274 } 274 }
275 } 275 }
276 } 276 }
277} 277} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 2de5975..4977a86 100644
--- a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -1,364 +1,356 @@
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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Net; 31using System.Net;
32using System.Text; 32using System.Text;
33using System.Threading; 33using System.Threading;
34using libsecondlife; 34using libsecondlife;
35using Nini.Config; 35using Nini.Config;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.Environment.Interfaces; 37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.Environment.Scenes; 38using 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
83namespace OpenSim.Region.Environment.Modules 83namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest
84{ 84{
85 public class ScriptHTTPRequests : IRegionModule, IHttpRequests 85 public class HttpRequestModule : IRegionModule, IHttpRequests
86 { 86 {
87 private Scene m_scene; 87 private Scene m_scene;
88 private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 88 private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
89 private object HttpListLock = new object(); 89 private object HttpListLock = new object();
90 private string m_name = "HttpScriptRequests"; 90 private string m_name = "HttpScriptRequests";
91 private int httpTimeout = 30000; 91 private int httpTimeout = 30000;
92 92
93 // <request id, HttpRequestClass> 93 // <request id, HttpRequestClass>
94 private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests; 94 private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests;
95 95
96 public ScriptHTTPRequests() 96 public HttpRequestModule()
97 { 97 {
98 } 98 }
99 99
100 public void Initialise(Scene scene, IConfigSource config) 100 public void Initialise(Scene scene, IConfigSource config)
101 { 101 {
102 m_scene = scene; 102 m_scene = scene;
103 103
104 m_scene.RegisterModuleInterface<IHttpRequests>(this); 104 m_scene.RegisterModuleInterface<IHttpRequests>(this);
105 105
106 m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>(); 106 m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>();
107 } 107 }
108 108
109 public void PostInitialise() 109 public void PostInitialise()
110 { 110 {
111 } 111 }
112 112
113 public void Close() 113 public void Close()
114 { 114 {
115 } 115 }
116 116
117 public string Name 117 public string Name
118 { 118 {
119 get { return m_name; } 119 get { return m_name; }
120 } 120 }
121 121
122 public bool IsSharedModule 122 public bool IsSharedModule
123 { 123 {
124 get { return true; } 124 get { return true; }
125 } 125 }
126 126
127 public LLUUID MakeHttpRequest(string url, string parameters, string body) 127 public LLUUID MakeHttpRequest(string url, string parameters, string body)
128 { 128 {
129 return LLUUID.Zero; 129 return LLUUID.Zero;
130 } 130 }
131 131
132 public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body) 132 public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body)
133 { 133 {
134 LLUUID reqID = LLUUID.Random(); 134 LLUUID reqID = LLUUID.Random();
135 HttpRequestClass htc = new HttpRequestClass(); 135 HttpRequestClass htc = new HttpRequestClass();
136 136
137 // Partial implementation: support for parameter flags needed 137 // Partial implementation: support for parameter flags needed
138 // see http://wiki.secondlife.com/wiki/LlHTTPRequest 138 // see http://wiki.secondlife.com/wiki/LlHTTPRequest
139 // 139 //
140 // Parameters are expected in {key, value, ... , key, value} 140 // Parameters are expected in {key, value, ... , key, value}
141 if (parameters != null) 141 if (parameters != null)
142 { 142 {
143 string[] parms = parameters.ToArray(); 143 string[] parms = parameters.ToArray();
144 for (int i = 0; i < parms.Length/2; i += 2) 144 for (int i = 0; i < parms.Length/2; i += 2)
145 { 145 {
146 switch (Int32.Parse(parms[i])) 146 switch (Int32.Parse(parms[i]))
147 { 147 {
148 case HttpRequestClass.HTTP_METHOD: 148 case HttpRequestClass.HTTP_METHOD:
149 149
150 htc.httpMethod = parms[i + 1]; 150 htc.httpMethod = parms[i + 1];
151 break; 151 break;
152 152
153 case HttpRequestClass.HTTP_MIMETYPE: 153 case HttpRequestClass.HTTP_MIMETYPE:
154 154
155 htc.httpMIMEType = parms[i + 1]; 155 htc.httpMIMEType = parms[i + 1];
156 break; 156 break;
157 157
158 case HttpRequestClass.HTTP_BODY_MAXLENGTH: 158 case HttpRequestClass.HTTP_BODY_MAXLENGTH:
159 159
160 // TODO implement me 160 // TODO implement me
161 break; 161 break;
162 162
163 case HttpRequestClass.HTTP_VERIFY_CERT: 163 case HttpRequestClass.HTTP_VERIFY_CERT:
164 164
165 // TODO implement me 165 // TODO implement me
166 break; 166 break;
167 } 167 }
168 } 168 }
169 } 169 }
170 170
171 htc.localID = localID; 171 htc.localID = localID;
172 htc.itemID = itemID; 172 htc.itemID = itemID;
173 htc.url = url; 173 htc.url = url;
174 htc.reqID = reqID; 174 htc.reqID = reqID;
175 htc.httpTimeout = httpTimeout; 175 htc.httpTimeout = httpTimeout;
176 htc.outbound_body = body; 176 htc.outbound_body = body;
177 177
178 lock (HttpListLock) 178 lock (HttpListLock)
179 { 179 {
180 m_pendingRequests.Add(reqID, htc); 180 m_pendingRequests.Add(reqID, htc);
181 } 181 }
182 182
183 htc.process(); 183 htc.process();
184 184
185 return reqID; 185 return reqID;
186 } 186 }
187 187
188 public void StopHttpRequest(uint m_localID, LLUUID m_itemID) 188 public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
189 { 189 {
190 if(m_pendingRequests != null) { 190 if(m_pendingRequests != null) {
191 lock (HttpListLock) 191 lock (HttpListLock)
192 { 192 {
193 HttpRequestClass tmpReq; 193 HttpRequestClass tmpReq;
194 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) 194 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
195 { 195 {
196 tmpReq.Stop(); 196 tmpReq.Stop();
197 m_pendingRequests.Remove(m_itemID); 197 m_pendingRequests.Remove(m_itemID);
198 } 198 }
199 } 199 }
200 } 200 }
201 } 201 }
202 202
203 /* 203 /*
204 * TODO 204 * TODO
205 * Not sure how important ordering is is here - the next first 205 * Not sure how important ordering is is here - the next first
206 * one completed in the list is returned, based soley on its list 206 * one completed in the list is returned, based soley on its list
207 * position, not the order in which the request was started or 207 * position, not the order in which the request was started or
208 * finsihed. I thought about setting up a queue for this, but 208 * finsihed. I thought about setting up a queue for this, but
209 * it will need some refactoring and this works 'enough' right now 209 * it will need some refactoring and this works 'enough' right now
210 */ 210 */
211 211
212 public HttpRequestClass GetNextCompletedRequest() 212 public HttpRequestClass GetNextCompletedRequest()
213 { 213 {
214 lock (HttpListLock) 214 lock (HttpListLock)
215 { 215 {
216 foreach (LLUUID luid in m_pendingRequests.Keys) 216 foreach (LLUUID luid in m_pendingRequests.Keys)
217 { 217 {
218 HttpRequestClass tmpReq; 218 HttpRequestClass tmpReq;
219 219
220 if (m_pendingRequests.TryGetValue(luid, out tmpReq)) 220 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
221 { 221 {
222 if (tmpReq.finished) 222 if (tmpReq.finished)
223 { 223 {
224 return tmpReq; 224 return tmpReq;
225 } 225 }
226 } 226 }
227 } 227 }
228 } 228 }
229 return null; 229 return null;
230 } 230 }
231 231
232 public void RemoveCompletedRequest(LLUUID id) 232 public void RemoveCompletedRequest(LLUUID id)
233 { 233 {
234 lock (HttpListLock) 234 lock (HttpListLock)
235 { 235 {
236 HttpRequestClass tmpReq; 236 HttpRequestClass tmpReq;
237 if (m_pendingRequests.TryGetValue(id, out tmpReq)) 237 if (m_pendingRequests.TryGetValue(id, out tmpReq))
238 { 238 {
239 tmpReq.Stop(); 239 tmpReq.Stop();
240 tmpReq = null; 240 tmpReq = null;
241 m_pendingRequests.Remove(id); 241 m_pendingRequests.Remove(id);
242 } 242 }
243 } 243 }
244 } 244 }
245 245
246 } 246 }
247 247
248 // 248 public class HttpRequestClass
249 // HTTP REAQUEST 249 {
250 // This class was originally in LSLLongCmdHandler 250 // Constants for parameters
251 // 251 public const int HTTP_METHOD = 0;
252 // TODO: setter/getter methods, maybe pass some in 252 public const int HTTP_MIMETYPE = 1;
253 // constructor 253 public const int HTTP_BODY_MAXLENGTH = 2;
254 // 254 public const int HTTP_VERIFY_CERT = 3;
255 255
256 public class HttpRequestClass 256 // Parameter members and default values
257 { 257 public string httpMethod = "GET";
258 // Constants for parameters 258 public string httpMIMEType = "text/plain;charset=utf-8";
259 public const int HTTP_METHOD = 0; 259 public int httpBodyMaxLen = 2048; // not implemented
260 public const int HTTP_MIMETYPE = 1; 260 public bool httpVerifyCert = true; // not implemented
261 public const int HTTP_BODY_MAXLENGTH = 2; 261
262 public const int HTTP_VERIFY_CERT = 3; 262 // Request info
263 263 public uint localID;
264 // Parameter members and default values 264 public LLUUID itemID;
265 public string httpMethod = "GET"; 265 public LLUUID reqID;
266 public string httpMIMEType = "text/plain;charset=utf-8"; 266 public int httpTimeout;
267 public int httpBodyMaxLen = 2048; // not implemented 267 public string url;
268 public bool httpVerifyCert = true; // not implemented 268 public string outbound_body;
269 269 public DateTime next;
270 // Request info 270 public int status;
271 public uint localID; 271 public bool finished;
272 public LLUUID itemID; 272 public List<string> response_metadata;
273 public LLUUID reqID; 273 public string response_body;
274 public int httpTimeout; 274 public HttpWebRequest request;
275 public string url; 275 private Thread httpThread;
276 public string outbound_body; 276
277 public DateTime next; 277 public void process()
278 public int status; 278 {
279 public bool finished; 279 httpThread = new Thread(SendRequest);
280 public List<string> response_metadata; 280 httpThread.Name = "HttpRequestThread";
281 public string response_body; 281 httpThread.Priority = ThreadPriority.BelowNormal;
282 public HttpWebRequest request; 282 httpThread.IsBackground = true;
283 private Thread httpThread; 283 finished = false;
284 284 httpThread.Start();
285 public void process() 285 ThreadTracker.Add(httpThread);
286 { 286 }
287 httpThread = new Thread(SendRequest); 287
288 httpThread.Name = "HttpRequestThread"; 288 /*
289 httpThread.Priority = ThreadPriority.BelowNormal; 289 * TODO: More work on the response codes. Right now
290 httpThread.IsBackground = true; 290 * returning 200 for success or 499 for exception
291 finished = false; 291 */
292 httpThread.Start(); 292
293 ThreadTracker.Add(httpThread); 293 public void SendRequest()
294 } 294 {
295 295 HttpWebResponse response = null;
296 /* 296 StringBuilder sb = new StringBuilder();
297 * TODO: More work on the response codes. Right now 297 byte[] buf = new byte[8192];
298 * returning 200 for success or 499 for exception 298 string tempString = null;
299 */ 299 int count = 0;
300 300
301 public void SendRequest() 301 try
302 { 302 {
303 HttpWebResponse response = null; 303 request = (HttpWebRequest)
304 StringBuilder sb = new StringBuilder(); 304 WebRequest.Create(url);
305 byte[] buf = new byte[8192]; 305 request.Method = httpMethod;
306 string tempString = null; 306 request.ContentType = httpMIMEType;
307 int count = 0; 307
308 308 request.Timeout = httpTimeout;
309 try 309 // execute the request
310 { 310 response = (HttpWebResponse)
311 request = (HttpWebRequest) 311 request.GetResponse();
312 WebRequest.Create(url); 312
313 request.Method = httpMethod; 313 Stream resStream = response.GetResponseStream();
314 request.ContentType = httpMIMEType; 314
315 315 do
316 request.Timeout = httpTimeout; 316 {
317 // execute the request 317 // fill the buffer with data
318 response = (HttpWebResponse) 318 count = resStream.Read(buf, 0, buf.Length);
319 request.GetResponse(); 319
320 320 // make sure we read some data
321 Stream resStream = response.GetResponseStream(); 321 if (count != 0)
322 322 {
323 do 323 // translate from bytes to ASCII text
324 { 324 tempString = Encoding.UTF8.GetString(buf, 0, count);
325 // fill the buffer with data 325
326 count = resStream.Read(buf, 0, buf.Length); 326 // continue building the string
327 327 sb.Append(tempString);
328 // make sure we read some data 328 }
329 if (count != 0) 329 } while (count > 0); // any more data to read?
330 { 330
331 // translate from bytes to ASCII text 331 response_body = sb.ToString();
332 tempString = Encoding.UTF8.GetString(buf, 0, count); 332 }
333 333 catch (Exception e)
334 // continue building the string 334 {
335 sb.Append(tempString); 335 status = 499;
336 } 336 response_body = e.Message;
337 } while (count > 0); // any more data to read? 337 finished = true;
338 338 return;
339 response_body = sb.ToString(); 339 }
340 } 340
341 catch (Exception e) 341 status = 200;
342 { 342 finished = true;
343 status = 499; 343 }
344 response_body = e.Message; 344
345 finished = true; 345 public void Stop()
346 return; 346 {
347 } 347 try
348 348 {
349 status = 200; 349 httpThread.Abort();
350 finished = true; 350 }
351 } 351 catch (Exception)
352 352 {
353 public void Stop() 353 }
354 { 354 }
355 try 355 }
356 { 356} \ No newline at end of file
357 httpThread.Abort();
358 }
359 catch (Exception)
360 {
361 }
362 }
363 }
364}
diff --git a/OpenSim/Region/Environment/Modules/LoadImageURLModule.cs b/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6c8b028..eaf9d36 100644
--- a/OpenSim/Region/Environment/Modules/LoadImageURLModule.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -1,180 +1,179 @@
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
28using System; 28using System;
29using System.Drawing; 29using System.Drawing;
30using System.IO; 30using System.IO;
31using System.Net; 31using System.Net;
32using libsecondlife; 32using libsecondlife;
33using Nini.Config; 33using Nini.Config;
34using OpenJPEGNet; 34using OpenJPEGNet;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Scenes; 36using OpenSim.Region.Environment.Scenes;
37 37
38namespace OpenSim.Region.Environment.Modules 38namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL
39{ 39{
40 40 public class LoadImageURLModule : IRegionModule, IDynamicTextureRender
41 public class LoadImageURLModule : IRegionModule, IDynamicTextureRender 41 {
42 { 42 private string m_name = "LoadImageURL";
43 private string m_name = "LoadImageURL"; 43 private IDynamicTextureManager m_textureManager;
44 private IDynamicTextureManager m_textureManager; 44 private Scene m_scene;
45 private Scene m_scene; 45
46 46 public void Initialise(Scene scene, IConfigSource config)
47 public void Initialise(Scene scene, IConfigSource config) 47 {
48 { 48 if (m_scene == null)
49 if (m_scene == null) 49 {
50 { 50 m_scene = scene;
51 m_scene = scene; 51 }
52 } 52 }
53 } 53
54 54 public void PostInitialise()
55 public void PostInitialise() 55 {
56 { 56 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
57 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); 57 if (m_textureManager != null)
58 if (m_textureManager != null) 58 {
59 { 59 m_textureManager.RegisterRender(GetContentType(), this);
60 m_textureManager.RegisterRender(GetContentType(), this); 60 }
61 } 61 }
62 } 62
63 63 public void Close()
64 public void Close() 64 {
65 { 65 }
66 } 66
67 67 public string Name
68 public string Name 68 {
69 { 69 get { return m_name; }
70 get { return m_name; } 70 }
71 } 71
72 72 public bool IsSharedModule
73 public bool IsSharedModule 73 {
74 { 74 get { return true; }
75 get { return true; } 75 }
76 } 76
77 77 public string GetName()
78 public string GetName() 78 {
79 { 79 return m_name;
80 return m_name; 80 }
81 } 81
82 82 public string GetContentType()
83 public string GetContentType() 83 {
84 { 84 return ("image");
85 return ("image"); 85 }
86 } 86
87 87 public bool SupportsAsynchronous()
88 public bool SupportsAsynchronous() 88 {
89 { 89 return true;
90 return true; 90 }
91 } 91
92 92 public byte[] ConvertUrl(string url, string extraParams)
93 public byte[] ConvertUrl(string url, string extraParams) 93 {
94 { 94 return null;
95 return null; 95 }
96 } 96
97 97 public byte[] ConvertStream(Stream data, string extraParams)
98 public byte[] ConvertStream(Stream data, string extraParams) 98 {
99 { 99 return null;
100 return null; 100 }
101 } 101
102 102 public bool AsyncConvertUrl(LLUUID id, string url, string extraParams)
103 public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) 103 {
104 { 104 MakeHttpRequest(url, id);
105 MakeHttpRequest(url, id); 105 return true;
106 return true; 106 }
107 } 107
108 108 public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams)
109 public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) 109 {
110 { 110 return false;
111 return false; 111 }
112 } 112
113 113 private void MakeHttpRequest(string url, LLUUID requestID)
114 private void MakeHttpRequest(string url, LLUUID requestID) 114 {
115 { 115 WebRequest request = HttpWebRequest.Create(url);
116 WebRequest request = HttpWebRequest.Create(url); 116 RequestState state = new RequestState((HttpWebRequest) request, requestID);
117 RequestState state = new RequestState((HttpWebRequest) request, requestID); 117 IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state);
118 IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); 118
119 119 TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
120 TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); 120 state.TimeOfRequest = (int) t.TotalSeconds;
121 state.TimeOfRequest = (int) t.TotalSeconds; 121 }
122 } 122
123 123 private void HttpRequestReturn(IAsyncResult result)
124 private void HttpRequestReturn(IAsyncResult result) 124 {
125 { 125 RequestState state = (RequestState) result.AsyncState;
126 RequestState state = (RequestState) result.AsyncState; 126 WebRequest request = (WebRequest) state.Request;
127 WebRequest request = (WebRequest) state.Request; 127 HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result);
128 HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result); 128 if (response.StatusCode == HttpStatusCode.OK)
129 if (response.StatusCode == HttpStatusCode.OK) 129 {
130 { 130 Bitmap image = new Bitmap(response.GetResponseStream());
131 Bitmap image = new Bitmap(response.GetResponseStream()); 131 Size newsize;
132 Size newsize; 132
133 133 // TODO: make this a bit less hard coded
134 // TODO: make this a bit less hard coded 134 if ((image.Height < 64) && (image.Width < 64))
135 if ((image.Height < 64) && (image.Width < 64)) 135 {
136 { 136 newsize = new Size(32, 32);
137 newsize = new Size(32, 32); 137 }
138 } 138 else if ((image.Height < 128) && (image.Width < 128))
139 else if ((image.Height < 128) && (image.Width < 128)) 139 {
140 { 140 newsize = new Size(64, 64);
141 newsize = new Size(64, 64); 141 }
142 } 142 else if ((image.Height <256) && (image.Width < 256))
143 else if ((image.Height <256) && (image.Width < 256)) 143 {
144 { 144 newsize = new Size(128, 128);
145 newsize = new Size(128, 128); 145 }
146 } 146 else if ((image.Height < 512 && image.Width < 512))
147 else if ((image.Height < 512 && image.Width < 512)) 147 {
148 { 148 newsize = new Size(256, 256);
149 newsize = new Size(256, 256); 149 }
150 } 150 else if ((image.Height < 1024 && image.Width < 1024))
151 else if ((image.Height < 1024 && image.Width < 1024)) 151 {
152 { 152 newsize = new Size(512, 512);
153 newsize = new Size(512, 512); 153 }
154 } 154 else
155 else 155 {
156 { 156 newsize = new Size(1024,1024);
157 newsize = new Size(1024,1024); 157 }
158 } 158
159 159 Bitmap resize = new Bitmap(image, newsize);
160 Bitmap resize = new Bitmap(image, newsize); 160 byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
161 byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); 161
162 162 m_textureManager.ReturnData(state.RequestID, imageJ2000);
163 m_textureManager.ReturnData(state.RequestID, imageJ2000); 163 }
164 } 164 }
165 } 165
166 166 public class RequestState
167 public class RequestState 167 {
168 { 168 public HttpWebRequest Request = null;
169 public HttpWebRequest Request = null; 169 public LLUUID RequestID = LLUUID.Zero;
170 public LLUUID RequestID = LLUUID.Zero; 170 public int TimeOfRequest = 0;
171 public int TimeOfRequest = 0; 171
172 172 public RequestState(HttpWebRequest request, LLUUID requestID)
173 public RequestState(HttpWebRequest request, LLUUID requestID) 173 {
174 { 174 Request = request;
175 Request = request; 175 RequestID = requestID;
176 RequestID = requestID; 176 }
177 } 177 }
178 } 178 }
179 } 179} \ No newline at end of file
180}
diff --git a/OpenSim/Region/Environment/Modules/VectorRenderModule.cs b/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs
index 0ea6fc3..4fba5b9 100644
--- a/OpenSim/Region/Environment/Modules/VectorRenderModule.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs
@@ -1,361 +1,361 @@
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
28using System; 28using System;
29using System.Drawing; 29using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Net; 33using System.Net;
34using libsecondlife; 34using libsecondlife;
35using Nini.Config; 35using Nini.Config;
36using OpenJPEGNet; 36using OpenJPEGNet;
37using OpenSim.Region.Environment.Interfaces; 37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
39using Image=System.Drawing.Image; 39using Image=System.Drawing.Image;
40 40
41//using Cairo; 41//using Cairo;
42 42
43namespace OpenSim.Region.Environment.Modules 43namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender
44{ 44{
45 public class VectorRenderModule : IRegionModule, IDynamicTextureRender 45 public class VectorRenderModule : IRegionModule, IDynamicTextureRender
46 { 46 {
47 private Scene m_scene; 47 private Scene m_scene;
48 private string m_name = "VectorRenderModule"; 48 private string m_name = "VectorRenderModule";
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 public void Initialise(Scene scene, IConfigSource config) 55 public void Initialise(Scene scene, IConfigSource config)
56 { 56 {
57 if (m_scene == null) 57 if (m_scene == null)
58 { 58 {
59 m_scene = scene; 59 m_scene = scene;
60 } 60 }
61 } 61 }
62 62
63 public void PostInitialise() 63 public void PostInitialise()
64 { 64 {
65 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); 65 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
66 if (m_textureManager != null) 66 if (m_textureManager != null)
67 { 67 {
68 m_textureManager.RegisterRender(GetContentType(), this); 68 m_textureManager.RegisterRender(GetContentType(), this);
69 } 69 }
70 } 70 }
71 71
72 public void Close() 72 public void Close()
73 { 73 {
74 } 74 }
75 75
76 public string Name 76 public string Name
77 { 77 {
78 get { return m_name; } 78 get { return m_name; }
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 private void Draw(string data, LLUUID id, string extraParams) 86 private void Draw(string data, LLUUID id, string extraParams)
87 { 87 {
88 // TODO: this is a brutal hack. extraParams should actually be parsed reasonably. 88 // TODO: this is a brutal hack. extraParams should actually be parsed reasonably.
89 int size = 256; 89 int size = 256;
90 try { 90 try {
91 size = Convert.ToInt32(extraParams); 91 size = Convert.ToInt32(extraParams);
92 } catch (Exception e) { 92 } catch (Exception e) {
93 93
94//Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used 94//Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used
95 Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString()); 95 Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString());
96 } 96 }
97 97
98 if ((size < 128) || (size > 1024)) 98 if ((size < 128) || (size > 1024))
99 size = 256; 99 size = 256;
100 100
101 Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb); 101 Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb);
102 102
103 Graphics graph = Graphics.FromImage(bitmap); 103 Graphics graph = Graphics.FromImage(bitmap);
104 104
105 extraParams = extraParams.ToLower(); 105 extraParams = extraParams.ToLower();
106 int alpha = 255; 106 int alpha = 255;
107 if (extraParams == "setalpha") 107 if (extraParams == "setalpha")
108 { 108 {
109 alpha = 0; 109 alpha = 0;
110 } 110 }
111 else 111 else
112 { 112 {
113 graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size); 113 graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size);
114 } 114 }
115 115
116 for (int w = 0; w < bitmap.Width; w++) 116 for (int w = 0; w < bitmap.Width; w++)
117 { 117 {
118 for (int h = 0; h < bitmap.Height; h++) 118 for (int h = 0; h < bitmap.Height; h++)
119 { 119 {
120 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); 120 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
121 } 121 }
122 } 122 }
123 123
124 124
125 125
126 GDIDraw(data, graph); 126 GDIDraw(data, graph);
127 127
128 byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); 128 byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
129 m_textureManager.ReturnData(id, imageJ2000); 129 m_textureManager.ReturnData(id, imageJ2000);
130 130
131 } 131 }
132 132
133/* 133/*
134 private void CairoDraw(string data, System.Drawing.Graphics graph) 134 private void CairoDraw(string data, System.Drawing.Graphics graph)
135 { 135 {
136 using (Win32Surface draw = new Win32Surface(graph.GetHdc())) 136 using (Win32Surface draw = new Win32Surface(graph.GetHdc()))
137 { 137 {
138 Context contex = new Context(draw); 138 Context contex = new Context(draw);
139 139
140 contex.Antialias = Antialias.None; //fastest method but low quality 140 contex.Antialias = Antialias.None; //fastest method but low quality
141 contex.LineWidth = 7; 141 contex.LineWidth = 7;
142 char[] lineDelimiter = { ';' }; 142 char[] lineDelimiter = { ';' };
143 char[] partsDelimiter = { ',' }; 143 char[] partsDelimiter = { ',' };
144 string[] lines = data.Split(lineDelimiter); 144 string[] lines = data.Split(lineDelimiter);
145 145
146 foreach (string line in lines) 146 foreach (string line in lines)
147 { 147 {
148 string nextLine = line.Trim(); 148 string nextLine = line.Trim();
149 149
150 if (nextLine.StartsWith("MoveTO")) 150 if (nextLine.StartsWith("MoveTO"))
151 { 151 {
152 float x = 0; 152 float x = 0;
153 float y = 0; 153 float y = 0;
154 GetParams(partsDelimiter, ref nextLine, ref x, ref y); 154 GetParams(partsDelimiter, ref nextLine, ref x, ref y);
155 contex.MoveTo(x, y); 155 contex.MoveTo(x, y);
156 } 156 }
157 else if (nextLine.StartsWith("LineTo")) 157 else if (nextLine.StartsWith("LineTo"))
158 { 158 {
159 float x = 0; 159 float x = 0;
160 float y = 0; 160 float y = 0;
161 GetParams(partsDelimiter, ref nextLine, ref x, ref y); 161 GetParams(partsDelimiter, ref nextLine, ref x, ref y);
162 contex.LineTo(x, y); 162 contex.LineTo(x, y);
163 contex.Stroke(); 163 contex.Stroke();
164 } 164 }
165 } 165 }
166 } 166 }
167 graph.ReleaseHdc(); 167 graph.ReleaseHdc();
168 } 168 }
169*/ 169*/
170 170
171 private void GDIDraw(string data, Graphics graph) 171 private void GDIDraw(string data, Graphics graph)
172 { 172 {
173 Point startPoint = new Point(0, 0); 173 Point startPoint = new Point(0, 0);
174 Point endPoint = new Point(0, 0); 174 Point endPoint = new Point(0, 0);
175 Pen drawPen = new Pen(Color.Black, 7); 175 Pen drawPen = new Pen(Color.Black, 7);
176 Font myFont = new Font("Times New Roman", 14); 176 Font myFont = new Font("Times New Roman", 14);
177 SolidBrush myBrush = new SolidBrush(Color.Black); 177 SolidBrush myBrush = new SolidBrush(Color.Black);
178 char[] lineDelimiter = { ';' }; 178 char[] lineDelimiter = { ';' };
179 char[] partsDelimiter = { ',' }; 179 char[] partsDelimiter = { ',' };
180 string[] lines = data.Split(lineDelimiter); 180 string[] lines = data.Split(lineDelimiter);
181 181
182 foreach (string line in lines) 182 foreach (string line in lines)
183 { 183 {
184 string nextLine = line.Trim(); 184 string nextLine = line.Trim();
185 //replace with switch, or even better, do some proper parsing 185 //replace with switch, or even better, do some proper parsing
186 if (nextLine.StartsWith("MoveTo")) 186 if (nextLine.StartsWith("MoveTo"))
187 { 187 {
188 float x = 0; 188 float x = 0;
189 float y = 0; 189 float y = 0;
190 GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); 190 GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
191 startPoint.X = (int)x; 191 startPoint.X = (int)x;
192 startPoint.Y = (int)y; 192 startPoint.Y = (int)y;
193 } 193 }
194 else if (nextLine.StartsWith("LineTo")) 194 else if (nextLine.StartsWith("LineTo"))
195 { 195 {
196 float x = 0; 196 float x = 0;
197 float y = 0; 197 float y = 0;
198 GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); 198 GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
199 endPoint.X = (int)x; 199 endPoint.X = (int)x;
200 endPoint.Y = (int)y; 200 endPoint.Y = (int)y;
201 graph.DrawLine(drawPen, startPoint, endPoint); 201 graph.DrawLine(drawPen, startPoint, endPoint);
202 startPoint.X = endPoint.X; 202 startPoint.X = endPoint.X;
203 startPoint.Y = endPoint.Y; 203 startPoint.Y = endPoint.Y;
204 } 204 }
205 else if (nextLine.StartsWith("Text")) 205 else if (nextLine.StartsWith("Text"))
206 { 206 {
207 nextLine = nextLine.Remove(0, 4); 207 nextLine = nextLine.Remove(0, 4);
208 nextLine = nextLine.Trim(); 208 nextLine = nextLine.Trim();
209 graph.DrawString(nextLine, myFont, myBrush, startPoint); 209 graph.DrawString(nextLine, myFont, myBrush, startPoint);
210 } 210 }
211 else if (nextLine.StartsWith("Image")) 211 else if (nextLine.StartsWith("Image"))
212 { 212 {
213 float x = 0; 213 float x = 0;
214 float y = 0; 214 float y = 0;
215 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 215 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
216 endPoint.X = (int)x; 216 endPoint.X = (int)x;
217 endPoint.Y = (int)y; 217 endPoint.Y = (int)y;
218 Image image = ImageHttpRequest(nextLine); 218 Image image = ImageHttpRequest(nextLine);
219 graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y); 219 graph.DrawImage(image, (float)startPoint.X, (float)startPoint.Y, x, y);
220 startPoint.X += endPoint.X; 220 startPoint.X += endPoint.X;
221 startPoint.Y += endPoint.Y; 221 startPoint.Y += endPoint.Y;
222 } 222 }
223 else if (nextLine.StartsWith("Rectangle")) 223 else if (nextLine.StartsWith("Rectangle"))
224 { 224 {
225 float x = 0; 225 float x = 0;
226 float y = 0; 226 float y = 0;
227 GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y); 227 GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
228 endPoint.X = (int)x; 228 endPoint.X = (int)x;
229 endPoint.Y = (int)y; 229 endPoint.Y = (int)y;
230 graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); 230 graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
231 startPoint.X += endPoint.X; 231 startPoint.X += endPoint.X;
232 startPoint.Y += endPoint.Y; 232 startPoint.Y += endPoint.Y;
233 } 233 }
234 else if (nextLine.StartsWith("FillRectangle")) 234 else if (nextLine.StartsWith("FillRectangle"))
235 { 235 {
236 float x = 0; 236 float x = 0;
237 float y = 0; 237 float y = 0;
238 GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y); 238 GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
239 endPoint.X = (int)x; 239 endPoint.X = (int)x;
240 endPoint.Y = (int)y; 240 endPoint.Y = (int)y;
241 graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); 241 graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
242 startPoint.X += endPoint.X; 242 startPoint.X += endPoint.X;
243 startPoint.Y += endPoint.Y; 243 startPoint.Y += endPoint.Y;
244 } 244 }
245 else if (nextLine.StartsWith("Ellipse")) 245 else if (nextLine.StartsWith("Ellipse"))
246 { 246 {
247 float x = 0; 247 float x = 0;
248 float y = 0; 248 float y = 0;
249 GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y); 249 GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
250 endPoint.X = (int)x; 250 endPoint.X = (int)x;
251 endPoint.Y = (int)y; 251 endPoint.Y = (int)y;
252 graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); 252 graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
253 startPoint.X += endPoint.X; 253 startPoint.X += endPoint.X;
254 startPoint.Y += endPoint.Y; 254 startPoint.Y += endPoint.Y;
255 } 255 }
256 else if (nextLine.StartsWith("FontSize")) 256 else if (nextLine.StartsWith("FontSize"))
257 { 257 {
258 nextLine = nextLine.Remove(0, 8); 258 nextLine = nextLine.Remove(0, 8);
259 nextLine = nextLine.Trim(); 259 nextLine = nextLine.Trim();
260 float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); 260 float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
261 myFont = new Font("Times New Roman", size); 261 myFont = new Font("Times New Roman", size);
262 } 262 }
263 else if (nextLine.StartsWith("PenSize")) 263 else if (nextLine.StartsWith("PenSize"))
264 { 264 {
265 nextLine = nextLine.Remove(0, 8); 265 nextLine = nextLine.Remove(0, 8);
266 nextLine = nextLine.Trim(); 266 nextLine = nextLine.Trim();
267 float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); 267 float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
268 drawPen.Width = size; 268 drawPen.Width = size;
269 } 269 }
270 else if (nextLine.StartsWith("PenColour")) 270 else if (nextLine.StartsWith("PenColour"))
271 { 271 {
272 nextLine = nextLine.Remove(0, 9); 272 nextLine = nextLine.Remove(0, 9);
273 nextLine = nextLine.Trim(); 273 nextLine = nextLine.Trim();
274 274
275 Color newColour = Color.FromName(nextLine); 275 Color newColour = Color.FromName(nextLine);
276 276
277 myBrush.Color = newColour; 277 myBrush.Color = newColour;
278 drawPen.Color = newColour; 278 drawPen.Color = newColour;
279 } 279 }
280 } 280 }
281 } 281 }
282 282
283 private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) 283 private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y)
284 { 284 {
285 line = line.Remove(0, startLength); 285 line = line.Remove(0, startLength);
286 string[] parts = line.Split(partsDelimiter); 286 string[] parts = line.Split(partsDelimiter);
287 if (parts.Length == 2) 287 if (parts.Length == 2)
288 { 288 {
289 string xVal = parts[0].Trim(); 289 string xVal = parts[0].Trim();
290 string yVal = parts[1].Trim(); 290 string yVal = parts[1].Trim();
291 x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); 291 x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
292 y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); 292 y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
293 } 293 }
294 else if (parts.Length > 2) 294 else if (parts.Length > 2)
295 { 295 {
296 string xVal = parts[0].Trim(); 296 string xVal = parts[0].Trim();
297 string yVal = parts[1].Trim(); 297 string yVal = parts[1].Trim();
298 x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); 298 x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
299 y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); 299 y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
300 300
301 line = ""; 301 line = "";
302 for (int i = 2; i < parts.Length; i++) 302 for (int i = 2; i < parts.Length; i++)
303 { 303 {
304 line = line + parts[i].Trim(); 304 line = line + parts[i].Trim();
305 line = line + " "; 305 line = line + " ";
306 } 306 }
307 } 307 }
308 } 308 }
309 309
310 private Bitmap ImageHttpRequest(string url) 310 private Bitmap ImageHttpRequest(string url)
311 { 311 {
312 WebRequest request = HttpWebRequest.Create(url); 312 WebRequest request = HttpWebRequest.Create(url);
313//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. 313//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used.
314//Ckrinke Stream str = null; 314//Ckrinke Stream str = null;
315 HttpWebResponse response = (HttpWebResponse)(request).GetResponse(); 315 HttpWebResponse response = (HttpWebResponse)(request).GetResponse();
316 if (response.StatusCode == HttpStatusCode.OK) 316 if (response.StatusCode == HttpStatusCode.OK)
317 { 317 {
318 Bitmap image = new Bitmap(response.GetResponseStream()); 318 Bitmap image = new Bitmap(response.GetResponseStream());
319 return image; 319 return image;
320 } 320 }
321 321
322 return null; 322 return null;
323 } 323 }
324 324
325 public string GetContentType() 325 public string GetContentType()
326 { 326 {
327 return ("vector"); 327 return ("vector");
328 } 328 }
329 329
330 public string GetName() 330 public string GetName()
331 { 331 {
332 return m_name; 332 return m_name;
333 } 333 }
334 334
335 public bool SupportsAsynchronous() 335 public bool SupportsAsynchronous()
336 { 336 {
337 return true; 337 return true;
338 } 338 }
339 339
340 public byte[] ConvertUrl(string url, string extraParams) 340 public byte[] ConvertUrl(string url, string extraParams)
341 { 341 {
342 return null; 342 return null;
343 } 343 }
344 344
345 public byte[] ConvertStream(Stream data, string extraParams) 345 public byte[] ConvertStream(Stream data, string extraParams)
346 { 346 {
347 return null; 347 return null;
348 } 348 }
349 349
350 public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) 350 public bool AsyncConvertUrl(LLUUID id, string url, string extraParams)
351 { 351 {
352 return false; 352 return false;
353 } 353 }
354 354
355 public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) 355 public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams)
356 { 356 {
357 Draw(bodyData, id, extraParams); 357 Draw(bodyData, id, extraParams);
358 return true; 358 return true;
359 } 359 }
360 } 360 }
361} 361} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/WorldCommModule.cs b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs
index 638deed..a949fb6 100644
--- a/OpenSim/Region/Environment/Modules/WorldCommModule.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs
@@ -1,584 +1,578 @@
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
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using libsecondlife; 30using libsecondlife;
31using Nini.Config; 31using Nini.Config;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using 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
66namespace OpenSim.Region.Environment.Modules 66namespace OpenSim.Region.Environment.Modules.Scripting.WorldComm
67{ 67{
68 public class WorldCommModule : IRegionModule, IWorldComm 68 public class WorldCommModule : IRegionModule, IWorldComm
69 { 69 {
70 private Scene m_scene; 70 private Scene m_scene;
71 private object CommListLock = new object(); 71 private object CommListLock = new object();
72 private object ListLock = new object(); 72 private object ListLock = new object();
73 private string m_name = "WorldCommModule"; 73 private string m_name = "WorldCommModule";
74 private ListenerManager m_listenerManager; 74 private ListenerManager m_listenerManager;
75 private Queue m_pendingQ; 75 private Queue m_pendingQ;
76 private Queue m_pending; 76 private Queue m_pending;
77 77
78 public WorldCommModule() 78 public WorldCommModule()
79 { 79 {
80 } 80 }
81 81
82 public void Initialise(Scene scene, IConfigSource config) 82 public void Initialise(Scene scene, IConfigSource config)
83 { 83 {
84 m_scene = scene; 84 m_scene = scene;
85 m_scene.RegisterModuleInterface<IWorldComm>(this); 85 m_scene.RegisterModuleInterface<IWorldComm>(this);
86 m_listenerManager = new ListenerManager(); 86 m_listenerManager = new ListenerManager();
87 m_scene.EventManager.OnNewClient += NewClient; 87 m_scene.EventManager.OnNewClient += NewClient;
88 m_pendingQ = new Queue(); 88 m_pendingQ = new Queue();
89 m_pending = Queue.Synchronized(m_pendingQ); 89 m_pending = Queue.Synchronized(m_pendingQ);
90 } 90 }
91 91
92 public void PostInitialise() 92 public void PostInitialise()
93 { 93 {
94 } 94 }
95 95
96 public void Close() 96 public void Close()
97 { 97 {
98 } 98 }
99 99
100 public string Name 100 public string Name
101 { 101 {
102 get { return m_name; } 102 get { return m_name; }
103 } 103 }
104 104
105 public bool IsSharedModule 105 public bool IsSharedModule
106 { 106 {
107 get { return false; } 107 get { return false; }
108 } 108 }
109 109
110 public void NewClient(IClientAPI client) 110 public void NewClient(IClientAPI client)
111 { 111 {
112 client.OnChatFromViewer += DeliverClientMessage; 112 client.OnChatFromViewer += DeliverClientMessage;
113 } 113 }
114 114
115 /******************************************************************** 115 /********************************************************************
116 * 116 *
117 * Listener Stuff 117 * Listener Stuff
118 * 118 *
119 * *****************************************************************/ 119 * *****************************************************************/
120 private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) 120 private void DeliverClientMessage(Object sender, ChatFromViewerArgs e)
121 { 121 {
122 DeliverMessage(e.Sender.AgentId.ToString(), 122 DeliverMessage(e.Sender.AgentId.ToString(),
123 e.Type, e.Channel, 123 e.Type, e.Channel,
124 e.Sender.FirstName + " " + e.Sender.LastName, 124 e.Sender.FirstName + " " + e.Sender.LastName,
125 e.Message); 125 e.Message);
126 } 126 }
127 127
128 public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) 128 public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
129 { 129 {
130 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); 130 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg);
131 } 131 }
132 132
133 public void ListenControl(int handle, int active) 133 public void ListenControl(int handle, int active)
134 { 134 {
135 if (m_listenerManager != null) 135 if (m_listenerManager != null)
136 { 136 {
137 if (active == 1) 137 if (active == 1)
138 m_listenerManager.Activate(handle); 138 m_listenerManager.Activate(handle);
139 else if (active == 0) 139 else if (active == 0)
140 m_listenerManager.Dectivate(handle); 140 m_listenerManager.Dectivate(handle);
141 } 141 }
142 } 142 }
143 143
144 public void ListenRemove(int handle) 144 public void ListenRemove(int handle)
145 { 145 {
146 if (m_listenerManager != null) 146 if (m_listenerManager != null)
147 { 147 {
148 m_listenerManager.Remove(handle); 148 m_listenerManager.Remove(handle);
149 } 149 }
150 } 150 }
151 151
152 public void DeleteListener(LLUUID itemID) 152 public void DeleteListener(LLUUID itemID)
153 { 153 {
154 if (m_listenerManager != null) 154 if (m_listenerManager != null)
155 { 155 {
156 m_listenerManager.DeleteListener(itemID); 156 m_listenerManager.DeleteListener(itemID);
157 } 157 }
158 } 158 }
159 159
160 // This method scans nearby objects and determines if they are listeners, 160 // This method scans nearby objects and determines if they are listeners,
161 // and if so if this message fits the filter. If it does, then 161 // and if so if this message fits the filter. If it does, then
162 // enqueue the message for delivery to the objects listen event handler. 162 // enqueue the message for delivery to the objects listen event handler.
163 // Objects that do an llSay have their messages delivered here, and for 163 // Objects that do an llSay have their messages delivered here, and for
164 // nearby avatars, the SimChat function is used. 164 // nearby avatars, the SimChat function is used.
165 public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) 165 public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg)
166 { 166 {
167 SceneObjectPart source = null; 167 SceneObjectPart source = null;
168 ScenePresence avatar = null; 168 ScenePresence avatar = null;
169 169
170 source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); 170 source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID));
171 if (source == null) 171 if (source == null)
172 { 172 {
173 avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); 173 avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID));
174 } 174 }
175 if ((avatar != null) || (source != null)) 175 if ((avatar != null) || (source != null))
176 { 176 {
177 // Loop through the objects in the scene 177 // Loop through the objects in the scene
178 // If they are in proximity, then if they are 178 // If they are in proximity, then if they are
179 // listeners, if so add them to the pending queue 179 // listeners, if so add them to the pending queue
180 180
181 foreach (ListenerInfo li in m_listenerManager.GetListeners()) 181 foreach (ListenerInfo li in m_listenerManager.GetListeners())
182 { 182 {
183 EntityBase sPart; 183 EntityBase sPart;
184 184
185 m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); 185 m_scene.Entities.TryGetValue(li.GetHostID(), out sPart);
186 186
187 if (sPart != null) 187 if (sPart != null)
188 { 188 {
189 double dis = 0; 189 double dis = 0;
190 190
191 if (source != null) 191 if (source != null)
192 dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); 192 dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition);
193 else 193 else
194 dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); 194 dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition);
195 195
196 switch (type) 196 switch (type)
197 { 197 {
198 case ChatTypeEnum.Whisper: 198 case ChatTypeEnum.Whisper:
199 199
200 if ((dis < 10) && (dis > -10)) 200 if ((dis < 10) && (dis > -10))
201 { 201 {
202 if (li.GetChannel() == channel) 202 if (li.GetChannel() == channel)
203 { 203 {
204 ListenerInfo isListener = m_listenerManager.IsListenerMatch( 204 ListenerInfo isListener = m_listenerManager.IsListenerMatch(
205 sourceItemID, sPart.UUID, channel, name, msg 205 sourceItemID, sPart.UUID, channel, name, msg
206 ); 206 );
207 if (isListener != null) 207 if (isListener != null)
208 { 208 {
209 lock (m_pending.SyncRoot) 209 lock (m_pending.SyncRoot)
210 { 210 {
211 m_pending.Enqueue(isListener); 211 m_pending.Enqueue(isListener);
212 } 212 }
213 } 213 }
214 } 214 }
215 } 215 }
216 break; 216 break;
217 217
218 case ChatTypeEnum.Say: 218 case ChatTypeEnum.Say:
219 219
220 if ((dis < 30) && (dis > -30)) 220 if ((dis < 30) && (dis > -30))
221 { 221 {
222 if (li.GetChannel() == channel) 222 if (li.GetChannel() == channel)
223 { 223 {
224 ListenerInfo isListener = m_listenerManager.IsListenerMatch( 224 ListenerInfo isListener = m_listenerManager.IsListenerMatch(
225 sourceItemID, sPart.UUID, channel, name, msg 225 sourceItemID, sPart.UUID, channel, name, msg
226 ); 226 );
227 if (isListener != null) 227 if (isListener != null)
228 { 228 {
229 lock (m_pending.SyncRoot) 229 lock (m_pending.SyncRoot)
230 { 230 {
231 m_pending.Enqueue(isListener); 231 m_pending.Enqueue(isListener);
232 } 232 }
233 } 233 }
234 } 234 }
235 } 235 }
236 break; 236 break;
237 237
238 case ChatTypeEnum.Shout: 238 case ChatTypeEnum.Shout:
239 if ((dis < 100) && (dis > -100)) 239 if ((dis < 100) && (dis > -100))
240 { 240 {
241 if (li.GetChannel() == channel) 241 if (li.GetChannel() == channel)
242 { 242 {
243 ListenerInfo isListener = m_listenerManager.IsListenerMatch( 243 ListenerInfo isListener = m_listenerManager.IsListenerMatch(
244 sourceItemID, sPart.UUID, channel, name, msg 244 sourceItemID, sPart.UUID, channel, name, msg
245 ); 245 );
246 if (isListener != null) 246 if (isListener != null)
247 { 247 {
248 lock (m_pending.SyncRoot) 248 lock (m_pending.SyncRoot)
249 { 249 {
250 m_pending.Enqueue(isListener); 250 m_pending.Enqueue(isListener);
251 } 251 }
252 } 252 }
253 } 253 }
254 } 254 }
255 break; 255 break;
256 256
257 case ChatTypeEnum.Broadcast: 257 case ChatTypeEnum.Broadcast:
258 // Dont process if this message is from itself! 258 // Dont process if this message is from itself!
259 if (li.GetHostID().ToString().Equals(sourceItemID) || 259 if (li.GetHostID().ToString().Equals(sourceItemID) ||
260 sPart.UUID.ToString().Equals(sourceItemID)) 260 sPart.UUID.ToString().Equals(sourceItemID))
261 continue; 261 continue;
262 262
263 if (li.GetChannel() == channel) 263 if (li.GetChannel() == channel)
264 { 264 {
265 ListenerInfo isListener = m_listenerManager.IsListenerMatch( 265 ListenerInfo isListener = m_listenerManager.IsListenerMatch(
266 sourceItemID, sPart.UUID, channel, name, msg 266 sourceItemID, sPart.UUID, channel, name, msg
267 ); 267 );
268 if (isListener != null) 268 if (isListener != null)
269 { 269 {
270 lock (m_pending.SyncRoot) 270 lock (m_pending.SyncRoot)
271 { 271 {
272 m_pending.Enqueue(isListener); 272 m_pending.Enqueue(isListener);
273 } 273 }
274 } 274 }
275 } 275 }
276 276
277 break; 277 break;
278 } 278 }
279 } 279 }
280 } 280 }
281 } 281 }
282 } 282 }
283 283
284 public bool HasMessages() 284 public bool HasMessages()
285 { 285 {
286 if (m_pending != null) 286 if (m_pending != null)
287 return (m_pending.Count > 0); 287 return (m_pending.Count > 0);
288 else 288 else
289 return false; 289 return false;
290 } 290 }
291 291
292 public ListenerInfo GetNextMessage() 292 public ListenerInfo GetNextMessage()
293 { 293 {
294 ListenerInfo li = null; 294 ListenerInfo li = null;
295 295
296 lock (m_pending.SyncRoot) 296 lock (m_pending.SyncRoot)
297 { 297 {
298 li = (ListenerInfo)m_pending.Dequeue(); 298 li = (ListenerInfo)m_pending.Dequeue();
299 } 299 }
300 300
301 return li; 301 return li;
302 } 302 }
303 303
304 public uint PeekNextMessageLocalID() 304 public uint PeekNextMessageLocalID()
305 { 305 {
306 return ((ListenerInfo)m_pending.Peek()).GetLocalID(); 306 return ((ListenerInfo)m_pending.Peek()).GetLocalID();
307 } 307 }
308 308
309 public LLUUID PeekNextMessageItemID() 309 public LLUUID PeekNextMessageItemID()
310 { 310 {
311 return ((ListenerInfo)m_pending.Peek()).GetItemID(); 311 return ((ListenerInfo)m_pending.Peek()).GetItemID();
312 } 312 }
313 } 313 }
314 314
315 /********************************************************** 315 public class ListenerManager
316 * 316 {
317 * Even more listener stuff 317 //private Dictionary<int, ListenerInfo> m_listeners;
318 * 318 private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable());
319 * ********************************************************/ 319 private object ListenersLock = new object();
320 public class ListenerManager 320 private int m_MaxListeners = 100;
321 { 321
322 //private Dictionary<int, ListenerInfo> m_listeners; 322 public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
323 private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); 323 {
324 private object ListenersLock = new object(); 324 if (m_listeners.Count < m_MaxListeners)
325 private int m_MaxListeners = 100; 325 {
326 326 ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg);
327 public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) 327
328 { 328 if (isListener == null)
329 if (m_listeners.Count < m_MaxListeners) 329 {
330 { 330 int newHandle = GetNewHandle();
331 ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); 331
332 332 if (newHandle > -1)
333 if (isListener == null) 333 {
334 { 334 ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg);
335 int newHandle = GetNewHandle(); 335
336 336 lock (m_listeners.SyncRoot)
337 if (newHandle > -1) 337 {
338 { 338 m_listeners.Add(newHandle, li);
339 ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); 339 }
340 340
341 lock (m_listeners.SyncRoot) 341 return newHandle;
342 { 342 }
343 m_listeners.Add(newHandle, li); 343 }
344 } 344 }
345 345
346 return newHandle; 346 return -1;
347 } 347 }
348 } 348
349 } 349 public void Remove(int handle)
350 350 {
351 return -1; 351 lock (m_listeners.SyncRoot)
352 } 352 {
353 353 m_listeners.Remove(handle);
354 public void Remove(int handle) 354 }
355 { 355 }
356 lock (m_listeners.SyncRoot) 356
357 { 357 public void DeleteListener(LLUUID itemID)
358 m_listeners.Remove(handle); 358 {
359 } 359 ArrayList removedListeners = new ArrayList();
360 } 360
361 361 lock (m_listeners.SyncRoot)
362 public void DeleteListener(LLUUID itemID) 362 {
363 { 363 IDictionaryEnumerator en = m_listeners.GetEnumerator();
364 ArrayList removedListeners = new ArrayList(); 364 while (en.MoveNext())
365 365 {
366 lock (m_listeners.SyncRoot) 366 ListenerInfo li = (ListenerInfo)en.Value;
367 { 367 if (li.GetItemID().Equals(itemID))
368 IDictionaryEnumerator en = m_listeners.GetEnumerator(); 368 {
369 while (en.MoveNext()) 369 removedListeners.Add(li.GetHandle());
370 { 370 }
371 ListenerInfo li = (ListenerInfo)en.Value; 371 }
372 if (li.GetItemID().Equals(itemID)) 372 foreach (int handle in removedListeners)
373 { 373 {
374 removedListeners.Add(li.GetHandle()); 374 m_listeners.Remove(handle);
375 } 375 }
376 } 376 }
377 foreach (int handle in removedListeners) 377 }
378 { 378
379 m_listeners.Remove(handle); 379 private int GetNewHandle()
380 } 380 {
381 } 381 for (int i = 0; i < int.MaxValue - 1; i++)
382 } 382 {
383 383 if (!m_listeners.ContainsKey(i))
384 private int GetNewHandle() 384 return i;
385 { 385 }
386 for (int i = 0; i < int.MaxValue - 1; i++) 386
387 { 387 return -1;
388 if (!m_listeners.ContainsKey(i)) 388 }
389 return i; 389
390 } 390 public bool IsListener(LLUUID hostID)
391 391 {
392 return -1; 392 foreach (ListenerInfo li in m_listeners.Values)
393 } 393 {
394 394 if (li.GetHostID().Equals(hostID))
395 public bool IsListener(LLUUID hostID) 395 return true;
396 { 396 }
397 foreach (ListenerInfo li in m_listeners.Values) 397
398 { 398 return false;
399 if (li.GetHostID().Equals(hostID)) 399 }
400 return true; 400
401 } 401 public void Activate(int handle)
402 402 {
403 return false; 403
404 } 404 if (m_listeners.ContainsKey(handle))
405 405 {
406 public void Activate(int handle) 406 lock (m_listeners.SyncRoot)
407 { 407 {
408 408 ListenerInfo li = (ListenerInfo)m_listeners[handle];
409 if (m_listeners.ContainsKey(handle)) 409 li.Activate();
410 { 410 }
411 lock (m_listeners.SyncRoot) 411 }
412 { 412 }
413 ListenerInfo li = (ListenerInfo)m_listeners[handle]; 413
414 li.Activate(); 414 public void Dectivate(int handle)
415 } 415 {
416 } 416
417 } 417 if (m_listeners.ContainsKey(handle))
418 418 {
419 public void Dectivate(int handle) 419 ListenerInfo li = (ListenerInfo)m_listeners[handle];
420 { 420 li.Deactivate();
421 421 }
422 if (m_listeners.ContainsKey(handle)) 422 }
423 { 423
424 ListenerInfo li = (ListenerInfo)m_listeners[handle]; 424 // Theres probably a more clever and efficient way to
425 li.Deactivate(); 425 // do this, maybe with regex.
426 } 426 public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name,
427 } 427 string msg)
428 428 {
429 // Theres probably a more clever and efficient way to 429 bool isMatch = true;
430 // do this, maybe with regex. 430 lock (m_listeners.SyncRoot)
431 public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, 431 {
432 string msg) 432 IDictionaryEnumerator en = m_listeners.GetEnumerator();
433 { 433 while (en.MoveNext())
434 bool isMatch = true; 434 {
435 lock (m_listeners.SyncRoot) 435 ListenerInfo li = (ListenerInfo)en.Value;
436 { 436
437 IDictionaryEnumerator en = m_listeners.GetEnumerator(); 437 if (li.IsActive())
438 while (en.MoveNext()) 438 {
439 { 439 if (li.GetHostID().Equals(listenerKey))
440 ListenerInfo li = (ListenerInfo)en.Value; 440 {
441 441 if (channel == li.GetChannel())
442 if (li.IsActive()) 442 {
443 { 443 if ((li.GetID().ToString().Length > 0) &&
444 if (li.GetHostID().Equals(listenerKey)) 444 (!li.GetID().Equals(LLUUID.Zero)))
445 { 445 {
446 if (channel == li.GetChannel()) 446 if (!li.GetID().ToString().Equals(sourceItemID))
447 { 447 {
448 if ((li.GetID().ToString().Length > 0) && 448 isMatch = false;
449 (!li.GetID().Equals(LLUUID.Zero))) 449 }
450 { 450 }
451 if (!li.GetID().ToString().Equals(sourceItemID)) 451 if (isMatch && (li.GetName().Length > 0))
452 { 452 {
453 isMatch = false; 453 if (li.GetName().Equals(name))
454 } 454 {
455 } 455 isMatch = false;
456 if (isMatch && (li.GetName().Length > 0)) 456 }
457 { 457 }
458 if (li.GetName().Equals(name)) 458 if (isMatch)
459 { 459 {
460 isMatch = false; 460 return new ListenerInfo(
461 } 461 li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(),
462 } 462 li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID)
463 if (isMatch) 463 );
464 { 464 }
465 return new ListenerInfo( 465 }
466 li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), 466 }
467 li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) 467 }
468 ); 468 }
469 } 469 }
470 } 470 return null;
471 } 471 }
472 } 472
473 } 473 public ICollection GetListeners()
474 } 474 {
475 return null; 475 return m_listeners.Values;
476 } 476 }
477 477 }
478 public ICollection GetListeners() 478
479 { 479 public class ListenerInfo
480 return m_listeners.Values; 480 {
481 } 481 private LLUUID m_itemID; // ID of the host script engine
482 } 482 private LLUUID m_hostID; // ID of the host/scene part
483 483 private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message
484 public class ListenerInfo 484 private int m_channel; // Channel
485 { 485 private int m_handle; // Assigned handle of this listener
486 private LLUUID m_itemID; // ID of the host script engine 486 private uint m_localID; // Local ID from script engine
487 private LLUUID m_hostID; // ID of the host/scene part 487 private string m_name; // Object name to filter messages from
488 private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message 488 private LLUUID m_id; // ID to filter messages from
489 private int m_channel; // Channel 489 private string m_message; // The message
490 private int m_handle; // Assigned handle of this listener 490 private bool m_active; // Listener is active or not
491 private uint m_localID; // Local ID from script engine 491
492 private string m_name; // Object name to filter messages from 492 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message)
493 private LLUUID m_id; // ID to filter messages from 493 {
494 private string m_message; // The message 494 Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
495 private bool m_active; // Listener is active or not 495 }
496 496
497 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) 497 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id,
498 { 498 string message, LLUUID sourceItemID)
499 Initialise(localID, handle, ItemID, hostID, channel, name, id, message); 499 {
500 } 500 Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
501 501 m_sourceItemID = sourceItemID;
502 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, 502 }
503 string message, LLUUID sourceItemID) 503
504 { 504 private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name,
505 Initialise(localID, handle, ItemID, hostID, channel, name, id, message); 505 LLUUID id, string message)
506 m_sourceItemID = sourceItemID; 506 {
507 } 507 m_handle = handle;
508 508 m_channel = channel;
509 private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, 509 m_itemID = ItemID;
510 LLUUID id, string message) 510 m_hostID = hostID;
511 { 511 m_name = name;
512 m_handle = handle; 512 m_id = id;
513 m_channel = channel; 513 m_message = message;
514 m_itemID = ItemID; 514 m_active = true;
515 m_hostID = hostID; 515 m_localID = localID;
516 m_name = name; 516 }
517 m_id = id; 517
518 m_message = message; 518 public LLUUID GetItemID()
519 m_active = true; 519 {
520 m_localID = localID; 520 return m_itemID;
521 } 521 }
522 522
523 public LLUUID GetItemID() 523 public LLUUID GetHostID()
524 { 524 {
525 return m_itemID; 525 return m_hostID;
526 } 526 }
527 527
528 public LLUUID GetHostID() 528 public LLUUID GetSourceItemID()
529 { 529 {
530 return m_hostID; 530 return m_sourceItemID;
531 } 531 }
532 532
533 public LLUUID GetSourceItemID() 533 public int GetChannel()
534 { 534 {
535 return m_sourceItemID; 535 return m_channel;
536 } 536 }
537 537
538 public int GetChannel() 538 public uint GetLocalID()
539 { 539 {
540 return m_channel; 540 return m_localID;
541 } 541 }
542 542
543 public uint GetLocalID() 543 public int GetHandle()
544 { 544 {
545 return m_localID; 545 return m_handle;
546 } 546 }
547 547
548 public int GetHandle() 548 public string GetMessage()
549 { 549 {
550 return m_handle; 550 return m_message;
551 } 551 }
552 552
553 public string GetMessage() 553 public string GetName()
554 { 554 {
555 return m_message; 555 return m_name;
556 } 556 }
557 557
558 public string GetName() 558 public bool IsActive()
559 { 559 {
560 return m_name; 560 return m_active;
561 } 561 }
562 562
563 public bool IsActive() 563 public void Deactivate()
564 { 564 {
565 return m_active; 565 m_active = false;
566 } 566 }
567 567
568 public void Deactivate() 568 public void Activate()
569 { 569 {
570 m_active = false; 570 m_active = true;
571 } 571 }
572 572
573 public void Activate() 573 public LLUUID GetID()
574 { 574 {
575 m_active = true; 575 return m_id;
576 } 576 }
577 577 }
578 public LLUUID GetID() 578} \ No newline at end of file
579 {
580 return m_id;
581 }
582 }
583
584}
diff --git a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs
index e915fb8..1139b4b 100644
--- a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
+++ b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -1,680 +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
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Reflection; 32using System.Reflection;
33using System.Threading; 33using System.Threading;
34using libsecondlife; 34using libsecondlife;
35using log4net; 35using log4net;
36using Nini.Config; 36using Nini.Config;
37using Nwc.XmlRpc; 37using Nwc.XmlRpc;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Framework.Servers; 39using OpenSim.Framework.Servers;
40using OpenSim.Region.Environment.Interfaces; 40using OpenSim.Region.Environment.Interfaces;
41using OpenSim.Region.Environment.Scenes; 41using 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
76namespace OpenSim.Region.Environment.Modules 76namespace 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 object XMLRPCListLock = new object(); 82 private object XMLRPCListLock = new object();
83 private string m_name = "XMLRPCModule"; 83 private string m_name = "XMLRPCModule";
84 private int RemoteReplyScriptWait = 300; 84 private int RemoteReplyScriptWait = 300;
85 private int RemoteReplyScriptTimeout = 9000; 85 private int RemoteReplyScriptTimeout = 9000;
86 private int m_remoteDataPort = 0; 86 private int m_remoteDataPort = 0;
87 private List<Scene> m_scenes = new List<Scene>(); 87 private List<Scene> m_scenes = new List<Scene>();
88 88
89 // <channel id, RPCChannelInfo> 89 // <channel id, RPCChannelInfo>
90 private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; 90 private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
91 91
92 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending; 92 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending;
93 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses; 93 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses;
94 94
95 private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses; 95 private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses;
96 96
97 public void Initialise(Scene scene, IConfigSource config) 97 public void Initialise(Scene scene, IConfigSource config)
98 { 98 {
99 try 99 try
100 { 100 {
101 m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort); 101 m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort);
102 } 102 }
103 catch (Exception) 103 catch (Exception)
104 { 104 {
105 } 105 }
106 106
107 if (!m_scenes.Contains(scene)) 107 if (!m_scenes.Contains(scene))
108 { 108 {
109 m_scenes.Add(scene); 109 m_scenes.Add(scene);
110 110
111 scene.RegisterModuleInterface<IXMLRPC>(this); 111 scene.RegisterModuleInterface<IXMLRPC>(this);
112 } 112 }
113 } 113 }
114 114
115 public void PostInitialise() 115 public void PostInitialise()
116 { 116 {
117 if (IsEnabled()) 117 if (IsEnabled())
118 { 118 {
119 m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); 119 m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>();
120 m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>(); 120 m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>();
121 m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>(); 121 m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>();
122 m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>(); 122 m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>();
123 123
124 // Start http server 124 // Start http server
125 // Attach xmlrpc handlers 125 // Attach xmlrpc handlers
126 m_log.Info("[REMOTE_DATA]: " + 126 m_log.Info("[REMOTE_DATA]: " +
127 "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); 127 "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
128 BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort); 128 BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort);
129 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); 129 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
130 httpServer.Start(); 130 httpServer.Start();
131 } 131 }
132 } 132 }
133 133
134 public void Close() 134 public void Close()
135 { 135 {
136 } 136 }
137 137
138 public string Name 138 public string Name
139 { 139 {
140 get { return m_name; } 140 get { return m_name; }
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 public bool IsEnabled() 148 public bool IsEnabled()
149 { 149 {
150 return (m_remoteDataPort > 0); 150 return (m_remoteDataPort > 0);
151 } 151 }
152 152
153 /********************************************** 153 /**********************************************
154 * OpenXMLRPCChannel 154 * OpenXMLRPCChannel
155 * 155 *
156 * Generate a LLUUID channel key and add it and 156 * Generate a LLUUID channel key and add it and
157 * the prim id to dictionary <channelUUID, primUUID> 157 * the prim id to dictionary <channelUUID, primUUID>
158 * 158 *
159 * First check if there is a channel assigned for 159 * First check if there is a channel assigned for
160 * this itemID. If there is, then someone called 160 * this itemID. If there is, then someone called
161 * llOpenRemoteDataChannel twice. Just return the 161 * llOpenRemoteDataChannel twice. Just return the
162 * original channel. Other option is to delete the 162 * original channel. Other option is to delete the
163 * current channel and assign a new one. 163 * current channel and assign a new one.
164 * 164 *
165 * ********************************************/ 165 * ********************************************/
166 166
167 public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID) 167 public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID)
168 { 168 {
169 LLUUID channel = new LLUUID(); 169 LLUUID channel = new LLUUID();
170 170
171 //Is a dupe? 171 //Is a dupe?
172 foreach (RPCChannelInfo ci in m_openChannels.Values) 172 foreach (RPCChannelInfo ci in m_openChannels.Values)
173 { 173 {
174 if (ci.GetItemID().Equals(itemID)) 174 if (ci.GetItemID().Equals(itemID))
175 { 175 {
176 // return the original channel ID for this item 176 // return the original channel ID for this item
177 channel = ci.GetChannelID(); 177 channel = ci.GetChannelID();
178 break; 178 break;
179 } 179 }
180 } 180 }
181 181
182 if (channel == LLUUID.Zero) 182 if (channel == LLUUID.Zero)
183 { 183 {
184 channel = LLUUID.Random(); 184 channel = LLUUID.Random();
185 RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel); 185 RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel);
186 lock (XMLRPCListLock) 186 lock (XMLRPCListLock)
187 { 187 {
188 m_openChannels.Add(channel, rpcChanInfo); 188 m_openChannels.Add(channel, rpcChanInfo);
189 } 189 }
190 } 190 }
191 191
192 return channel; 192 return channel;
193 } 193 }
194 194
195 // Delete channels based on itemID 195 // Delete channels based on itemID
196 // for when a script is deleted 196 // for when a script is deleted
197 public void DeleteChannels(LLUUID itemID) 197 public void DeleteChannels(LLUUID itemID)
198 { 198 {
199 199
200 if (m_openChannels != null) 200 if (m_openChannels != null)
201 { 201 {
202 ArrayList tmp = new ArrayList(); 202 ArrayList tmp = new ArrayList();
203 203
204 lock (XMLRPCListLock) 204 lock (XMLRPCListLock)
205 { 205 {
206 foreach (RPCChannelInfo li in m_openChannels.Values) 206 foreach (RPCChannelInfo li in m_openChannels.Values)
207 { 207 {
208 if (li.GetItemID().Equals(itemID)) 208 if (li.GetItemID().Equals(itemID))
209 { 209 {
210 tmp.Add(itemID); 210 tmp.Add(itemID);
211 } 211 }
212 } 212 }
213 213
214 IEnumerator tmpEnumerator = tmp.GetEnumerator(); 214 IEnumerator tmpEnumerator = tmp.GetEnumerator();
215 while ( tmpEnumerator.MoveNext() ) 215 while ( tmpEnumerator.MoveNext() )
216 m_openChannels.Remove((LLUUID)tmpEnumerator.Current); 216 m_openChannels.Remove((LLUUID)tmpEnumerator.Current);
217 } 217 }
218 218
219 } 219 }
220 220
221 } 221 }
222 222
223 /********************************************** 223 /**********************************************
224 * Remote Data Reply 224 * Remote Data Reply
225 * 225 *
226 * Response to RPC message 226 * Response to RPC message
227 * 227 *
228 *********************************************/ 228 *********************************************/
229 229
230 public void RemoteDataReply(string channel, string message_id, string sdata, int idata) 230 public void RemoteDataReply(string channel, string message_id, string sdata, int idata)
231 { 231 {
232 RPCRequestInfo rpcInfo; 232 RPCRequestInfo rpcInfo;
233 LLUUID message_key = new LLUUID(message_id); 233 LLUUID message_key = new LLUUID(message_id);
234 234
235 if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo)) 235 if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo))
236 { 236 {
237 rpcInfo.SetStrRetval(sdata); 237 rpcInfo.SetStrRetval(sdata);
238 rpcInfo.SetIntRetval(idata); 238 rpcInfo.SetIntRetval(idata);
239 rpcInfo.SetProcessed(true); 239 rpcInfo.SetProcessed(true);
240 m_rpcPendingResponses.Remove(message_key); 240 m_rpcPendingResponses.Remove(message_key);
241 } 241 }
242 } 242 }
243 243
244 /********************************************** 244 /**********************************************
245 * CloseXMLRPCChannel 245 * CloseXMLRPCChannel
246 * 246 *
247 * Remove channel from dictionary 247 * Remove channel from dictionary
248 * 248 *
249 *********************************************/ 249 *********************************************/
250 250
251 public void CloseXMLRPCChannel(LLUUID channelKey) 251 public void CloseXMLRPCChannel(LLUUID channelKey)
252 { 252 {
253 if (m_openChannels.ContainsKey(channelKey)) 253 if (m_openChannels.ContainsKey(channelKey))
254 m_openChannels.Remove(channelKey); 254 m_openChannels.Remove(channelKey);
255 } 255 }
256 256
257 257
258 public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request) 258 public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request)
259 { 259 {
260 XmlRpcResponse response = new XmlRpcResponse(); 260 XmlRpcResponse response = new XmlRpcResponse();
261 261
262 Hashtable requestData = (Hashtable)request.Params[0]; 262 Hashtable requestData = (Hashtable)request.Params[0];
263 bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && 263 bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") &&
264 requestData.Contains("StringValue")); 264 requestData.Contains("StringValue"));
265 265
266 if (GoodXML) 266 if (GoodXML)
267 { 267 {
268 LLUUID channel = new LLUUID((string)requestData["Channel"]); 268 LLUUID channel = new LLUUID((string)requestData["Channel"]);
269 RPCChannelInfo rpcChanInfo; 269 RPCChannelInfo rpcChanInfo;
270 if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) 270 if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
271 { 271 {
272 string intVal = (string)requestData["IntValue"]; 272 string intVal = (string)requestData["IntValue"];
273 string strVal = (string)requestData["StringValue"]; 273 string strVal = (string)requestData["StringValue"];
274 274
275 RPCRequestInfo rpcInfo; 275 RPCRequestInfo rpcInfo;
276 276
277 lock (XMLRPCListLock) 277 lock (XMLRPCListLock)
278 { 278 {
279 rpcInfo = 279 rpcInfo =
280 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, 280 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
281 intVal); 281 intVal);
282 m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo); 282 m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
283 } 283 }
284 284
285 int timeoutCtr = 0; 285 int timeoutCtr = 0;
286 286
287 while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout)) 287 while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout))
288 { 288 {
289 Thread.Sleep(RemoteReplyScriptWait); 289 Thread.Sleep(RemoteReplyScriptWait);
290 timeoutCtr += RemoteReplyScriptWait; 290 timeoutCtr += RemoteReplyScriptWait;
291 } 291 }
292 if (rpcInfo.IsProcessed()) 292 if (rpcInfo.IsProcessed())
293 { 293 {
294 Hashtable param = new Hashtable(); 294 Hashtable param = new Hashtable();
295 param["StringValue"] = rpcInfo.GetStrRetval(); 295 param["StringValue"] = rpcInfo.GetStrRetval();
296 param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval()); 296 param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval());
297 297
298 ArrayList parameters = new ArrayList(); 298 ArrayList parameters = new ArrayList();
299 parameters.Add(param); 299 parameters.Add(param);
300 300
301 response.Value = parameters; 301 response.Value = parameters;
302 rpcInfo = null; 302 rpcInfo = null;
303 } 303 }
304 else 304 else
305 { 305 {
306 response.SetFault(-1, "Script timeout"); 306 response.SetFault(-1, "Script timeout");
307 rpcInfo = null; 307 rpcInfo = null;
308 } 308 }
309 } 309 }
310 else 310 else
311 { 311 {
312 response.SetFault(-1, "Invalid channel"); 312 response.SetFault(-1, "Invalid channel");
313 } 313 }
314 } 314 }
315 315
316 return response; 316 return response;
317 } 317 }
318 318
319 public bool hasRequests() 319 public bool hasRequests()
320 { 320 {
321 lock (XMLRPCListLock) 321 lock (XMLRPCListLock)
322 { 322 {
323 if (m_rpcPending != null) 323 if (m_rpcPending != null)
324 return (m_rpcPending.Count > 0); 324 return (m_rpcPending.Count > 0);
325 else 325 else
326 return false; 326 return false;
327 } 327 }
328 } 328 }
329 329
330 public RPCRequestInfo GetNextCompletedRequest() 330 public RPCRequestInfo GetNextCompletedRequest()
331 { 331 {
332 if (m_rpcPending != null) 332 if (m_rpcPending != null)
333 { 333 {
334 lock (XMLRPCListLock) 334 lock (XMLRPCListLock)
335 { 335 {
336 foreach (LLUUID luid in m_rpcPending.Keys) 336 foreach (LLUUID luid in m_rpcPending.Keys)
337 { 337 {
338 RPCRequestInfo tmpReq; 338 RPCRequestInfo tmpReq;
339 339
340 if (m_rpcPending.TryGetValue(luid, out tmpReq)) 340 if (m_rpcPending.TryGetValue(luid, out tmpReq))
341 { 341 {
342 342
343 if (!tmpReq.IsProcessed()) return tmpReq; 343 if (!tmpReq.IsProcessed()) return tmpReq;
344 } 344 }
345 } 345 }
346 } 346 }
347 } 347 }
348 return null; 348 return null;
349 } 349 }
350 350
351 public void RemoveCompletedRequest(LLUUID id) 351 public void RemoveCompletedRequest(LLUUID id)
352 { 352 {
353 lock (XMLRPCListLock) 353 lock (XMLRPCListLock)
354 { 354 {
355 RPCRequestInfo tmp; 355 RPCRequestInfo tmp;
356 if (m_rpcPending.TryGetValue(id, out tmp)) 356 if (m_rpcPending.TryGetValue(id, out tmp))
357 { 357 {
358 m_rpcPending.Remove(id); 358 m_rpcPending.Remove(id);
359 m_rpcPendingResponses.Add(id, tmp); 359 m_rpcPendingResponses.Add(id, tmp);
360 } 360 }
361 else 361 else
362 { 362 {
363 Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST"); 363 Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST");
364 } 364 }
365 } 365 }
366 } 366 }
367 367
368 public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) 368 public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
369 { 369 {
370 370
371 SendRemoteDataRequest req = new SendRemoteDataRequest( 371 SendRemoteDataRequest req = new SendRemoteDataRequest(
372 localID, itemID, channel, dest, idata, sdata 372 localID, itemID, channel, dest, idata, sdata
373 ); 373 );
374 m_pendingSRDResponses.Add(req.GetReqID(), req); 374 m_pendingSRDResponses.Add(req.GetReqID(), req);
375 return req.process(); 375 return req.process();
376 376
377 } 377 }
378 378
379 public SendRemoteDataRequest GetNextCompletedSRDRequest() 379 public SendRemoteDataRequest GetNextCompletedSRDRequest()
380 { 380 {
381 if (m_pendingSRDResponses != null) 381 if (m_pendingSRDResponses != null)
382 { 382 {
383 lock (XMLRPCListLock) 383 lock (XMLRPCListLock)
384 { 384 {
385 foreach (LLUUID luid in m_pendingSRDResponses.Keys) 385 foreach (LLUUID luid in m_pendingSRDResponses.Keys)
386 { 386 {
387 SendRemoteDataRequest tmpReq; 387 SendRemoteDataRequest tmpReq;
388 388
389 if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq)) 389 if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq))
390 { 390 {
391 if (tmpReq.finished) 391 if (tmpReq.finished)
392 return tmpReq; 392 return tmpReq;
393 } 393 }
394 } 394 }
395 } 395 }
396 } 396 }
397 return null; 397 return null;
398 } 398 }
399 399
400 public void RemoveCompletedSRDRequest(LLUUID id) 400 public void RemoveCompletedSRDRequest(LLUUID id)
401 { 401 {
402 lock (XMLRPCListLock) 402 lock (XMLRPCListLock)
403 { 403 {
404 SendRemoteDataRequest tmpReq; 404 SendRemoteDataRequest tmpReq;
405 if (m_pendingSRDResponses.TryGetValue(id, out tmpReq)) 405 if (m_pendingSRDResponses.TryGetValue(id, out tmpReq))
406 { 406 {
407 m_pendingSRDResponses.Remove(id); 407 m_pendingSRDResponses.Remove(id);
408 } 408 }
409 } 409 }
410 } 410 }
411 411
412 public void CancelSRDRequests(LLUUID itemID) 412 public void CancelSRDRequests(LLUUID itemID)
413 { 413 {
414 if (m_pendingSRDResponses != null) 414 if (m_pendingSRDResponses != null)
415 { 415 {
416 lock (XMLRPCListLock) 416 lock (XMLRPCListLock)
417 { 417 {
418 foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values) 418 foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values)
419 { 419 {
420 if (li.m_itemID.Equals(itemID)) 420 if (li.m_itemID.Equals(itemID))
421 m_pendingSRDResponses.Remove(li.GetReqID()); 421 m_pendingSRDResponses.Remove(li.GetReqID());
422 } 422 }
423 } 423 }
424 } 424 }
425 } 425 }
426 } 426 }
427 427
428 /************************************************************** 428 public class RPCRequestInfo
429 * 429 {
430 * Class RPCRequestInfo 430 private string m_StrVal;
431 * 431 private string m_IntVal;
432 * Holds details about incoming requests until they are picked 432 private bool m_processed;
433 * from the queue by LSLLongCmdHandler 433 private string m_respStr;
434 * ***********************************************************/ 434 private int m_respInt;
435 435 private uint m_localID;
436 public class RPCRequestInfo 436 private LLUUID m_ItemID;
437 { 437 private LLUUID m_MessageID;
438 private string m_StrVal; 438 private LLUUID m_ChannelKey;
439 private string m_IntVal; 439
440 private bool m_processed; 440 public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
441 private string m_respStr; 441 {
442 private int m_respInt; 442 m_localID = localID;
443 private uint m_localID; 443 m_StrVal = strVal;
444 private LLUUID m_ItemID; 444 m_IntVal = intVal;
445 private LLUUID m_MessageID; 445 m_ItemID = itemID;
446 private LLUUID m_ChannelKey; 446 m_ChannelKey = channelKey;
447 447 m_MessageID = LLUUID.Random();
448 public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal) 448 m_processed = false;
449 { 449 m_respStr = String.Empty;
450 m_localID = localID; 450 m_respInt = 0;
451 m_StrVal = strVal; 451 }
452 m_IntVal = intVal; 452
453 m_ItemID = itemID; 453 public bool IsProcessed()
454 m_ChannelKey = channelKey; 454 {
455 m_MessageID = LLUUID.Random(); 455 return m_processed;
456 m_processed = false; 456 }
457 m_respStr = String.Empty; 457
458 m_respInt = 0; 458 public LLUUID GetChannelKey()
459 } 459 {
460 460 return m_ChannelKey;
461 public bool IsProcessed() 461 }
462 { 462
463 return m_processed; 463 public void SetProcessed(bool processed)
464 } 464 {
465 465 m_processed = processed;
466 public LLUUID GetChannelKey() 466 }
467 { 467
468 return m_ChannelKey; 468 public void SetStrRetval(string resp)
469 } 469 {
470 470 m_respStr = resp;
471 public void SetProcessed(bool processed) 471 }
472 { 472
473 m_processed = processed; 473 public string GetStrRetval()
474 } 474 {
475 475 return m_respStr;
476 public void SetStrRetval(string resp) 476 }
477 { 477 public void SetIntRetval(int resp)
478 m_respStr = resp; 478 {
479 } 479 m_respInt = resp;
480 480 }
481 public string GetStrRetval() 481
482 { 482 public int GetIntRetval()
483 return m_respStr; 483 {
484 } 484 return m_respInt;
485 public void SetIntRetval(int resp) 485 }
486 { 486 public uint GetLocalID()
487 m_respInt = resp; 487 {
488 } 488 return m_localID;
489 489 }
490 public int GetIntRetval() 490
491 { 491 public LLUUID GetItemID()
492 return m_respInt; 492 {
493 } 493 return m_ItemID;
494 public uint GetLocalID() 494 }
495 { 495
496 return m_localID; 496 public string GetStrVal()
497 } 497 {
498 498 return m_StrVal;
499 public LLUUID GetItemID() 499 }
500 { 500
501 return m_ItemID; 501 public int GetIntValue()
502 } 502 {
503 503 return int.Parse(m_IntVal);
504 public string GetStrVal() 504 }
505 { 505
506 return m_StrVal; 506 public LLUUID GetMessageID()
507 } 507 {
508 508 return m_MessageID;
509 public int GetIntValue() 509 }
510 { 510 }
511 return int.Parse(m_IntVal); 511
512 } 512 public class RPCChannelInfo
513 513 {
514 public LLUUID GetMessageID() 514 private LLUUID m_itemID;
515 { 515 private uint m_localID;
516 return m_MessageID; 516 private LLUUID m_ChannelKey;
517 } 517
518 } 518 public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
519 519 {
520 public class RPCChannelInfo 520 m_ChannelKey = channelID;
521 { 521 m_localID = localID;
522 private LLUUID m_itemID; 522 m_itemID = itemID;
523 private uint m_localID; 523 }
524 private LLUUID m_ChannelKey; 524
525 525 public LLUUID GetItemID()
526 public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID) 526 {
527 { 527 return m_itemID;
528 m_ChannelKey = channelID; 528 }
529 m_localID = localID; 529
530 m_itemID = itemID; 530 public LLUUID GetChannelID()
531 } 531 {
532 532 return m_ChannelKey;
533 public LLUUID GetItemID() 533 }
534 { 534
535 return m_itemID; 535 public uint GetLocalID()
536 } 536 {
537 537 return m_localID;
538 public LLUUID GetChannelID() 538 }
539 { 539
540 return m_ChannelKey; 540 }
541 } 541
542 542 public class SendRemoteDataRequest
543 public uint GetLocalID() 543 {
544 { 544
545 return m_localID; 545 public LLUUID reqID;
546 } 546 public string destURL;
547 547 public string channel;
548 } 548 public string sdata;
549 549 public int idata;
550 public class SendRemoteDataRequest 550 public bool finished;
551 { 551 public string response_sdata;
552 552 public int response_idata;
553 public LLUUID reqID; 553 public XmlRpcRequest request;
554 public string destURL; 554 private Thread httpThread;
555 public string channel; 555 public LLUUID m_itemID;
556 public string sdata; 556 public uint m_localID;
557 public int idata; 557 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
558 public bool finished; 558
559 public string response_sdata; 559 public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
560 public int response_idata; 560 {
561 public XmlRpcRequest request; 561
562 private Thread httpThread; 562 this.channel = channel;
563 public LLUUID m_itemID; 563 this.destURL = dest;
564 public uint m_localID; 564 this.idata = idata;
565 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 565 this.sdata = sdata;
566 566 m_itemID = itemID;
567 public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) 567 m_localID = localID;
568 { 568
569 569 reqID = LLUUID.Random();
570 this.channel = channel; 570
571 this.destURL = dest; 571 }
572 this.idata = idata; 572
573 this.sdata = sdata; 573 public LLUUID process()
574 m_itemID = itemID; 574 {
575 m_localID = localID; 575 httpThread = new Thread(SendRequest);
576 576 httpThread.Name = "HttpRequestThread";
577 reqID = LLUUID.Random(); 577 httpThread.Priority = ThreadPriority.BelowNormal;
578 578 httpThread.IsBackground = true;
579 } 579 finished = false;
580 580 httpThread.Start();
581 public LLUUID process() 581 ThreadTracker.Add(httpThread);
582 { 582
583 httpThread = new Thread(SendRequest); 583 return reqID;
584 httpThread.Name = "HttpRequestThread"; 584
585 httpThread.Priority = ThreadPriority.BelowNormal; 585 }
586 httpThread.IsBackground = true; 586
587 finished = false; 587 /*
588 httpThread.Start(); 588 * TODO: More work on the response codes. Right now
589 ThreadTracker.Add(httpThread); 589 * returning 200 for success or 499 for exception
590 590 */
591 return reqID; 591
592 592 public void SendRequest()
593 } 593 {
594 594 Hashtable param = new Hashtable();
595 /* 595
596 * TODO: More work on the response codes. Right now 596 // Check if channel is an LLUUID
597 * returning 200 for success or 499 for exception 597 // if not, use as method name
598 */ 598 LLUUID parseUID;
599 599 string mName = "llRemoteData";
600 public void SendRequest() 600 if( (channel != null) && (channel != "") )
601 { 601 if( !LLUUID.TryParse(channel, out parseUID) )
602 Hashtable param = new Hashtable(); 602 mName = channel;
603 603 else
604 // Check if channel is an LLUUID 604 param["Channel"] = channel;
605 // if not, use as method name 605
606 LLUUID parseUID; 606 param["StringValue"] = sdata;
607 string mName = "llRemoteData"; 607 param["IntValue"] = Convert.ToString(idata);
608 if( (channel != null) && (channel != "") ) 608
609 if( !LLUUID.TryParse(channel, out parseUID) ) 609 ArrayList parameters = new ArrayList();
610 mName = channel; 610 parameters.Add(param);
611 else 611 XmlRpcRequest req = new XmlRpcRequest(mName, parameters);
612 param["Channel"] = channel; 612 try
613 613 {
614 param["StringValue"] = sdata; 614 XmlRpcResponse resp = req.Send(destURL, 30000);
615 param["IntValue"] = Convert.ToString(idata); 615 if (resp != null)
616 616 {
617 ArrayList parameters = new ArrayList(); 617 Hashtable respParms;
618 parameters.Add(param); 618 if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) {
619 XmlRpcRequest req = new XmlRpcRequest(mName, parameters); 619 respParms = (Hashtable)resp.Value;
620 try 620 }
621 { 621 else {
622 XmlRpcResponse resp = req.Send(destURL, 30000); 622 ArrayList respData = (ArrayList)resp.Value;
623 if (resp != null) 623 respParms = (Hashtable)respData[0];
624 { 624 }
625 Hashtable respParms; 625 if (respParms != null)
626 if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) { 626 {
627 respParms = (Hashtable)resp.Value; 627 if (respParms.Contains("StringValue"))
628 } 628 {
629 else { 629 sdata = (string)respParms["StringValue"];
630 ArrayList respData = (ArrayList)resp.Value; 630 }
631 respParms = (Hashtable)respData[0]; 631 if (respParms.Contains("IntValue"))
632 } 632 {
633 if (respParms != null) 633 idata = Convert.ToInt32((string)respParms["IntValue"]);
634 { 634 }
635 if (respParms.Contains("StringValue")) 635 if (respParms.Contains("faultString"))
636 { 636 {
637 sdata = (string)respParms["StringValue"]; 637 sdata = (string)respParms["faultString"];
638 } 638 }
639 if (respParms.Contains("IntValue")) 639 if (respParms.Contains("faultCode"))
640 { 640 {
641 idata = Convert.ToInt32((string)respParms["IntValue"]); 641 idata = Convert.ToInt32(respParms["faultCode"]);
642 } 642 }
643 if (respParms.Contains("faultString")) 643 }
644 { 644 }
645 sdata = (string)respParms["faultString"]; 645 }
646 } 646 catch (WebException we)
647 if (respParms.Contains("faultCode")) 647 {
648 { 648 sdata = we.Message;
649 idata = Convert.ToInt32(respParms["faultCode"]); 649 m_log.Warn("[SendRemoteDataRequest]: Request failed");
650 } 650 m_log.Warn(we.StackTrace);
651 } 651 }
652 } 652
653 } 653 finished = true;
654 catch (WebException we) 654 }
655 { 655
656 sdata = we.Message; 656 public void Stop()
657 m_log.Warn("[SendRemoteDataRequest]: Request failed"); 657 {
658 m_log.Warn(we.StackTrace); 658 try
659 } 659 {
660 660 httpThread.Abort();
661 finished = true; 661 }
662 } 662 catch (Exception)
663 663 {
664 public void Stop() 664 }
665 { 665 }
666 try 666
667 { 667 public LLUUID GetReqID()
668 httpThread.Abort(); 668 {
669 } 669 return reqID;
670 catch (Exception) 670 }
671 { 671 }
672 } 672} \ No newline at end of file
673 }
674
675 public LLUUID GetReqID()
676 {
677 return reqID;
678 }
679 }
680}
diff --git a/OpenSim/Region/Environment/Modules/SunModule.cs b/OpenSim/Region/Environment/Modules/SunModule.cs
deleted file mode 100644
index e6801e8..0000000
--- a/OpenSim/Region/Environment/Modules/SunModule.cs
+++ /dev/null
@@ -1,195 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using libsecondlife;
31using Nini.Config;
32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes;
35
36namespace OpenSim.Region.Environment.Modules
37{
38 public class SunModule : IRegionModule
39 {
40 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
41
42 private const double m_real_day = 24.0;
43 private const int m_default_frame = 100;
44 private int m_frame_mod;
45 private double m_day_length;
46 private int m_dilation;
47 private int m_frame;
48 private long m_start;
49
50 private Scene m_scene;
51
52 public void Initialise(Scene scene, IConfigSource config)
53 {
54 m_start = DateTime.Now.Ticks;
55 m_frame = 0;
56
57 // Just in case they don't have the stanzas
58 try
59 {
60 m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day);
61 m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame);
62 }
63 catch (Exception)
64 {
65 m_day_length = m_real_day;
66 m_frame_mod = m_default_frame;
67 }
68
69 m_dilation = (int) (m_real_day/m_day_length);
70 m_scene = scene;
71 scene.EventManager.OnFrame += SunUpdate;
72 scene.EventManager.OnNewClient += SunToClient;
73 }
74
75 public void PostInitialise()
76 {
77 }
78
79 public void Close()
80 {
81 }
82
83 public string Name
84 {
85 get { return "SunModule"; }
86 }
87
88 public bool IsSharedModule
89 {
90 get { return false; }
91 }
92
93 public void SunToClient(IClientAPI client)
94 {
95 client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
96 }
97
98 public void SunUpdate()
99 {
100 if (m_frame < m_frame_mod)
101 {
102 m_frame++;
103 return;
104 }
105 // m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay());
106 List<ScenePresence> avatars = m_scene.GetAvatars();
107 foreach (ScenePresence avatar in avatars)
108 {
109 avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
110 }
111 // set estate settings for region access to sun position
112 m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay());
113
114 m_frame = 0;
115 }
116
117 // Hour of the Day figures out the hour of the day as a float.
118 // The intent here is that we seed hour of the day with real
119 // time when the simulator starts, then run time forward
120 // faster based on time dilation factor. This means that
121 // ticks don't get out of hand
122 private double HourOfTheDay()
123 {
124 long m_addticks = (DateTime.Now.Ticks - m_start)*m_dilation;
125 DateTime dt = new DateTime(m_start + m_addticks);
126 return (double) dt.Hour + ((double) dt.Minute/60.0);
127 }
128
129 private LLVector3 SunPos(double hour)
130 {
131 // now we have our radian position
132 double rad = (hour/m_real_day)*2*Math.PI - (Math.PI/2.0);
133 double z = Math.Sin(rad);
134 double x = Math.Cos(rad);
135 return new LLVector3((float) x, 0f, (float) z);
136 }
137
138 // TODO: clear this out. This is here so that I remember to
139 // figure out if we need those other packet fields that I've
140 // left out so far
141 //
142 // public void SendViewerTime(int phase)
143 // {
144 // Console.WriteLine("SunPhase: {0}", phase);
145 // SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
146 // //viewertime.TimeInfo.SecPerDay = 86400;
147 // // viewertime.TimeInfo.SecPerYear = 31536000;
148 // viewertime.TimeInfo.SecPerDay = 1000;
149 // viewertime.TimeInfo.SecPerYear = 365000;
150 // viewertime.TimeInfo.SunPhase = 1;
151 // int sunPhase = (phase + 2)/2;
152 // if ((sunPhase < 6) || (sunPhase > 36))
153 // {
154 // viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f);
155 // Console.WriteLine("sending night");
156 // }
157 // else
158 // {
159 // if (sunPhase < 12)
160 // {
161 // sunPhase = 12;
162 // }
163 // sunPhase = sunPhase - 12;
164 //
165 // float yValue = 0.1f*(sunPhase);
166 // Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue);
167 // if (yValue > 1.2f)
168 // {
169 // yValue = yValue - 1.2f;
170 // }
171 // if (yValue > 1)
172 // {
173 // yValue = 1;
174 // }
175 // if (yValue < 0)
176 // {
177 // yValue = 0;
178 // }
179 // if (sunPhase < 14)
180 // {
181 // yValue = 1 - yValue;
182 // }
183 // if (sunPhase < 12)
184 // {
185 // yValue *= -1;
186 // }
187 // viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f);
188 // Console.WriteLine("sending sun update " + yValue);
189 // }
190 // viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f);
191 // viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
192 // // OutPacket(viewertime);
193 // }
194 }
195}
diff --git a/OpenSim/Region/Environment/Modules/TeleportModule.cs b/OpenSim/Region/Environment/Modules/TeleportModule.cs
deleted file mode 100644
index 9a90377..0000000
--- a/OpenSim/Region/Environment/Modules/TeleportModule.cs
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Region.Environment.Modules
29{
30 internal class TeleportModule
31 {
32 }
33}
diff --git a/OpenSim/Region/Environment/Modules/Terrain/Effects/CookieCutter.cs b/OpenSim/Region/Environment/Modules/Terrain/Effects/CookieCutter.cs
deleted file mode 100644
index 6d41eba..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/Effects/CookieCutter.cs
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using OpenSim.Region.Environment.Interfaces;
29using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes;
30using OpenSim.Region.Environment.Modules.Terrain.PaintBrushes;
31
32namespace OpenSim.Region.Environment.Modules.Terrain.Effects
33{
34 internal class CookieCutter : ITerrainEffect
35 {
36 #region ITerrainEffect Members
37
38 public void RunEffect(ITerrainChannel map)
39 {
40 SmoothArea smooth = new SmoothArea();
41 ITerrainPaintableEffect eroder = new WeatherSphere();
42
43 bool[,] cliffMask = new bool[map.Width,map.Height];
44 bool[,] channelMask = new bool[map.Width,map.Height];
45 bool[,] smoothMask = new bool[map.Width,map.Height];
46
47 Console.WriteLine("S1");
48
49 // Step one, generate rough mask
50 int x, y;
51 for (x = 0; x < map.Width; x++)
52 {
53 for (y = 0; y < map.Height; y++)
54 {
55 Console.Write(".");
56 smoothMask[x, y] = true;
57
58 // Start underwater
59 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
60 // Add a little height. (terrain should now be above water, mostly.)
61 map[x, y] += 20;
62
63 int channelsX = 4;
64 int channelWidth = (map.Width / channelsX / 4);
65 int channelsY = 4;
66 int channelHeight = (map.Height / channelsY / 4);
67
68 SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
69 SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
70 }
71 }
72
73 Console.WriteLine("S2");
74 //smooth.FloodEffect(map, smoothMask, 4.0);
75
76 Console.WriteLine("S3");
77 for (x = 0; x < map.Width; x++)
78 {
79 for (y = 0; y < map.Height; y++)
80 {
81 if (cliffMask[x, y] == true)
82 eroder.PaintEffect(map, x, y, 4, 0.1);
83 }
84 }
85
86 for (x = 0; x < map.Width; x += 2)
87 {
88 for (y = 0; y < map.Height; y += 2)
89 {
90 if (map[x, y] < 0.1)
91 map[x, y] = 0.1;
92 if (map[x, y] > 256)
93 map[x, y] = 256;
94 }
95 }
96 //smooth.FloodEffect(map, smoothMask, 4.0);
97 }
98
99 #endregion
100
101 private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth,
102 int mapSize, int rp)
103 {
104 for (int i = 0; i < numChannels; i++)
105 {
106 double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i));
107
108 if (distanceToLine < channelWidth)
109 {
110 if (channelMask[x, y])
111 return;
112
113 // Remove channels
114 map[x, y] -= 10;
115 channelMask[x, y] = true;
116 }
117 if (distanceToLine < 1)
118 {
119 cliffMask[x, y] = true;
120 }
121 }
122 }
123 }
124} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/Effects/DefaultTerrainGenerator.cs b/OpenSim/Region/Environment/Modules/Terrain/Effects/DefaultTerrainGenerator.cs
deleted file mode 100644
index 2327275..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/Effects/DefaultTerrainGenerator.cs
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using OpenSim.Framework;
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.Effects
31{
32 internal class DefaultTerrainGenerator : ITerrainEffect
33 {
34 #region ITerrainEffect Members
35
36 public void RunEffect(ITerrainChannel map)
37 {
38 int x, y;
39 for (x = 0; x < map.Width; x++)
40 {
41 for (y = 0; y < map.Height; y++)
42 {
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;
45 if (map[x, y] < spherFac)
46 {
47 map[x, y] = spherFac;
48 }
49 }
50 }
51 }
52
53 #endregion
54 }
55} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/BMP.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/BMP.cs
deleted file mode 100644
index f975872..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/BMP.cs
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
32{
33 /// <summary>
34 /// A generic windows bitmap loader.
35 /// Should be capable of handling 24-bit RGB images.
36 ///
37 /// Uses the System.Drawing filesystem loader.
38 /// </summary>
39 internal class BMP : GenericSystemDrawing
40 {
41 /// <summary>
42 /// Exports a file to a image on the disk using a System.Drawing exporter.
43 /// </summary>
44 /// <param name="filename">The target filename</param>
45 /// <param name="map">The terrain channel being saved</param>
46 public override void SaveFile(string filename, ITerrainChannel map)
47 {
48 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
49
50 colours.Save(filename, ImageFormat.Bmp);
51 }
52
53 /// <summary>
54 /// The human readable version of the file format(s) this loader handles
55 /// </summary>
56 /// <returns></returns>
57 public override string ToString()
58 {
59 return "BMP";
60 }
61 }
62} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GIF.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GIF.cs
deleted file mode 100644
index cf82000..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GIF.cs
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
32{
33 internal class GIF : GenericSystemDrawing
34 {
35 public override void SaveFile(string filename, ITerrainChannel map)
36 {
37 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
38
39 colours.Save(filename, ImageFormat.Gif);
40 }
41
42 public override string ToString()
43 {
44 return "GIF";
45 }
46 }
47} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GenericSystemDrawing.cs
deleted file mode 100644
index b05c1cd..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using System.Drawing.Imaging;
31using OpenSim.Region.Environment.Interfaces;
32
33namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
34{
35 /// <summary>
36 /// A virtual class designed to have methods overloaded,
37 /// this class provides an interface for a generic image
38 /// saving and loading mechanism, but does not specify the
39 /// format. It should not be insubstantiated directly.
40 /// </summary>
41 public class GenericSystemDrawing : ITerrainLoader
42 {
43 #region ITerrainLoader Members
44
45 public string FileExtension
46 {
47 get { return ".gsd"; }
48 }
49
50 /// <summary>
51 /// Loads a file from a specified filename on the disk,
52 /// parses the image using the System.Drawing parsers
53 /// then returns a terrain channel. Values are
54 /// returned based on HSL brightness between 0m and 128m
55 /// </summary>
56 /// <param name="filename">The target image to load</param>
57 /// <returns>A terrain channel generated from the image.</returns>
58 public virtual ITerrainChannel LoadFile(string filename)
59 {
60 Bitmap file = new Bitmap(filename);
61
62 ITerrainChannel retval = new TerrainChannel(file.Width, file.Height);
63
64 int x, y;
65 for (x = 0; x < file.Width; x++)
66 {
67 for (y = 0; y < file.Height; y++)
68 {
69 retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128;
70 }
71 }
72
73 return retval;
74 }
75
76 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
77 {
78 throw new NotImplementedException();
79 }
80
81 /// <summary>
82 /// Exports a file to a image on the disk using a System.Drawing exporter.
83 /// </summary>
84 /// <param name="filename">The target filename</param>
85 /// <param name="map">The terrain channel being saved</param>
86 public virtual void SaveFile(string filename, ITerrainChannel map)
87 {
88 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
89
90 colours.Save(filename, ImageFormat.Png);
91 }
92
93 #endregion
94
95 public override string ToString()
96 {
97 return "SYS.DRAWING";
98 }
99
100 /// <summary>
101 /// Protected method, generates a grayscale bitmap
102 /// image from a specified terrain channel.
103 /// </summary>
104 /// <param name="map">The terrain channel to export to bitmap</param>
105 /// <returns>A System.Drawing.Bitmap containing a grayscale image</returns>
106 protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
107 {
108 Bitmap bmp = new Bitmap(map.Width, map.Height);
109
110 int pallete = 256;
111
112 Color[] grays = new Color[pallete];
113 for (int i = 0; i < grays.Length; i++)
114 {
115 grays[i] = Color.FromArgb(i, i, i);
116 }
117
118 for (int y = 0; y < map.Height; y++)
119 {
120 for (int x = 0; x < map.Width; x++)
121 {
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));
124
125 // Handle error conditions
126 if (colorindex > pallete - 1 || colorindex < 0)
127 bmp.SetPixel(x, map.Height - y - 1, Color.Red);
128 else
129 bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]);
130 }
131 }
132 return bmp;
133 }
134
135 /// <summary>
136 /// Protected method, generates a coloured bitmap
137 /// image from a specified terrain channel.
138 /// </summary>
139 /// <param name="map">The terrain channel to export to bitmap</param>
140 /// <returns>A System.Drawing.Bitmap containing a coloured image</returns>
141 protected Bitmap CreateBitmapFromMap(ITerrainChannel map)
142 {
143 Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
144
145 int pallete = gradientmapLd.Height;
146
147 Bitmap bmp = new Bitmap(map.Width, map.Height);
148 Color[] colours = new Color[pallete];
149
150 for (int i = 0; i < pallete; i++)
151 {
152 colours[i] = gradientmapLd.GetPixel(0, i);
153 }
154
155 for (int y = 0; y < map.Height; y++)
156 {
157 for (int x = 0; x < map.Width; x++)
158 {
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));
161
162 // Handle error conditions
163 if (colorindex > pallete - 1 || colorindex < 0)
164 bmp.SetPixel(x, map.Height - y - 1, Color.Red);
165 else
166 bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
167 }
168 }
169 return bmp;
170 }
171 }
172} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs
deleted file mode 100644
index c2ac9d0..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/JPEG.cs
+++ /dev/null
@@ -1,94 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using System.Drawing.Imaging;
31using OpenSim.Region.Environment.Interfaces;
32
33namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
34{
35 public class JPEG : ITerrainLoader
36 {
37 #region ITerrainLoader Members
38
39 public string FileExtension
40 {
41 get { return ".jpg"; }
42 }
43
44 public ITerrainChannel LoadFile(string filename)
45 {
46 throw new NotImplementedException();
47 }
48
49 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
50 {
51 throw new NotImplementedException();
52 }
53
54 public void SaveFile(string filename, ITerrainChannel map)
55 {
56 Bitmap colours = CreateBitmapFromMap(map);
57
58 colours.Save(filename, ImageFormat.Jpeg);
59 }
60
61 #endregion
62
63 public override string ToString()
64 {
65 return "JPEG";
66 }
67
68 private Bitmap CreateBitmapFromMap(ITerrainChannel map)
69 {
70 Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
71
72 int pallete = gradientmapLd.Height;
73
74 Bitmap bmp = new Bitmap(map.Width, map.Height);
75 Color[] colours = new Color[pallete];
76
77 for (int i = 0; i < pallete; i++)
78 {
79 colours[i] = gradientmapLd.GetPixel(0, i);
80 }
81
82 for (int y = 0; y < map.Height; y++)
83 {
84 for (int x = 0; x < map.Width; x++)
85 {
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));
88 bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
89 }
90 }
91 return bmp;
92 }
93 }
94} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs
deleted file mode 100644
index 6ed7340..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/LLRAW.cs
+++ /dev/null
@@ -1,148 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using OpenSim.Region.Environment.Interfaces;
31
32namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
33{
34 public class LLRAW : ITerrainLoader
35 {
36 #region ITerrainLoader Members
37
38 public ITerrainChannel LoadFile(string filename)
39 {
40 TerrainChannel retval = new TerrainChannel();
41
42 FileInfo file = new FileInfo(filename);
43 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
44 BinaryReader bs = new BinaryReader(s);
45 int x, y;
46 for (y = 0; y < retval.Height; y++)
47 {
48 for (x = 0; x < retval.Width; x++)
49 {
50 retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0);
51 bs.ReadBytes(11); // Advance the stream to next bytes.
52 }
53 }
54
55 bs.Close();
56 s.Close();
57
58 return retval;
59 }
60
61 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
62 {
63 throw new NotImplementedException();
64 }
65
66 public void SaveFile(string filename, ITerrainChannel map)
67 {
68 FileInfo file = new FileInfo(filename);
69 FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
70 BinaryWriter binStream = new BinaryWriter(s);
71
72 // Generate a smegging big lookup table to speed the operation up (it needs it)
73 double[] lookupHeightTable = new double[65536];
74 int i, j, x, y;
75 for (i = 0; i < 256; i++)
76 {
77 for (j = 0; j < 256; j++)
78 {
79 lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0));
80 }
81 }
82
83 // Output the calculated raw
84 for (y = 0; y < map.Height; y++)
85 {
86 for (x = 0; x < map.Width; x++)
87 {
88 double t = map[x, y];
89 double min = double.MaxValue;
90 int index = 0;
91
92 for (i = 0; i < 65536; i++)
93 {
94 if (Math.Abs(t - lookupHeightTable[i]) < min)
95 {
96 min = Math.Abs(t - lookupHeightTable[i]);
97 index = i;
98 }
99 }
100
101 byte red = (byte) (index & 0xFF);
102 byte green = (byte) ((index >> 8) & 0xFF);
103 byte blue = 20;
104 byte alpha1 = 0; // Land Parcels
105 byte alpha2 = 0; // For Sale Land
106 byte alpha3 = 0; // Public Edit Object
107 byte alpha4 = 0; // Public Edit Land
108 byte alpha5 = 255; // Safe Land
109 byte alpha6 = 255; // Flying Allowed
110 byte alpha7 = 255; // Create Landmark
111 byte alpha8 = 255; // Outside Scripts
112 byte alpha9 = red;
113 byte alpha10 = green;
114
115 binStream.Write(red);
116 binStream.Write(green);
117 binStream.Write(blue);
118 binStream.Write(alpha1);
119 binStream.Write(alpha2);
120 binStream.Write(alpha3);
121 binStream.Write(alpha4);
122 binStream.Write(alpha5);
123 binStream.Write(alpha6);
124 binStream.Write(alpha7);
125 binStream.Write(alpha8);
126 binStream.Write(alpha9);
127 binStream.Write(alpha10);
128 }
129 }
130
131 binStream.Close();
132 s.Close();
133 }
134
135
136 public string FileExtension
137 {
138 get { return ".raw"; }
139 }
140
141 #endregion
142
143 public override string ToString()
144 {
145 return "LL/SL RAW";
146 }
147 }
148} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/PNG.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/PNG.cs
deleted file mode 100644
index 16f1e3c..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/PNG.cs
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
32{
33 internal class PNG : GenericSystemDrawing
34 {
35 public override void SaveFile(string filename, ITerrainChannel map)
36 {
37 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
38
39 colours.Save(filename, ImageFormat.Png);
40 }
41
42 public override string ToString()
43 {
44 return "PNG";
45 }
46 }
47} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs
deleted file mode 100644
index edc379b..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/RAW32.cs
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
32{
33 public class RAW32 : ITerrainLoader
34 {
35 #region ITerrainLoader Members
36
37 public string FileExtension
38 {
39 get { return ".r32"; }
40 }
41
42 public ITerrainChannel LoadFile(string filename)
43 {
44 TerrainChannel retval = new TerrainChannel();
45
46 FileInfo file = new FileInfo(filename);
47 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
48 BinaryReader bs = new BinaryReader(s);
49 int x, y;
50 for (y = 0; y < retval.Height; y++)
51 {
52 for (x = 0; x < retval.Width; x++)
53 {
54 retval[x, y] = bs.ReadSingle();
55 }
56 }
57
58 bs.Close();
59 s.Close();
60
61 return retval;
62 }
63
64 public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
65 {
66 TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
67
68 FileInfo file = new FileInfo(filename);
69 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
70 BinaryReader bs = new BinaryReader(s);
71
72 int currFileXOffset = 0;
73 int currFileYOffset = 0;
74
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
77 while (currFileYOffset < offsetY)
78 {
79 // read a whole strip of regions
80 int heightsToRead = sectionHeight * (fileWidth * sectionWidth);
81 bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file
82 currFileYOffset++;
83 }
84
85 // got to the Y start offset within the file of our region
86 // so read the file bits associated with our region
87 int x, y;
88 // for each Y within our Y offset
89 for (y = 0; y < sectionHeight; y++)
90 {
91 currFileXOffset = 0;
92
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
95 // i.e. eat X upto where we start
96 while (currFileXOffset < offsetX)
97 {
98 bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
99 currFileXOffset++;
100 }
101
102 // got to our X offset, so write our regions X line
103 for (x = 0; x < sectionWidth; x++)
104 {
105 // Read a strip and continue
106 retval[x, y] = bs.ReadSingle();
107 }
108 // record that we wrote it
109 currFileXOffset++;
110
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
113 while (currFileXOffset < fileWidth)
114 {
115 // eat the next regions x line
116 bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
117 currFileXOffset++;
118 }
119 }
120
121 bs.Close();
122 s.Close();
123
124 return retval;
125 }
126
127 public void SaveFile(string filename, ITerrainChannel map)
128 {
129 FileInfo file = new FileInfo(filename);
130 FileStream s = file.Open(FileMode.Create, FileAccess.Write);
131 BinaryWriter bs = new BinaryWriter(s);
132
133 int x, y;
134 for (y = 0; y < map.Height; y++)
135 {
136 for (x = 0; x < map.Width; x++)
137 {
138 bs.Write((float) map[x, y]);
139 }
140 }
141
142 bs.Close();
143 s.Close();
144 }
145
146 #endregion
147
148 public override string ToString()
149 {
150 return "RAW32";
151 }
152 }
153} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/TIFF.cs
deleted file mode 100644
index 39c2428..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/TIFF.cs
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System.Drawing;
28using System.Drawing.Imaging;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
32{
33 internal class TIFF : GenericSystemDrawing
34 {
35 public override void SaveFile(string filename, ITerrainChannel map)
36 {
37 Bitmap colours = CreateGrayscaleBitmapFromMap(map);
38
39 colours.Save(filename, ImageFormat.Tiff);
40 }
41
42 public override string ToString()
43 {
44 return "TIFF";
45 }
46 }
47} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs
deleted file mode 100644
index 2a4a8f8..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FileLoaders/Terragen.cs
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Text;
31using OpenSim.Region.Environment.Interfaces;
32
33namespace OpenSim.Region.Environment.Modules.Terrain.FileLoaders
34{
35 /// <summary>
36 /// Terragen File Format Loader
37 /// Built from specification at
38 /// http://www.planetside.co.uk/terragen/dev/tgterrain.html
39 /// </summary>
40 internal class Terragen : ITerrainLoader
41 {
42 #region ITerrainLoader Members
43
44 public ITerrainChannel LoadFile(string filename)
45 {
46 TerrainChannel retval = new TerrainChannel();
47
48 FileInfo file = new FileInfo(filename);
49 FileStream s = file.Open(FileMode.Open, FileAccess.Read);
50 BinaryReader bs = new BinaryReader(s);
51
52 bool eof = false;
53 if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
54 {
55 // Terragen file
56 while (eof == false)
57 {
58 int w = 256;
59 int h = 256;
60 string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4));
61 switch (tmp)
62 {
63 case "SIZE":
64 int sztmp = bs.ReadInt16() + 1;
65 w = sztmp;
66 h = sztmp;
67 bs.ReadInt16();
68 break;
69 case "XPTS":
70 w = bs.ReadInt16();
71 bs.ReadInt16();
72 break;
73 case "YPTS":
74 h = bs.ReadInt16();
75 bs.ReadInt16();
76 break;
77 case "ALTW":
78 eof = true;
79 Int16 heightScale = bs.ReadInt16();
80 Int16 baseHeight = bs.ReadInt16();
81 retval = new TerrainChannel(w, h);
82 int x, y;
83 for (x = 0; x < w; x++)
84 {
85 for (y = 0; y < h; y++)
86 {
87 retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0;
88 }
89 }
90 break;
91 default:
92 bs.ReadInt32();
93 break;
94 }
95 }
96 }
97
98 bs.Close();
99 s.Close();
100
101 return retval;
102 }
103
104 public void SaveFile(string filename, ITerrainChannel map)
105 {
106 char[] header = "TERRAGENTERRAIN".ToCharArray();
107 throw new NotImplementedException();
108 }
109
110 public string FileExtension
111 {
112 get { return ".ter"; }
113 }
114
115 public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
116 {
117 throw new NotImplementedException();
118 }
119
120 #endregion
121
122 public override string ToString()
123 {
124 return "Terragen";
125 }
126 }
127} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs
deleted file mode 100644
index 1e0b151..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/FlattenArea.cs
+++ /dev/null
@@ -1,71 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
31{
32 public class FlattenArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 double sum = 0.0;
39 double steps = 0.0;
40 double avg;
41
42 int x, y;
43 for (x = 0; x < map.Width; x++)
44 {
45 for (y = 0; y < map.Height; y++)
46 {
47 if (fillArea[x, y])
48 {
49 sum += map[x, y];
50 steps += 1.0;
51 }
52 }
53 }
54
55 avg = sum / steps;
56
57 double str = 0.1 * strength; // == 0.2 in the default client
58
59 for (x = 0; x < map.Width; x++)
60 {
61 for (y = 0; y < map.Height; y++)
62 {
63 if (fillArea[x, y])
64 map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
65 }
66 }
67 }
68
69 #endregion
70 }
71} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/LowerArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/LowerArea.cs
deleted file mode 100644
index 410d0cf..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/LowerArea.cs
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
31{
32 public class LowerArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 int x;
39 for (x = 0; x < map.Width; x++)
40 {
41 int y;
42 for (y = 0; y < map.Height; y++)
43 {
44 if (fillArea[x, y])
45 {
46 map[x, y] -= strength;
47 }
48 }
49 }
50 }
51
52 #endregion
53 }
54} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs
deleted file mode 100644
index 2ea1b90..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/NoiseArea.cs
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Framework;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
32{
33 public class NoiseArea : ITerrainFloodEffect
34 {
35 #region ITerrainFloodEffect Members
36
37 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
38 {
39 int x, y;
40 for (x = 0; x < map.Width; x++)
41 {
42 for (y = 0; y < map.Height; y++)
43 {
44 if (fillArea[x, y])
45 {
46 double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0);
47
48 map[x, y] += noise * strength;
49 }
50 }
51 }
52 }
53
54 #endregion
55 }
56} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RaiseArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RaiseArea.cs
deleted file mode 100644
index 4ea06c8..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RaiseArea.cs
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
31{
32 public class RaiseArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 int x, y;
39 for (x = 0; x < map.Width; x++)
40 {
41 for (y = 0; y < map.Height; y++)
42 {
43 if (fillArea[x, y])
44 {
45 map[x, y] += strength;
46 }
47 }
48 }
49 }
50
51 #endregion
52 }
53} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RevertArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RevertArea.cs
deleted file mode 100644
index 198b309..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/RevertArea.cs
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
31{
32 public class RevertArea : ITerrainFloodEffect
33 {
34 private readonly ITerrainChannel m_revertmap;
35
36 public RevertArea(ITerrainChannel revertmap)
37 {
38 m_revertmap = revertmap;
39 }
40
41 #region ITerrainFloodEffect Members
42
43 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
44 {
45 int x, y;
46 for (x = 0; x < map.Width; x++)
47 {
48 for (y = 0; y < map.Height; y++)
49 {
50 if (fillArea[x, y])
51 {
52 map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength);
53 }
54 }
55 }
56 }
57
58 #endregion
59 }
60} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/SmoothArea.cs b/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/SmoothArea.cs
deleted file mode 100644
index 49d8883..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/FloodBrushes/SmoothArea.cs
+++ /dev/null
@@ -1,114 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.FloodBrushes
31{
32 public class SmoothArea : ITerrainFloodEffect
33 {
34 #region ITerrainFloodEffect Members
35
36 public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
37 {
38 double area = strength;
39 double step = strength / 4.0;
40
41 double[,] manipulate = new double[map.Width,map.Height];
42 int x, y;
43 for (x = 0; x < map.Width; x++)
44 {
45 for (y = 0; y < map.Height; y++)
46 {
47 if (!fillArea[x, y])
48 continue;
49
50 double average = 0.0;
51 int avgsteps = 0;
52
53 double n;
54 for (n = 0.0 - area; n < area; n += step)
55 {
56 double l;
57 for (l = 0.0 - area; l < area; l += step)
58 {
59 avgsteps++;
60 average += GetBilinearInterpolate(x + n, y + l, map);
61 }
62 }
63
64 manipulate[x, y] = average / avgsteps;
65 }
66 }
67 for (x = 0; x < map.Width; x++)
68 {
69 for (y = 0; y < map.Height; y++)
70 {
71 if (!fillArea[x, y])
72 continue;
73
74 map[x, y] = manipulate[x, y];
75 }
76 }
77 }
78
79 #endregion
80
81 private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
82 {
83 int w = map.Width;
84 int h = map.Height;
85
86 if (x > w - 2.0)
87 x = w - 2.0;
88 if (y > h - 2.0)
89 y = h - 2.0;
90 if (x < 0.0)
91 x = 0.0;
92 if (y < 0.0)
93 y = 0.0;
94
95 int stepSize = 1;
96 double h00 = map[(int) x, (int) y];
97 double h10 = map[(int) x + stepSize, (int) y];
98 double h01 = map[(int) x, (int) y + stepSize];
99 double h11 = map[(int) x + stepSize, (int) y + stepSize];
100 double h1 = h00;
101 double h2 = h10;
102 double h3 = h01;
103 double h4 = h11;
104 double a00 = h1;
105 double a10 = h2 - h1;
106 double a01 = h3 - h1;
107 double a11 = h1 - h2 - h3 + h4;
108 double partialx = x - (int) x;
109 double partialz = y - (int) y;
110 double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
111 return hi;
112 }
113 }
114} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs
deleted file mode 100644
index 96e92f2..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/ITerrainEffect.cs
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain
31{
32 public interface ITerrainEffect
33 {
34 void RunEffect(ITerrainChannel map);
35 }
36} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs
deleted file mode 100644
index 7d33bf8..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/ITerrainFloodEffect.cs
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain
32{
33 public interface ITerrainFloodEffect
34 {
35 void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength);
36 }
37} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs
deleted file mode 100644
index c718a32..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/ITerrainLoader.cs
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain
31{
32 public interface ITerrainLoader
33 {
34 string FileExtension { get; }
35 ITerrainChannel LoadFile(string filename);
36 ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
37 void SaveFile(string filename, ITerrainChannel map);
38 }
39} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainModule.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainModule.cs
deleted file mode 100644
index d1ea2a4..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/ITerrainModule.cs
+++ /dev/null
@@ -1,8 +0,0 @@
1namespace OpenSim.Region.Environment.Modules.Terrain
2{
3 public interface ITerrainModule
4 {
5 void LoadFromFile(string filename);
6 void SaveToFile(string filename);
7 }
8} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs b/OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs
deleted file mode 100644
index 07fcb72..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/ITerrainPaintableEffect.cs
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain
31{
32 public interface ITerrainPaintableEffect
33 {
34 void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration);
35 }
36} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/MapImageModule.cs b/OpenSim/Region/Environment/Modules/Terrain/MapImageModule.cs
deleted file mode 100644
index 763735f..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/MapImageModule.cs
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using Nini.Config;
31using OpenJPEGNet;
32using OpenSim.Region.Environment.Interfaces;
33using OpenSim.Region.Environment.Scenes;
34
35namespace OpenSim.Region.Environment.Modules.Terrain
36{
37 internal class MapImageModule : IMapImageGenerator, IRegionModule
38 {
39 private Scene m_scene;
40
41 #region IMapImageGenerator Members
42
43 public byte[] WriteJpeg2000Image(string gradientmap)
44 {
45 byte[] imageData = null;
46
47 Bitmap bmp = TerrainToBitmap(gradientmap);
48
49 try
50 {
51 imageData = OpenJPEG.EncodeFromImage(bmp, true);
52 }
53 catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
54 {
55 Console.WriteLine("Failed generating terrain map: " + e);
56 }
57
58 return imageData;
59 }
60
61 #endregion
62
63 #region IRegionModule Members
64
65 public void Initialise(Scene scene, IConfigSource source)
66 {
67 m_scene = scene;
68 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
69 }
70
71 public void PostInitialise()
72 {
73 }
74
75 public void Close()
76 {
77 }
78
79 public string Name
80 {
81 get { return "MapImageModule"; }
82 }
83
84 public bool IsSharedModule
85 {
86 get { return false; }
87 }
88
89 #endregion
90
91 private void ShadeBuildings(ref Bitmap map)
92 {
93 lock (map)
94 {
95 lock (m_scene.Entities)
96 {
97 foreach (EntityBase entity in m_scene.Entities.Values)
98 {
99 if (entity is SceneObjectGroup)
100 {
101 SceneObjectGroup sog = (SceneObjectGroup) entity;
102
103 foreach (SceneObjectPart primitive in sog.Children.Values)
104 {
105 int x, y, w, h;
106 x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
107 y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
108 w = (int) primitive.Scale.X;
109 h = (int) primitive.Scale.Y;
110
111 int dx;
112 for (dx = x; dx < x + w; dx++)
113 {
114 int dy;
115 for (dy = y; dy < y + h; dy++)
116 {
117 if (x < 0 || y < 0)
118 continue;
119 if (x >= map.Width || y >= map.Height)
120 continue;
121
122 map.SetPixel(dx, dy, Color.DarkGray);
123 }
124 }
125 }
126 }
127 }
128 }
129 }
130 }
131
132 private Bitmap TerrainToBitmap(string gradientmap)
133 {
134 Bitmap gradientmapLd = new Bitmap(gradientmap);
135
136 int pallete = gradientmapLd.Height;
137
138 Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height);
139 Color[] colours = new Color[pallete];
140
141 for (int i = 0; i < pallete; i++)
142 {
143 colours[i] = gradientmapLd.GetPixel(0, i);
144 }
145
146 lock (m_scene.Heightmap)
147 {
148 ITerrainChannel copy = m_scene.Heightmap;
149 for (int y = 0; y < copy.Height; y++)
150 {
151 for (int x = 0; x < copy.Width; x++)
152 {
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));
155
156 // Handle error conditions
157 if (colorindex > pallete - 1 || colorindex < 0)
158 bmp.SetPixel(x, copy.Height - y - 1, Color.Red);
159 else
160 bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]);
161 }
162 }
163 ShadeBuildings(ref bmp);
164 return bmp;
165 }
166 }
167 }
168} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/ErodeSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/ErodeSphere.cs
deleted file mode 100644
index cfb1f60..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/ErodeSphere.cs
+++ /dev/null
@@ -1,312 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
32{
33 /// <summary>
34 /// Hydraulic Erosion Brush
35 /// </summary>
36 public class ErodeSphere : ITerrainPaintableEffect
37 {
38 private double rainHeight = 0.2;
39 private int rounds = 10;
40 private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
41 private double waterSaturation = 0.30; // Can carry 1% of water in height
42
43 #region Supporting Functions
44
45 private int[] Neighbours(NeighbourSystem type, int index)
46 {
47 int[] coord = new int[2];
48
49 index++;
50
51 switch (type)
52 {
53 case NeighbourSystem.Moore:
54 switch (index)
55 {
56 case 1:
57 coord[0] = -1;
58 coord[1] = -1;
59 break;
60
61 case 2:
62 coord[0] = -0;
63 coord[1] = -1;
64 break;
65
66 case 3:
67 coord[0] = +1;
68 coord[1] = -1;
69 break;
70
71 case 4:
72 coord[0] = -1;
73 coord[1] = -0;
74 break;
75
76 case 5:
77 coord[0] = -0;
78 coord[1] = -0;
79 break;
80
81 case 6:
82 coord[0] = +1;
83 coord[1] = -0;
84 break;
85
86 case 7:
87 coord[0] = -1;
88 coord[1] = +1;
89 break;
90
91 case 8:
92 coord[0] = -0;
93 coord[1] = +1;
94 break;
95
96 case 9:
97 coord[0] = +1;
98 coord[1] = +1;
99 break;
100
101 default:
102 break;
103 }
104 break;
105
106 case NeighbourSystem.VonNeumann:
107 switch (index)
108 {
109 case 1:
110 coord[0] = 0;
111 coord[1] = -1;
112 break;
113
114 case 2:
115 coord[0] = -1;
116 coord[1] = 0;
117 break;
118
119 case 3:
120 coord[0] = +1;
121 coord[1] = 0;
122 break;
123
124 case 4:
125 coord[0] = 0;
126 coord[1] = +1;
127 break;
128
129 case 5:
130 coord[0] = -0;
131 coord[1] = -0;
132 break;
133
134 default:
135 break;
136 }
137 break;
138 }
139
140 return coord;
141 }
142
143 private enum NeighbourSystem
144 {
145 Moore,
146 VonNeumann
147 } ;
148
149 #endregion
150
151 #region ITerrainPaintableEffect Members
152
153 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
154 {
155 strength = TerrainUtil.MetersToSphericalStrength(strength);
156
157 int x, y;
158 // Using one 'rain' round for this, so skipping a useless loop
159 // Will need to adapt back in for the Flood brush
160
161 ITerrainChannel water = new TerrainChannel(map.Width, map.Height);
162 ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
163
164 // Fill with rain
165 for (x = 0; x < water.Width; x++)
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);
168
169 for (int i = 0; i < rounds; i++)
170 {
171 // Erode underlying terrain
172 for (x = 0; x < water.Width; x++)
173 {
174 for (y = 0; y < water.Height; y++)
175 {
176 double solConst = (1.0 / rounds);
177 double sedDelta = water[x, y] * solConst;
178 map[x, y] -= sedDelta;
179 sediment[x, y] += sedDelta;
180 }
181 }
182
183 // Move water
184 for (x = 0; x < water.Width; x++)
185 {
186 for (y = 0; y < water.Height; y++)
187 {
188 if (water[x, y] <= 0)
189 continue;
190
191 // Step 1. Calculate average of neighbours
192
193 int neighbours = 0;
194 double altitudeTotal = 0.0;
195 double altitudeMe = map[x, y] + water[x, y];
196
197 int NEIGHBOUR_ME = 4;
198
199 int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
200
201 for (int j = 0; j < NEIGHBOUR_MAX; j++)
202 {
203 if (j != NEIGHBOUR_ME)
204 {
205 int[] coords = Neighbours(type, j);
206
207 coords[0] += x;
208 coords[1] += y;
209
210 if (coords[0] > map.Width - 1)
211 continue;
212 if (coords[1] > map.Height - 1)
213 continue;
214 if (coords[0] < 0)
215 continue;
216 if (coords[1] < 0)
217 continue;
218
219 // Calculate total height of this neighbour
220 double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
221
222 // If it's greater than me...
223 if (altitudeNeighbour - altitudeMe < 0)
224 {
225 // Add it to our calculations
226 neighbours++;
227 altitudeTotal += altitudeNeighbour;
228 }
229 }
230 }
231
232 if (neighbours == 0)
233 continue;
234
235 double altitudeAvg = altitudeTotal / neighbours;
236
237 // Step 2. Allocate water to neighbours.
238 for (int j = 0; j < NEIGHBOUR_MAX; j++)
239 {
240 if (j != NEIGHBOUR_ME)
241 {
242 int[] coords = Neighbours(type, j);
243
244 coords[0] += x;
245 coords[1] += y;
246
247 if (coords[0] > map.Width - 1)
248 continue;
249 if (coords[1] > map.Height - 1)
250 continue;
251 if (coords[0] < 0)
252 continue;
253 if (coords[1] < 0)
254 continue;
255
256 // Skip if we dont have water to begin with.
257 if (water[x, y] < 0)
258 continue;
259
260 // Calculate our delta average
261 double altitudeDelta = altitudeMe - altitudeAvg;
262
263 if (altitudeDelta < 0)
264 continue;
265
266 // Calculate how much water we can move
267 double waterMin = Math.Min(water[x, y], altitudeDelta);
268 double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
269 / altitudeTotal);
270
271 double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
272
273 if (sedimentDelta > 0)
274 {
275 sediment[x, y] -= sedimentDelta;
276 sediment[coords[0], coords[1]] += sedimentDelta;
277 }
278 }
279 }
280 }
281 }
282
283 // Evaporate
284
285 for (x = 0; x < water.Width; x++)
286 {
287 for (y = 0; y < water.Height; y++)
288 {
289 water[x, y] *= 1.0 - (rainHeight / rounds);
290
291 double waterCapacity = waterSaturation * water[x, y];
292
293 double sedimentDeposit = sediment[x, y] - waterCapacity;
294 if (sedimentDeposit > 0)
295 {
296 sediment[x, y] -= sedimentDeposit;
297 map[x, y] += sedimentDeposit;
298 }
299 }
300 }
301 }
302
303 // Deposit any remainder (should be minimal)
304 for (x = 0; x < water.Width; x++)
305 for (y = 0; y < water.Height; y++)
306 if (sediment[x, y] > 0)
307 map[x, y] += sediment[x, y];
308 }
309
310 #endregion
311 }
312} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/FlattenSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/FlattenSphere.cs
deleted file mode 100644
index d907ed2..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/FlattenSphere.cs
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
31{
32 public class FlattenSphere : ITerrainPaintableEffect
33 {
34// TODO: unused
35// private double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
36// {
37// int w = map.Width;
38// int h = map.Height;
39
40// if (x > w - 2.0)
41// x = w - 2.0;
42// if (y > h - 2.0)
43// y = h - 2.0;
44// if (x < 0.0)
45// x = 0.0;
46// if (y < 0.0)
47// y = 0.0;
48
49// int stepSize = 1;
50// double h00 = map[(int)x, (int)y];
51// double h10 = map[(int)x + stepSize, (int)y];
52// double h01 = map[(int)x, (int)y + stepSize];
53// double h11 = map[(int)x + stepSize, (int)y + stepSize];
54// double h1 = h00;
55// double h2 = h10;
56// double h3 = h01;
57// double h4 = h11;
58// double a00 = h1;
59// double a10 = h2 - h1;
60// double a01 = h3 - h1;
61// double a11 = h1 - h2 - h3 + h4;
62// double partialx = x - (int)x;
63// double partialz = y - (int)y;
64// double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
65// return hi;
66// }
67
68 #region ITerrainPaintableEffect Members
69
70 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
71 {
72 strength = TerrainUtil.MetersToSphericalStrength(strength);
73
74 int x, y;
75 double[,] tweak = new double[map.Width,map.Height];
76
77 double area = strength;
78 double step = strength / 4.0;
79
80 double sum = 0.0;
81 double step2 = 0.0;
82 double avg = 0.0;
83
84 // compute delta map
85 for (x = 0; x < map.Width; x++)
86 {
87 for (y = 0; y < map.Height; y++)
88 {
89 double z = SphericalFactor(x, y, rx, ry, strength);
90
91 if (z > 0) // add in non-zero amount
92 {
93 sum += map[x, y] * z;
94 step2 += z;
95 }
96 }
97 }
98
99 avg = sum / step2;
100
101 // blend in map
102 for (x = 0; x < map.Width; x++)
103 {
104 for (y = 0; y < map.Height; y++)
105 {
106 double z = SphericalFactor(x, y, rx, ry, strength) * duration;
107
108 if (z > 0) // add in non-zero amount
109 {
110 if (z > 1.0)
111 z = 1.0;
112
113 map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z);
114 }
115 }
116 }
117 }
118
119 #endregion
120
121 private double SphericalFactor(double x, double y, double rx, double ry, double size)
122 {
123 double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
124 return z;
125 }
126 }
127} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/LowerSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/LowerSphere.cs
deleted file mode 100644
index ead1a49..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/LowerSphere.cs
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
32{
33 public class LowerSphere : ITerrainPaintableEffect
34 {
35 #region ITerrainPaintableEffect Members
36
37 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
38 {
39 strength = TerrainUtil.MetersToSphericalStrength(strength);
40
41 int x, y;
42 for (x = 0; x < map.Width; x++)
43 {
44 // Skip everything unlikely to be affected
45 if (Math.Abs(x - rx) > strength * 1.1)
46 continue;
47
48 for (y = 0; y < map.Height; y++)
49 {
50 // Skip everything unlikely to be affected
51 if (Math.Abs(y - ry) > strength * 1.1)
52 continue;
53
54 // Calculate a sphere and add it to the heighmap
55 double z = strength;
56 z *= z;
57 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
58
59 if (z > 0.0)
60 map[x, y] -= z * duration;
61 }
62 }
63 }
64
65 #endregion
66 }
67} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs
deleted file mode 100644
index e3babbf..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/NoiseSphere.cs
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Framework;
30using OpenSim.Region.Environment.Interfaces;
31
32namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
33{
34 public class NoiseSphere : ITerrainPaintableEffect
35 {
36 #region ITerrainPaintableEffect Members
37
38 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
39 {
40 strength = TerrainUtil.MetersToSphericalStrength(strength);
41
42 int x, y;
43 for (x = 0; x < map.Width; x++)
44 {
45 // Skip everything unlikely to be affected
46 if (Math.Abs(x - rx) > strength * 1.1)
47 continue;
48
49 for (y = 0; y < map.Height; y++)
50 {
51 // Skip everything unlikely to be affected
52 if (Math.Abs(y - ry) > strength * 1.1)
53 continue;
54
55 // Calculate a sphere and add it to the heighmap
56 double z = strength;
57 z *= z;
58 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
59
60 double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0);
61
62 if (z > 0.0)
63 map[x, y] += noise * z * duration;
64 }
65 }
66 }
67
68 #endregion
69 }
70} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/OlsenSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/OlsenSphere.cs
deleted file mode 100644
index 153fc15..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/OlsenSphere.cs
+++ /dev/null
@@ -1,225 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
32{
33 /// <summary>
34 /// Speed-Optimised Hybrid Erosion Brush
35 ///
36 /// As per Jacob Olsen's Paper
37 /// http://www.oddlabs.com/download/terrain_generation.pdf
38 /// </summary>
39 public class OlsenSphere : ITerrainPaintableEffect
40 {
41 private double nConst = 1024.0;
42 private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
43
44 #region Supporting Functions
45
46 private int[] Neighbours(NeighbourSystem type, int index)
47 {
48 int[] coord = new int[2];
49
50 index++;
51
52 switch (type)
53 {
54 case NeighbourSystem.Moore:
55 switch (index)
56 {
57 case 1:
58 coord[0] = -1;
59 coord[1] = -1;
60 break;
61
62 case 2:
63 coord[0] = -0;
64 coord[1] = -1;
65 break;
66
67 case 3:
68 coord[0] = +1;
69 coord[1] = -1;
70 break;
71
72 case 4:
73 coord[0] = -1;
74 coord[1] = -0;
75 break;
76
77 case 5:
78 coord[0] = -0;
79 coord[1] = -0;
80 break;
81
82 case 6:
83 coord[0] = +1;
84 coord[1] = -0;
85 break;
86
87 case 7:
88 coord[0] = -1;
89 coord[1] = +1;
90 break;
91
92 case 8:
93 coord[0] = -0;
94 coord[1] = +1;
95 break;
96
97 case 9:
98 coord[0] = +1;
99 coord[1] = +1;
100 break;
101
102 default:
103 break;
104 }
105 break;
106
107 case NeighbourSystem.VonNeumann:
108 switch (index)
109 {
110 case 1:
111 coord[0] = 0;
112 coord[1] = -1;
113 break;
114
115 case 2:
116 coord[0] = -1;
117 coord[1] = 0;
118 break;
119
120 case 3:
121 coord[0] = +1;
122 coord[1] = 0;
123 break;
124
125 case 4:
126 coord[0] = 0;
127 coord[1] = +1;
128 break;
129
130 case 5:
131 coord[0] = -0;
132 coord[1] = -0;
133 break;
134
135 default:
136 break;
137 }
138 break;
139 }
140
141 return coord;
142 }
143
144 private double SphericalFactor(double x, double y, double rx, double ry, double size)
145 {
146 double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
147 return z;
148 }
149
150 private enum NeighbourSystem
151 {
152 Moore,
153 VonNeumann
154 } ;
155
156 #endregion
157
158 #region ITerrainPaintableEffect Members
159
160 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
161 {
162 strength = TerrainUtil.MetersToSphericalStrength(strength);
163
164 int x, y;
165
166 for (x = 0; x < map.Width; x++)
167 {
168 for (y = 0; y < map.Height; y++)
169 {
170 double z = SphericalFactor(x, y, rx, ry, strength);
171
172 if (z > 0) // add in non-zero amount
173 {
174 int NEIGHBOUR_ME = 4;
175 int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
176
177 double max = Double.MinValue;
178 int loc = 0;
179 double cellmax = 0;
180
181
182 for (int j = 0; j < NEIGHBOUR_MAX; j++)
183 {
184 if (j != NEIGHBOUR_ME)
185 {
186 int[] coords = Neighbours(type, j);
187
188 coords[0] += x;
189 coords[1] += y;
190
191 if (coords[0] > map.Width - 1)
192 continue;
193 if (coords[1] > map.Height - 1)
194 continue;
195 if (coords[0] < 0)
196 continue;
197 if (coords[1] < 0)
198 continue;
199
200 cellmax = map[x, y] - map[coords[0], coords[1]];
201 if (cellmax > max)
202 {
203 max = cellmax;
204 loc = j;
205 }
206 }
207 }
208
209 double T = nConst / ((map.Width + map.Height) / 2);
210 // Apply results
211 if (0 < max && max <= T)
212 {
213 int[] maxCoords = Neighbours(type, loc);
214 double heightDelta = 0.5 * max * z * duration;
215 map[x, y] -= heightDelta;
216 map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
217 }
218 }
219 }
220 }
221 }
222
223 #endregion
224 }
225} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RaiseSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RaiseSphere.cs
deleted file mode 100644
index 8d61a7e..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RaiseSphere.cs
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
32{
33 public class RaiseSphere : ITerrainPaintableEffect
34 {
35 #region ITerrainPaintableEffect Members
36
37 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
38 {
39 strength = TerrainUtil.MetersToSphericalStrength(strength);
40
41 int x, y;
42 for (x = 0; x < map.Width; x++)
43 {
44 // Skip everything unlikely to be affected
45 if (Math.Abs(x - rx) > strength * 1.1)
46 continue;
47
48 for (y = 0; y < map.Height; y++)
49 {
50 // Skip everything unlikely to be affected
51 if (Math.Abs(y - ry) > strength * 1.1)
52 continue;
53
54 // Calculate a sphere and add it to the heighmap
55 double z = strength;
56 z *= z;
57 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
58
59 if (z > 0.0)
60 map[x, y] += z * duration;
61 }
62 }
63 }
64
65 #endregion
66 }
67} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RevertSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RevertSphere.cs
deleted file mode 100644
index ee0edb5..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/RevertSphere.cs
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
32{
33 public class RevertSphere : ITerrainPaintableEffect
34 {
35 private ITerrainChannel m_revertmap;
36
37 public RevertSphere(ITerrainChannel revertmap)
38 {
39 m_revertmap = revertmap;
40 }
41
42 #region ITerrainPaintableEffect Members
43
44 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
45 {
46 strength = TerrainUtil.MetersToSphericalStrength(strength);
47
48 if (duration > 1.0)
49 duration = 1.0;
50 if (duration < 0)
51 return;
52
53 int x, y;
54 for (x = 0; x < map.Width; x++)
55 {
56 // Skip everything unlikely to be affected
57 if (Math.Abs(x - rx) > strength * 1.1)
58 continue;
59
60 for (y = 0; y < map.Height; y++)
61 {
62 // Skip everything unlikely to be affected
63 if (Math.Abs(y - ry) > strength * 1.1)
64 continue;
65
66 // Calculate a sphere and add it to the heighmap
67 double z = strength;
68 z *= z;
69 z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
70
71 if (z > 0.0)
72 {
73 z *= duration;
74 map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z);
75 }
76 }
77 }
78 }
79
80 #endregion
81 }
82} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/SmoothSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/SmoothSphere.cs
deleted file mode 100644
index 86a01cc..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/SmoothSphere.cs
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
31{
32 public class SmoothSphere : ITerrainPaintableEffect
33 {
34 #region ITerrainPaintableEffect Members
35
36 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
37 {
38 strength = TerrainUtil.MetersToSphericalStrength(strength);
39
40 int x, y;
41 double[,] tweak = new double[map.Width,map.Height];
42
43 double n, l;
44 double area = strength;
45 double step = strength / 4.0;
46
47 // compute delta map
48 for (x = 0; x < map.Width; x++)
49 {
50 for (y = 0; y < map.Height; y++)
51 {
52 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
53
54 if (z > 0) // add in non-zero amount
55 {
56 double average = 0.0;
57 int avgsteps = 0;
58
59 for (n = 0.0 - area; n < area; n += step)
60 {
61 for (l = 0.0 - area; l < area; l += step)
62 {
63 avgsteps++;
64 average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
65 }
66 }
67 tweak[x, y] = average / avgsteps;
68 }
69 }
70 }
71 // blend in map
72 for (x = 0; x < map.Width; x++)
73 {
74 for (y = 0; y < map.Height; y++)
75 {
76 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
77
78 if (z > 0) // add in non-zero amount
79 {
80 double da = z;
81 double a = (map[x, y] - tweak[x, y]) * da;
82 double newz = map[x, y] - (a * duration);
83
84 if (newz > 0.0)
85 map[x, y] = newz;
86 }
87 }
88 }
89 }
90
91 #endregion
92 }
93} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/WeatherSphere.cs b/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/WeatherSphere.cs
deleted file mode 100644
index f46ba8f..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/PaintBrushes/WeatherSphere.cs
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Region.Environment.Interfaces;
29
30namespace OpenSim.Region.Environment.Modules.Terrain.PaintBrushes
31{
32 /// <summary>
33 /// Thermal Weathering Paint Brush
34 /// </summary>
35 public class WeatherSphere : ITerrainPaintableEffect
36 {
37 private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required.
38 private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
39
40 #region Supporting Functions
41
42 private int[] Neighbours(NeighbourSystem type, int index)
43 {
44 int[] coord = new int[2];
45
46 index++;
47
48 switch (type)
49 {
50 case NeighbourSystem.Moore:
51 switch (index)
52 {
53 case 1:
54 coord[0] = -1;
55 coord[1] = -1;
56 break;
57
58 case 2:
59 coord[0] = -0;
60 coord[1] = -1;
61 break;
62
63 case 3:
64 coord[0] = +1;
65 coord[1] = -1;
66 break;
67
68 case 4:
69 coord[0] = -1;
70 coord[1] = -0;
71 break;
72
73 case 5:
74 coord[0] = -0;
75 coord[1] = -0;
76 break;
77
78 case 6:
79 coord[0] = +1;
80 coord[1] = -0;
81 break;
82
83 case 7:
84 coord[0] = -1;
85 coord[1] = +1;
86 break;
87
88 case 8:
89 coord[0] = -0;
90 coord[1] = +1;
91 break;
92
93 case 9:
94 coord[0] = +1;
95 coord[1] = +1;
96 break;
97
98 default:
99 break;
100 }
101 break;
102
103 case NeighbourSystem.VonNeumann:
104 switch (index)
105 {
106 case 1:
107 coord[0] = 0;
108 coord[1] = -1;
109 break;
110
111 case 2:
112 coord[0] = -1;
113 coord[1] = 0;
114 break;
115
116 case 3:
117 coord[0] = +1;
118 coord[1] = 0;
119 break;
120
121 case 4:
122 coord[0] = 0;
123 coord[1] = +1;
124 break;
125
126 case 5:
127 coord[0] = -0;
128 coord[1] = -0;
129 break;
130
131 default:
132 break;
133 }
134 break;
135 }
136
137 return coord;
138 }
139
140 private enum NeighbourSystem
141 {
142 Moore,
143 VonNeumann
144 } ;
145
146 #endregion
147
148 #region ITerrainPaintableEffect Members
149
150 public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
151 {
152 strength = TerrainUtil.MetersToSphericalStrength(strength);
153
154 int x, y;
155
156 for (x = 0; x < map.Width; x++)
157 {
158 for (y = 0; y < map.Height; y++)
159 {
160 double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
161
162 if (z > 0) // add in non-zero amount
163 {
164 int NEIGHBOUR_ME = 4;
165
166 int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
167
168 for (int j = 0; j < NEIGHBOUR_MAX; j++)
169 {
170 if (j != NEIGHBOUR_ME)
171 {
172 int[] coords = Neighbours(type, j);
173
174 coords[0] += x;
175 coords[1] += y;
176
177 if (coords[0] > map.Width - 1)
178 continue;
179 if (coords[1] > map.Height - 1)
180 continue;
181 if (coords[0] < 0)
182 continue;
183 if (coords[1] < 0)
184 continue;
185
186 double heightF = map[x, y];
187 double target = map[coords[0], coords[1]];
188
189 if (target > heightF + talus)
190 {
191 double calc = duration * ((target - heightF) - talus) * z;
192 heightF += calc;
193 target -= calc;
194 }
195
196 map[x, y] = heightF;
197 map[coords[0], coords[1]] = target;
198 }
199 }
200 }
201 }
202 }
203 }
204
205 #endregion
206 }
207} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs
deleted file mode 100644
index 1344715..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/TerrainChannel.cs
+++ /dev/null
@@ -1,157 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenSim.Framework;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain
32{
33 /// <summary>
34 /// A new version of the old Channel class, simplified
35 /// </summary>
36 public class TerrainChannel : ITerrainChannel
37 {
38 private readonly bool[,] taint;
39 private double[,] map;
40
41 public TerrainChannel()
42 {
43 map = new double[Constants.RegionSize,Constants.RegionSize];
44 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
45
46 int x;
47 for (x = 0; x < Constants.RegionSize; x++)
48 {
49 int y;
50 for (y = 0; y < Constants.RegionSize; y++)
51 {
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;
54 if (map[x, y] < spherFac)
55 {
56 map[x, y] = spherFac;
57 }
58 }
59 }
60 }
61
62 public TerrainChannel(double[,] import)
63 {
64 map = import;
65 taint = new bool[import.GetLength(0),import.GetLength(1)];
66 }
67
68 public TerrainChannel(bool createMap)
69 {
70 if (createMap)
71 {
72 map = new double[Constants.RegionSize,Constants.RegionSize];
73 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
74 }
75 }
76
77 public TerrainChannel(int w, int h)
78 {
79 map = new double[w,h];
80 taint = new bool[w / 16,h / 16];
81 }
82
83 #region ITerrainChannel Members
84
85 public int Width
86 {
87 get { return map.GetLength(0); }
88 }
89
90 public int Height
91 {
92 get { return map.GetLength(1); }
93 }
94
95 public ITerrainChannel MakeCopy()
96 {
97 TerrainChannel copy = new TerrainChannel(false);
98 copy.map = (double[,]) map.Clone();
99
100 return copy;
101 }
102
103 public float[] GetFloatsSerialised()
104 {
105 float[] heights = new float[Width * Height];
106 int i;
107
108 for (i = 0; i < Width * Height; i++)
109 {
110 heights[i] = (float) map[i % Width, i / Width];
111 }
112
113 return heights;
114 }
115
116 public double[,] GetDoubles()
117 {
118 return map;
119 }
120
121 public double this[int x, int y]
122 {
123 get { return map[x, y]; }
124 set
125 {
126 if (map[x, y] != value)
127 {
128 taint[x / 16, y / 16] = true;
129 map[x, y] = value;
130 }
131 }
132 }
133
134 public bool Tainted(int x, int y)
135 {
136 if (taint[x / 16, y / 16])
137 {
138 taint[x / 16, y / 16] = false;
139 return true;
140 }
141 else
142 {
143 return false;
144 }
145 }
146
147 #endregion
148
149 public TerrainChannel Copy()
150 {
151 TerrainChannel copy = new TerrainChannel(false);
152 copy.map = (double[,]) map.Clone();
153
154 return copy;
155 }
156 }
157} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainException.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainException.cs
deleted file mode 100644
index d357063..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/TerrainException.cs
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29
30namespace OpenSim.Region.Environment.Modules.Terrain
31{
32 public class TerrainException : Exception
33 {
34 public TerrainException() : base()
35 {
36 }
37
38 public TerrainException(string msg) : base(msg)
39 {
40 }
41
42 public TerrainException(string msg, Exception e) : base(msg, e)
43 {
44 }
45 }
46} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs
deleted file mode 100644
index 67acef7..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/TerrainModule.cs
+++ /dev/null
@@ -1,734 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using libsecondlife;
33using log4net;
34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Modules.ModuleFramework;
38using OpenSim.Region.Environment.Modules.Terrain.FileLoaders;
39using OpenSim.Region.Environment.Modules.Terrain.FloodBrushes;
40using OpenSim.Region.Environment.Modules.Terrain.PaintBrushes;
41using OpenSim.Region.Environment.Scenes;
42
43namespace OpenSim.Region.Environment.Modules.Terrain
44{
45 public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule
46 {
47 #region StandardTerrainEffects enum
48
49 /// <summary>
50 /// A standard set of terrain brushes and effects recognised by viewers
51 /// </summary>
52 public enum StandardTerrainEffects : byte
53 {
54 Flatten = 0,
55 Raise = 1,
56 Lower = 2,
57 Smooth = 3,
58 Noise = 4,
59 Revert = 5,
60
61 // Extended brushes
62 Erode = 255,
63 Weather = 254,
64 Olsen = 253
65 }
66
67 #endregion
68
69 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
70
71 private readonly Commander m_commander = new Commander("Terrain");
72
73 private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects =
74 new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>();
75
76 private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
77
78 private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
79 new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
80
81 private ITerrainChannel m_channel;
82 private Dictionary<string, ITerrainEffect> m_plugineffects;
83 private ITerrainChannel m_revert;
84 private Scene m_scene;
85 private bool m_tainted = false;
86
87 #region ICommandableModule Members
88
89 public ICommander CommandInterface
90 {
91 get { return m_commander; }
92 }
93
94 #endregion
95
96 #region IRegionModule Members
97
98 /// <summary>
99 /// Creates and initialises a terrain module for a region
100 /// </summary>
101 /// <param name="scene">Region initialising</param>
102 /// <param name="config">Config for the region</param>
103 public void Initialise(Scene scene, IConfigSource config)
104 {
105 m_scene = scene;
106
107 // Install terrain module in the simulator
108 if (m_scene.Heightmap == null)
109 {
110 lock (m_scene)
111 {
112 m_channel = new TerrainChannel();
113 m_scene.Heightmap = m_channel;
114 m_revert = new TerrainChannel();
115 UpdateRevertMap();
116 }
117 }
118 else
119 {
120 m_channel = m_scene.Heightmap;
121 m_revert = new TerrainChannel();
122 UpdateRevertMap();
123 }
124
125 m_scene.RegisterModuleInterface<ITerrainModule>(this);
126 m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
127 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
128 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
129 }
130
131 /// <summary>
132 /// Enables terrain module when called
133 /// </summary>
134 public void PostInitialise()
135 {
136 InstallDefaultEffects();
137 InstallInterfaces();
138 LoadPlugins();
139 }
140
141 public void Close()
142 {
143 }
144
145 public string Name
146 {
147 get { return "TerrainModule"; }
148 }
149
150 public bool IsSharedModule
151 {
152 get { return false; }
153 }
154
155 #endregion
156
157 #region ITerrainModule Members
158
159 /// <summary>
160 /// Loads a terrain file from disk and installs it in the scene.
161 /// </summary>
162 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
163 public void LoadFromFile(string filename)
164 {
165 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
166 {
167 if (filename.EndsWith(loader.Key))
168 {
169 lock (m_scene)
170 {
171 try
172 {
173 ITerrainChannel channel = loader.Value.LoadFile(filename);
174 m_scene.Heightmap = channel;
175 m_channel = channel;
176 UpdateRevertMap();
177 }
178 catch (NotImplementedException)
179 {
180 m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value +
181 " parser does not support file loading. (May be save only)");
182 throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value));
183 }
184 catch (FileNotFoundException)
185 {
186 m_log.Error(
187 "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
188 throw new TerrainException(
189 String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename));
190 }
191 }
192 CheckForTerrainUpdates();
193 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
194 return;
195 }
196 }
197 m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
198 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
199 }
200
201 /// <summary>
202 /// Saves the current heightmap to a specified file.
203 /// </summary>
204 /// <param name="filename">The destination filename</param>
205 public void SaveToFile(string filename)
206 {
207 try
208 {
209 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
210 {
211 if (filename.EndsWith(loader.Key))
212 {
213 loader.Value.SaveFile(filename, m_channel);
214 return;
215 }
216 }
217 }
218 catch (NotImplementedException)
219 {
220 m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented.");
221 throw new TerrainException(String.Format("unable to save heightmap: {0}: saving of this file format not implemented"));
222 }
223 }
224
225 #region Plugin Loading Methods
226
227 private void LoadPlugins()
228 {
229 m_plugineffects = new Dictionary<string, ITerrainEffect>();
230 // Load the files in the Terrain/ dir
231 string[] files = Directory.GetFiles("Terrain");
232 foreach (string file in files)
233 {
234 m_log.Info("Loading effects in " + file);
235 try
236 {
237 Assembly library = Assembly.LoadFrom(file);
238 foreach (Type pluginType in library.GetTypes())
239 {
240 try
241 {
242 if (pluginType.IsAbstract || pluginType.IsNotPublic)
243 continue;
244
245 if (pluginType.GetInterface("ITerrainEffect", false) != null)
246 {
247 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
248 if (!m_plugineffects.ContainsKey(pluginType.Name))
249 {
250 m_plugineffects.Add(pluginType.Name, terEffect);
251 m_log.Info("E ... " + pluginType.Name);
252 } else
253 {
254 m_log.Warn("E ... " + pluginType.Name + " (Already added)");
255 }
256 }
257 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
258 {
259 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
260 m_loaders[terLoader.FileExtension] = terLoader;
261 m_log.Info("L ... " + pluginType.Name);
262 }
263 }
264 catch (AmbiguousMatchException)
265 {
266 }
267 }
268 }
269 catch (BadImageFormatException)
270 {
271 }
272 }
273 }
274
275 #endregion
276
277 #endregion
278
279 /// <summary>
280 /// Installs into terrain module the standard suite of brushes
281 /// </summary>
282 private void InstallDefaultEffects()
283 {
284 // Draggable Paint Brush Effects
285 m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere();
286 m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere();
287 m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere();
288 m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere();
289 m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere();
290 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert);
291 m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere();
292 m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere();
293 m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere();
294
295 // Area of effect selection effects
296 m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea();
297 m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea();
298 m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea();
299 m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea();
300 m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea();
301 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert);
302
303 // Filesystem load/save loaders
304 m_loaders[".r32"] = new RAW32();
305 m_loaders[".f32"] = m_loaders[".r32"];
306 m_loaders[".ter"] = new Terragen();
307 m_loaders[".raw"] = new LLRAW();
308 m_loaders[".jpg"] = new JPEG();
309 m_loaders[".jpeg"] = m_loaders[".jpg"];
310 m_loaders[".bmp"] = new BMP();
311 m_loaders[".png"] = new PNG();
312 m_loaders[".gif"] = new GIF();
313 m_loaders[".tif"] = new TIFF();
314 m_loaders[".tiff"] = m_loaders[".tif"];
315 }
316
317 /// <summary>
318 /// Saves the current state of the region into the revert map buffer.
319 /// </summary>
320 public void UpdateRevertMap()
321 {
322 int x;
323 for (x = 0; x < m_channel.Width; x++)
324 {
325 int y;
326 for (y = 0; y < m_channel.Height; y++)
327 {
328 m_revert[x, y] = m_channel[x, y];
329 }
330 }
331 }
332
333 /// <summary>
334 /// Loads a tile from a larger terrain file and installs it into the region.
335 /// </summary>
336 /// <param name="filename">The terrain file to load</param>
337 /// <param name="fileWidth">The width of the file in units</param>
338 /// <param name="fileHeight">The height of the file in units</param>
339 /// <param name="fileStartX">Where to begin our slice</param>
340 /// <param name="fileStartY">Where to begin our slice</param>
341 public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
342 {
343 int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX;
344 int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY;
345
346 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
347 {
348 // this region is included in the tile request
349 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
350 {
351 if (filename.EndsWith(loader.Key))
352 {
353 lock (m_scene)
354 {
355 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
356 fileWidth, fileHeight,
357 (int) Constants.RegionSize,
358 (int) Constants.RegionSize);
359 m_scene.Heightmap = channel;
360 m_channel = channel;
361 UpdateRevertMap();
362 }
363 return;
364 }
365 }
366 }
367 }
368
369 /// <summary>
370 /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
371 /// </summary>
372 private void EventManager_OnTerrainTick()
373 {
374 if (m_tainted)
375 {
376 m_tainted = false;
377 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
378 m_scene.SaveTerrain();
379 m_scene.CreateTerrainTexture(true);
380 }
381 }
382
383 /// <summary>
384 /// Processes commandline input. Do not call directly.
385 /// </summary>
386 /// <param name="args">Commandline arguments</param>
387 private void EventManager_OnPluginConsole(string[] args)
388 {
389 if (args[0] == "terrain")
390 {
391 string[] tmpArgs = new string[args.Length - 2];
392 int i;
393 for (i = 2; i < args.Length; i++)
394 tmpArgs[i - 2] = args[i];
395
396 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
397 }
398 }
399
400 /// <summary>
401 /// Installs terrain brush hook to IClientAPI
402 /// </summary>
403 /// <param name="client"></param>
404 private void EventManager_OnNewClient(IClientAPI client)
405 {
406 client.OnModifyTerrain += client_OnModifyTerrain;
407 }
408
409 /// <summary>
410 /// Checks to see if the terrain has been modified since last check
411 /// </summary>
412 private void CheckForTerrainUpdates()
413 {
414 bool shouldTaint = false;
415 float[] serialised = m_channel.GetFloatsSerialised();
416 int x;
417 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
418 {
419 int y;
420 for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
421 {
422 if (m_channel.Tainted(x, y))
423 {
424 SendToClients(serialised, x, y);
425 shouldTaint = true;
426 }
427 }
428 }
429 if (shouldTaint)
430 {
431 m_tainted = true;
432 }
433 }
434
435 /// <summary>
436 /// Sends a copy of the current terrain to the scenes clients
437 /// </summary>
438 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
439 /// <param name="x">The patch corner to send</param>
440 /// <param name="y">The patch corner to send</param>
441 private void SendToClients(float[] serialised, int x, int y)
442 {
443 m_scene.ForEachClient(
444 delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); });
445 }
446
447 private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west,
448 float south, float east, IClientAPI remoteClient)
449 {
450 // Not a good permissions check, if in area mode, need to check the entire area.
451 if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0)))
452 {
453 if (north == south && east == west)
454 {
455 if (m_painteffects.ContainsKey((StandardTerrainEffects) action))
456 {
457 m_painteffects[(StandardTerrainEffects) action].PaintEffect(
458 m_channel, west, south, size, seconds);
459
460 CheckForTerrainUpdates();
461 }
462 else
463 {
464 m_log.Debug("Unknown terrain brush type " + action);
465 }
466 }
467 else
468 {
469 if (m_floodeffects.ContainsKey((StandardTerrainEffects) action))
470 {
471 bool[,] fillArea = new bool[m_channel.Width,m_channel.Height];
472 fillArea.Initialize();
473
474 int x;
475 for (x = 0; x < m_channel.Width; x++)
476 {
477 int y;
478 for (y = 0; y < m_channel.Height; y++)
479 {
480 if (x < east && x > west)
481 {
482 if (y < north && y > south)
483 {
484 fillArea[x, y] = true;
485 }
486 }
487 }
488 }
489
490 m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
491 m_channel, fillArea, size);
492
493 CheckForTerrainUpdates();
494 }
495 else
496 {
497 m_log.Debug("Unknown terrain flood type " + action);
498 }
499 }
500 }
501 }
502
503 #region Console Commands
504
505 private void InterfaceLoadFile(Object[] args)
506 {
507 LoadFromFile((string) args[0]);
508 CheckForTerrainUpdates();
509 }
510
511 private void InterfaceLoadTileFile(Object[] args)
512 {
513 LoadFromFile((string) args[0],
514 (int) args[1],
515 (int) args[2],
516 (int) args[3],
517 (int) args[4]);
518 CheckForTerrainUpdates();
519 }
520
521 private void InterfaceSaveFile(Object[] args)
522 {
523 SaveToFile((string) args[0]);
524 }
525
526 private void InterfaceBakeTerrain(Object[] args)
527 {
528 UpdateRevertMap();
529 }
530
531 private void InterfaceRevertTerrain(Object[] args)
532 {
533 int x, y;
534 for (x = 0; x < m_channel.Width; x++)
535 for (y = 0; y < m_channel.Height; y++)
536 m_channel[x, y] = m_revert[x, y];
537
538 CheckForTerrainUpdates();
539 }
540
541 private void InterfaceElevateTerrain(Object[] args)
542 {
543 int x, y;
544 for (x = 0; x < m_channel.Width; x++)
545 for (y = 0; y < m_channel.Height; y++)
546 m_channel[x, y] += (double) args[0];
547 CheckForTerrainUpdates();
548 }
549
550 private void InterfaceMultiplyTerrain(Object[] args)
551 {
552 int x, y;
553 for (x = 0; x < m_channel.Width; x++)
554 for (y = 0; y < m_channel.Height; y++)
555 m_channel[x, y] *= (double) args[0];
556 CheckForTerrainUpdates();
557 }
558
559 private void InterfaceLowerTerrain(Object[] args)
560 {
561 int x, y;
562 for (x = 0; x < m_channel.Width; x++)
563 for (y = 0; y < m_channel.Height; y++)
564 m_channel[x, y] -= (double) args[0];
565 CheckForTerrainUpdates();
566 }
567
568 private void InterfaceFillTerrain(Object[] args)
569 {
570 int x, y;
571
572 for (x = 0; x < m_channel.Width; x++)
573 for (y = 0; y < m_channel.Height; y++)
574 m_channel[x, y] = (double) args[0];
575 CheckForTerrainUpdates();
576 }
577
578 private void InterfaceShowDebugStats(Object[] args)
579 {
580 double max = Double.MinValue;
581 double min = double.MaxValue;
582 double avg;
583 double sum = 0;
584
585 int x;
586 for (x = 0; x < m_channel.Width; x++)
587 {
588 int y;
589 for (y = 0; y < m_channel.Height; y++)
590 {
591 sum += m_channel[x, y];
592 if (max < m_channel[x, y])
593 max = m_channel[x, y];
594 if (min > m_channel[x, y])
595 min = m_channel[x, y];
596 }
597 }
598
599 avg = sum / (m_channel.Height * m_channel.Width);
600
601 m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height);
602 m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum);
603 }
604
605 private void InterfaceEnableExperimentalBrushes(Object[] args)
606 {
607 if ((bool) args[0])
608 {
609 m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere();
610 m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere();
611 m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere();
612 }
613 else
614 {
615 InstallDefaultEffects();
616 }
617 }
618
619 private void InterfaceRunPluginEffect(Object[] args)
620 {
621 if ((string) args[0] == "list")
622 {
623 m_log.Info("List of loaded plugins");
624 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
625 {
626 m_log.Info(kvp.Key);
627 }
628 return;
629 }
630 if ((string) args[0] == "reload")
631 {
632 LoadPlugins();
633 return;
634 }
635 if (m_plugineffects.ContainsKey((string) args[0]))
636 {
637 m_plugineffects[(string) args[0]].RunEffect(m_channel);
638 CheckForTerrainUpdates();
639 }
640 else
641 {
642 m_log.Warn("No such plugin effect loaded.");
643 }
644 }
645
646 private void InstallInterfaces()
647 {
648 // Load / Save
649 string supportedFileExtensions = "";
650 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
651 supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")";
652
653 Command loadFromFileCommand =
654 new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file.");
655 loadFromFileCommand.AddArgument("filename",
656 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
657 supportedFileExtensions, "String");
658
659 Command saveToFileCommand =
660 new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file.");
661 saveToFileCommand.AddArgument("filename",
662 "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " +
663 supportedFileExtensions, "String");
664
665 Command loadFromTileCommand =
666 new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file.");
667 loadFromTileCommand.AddArgument("filename",
668 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
669 supportedFileExtensions, "String");
670 loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
671 loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
672 loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
673 "Integer");
674 loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
675 "Integer");
676
677 // Terrain adjustments
678 Command fillRegionCommand =
679 new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
680 fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.",
681 "Double");
682
683 Command elevateCommand =
684 new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount.");
685 elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double");
686
687 Command lowerCommand =
688 new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount.");
689 lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double");
690
691 Command multiplyCommand =
692 new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified.");
693 multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
694
695 Command bakeRegionCommand =
696 new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map.");
697 Command revertRegionCommand =
698 new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap.");
699
700 // Debug
701 Command showDebugStatsCommand =
702 new Command("stats", InterfaceShowDebugStats,
703 "Shows some information about the regions heightmap for debugging purposes.");
704
705 Command experimentalBrushesCommand =
706 new Command("newbrushes", InterfaceEnableExperimentalBrushes,
707 "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time.");
708 experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean");
709
710 //Plugins
711 Command pluginRunCommand =
712 new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect");
713 pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String");
714
715 m_commander.RegisterCommand("load", loadFromFileCommand);
716 m_commander.RegisterCommand("load-tile", loadFromTileCommand);
717 m_commander.RegisterCommand("save", saveToFileCommand);
718 m_commander.RegisterCommand("fill", fillRegionCommand);
719 m_commander.RegisterCommand("elevate", elevateCommand);
720 m_commander.RegisterCommand("lower", lowerCommand);
721 m_commander.RegisterCommand("multiply", multiplyCommand);
722 m_commander.RegisterCommand("bake", bakeRegionCommand);
723 m_commander.RegisterCommand("revert", revertRegionCommand);
724 m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand);
725 m_commander.RegisterCommand("stats", showDebugStatsCommand);
726 m_commander.RegisterCommand("effect", pluginRunCommand);
727
728 // Add this to our scene so scripts can call these functions
729 m_scene.RegisterModuleCommander("Terrain", m_commander);
730 }
731
732 #endregion
733 }
734} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs b/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs
deleted file mode 100644
index d4d0922..0000000
--- a/OpenSim/Region/Environment/Modules/Terrain/TerrainUtil.cs
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Region.Environment.Interfaces;
30
31namespace OpenSim.Region.Environment.Modules.Terrain
32{
33 public static class TerrainUtil
34 {
35 public static double MetersToSphericalStrength(double size)
36 {
37 return Math.Pow(2, size);
38 }
39
40 public static double SphericalFactor(double x, double y, double rx, double ry, double size)
41 {
42 return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
43 }
44
45 public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
46 {
47 int w = map.Width;
48 int h = map.Height;
49
50 if (x > w - 2.0)
51 x = w - 2.0;
52 if (y > h - 2.0)
53 y = h - 2.0;
54 if (x < 0.0)
55 x = 0.0;
56 if (y < 0.0)
57 y = 0.0;
58
59 int stepSize = 1;
60 double h00 = map[(int) x, (int) y];
61 double h10 = map[(int) x + stepSize, (int) y];
62 double h01 = map[(int) x, (int) y + stepSize];
63 double h11 = map[(int) x + stepSize, (int) y + stepSize];
64 double h1 = h00;
65 double h2 = h10;
66 double h3 = h01;
67 double h4 = h11;
68 double a00 = h1;
69 double a10 = h2 - h1;
70 double a01 = h3 - h1;
71 double a11 = h1 - h2 - h3 + h4;
72 double partialx = x - (int) x;
73 double partialz = y - (int) y;
74 double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
75 return hi;
76 }
77
78 private static double Noise(double x, double y)
79 {
80 int n = (int) x + (int) (y * 749);
81 n = (n << 13) ^ n;
82 return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
83 }
84
85 private static double SmoothedNoise1(double x, double y)
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;
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;
90 return corners + sides + center;
91 }
92
93 private static double Interpolate(double x, double y, double z)
94 {
95 return (x * (1.0 - z)) + (y * z);
96 }
97
98 private static double InterpolatedNoise(double x, double y)
99 {
100 int integer_X = (int) (x);
101 double fractional_X = x - integer_X;
102
103 int integer_Y = (int) y;
104 double fractional_Y = y - integer_Y;
105
106 double v1 = SmoothedNoise1(integer_X, integer_Y);
107 double v2 = SmoothedNoise1(integer_X + 1, integer_Y);
108 double v3 = SmoothedNoise1(integer_X, integer_Y + 1);
109 double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
110
111 double i1 = Interpolate(v1, v2, fractional_X);
112 double i2 = Interpolate(v3, v4, fractional_X);
113
114 return Interpolate(i1, i2, fractional_Y);
115 }
116
117 public static double PerlinNoise2D(double x, double y, int octaves, double persistence)
118 {
119 double frequency = 0.0;
120 double amplitude = 0.0;
121 double total = 0.0;
122
123 for (int i = 0; i < octaves; i++)
124 {
125 frequency = Math.Pow(2, i);
126 amplitude = Math.Pow(persistence, i);
127
128 total += InterpolatedNoise(x * frequency, y * frequency) * amplitude;
129 }
130 return total;
131 }
132 }
133} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/TreePopulatorModule.cs b/OpenSim/Region/Environment/Modules/TreePopulatorModule.cs
deleted file mode 100644
index 2051a0f..0000000
--- a/OpenSim/Region/Environment/Modules/TreePopulatorModule.cs
+++ /dev/null
@@ -1,248 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Timers;
32using Axiom.Math;
33using libsecondlife;
34using log4net;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.Environment.Scenes;
39
40namespace OpenSim.Region.Environment.Modules
41{
42 /// <summary>
43 /// Version 2.0 - Very hacky compared to the original. Will fix original and release as 0.3 later.
44 /// </summary>
45 public class TreePopulatorModule : IRegionModule
46 {
47 private Scene m_scene;
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 private List<LLUUID> m_trees;
51
52 public double m_tree_density = 50.0; // Aim for this many per region
53 public double m_tree_updates = 1000.0; // MS between updates
54
55 public void Initialise(Scene scene, IConfigSource config)
56 {
57 try
58 {
59 m_tree_density = config.Configs["Trees"].GetDouble("tree_density", m_tree_density);
60 }
61 catch (Exception)
62 { }
63
64 m_trees = new List<LLUUID>();
65 m_scene = scene;
66
67 m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole);
68
69 Timer CalculateTrees = new Timer(m_tree_updates);
70 CalculateTrees.Elapsed += new ElapsedEventHandler(CalculateTrees_Elapsed);
71 CalculateTrees.Start();
72 m_log.Debug("[TREES]: Initialised tree module");
73 }
74
75 void EventManager_OnPluginConsole(string[] args)
76 {
77 if (args[0] == "tree")
78 {
79 m_log.Debug("[TREES]: New tree planting");
80 CreateTree(new LLVector3(128.0f, 128.0f, 0.0f));
81 }
82 }
83
84 void growTrees()
85 {
86 foreach (LLUUID tree in m_trees)
87 {
88 if (m_scene.Entities.ContainsKey(tree))
89 {
90 SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
91
92 // 100 seconds to grow 1m
93 s_tree.Scale += new LLVector3(0.1f, 0.1f, 0.1f);
94 s_tree.SendFullUpdateToAllClients();
95 //s_tree.ScheduleTerseUpdate();
96 }
97 else
98 {
99 m_trees.Remove(tree);
100 }
101 }
102 }
103
104 void seedTrees()
105 {
106 foreach (LLUUID tree in m_trees)
107 {
108 if (m_scene.Entities.ContainsKey(tree))
109 {
110 SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
111
112 if (s_tree.Scale.X > 0.5)
113 {
114 if (Util.RandomClass.NextDouble() > 0.75)
115 {
116 SpawnChild(s_tree);
117 }
118 }
119
120 }
121 else
122 {
123 m_trees.Remove(tree);
124 }
125 }
126 }
127
128 void killTrees()
129 {
130 foreach (LLUUID tree in m_trees)
131 {
132 double killLikelyhood = 0.0;
133
134 if (m_scene.Entities.ContainsKey(tree))
135 {
136 SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart;
137 double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) +
138 Math.Pow(selectedTree.Scale.Y, 2) +
139 Math.Pow(selectedTree.Scale.Z, 2));
140
141 foreach (LLUUID picktree in m_trees)
142 {
143 if (picktree != tree)
144 {
145 SceneObjectPart pickedTree = ((SceneObjectGroup)m_scene.Entities[picktree]).RootPart;
146
147 double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) +
148 Math.Pow(pickedTree.Scale.Y, 2) +
149 Math.Pow(pickedTree.Scale.Z, 2));
150
151 double pickedTreeDistance = Math.Sqrt(Math.Pow(Math.Abs(pickedTree.AbsolutePosition.X - selectedTree.AbsolutePosition.X), 2) +
152 Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Y - selectedTree.AbsolutePosition.Y), 2) +
153 Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Z - selectedTree.AbsolutePosition.Z), 2));
154
155 killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1;
156 }
157 }
158
159 if (Util.RandomClass.NextDouble() < killLikelyhood)
160 {
161 m_scene.RemoveEntity(selectedTree.ParentGroup);
162 m_trees.Remove(selectedTree.ParentGroup.UUID);
163
164 m_scene.ForEachClient(delegate(IClientAPI controller)
165 {
166 controller.SendKillObject(m_scene.RegionInfo.RegionHandle,
167 selectedTree.LocalId);
168 });
169
170 break;
171 }
172 else
173 {
174 selectedTree.SetText(killLikelyhood.ToString(), new Vector3(1.0f, 1.0f, 1.0f), 1.0);
175 }
176 }
177 else
178 {
179 m_trees.Remove(tree);
180 }
181 }
182 }
183
184 private void SpawnChild(SceneObjectPart s_tree)
185 {
186 LLVector3 position = new LLVector3();
187
188 position.X = s_tree.AbsolutePosition.X + (1 * (-1 * Util.RandomClass.Next(1)));
189 if (position.X > 255)
190 position.X = 255;
191 if (position.X < 0)
192 position.X = 0;
193 position.Y = s_tree.AbsolutePosition.Y + (1 * (-1 * Util.RandomClass.Next(1)));
194 if (position.Y > 255)
195 position.Y = 255;
196 if (position.Y < 0)
197 position.Y = 0;
198
199 double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
200 double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
201
202 position.X += (float)randX;
203 position.Y += (float)randY;
204
205 CreateTree(position);
206 }
207
208 private void CreateTree(LLVector3 position)
209 {
210 position.Z = (float)m_scene.Heightmap[(int)position.X, (int)position.Y];
211
212 SceneObjectGroup tree =
213 m_scene.AddTree(new LLVector3(0.1f, 0.1f, 0.1f),
214 LLQuaternion.Identity,
215 position,
216 Tree.Cypress1,
217 false);
218
219 m_trees.Add(tree.UUID);
220 tree.SendGroupFullUpdate();
221 }
222
223 void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e)
224 {
225 growTrees();
226 seedTrees();
227 killTrees();
228 }
229
230 public void PostInitialise()
231 {
232 }
233
234 public void Close()
235 {
236 }
237
238 public string Name
239 {
240 get { return "TreePopulatorModule"; }
241 }
242
243 public bool IsSharedModule
244 {
245 get { return false; }
246 }
247 }
248}