diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Scripting')
6 files changed, 2458 insertions, 2458 deletions
diff --git a/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs index 68ca5e9..c0e3d3b 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/DynamicTexture/DynamicTextureModule.cs | |||
@@ -1,283 +1,283 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Drawing; | 30 | using System.Drawing; |
31 | using System.Drawing.Imaging; | 31 | using System.Drawing.Imaging; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenJPEGNet; | 34 | using OpenJPEGNet; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
37 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
38 | 38 | ||
39 | namespace OpenSim.Region.Environment.Modules.Scripting.DynamicTexture | 39 | namespace OpenSim.Region.Environment.Modules.Scripting.DynamicTexture |
40 | { | 40 | { |
41 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager | 41 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager |
42 | { | 42 | { |
43 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); | 43 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); |
44 | 44 | ||
45 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = | 45 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = |
46 | new Dictionary<string, IDynamicTextureRender>(); | 46 | new Dictionary<string, IDynamicTextureRender>(); |
47 | 47 | ||
48 | private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>(); | 48 | private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>(); |
49 | 49 | ||
50 | #region IDynamicTextureManager Members | 50 | #region IDynamicTextureManager Members |
51 | 51 | ||
52 | public void RegisterRender(string handleType, IDynamicTextureRender render) | 52 | public void RegisterRender(string handleType, IDynamicTextureRender render) |
53 | { | 53 | { |
54 | if (!RenderPlugins.ContainsKey(handleType)) | 54 | if (!RenderPlugins.ContainsKey(handleType)) |
55 | { | 55 | { |
56 | RenderPlugins.Add(handleType, render); | 56 | RenderPlugins.Add(handleType, render); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | public void ReturnData(LLUUID id, byte[] data) | 60 | public void ReturnData(LLUUID id, byte[] data) |
61 | { | 61 | { |
62 | if (Updaters.ContainsKey(id)) | 62 | if (Updaters.ContainsKey(id)) |
63 | { | 63 | { |
64 | DynamicTextureUpdater updater = Updaters[id]; | 64 | DynamicTextureUpdater updater = Updaters[id]; |
65 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) | 65 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) |
66 | { | 66 | { |
67 | Scene scene = RegisteredScenes[updater.SimUUID]; | 67 | Scene scene = RegisteredScenes[updater.SimUUID]; |
68 | updater.DataReceived(data, scene); | 68 | updater.DataReceived(data, scene); |
69 | } | 69 | } |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | 73 | ||
74 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, | 74 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, |
75 | string extraParams, int updateTimer) | 75 | string extraParams, int updateTimer) |
76 | { | 76 | { |
77 | return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); | 77 | return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); |
78 | } | 78 | } |
79 | 79 | ||
80 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, | 80 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, |
81 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) | 81 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) |
82 | { | 82 | { |
83 | if (RenderPlugins.ContainsKey(contentType)) | 83 | if (RenderPlugins.ContainsKey(contentType)) |
84 | { | 84 | { |
85 | //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType); | 85 | //Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType); |
86 | 86 | ||
87 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | 87 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); |
88 | updater.SimUUID = simID; | 88 | updater.SimUUID = simID; |
89 | updater.PrimID = primID; | 89 | updater.PrimID = primID; |
90 | updater.ContentType = contentType; | 90 | updater.ContentType = contentType; |
91 | updater.Url = url; | 91 | updater.Url = url; |
92 | updater.UpdateTimer = updateTimer; | 92 | updater.UpdateTimer = updateTimer; |
93 | updater.UpdaterID = LLUUID.Random(); | 93 | updater.UpdaterID = LLUUID.Random(); |
94 | updater.Params = extraParams; | 94 | updater.Params = extraParams; |
95 | updater.BlendWithOldTexture = SetBlending; | 95 | updater.BlendWithOldTexture = SetBlending; |
96 | updater.FrontAlpha = AlphaValue; | 96 | updater.FrontAlpha = AlphaValue; |
97 | 97 | ||
98 | if (!Updaters.ContainsKey(updater.UpdaterID)) | 98 | if (!Updaters.ContainsKey(updater.UpdaterID)) |
99 | { | 99 | { |
100 | Updaters.Add(updater.UpdaterID, updater); | 100 | Updaters.Add(updater.UpdaterID, updater); |
101 | } | 101 | } |
102 | 102 | ||
103 | RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); | 103 | RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); |
104 | return updater.UpdaterID; | 104 | return updater.UpdaterID; |
105 | } | 105 | } |
106 | return LLUUID.Zero; | 106 | return LLUUID.Zero; |
107 | } | 107 | } |
108 | 108 | ||
109 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, | 109 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, |
110 | string extraParams, int updateTimer) | 110 | string extraParams, int updateTimer) |
111 | { | 111 | { |
112 | return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); | 112 | return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); |
113 | } | 113 | } |
114 | 114 | ||
115 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, | 115 | public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data, |
116 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) | 116 | string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) |
117 | { | 117 | { |
118 | if (RenderPlugins.ContainsKey(contentType)) | 118 | if (RenderPlugins.ContainsKey(contentType)) |
119 | { | 119 | { |
120 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | 120 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); |
121 | updater.SimUUID = simID; | 121 | updater.SimUUID = simID; |
122 | updater.PrimID = primID; | 122 | updater.PrimID = primID; |
123 | updater.ContentType = contentType; | 123 | updater.ContentType = contentType; |
124 | updater.BodyData = data; | 124 | updater.BodyData = data; |
125 | updater.UpdateTimer = updateTimer; | 125 | updater.UpdateTimer = updateTimer; |
126 | updater.UpdaterID = LLUUID.Random(); | 126 | updater.UpdaterID = LLUUID.Random(); |
127 | updater.Params = extraParams; | 127 | updater.Params = extraParams; |
128 | updater.BlendWithOldTexture = SetBlending; | 128 | updater.BlendWithOldTexture = SetBlending; |
129 | updater.FrontAlpha = AlphaValue; | 129 | updater.FrontAlpha = AlphaValue; |
130 | 130 | ||
131 | if (!Updaters.ContainsKey(updater.UpdaterID)) | 131 | if (!Updaters.ContainsKey(updater.UpdaterID)) |
132 | { | 132 | { |
133 | Updaters.Add(updater.UpdaterID, updater); | 133 | Updaters.Add(updater.UpdaterID, updater); |
134 | } | 134 | } |
135 | 135 | ||
136 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); | 136 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); |
137 | return updater.UpdaterID; | 137 | return updater.UpdaterID; |
138 | } | 138 | } |
139 | return LLUUID.Zero; | 139 | return LLUUID.Zero; |
140 | } | 140 | } |
141 | 141 | ||
142 | #endregion | 142 | #endregion |
143 | 143 | ||
144 | #region IRegionModule Members | 144 | #region IRegionModule Members |
145 | 145 | ||
146 | public void Initialise(Scene scene, IConfigSource config) | 146 | public void Initialise(Scene scene, IConfigSource config) |
147 | { | 147 | { |
148 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | 148 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) |
149 | { | 149 | { |
150 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); | 150 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); |
151 | scene.RegisterModuleInterface<IDynamicTextureManager>(this); | 151 | scene.RegisterModuleInterface<IDynamicTextureManager>(this); |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | public void PostInitialise() | 155 | public void PostInitialise() |
156 | { | 156 | { |
157 | } | 157 | } |
158 | 158 | ||
159 | public void Close() | 159 | public void Close() |
160 | { | 160 | { |
161 | } | 161 | } |
162 | 162 | ||
163 | public string Name | 163 | public string Name |
164 | { | 164 | { |
165 | get { return "DynamicTextureModule"; } | 165 | get { return "DynamicTextureModule"; } |
166 | } | 166 | } |
167 | 167 | ||
168 | public bool IsSharedModule | 168 | public bool IsSharedModule |
169 | { | 169 | { |
170 | get { return true; } | 170 | get { return true; } |
171 | } | 171 | } |
172 | 172 | ||
173 | #endregion | 173 | #endregion |
174 | 174 | ||
175 | #region Nested type: DynamicTextureUpdater | 175 | #region Nested type: DynamicTextureUpdater |
176 | 176 | ||
177 | public class DynamicTextureUpdater | 177 | public class DynamicTextureUpdater |
178 | { | 178 | { |
179 | public bool BlendWithOldTexture = false; | 179 | public bool BlendWithOldTexture = false; |
180 | public string BodyData; | 180 | public string BodyData; |
181 | public string ContentType; | 181 | public string ContentType; |
182 | public byte FrontAlpha = 255; | 182 | public byte FrontAlpha = 255; |
183 | public LLUUID LastAssetID; | 183 | public LLUUID LastAssetID; |
184 | public string Params; | 184 | public string Params; |
185 | public LLUUID PrimID; | 185 | public LLUUID PrimID; |
186 | public bool SetNewFrontAlpha = false; | 186 | public bool SetNewFrontAlpha = false; |
187 | public LLUUID SimUUID; | 187 | public LLUUID SimUUID; |
188 | public LLUUID UpdaterID; | 188 | public LLUUID UpdaterID; |
189 | public int UpdateTimer; | 189 | public int UpdateTimer; |
190 | public string Url; | 190 | public string Url; |
191 | 191 | ||
192 | public DynamicTextureUpdater() | 192 | public DynamicTextureUpdater() |
193 | { | 193 | { |
194 | LastAssetID = LLUUID.Zero; | 194 | LastAssetID = LLUUID.Zero; |
195 | UpdateTimer = 0; | 195 | UpdateTimer = 0; |
196 | BodyData = null; | 196 | BodyData = null; |
197 | } | 197 | } |
198 | 198 | ||
199 | public void DataReceived(byte[] data, Scene scene) | 199 | public void DataReceived(byte[] data, Scene scene) |
200 | { | 200 | { |
201 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); | 201 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); |
202 | byte[] assetData; | 202 | byte[] assetData; |
203 | AssetBase oldAsset = null; | 203 | AssetBase oldAsset = null; |
204 | if (BlendWithOldTexture) | 204 | if (BlendWithOldTexture) |
205 | { | 205 | { |
206 | LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; | 206 | LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID; |
207 | oldAsset = scene.AssetCache.GetAsset(lastTextureID, true); | 207 | oldAsset = scene.AssetCache.GetAsset(lastTextureID, true); |
208 | if (oldAsset != null) | 208 | if (oldAsset != null) |
209 | { | 209 | { |
210 | assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); | 210 | assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); |
211 | } | 211 | } |
212 | else | 212 | else |
213 | { | 213 | { |
214 | assetData = new byte[data.Length]; | 214 | assetData = new byte[data.Length]; |
215 | Array.Copy(data, assetData, data.Length); | 215 | Array.Copy(data, assetData, data.Length); |
216 | } | 216 | } |
217 | } | 217 | } |
218 | else | 218 | else |
219 | { | 219 | { |
220 | assetData = new byte[data.Length]; | 220 | assetData = new byte[data.Length]; |
221 | Array.Copy(data, assetData, data.Length); | 221 | Array.Copy(data, assetData, data.Length); |
222 | } | 222 | } |
223 | 223 | ||
224 | //TODO delete the last asset(data), if it was a dynamic texture | 224 | //TODO delete the last asset(data), if it was a dynamic texture |
225 | AssetBase asset = new AssetBase(); | 225 | AssetBase asset = new AssetBase(); |
226 | asset.FullID = LLUUID.Random(); | 226 | asset.FullID = LLUUID.Random(); |
227 | asset.Data = assetData; | 227 | asset.Data = assetData; |
228 | asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); | 228 | asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); |
229 | asset.Type = 0; | 229 | asset.Type = 0; |
230 | asset.Description = "dynamic image"; | 230 | asset.Description = "dynamic image"; |
231 | asset.Local = false; | 231 | asset.Local = false; |
232 | asset.Temporary = true; | 232 | asset.Temporary = true; |
233 | scene.AssetCache.AddAsset(asset); | 233 | scene.AssetCache.AddAsset(asset); |
234 | 234 | ||
235 | LastAssetID = asset.FullID; | 235 | LastAssetID = asset.FullID; |
236 | 236 | ||
237 | 237 | ||
238 | part.Shape.Textures = new LLObject.TextureEntry(asset.FullID); | 238 | part.Shape.Textures = new LLObject.TextureEntry(asset.FullID); |
239 | part.ScheduleFullUpdate(); | 239 | part.ScheduleFullUpdate(); |
240 | } | 240 | } |
241 | 241 | ||
242 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) | 242 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) |
243 | { | 243 | { |
244 | Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage)); | 244 | Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage)); |
245 | Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage)); | 245 | Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage)); |
246 | if (setNewAlpha) | 246 | if (setNewAlpha) |
247 | { | 247 | { |
248 | SetAlpha(ref image1, newAlpha); | 248 | SetAlpha(ref image1, newAlpha); |
249 | } | 249 | } |
250 | Bitmap joint = MergeBitMaps(image1, image2); | 250 | Bitmap joint = MergeBitMaps(image1, image2); |
251 | 251 | ||
252 | return OpenJPEG.EncodeFromImage(joint, true); | 252 | return OpenJPEG.EncodeFromImage(joint, true); |
253 | } | 253 | } |
254 | 254 | ||
255 | public Bitmap MergeBitMaps(Bitmap front, Bitmap back) | 255 | public Bitmap MergeBitMaps(Bitmap front, Bitmap back) |
256 | { | 256 | { |
257 | Bitmap joint; | 257 | Bitmap joint; |
258 | Graphics jG; | 258 | Graphics jG; |
259 | 259 | ||
260 | joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb); | 260 | joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb); |
261 | jG = Graphics.FromImage(joint); | 261 | jG = Graphics.FromImage(joint); |
262 | 262 | ||
263 | jG.DrawImage(back, 0, 0, back.Width, back.Height); | 263 | jG.DrawImage(back, 0, 0, back.Width, back.Height); |
264 | jG.DrawImage(front, 0, 0, back.Width, back.Height); | 264 | jG.DrawImage(front, 0, 0, back.Width, back.Height); |
265 | 265 | ||
266 | return joint; | 266 | return joint; |
267 | } | 267 | } |
268 | 268 | ||
269 | private void SetAlpha(ref Bitmap b, byte alpha) | 269 | private void SetAlpha(ref Bitmap b, byte alpha) |
270 | { | 270 | { |
271 | for (int w = 0; w < b.Width; w++) | 271 | for (int w = 0; w < b.Width; w++) |
272 | { | 272 | { |
273 | for (int h = 0; h < b.Height; h++) | 273 | for (int h = 0; h < b.Height; h++) |
274 | { | 274 | { |
275 | b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h))); | 275 | b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h))); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | } | 278 | } |
279 | } | 279 | } |
280 | 280 | ||
281 | #endregion | 281 | #endregion |
282 | } | 282 | } |
283 | } \ No newline at end of file | 283 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 184e026..e1339a3 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -1,364 +1,364 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Threading; | 33 | using System.Threading; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | 39 | ||
40 | /***************************************************** | 40 | /***************************************************** |
41 | * | 41 | * |
42 | * ScriptsHttpRequests | 42 | * ScriptsHttpRequests |
43 | * | 43 | * |
44 | * Implements the llHttpRequest and http_response | 44 | * Implements the llHttpRequest and http_response |
45 | * callback. | 45 | * callback. |
46 | * | 46 | * |
47 | * Some stuff was already in LSLLongCmdHandler, and then | 47 | * Some stuff was already in LSLLongCmdHandler, and then |
48 | * there was this file with a stub class in it. So, | 48 | * there was this file with a stub class in it. So, |
49 | * I am moving some of the objects and functions out of | 49 | * I am moving some of the objects and functions out of |
50 | * LSLLongCmdHandler, such as the HttpRequestClass, the | 50 | * LSLLongCmdHandler, such as the HttpRequestClass, the |
51 | * start and stop methods, and setting up pending and | 51 | * start and stop methods, and setting up pending and |
52 | * completed queues. These are processed in the | 52 | * completed queues. These are processed in the |
53 | * LSLLongCmdHandler polling loop. Similiar to the | 53 | * LSLLongCmdHandler polling loop. Similiar to the |
54 | * XMLRPCModule, since that seems to work. | 54 | * XMLRPCModule, since that seems to work. |
55 | * | 55 | * |
56 | * //TODO | 56 | * //TODO |
57 | * | 57 | * |
58 | * This probably needs some throttling mechanism but | 58 | * This probably needs some throttling mechanism but |
59 | * its wide open right now. This applies to both | 59 | * its wide open right now. This applies to both |
60 | * number of requests and data volume. | 60 | * number of requests and data volume. |
61 | * | 61 | * |
62 | * Linden puts all kinds of header fields in the requests. | 62 | * Linden puts all kinds of header fields in the requests. |
63 | * Not doing any of that: | 63 | * Not doing any of that: |
64 | * User-Agent | 64 | * User-Agent |
65 | * X-SecondLife-Shard | 65 | * X-SecondLife-Shard |
66 | * X-SecondLife-Object-Name | 66 | * X-SecondLife-Object-Name |
67 | * X-SecondLife-Object-Key | 67 | * X-SecondLife-Object-Key |
68 | * X-SecondLife-Region | 68 | * X-SecondLife-Region |
69 | * X-SecondLife-Local-Position | 69 | * X-SecondLife-Local-Position |
70 | * X-SecondLife-Local-Velocity | 70 | * X-SecondLife-Local-Velocity |
71 | * X-SecondLife-Local-Rotation | 71 | * X-SecondLife-Local-Rotation |
72 | * X-SecondLife-Owner-Name | 72 | * X-SecondLife-Owner-Name |
73 | * X-SecondLife-Owner-Key | 73 | * X-SecondLife-Owner-Key |
74 | * | 74 | * |
75 | * HTTPS support | 75 | * HTTPS support |
76 | * | 76 | * |
77 | * Configurable timeout? | 77 | * Configurable timeout? |
78 | * Configurable max repsonse size? | 78 | * Configurable max repsonse size? |
79 | * Configurable | 79 | * Configurable |
80 | * | 80 | * |
81 | * **************************************************/ | 81 | * **************************************************/ |
82 | 82 | ||
83 | namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest | 83 | namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest |
84 | { | 84 | { |
85 | public class HttpRequestModule : IRegionModule, IHttpRequests | 85 | public class HttpRequestModule : IRegionModule, IHttpRequests |
86 | { | 86 | { |
87 | private object HttpListLock = new object(); | 87 | private object HttpListLock = new object(); |
88 | private int httpTimeout = 30000; | 88 | private int httpTimeout = 30000; |
89 | private string m_name = "HttpScriptRequests"; | 89 | private string m_name = "HttpScriptRequests"; |
90 | 90 | ||
91 | // <request id, HttpRequestClass> | 91 | // <request id, HttpRequestClass> |
92 | private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests; | 92 | private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests; |
93 | private Scene m_scene; | 93 | private Scene m_scene; |
94 | private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); | 94 | private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); |
95 | 95 | ||
96 | public HttpRequestModule() | 96 | public HttpRequestModule() |
97 | { | 97 | { |
98 | } | 98 | } |
99 | 99 | ||
100 | #region IHttpRequests Members | 100 | #region IHttpRequests Members |
101 | 101 | ||
102 | public LLUUID MakeHttpRequest(string url, string parameters, string body) | 102 | public LLUUID MakeHttpRequest(string url, string parameters, string body) |
103 | { | 103 | { |
104 | return LLUUID.Zero; | 104 | return LLUUID.Zero; |
105 | } | 105 | } |
106 | 106 | ||
107 | public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body) | 107 | public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body) |
108 | { | 108 | { |
109 | LLUUID reqID = LLUUID.Random(); | 109 | LLUUID reqID = LLUUID.Random(); |
110 | HttpRequestClass htc = new HttpRequestClass(); | 110 | HttpRequestClass htc = new HttpRequestClass(); |
111 | 111 | ||
112 | // Partial implementation: support for parameter flags needed | 112 | // Partial implementation: support for parameter flags needed |
113 | // see http://wiki.secondlife.com/wiki/LlHTTPRequest | 113 | // see http://wiki.secondlife.com/wiki/LlHTTPRequest |
114 | // | 114 | // |
115 | // Parameters are expected in {key, value, ... , key, value} | 115 | // Parameters are expected in {key, value, ... , key, value} |
116 | if (parameters != null) | 116 | if (parameters != null) |
117 | { | 117 | { |
118 | string[] parms = parameters.ToArray(); | 118 | string[] parms = parameters.ToArray(); |
119 | for (int i = 0; i < parms.Length / 2; i += 2) | 119 | for (int i = 0; i < parms.Length / 2; i += 2) |
120 | { | 120 | { |
121 | switch (Int32.Parse(parms[i])) | 121 | switch (Int32.Parse(parms[i])) |
122 | { | 122 | { |
123 | case HttpRequestClass.HTTP_METHOD: | 123 | case HttpRequestClass.HTTP_METHOD: |
124 | 124 | ||
125 | htc.httpMethod = parms[i + 1]; | 125 | htc.httpMethod = parms[i + 1]; |
126 | break; | 126 | break; |
127 | 127 | ||
128 | case HttpRequestClass.HTTP_MIMETYPE: | 128 | case HttpRequestClass.HTTP_MIMETYPE: |
129 | 129 | ||
130 | htc.httpMIMEType = parms[i + 1]; | 130 | htc.httpMIMEType = parms[i + 1]; |
131 | break; | 131 | break; |
132 | 132 | ||
133 | case HttpRequestClass.HTTP_BODY_MAXLENGTH: | 133 | case HttpRequestClass.HTTP_BODY_MAXLENGTH: |
134 | 134 | ||
135 | // TODO implement me | 135 | // TODO implement me |
136 | break; | 136 | break; |
137 | 137 | ||
138 | case HttpRequestClass.HTTP_VERIFY_CERT: | 138 | case HttpRequestClass.HTTP_VERIFY_CERT: |
139 | 139 | ||
140 | // TODO implement me | 140 | // TODO implement me |
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
146 | htc.localID = localID; | 146 | htc.localID = localID; |
147 | htc.itemID = itemID; | 147 | htc.itemID = itemID; |
148 | htc.url = url; | 148 | htc.url = url; |
149 | htc.reqID = reqID; | 149 | htc.reqID = reqID; |
150 | htc.httpTimeout = httpTimeout; | 150 | htc.httpTimeout = httpTimeout; |
151 | htc.outbound_body = body; | 151 | htc.outbound_body = body; |
152 | 152 | ||
153 | lock (HttpListLock) | 153 | lock (HttpListLock) |
154 | { | 154 | { |
155 | m_pendingRequests.Add(reqID, htc); | 155 | m_pendingRequests.Add(reqID, htc); |
156 | } | 156 | } |
157 | 157 | ||
158 | htc.process(); | 158 | htc.process(); |
159 | 159 | ||
160 | return reqID; | 160 | return reqID; |
161 | } | 161 | } |
162 | 162 | ||
163 | public void StopHttpRequest(uint m_localID, LLUUID m_itemID) | 163 | public void StopHttpRequest(uint m_localID, LLUUID m_itemID) |
164 | { | 164 | { |
165 | if (m_pendingRequests != null) | 165 | if (m_pendingRequests != null) |
166 | { | 166 | { |
167 | lock (HttpListLock) | 167 | lock (HttpListLock) |
168 | { | 168 | { |
169 | HttpRequestClass tmpReq; | 169 | HttpRequestClass tmpReq; |
170 | if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) | 170 | if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) |
171 | { | 171 | { |
172 | tmpReq.Stop(); | 172 | tmpReq.Stop(); |
173 | m_pendingRequests.Remove(m_itemID); | 173 | m_pendingRequests.Remove(m_itemID); |
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
179 | /* | 179 | /* |
180 | * TODO | 180 | * TODO |
181 | * Not sure how important ordering is is here - the next first | 181 | * Not sure how important ordering is is here - the next first |
182 | * one completed in the list is returned, based soley on its list | 182 | * one completed in the list is returned, based soley on its list |
183 | * position, not the order in which the request was started or | 183 | * position, not the order in which the request was started or |
184 | * finsihed. I thought about setting up a queue for this, but | 184 | * finsihed. I thought about setting up a queue for this, but |
185 | * it will need some refactoring and this works 'enough' right now | 185 | * it will need some refactoring and this works 'enough' right now |
186 | */ | 186 | */ |
187 | 187 | ||
188 | public HttpRequestClass GetNextCompletedRequest() | 188 | public HttpRequestClass GetNextCompletedRequest() |
189 | { | 189 | { |
190 | lock (HttpListLock) | 190 | lock (HttpListLock) |
191 | { | 191 | { |
192 | foreach (LLUUID luid in m_pendingRequests.Keys) | 192 | foreach (LLUUID luid in m_pendingRequests.Keys) |
193 | { | 193 | { |
194 | HttpRequestClass tmpReq; | 194 | HttpRequestClass tmpReq; |
195 | 195 | ||
196 | if (m_pendingRequests.TryGetValue(luid, out tmpReq)) | 196 | if (m_pendingRequests.TryGetValue(luid, out tmpReq)) |
197 | { | 197 | { |
198 | if (tmpReq.finished) | 198 | if (tmpReq.finished) |
199 | { | 199 | { |
200 | return tmpReq; | 200 | return tmpReq; |
201 | } | 201 | } |
202 | } | 202 | } |
203 | } | 203 | } |
204 | } | 204 | } |
205 | return null; | 205 | return null; |
206 | } | 206 | } |
207 | 207 | ||
208 | public void RemoveCompletedRequest(LLUUID id) | 208 | public void RemoveCompletedRequest(LLUUID id) |
209 | { | 209 | { |
210 | lock (HttpListLock) | 210 | lock (HttpListLock) |
211 | { | 211 | { |
212 | HttpRequestClass tmpReq; | 212 | HttpRequestClass tmpReq; |
213 | if (m_pendingRequests.TryGetValue(id, out tmpReq)) | 213 | if (m_pendingRequests.TryGetValue(id, out tmpReq)) |
214 | { | 214 | { |
215 | tmpReq.Stop(); | 215 | tmpReq.Stop(); |
216 | tmpReq = null; | 216 | tmpReq = null; |
217 | m_pendingRequests.Remove(id); | 217 | m_pendingRequests.Remove(id); |
218 | } | 218 | } |
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | #endregion | 222 | #endregion |
223 | 223 | ||
224 | #region IRegionModule Members | 224 | #region IRegionModule Members |
225 | 225 | ||
226 | public void Initialise(Scene scene, IConfigSource config) | 226 | public void Initialise(Scene scene, IConfigSource config) |
227 | { | 227 | { |
228 | m_scene = scene; | 228 | m_scene = scene; |
229 | 229 | ||
230 | m_scene.RegisterModuleInterface<IHttpRequests>(this); | 230 | m_scene.RegisterModuleInterface<IHttpRequests>(this); |
231 | 231 | ||
232 | m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>(); | 232 | m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>(); |
233 | } | 233 | } |
234 | 234 | ||
235 | public void PostInitialise() | 235 | public void PostInitialise() |
236 | { | 236 | { |
237 | } | 237 | } |
238 | 238 | ||
239 | public void Close() | 239 | public void Close() |
240 | { | 240 | { |
241 | } | 241 | } |
242 | 242 | ||
243 | public string Name | 243 | public string Name |
244 | { | 244 | { |
245 | get { return m_name; } | 245 | get { return m_name; } |
246 | } | 246 | } |
247 | 247 | ||
248 | public bool IsSharedModule | 248 | public bool IsSharedModule |
249 | { | 249 | { |
250 | get { return true; } | 250 | get { return true; } |
251 | } | 251 | } |
252 | 252 | ||
253 | #endregion | 253 | #endregion |
254 | } | 254 | } |
255 | 255 | ||
256 | public class HttpRequestClass | 256 | public class HttpRequestClass |
257 | { | 257 | { |
258 | // Constants for parameters | 258 | // Constants for parameters |
259 | public const int HTTP_BODY_MAXLENGTH = 2; | 259 | public const int HTTP_BODY_MAXLENGTH = 2; |
260 | public const int HTTP_METHOD = 0; | 260 | public const int HTTP_METHOD = 0; |
261 | public const int HTTP_MIMETYPE = 1; | 261 | public const int HTTP_MIMETYPE = 1; |
262 | public const int HTTP_VERIFY_CERT = 3; | 262 | public const int HTTP_VERIFY_CERT = 3; |
263 | public bool finished; | 263 | public bool finished; |
264 | public int httpBodyMaxLen = 2048; // not implemented | 264 | public int httpBodyMaxLen = 2048; // not implemented |
265 | 265 | ||
266 | // Parameter members and default values | 266 | // Parameter members and default values |
267 | public string httpMethod = "GET"; | 267 | public string httpMethod = "GET"; |
268 | public string httpMIMEType = "text/plain;charset=utf-8"; | 268 | public string httpMIMEType = "text/plain;charset=utf-8"; |
269 | private Thread httpThread; | 269 | private Thread httpThread; |
270 | public int httpTimeout; | 270 | public int httpTimeout; |
271 | public bool httpVerifyCert = true; // not implemented | 271 | public bool httpVerifyCert = true; // not implemented |
272 | 272 | ||
273 | // Request info | 273 | // Request info |
274 | public LLUUID itemID; | 274 | public LLUUID itemID; |
275 | public uint localID; | 275 | public uint localID; |
276 | public DateTime next; | 276 | public DateTime next; |
277 | public string outbound_body; | 277 | public string outbound_body; |
278 | public LLUUID reqID; | 278 | public LLUUID reqID; |
279 | public HttpWebRequest request; | 279 | public HttpWebRequest request; |
280 | public string response_body; | 280 | public string response_body; |
281 | public List<string> response_metadata; | 281 | public List<string> response_metadata; |
282 | public int status; | 282 | public int status; |
283 | public string url; | 283 | public string url; |
284 | 284 | ||
285 | public void process() | 285 | public void process() |
286 | { | 286 | { |
287 | httpThread = new Thread(SendRequest); | 287 | httpThread = new Thread(SendRequest); |
288 | httpThread.Name = "HttpRequestThread"; | 288 | httpThread.Name = "HttpRequestThread"; |
289 | httpThread.Priority = ThreadPriority.BelowNormal; | 289 | httpThread.Priority = ThreadPriority.BelowNormal; |
290 | httpThread.IsBackground = true; | 290 | httpThread.IsBackground = true; |
291 | finished = false; | 291 | finished = false; |
292 | httpThread.Start(); | 292 | httpThread.Start(); |
293 | ThreadTracker.Add(httpThread); | 293 | ThreadTracker.Add(httpThread); |
294 | } | 294 | } |
295 | 295 | ||
296 | /* | 296 | /* |
297 | * TODO: More work on the response codes. Right now | 297 | * TODO: More work on the response codes. Right now |
298 | * returning 200 for success or 499 for exception | 298 | * returning 200 for success or 499 for exception |
299 | */ | 299 | */ |
300 | 300 | ||
301 | public void SendRequest() | 301 | public void SendRequest() |
302 | { | 302 | { |
303 | HttpWebResponse response = null; | 303 | HttpWebResponse response = null; |
304 | StringBuilder sb = new StringBuilder(); | 304 | StringBuilder sb = new StringBuilder(); |
305 | byte[] buf = new byte[8192]; | 305 | byte[] buf = new byte[8192]; |
306 | string tempString = null; | 306 | string tempString = null; |
307 | int count = 0; | 307 | int count = 0; |
308 | 308 | ||
309 | try | 309 | try |
310 | { | 310 | { |
311 | request = (HttpWebRequest) | 311 | request = (HttpWebRequest) |
312 | WebRequest.Create(url); | 312 | WebRequest.Create(url); |
313 | request.Method = httpMethod; | 313 | request.Method = httpMethod; |
314 | request.ContentType = httpMIMEType; | 314 | request.ContentType = httpMIMEType; |
315 | 315 | ||
316 | request.Timeout = httpTimeout; | 316 | request.Timeout = httpTimeout; |
317 | // execute the request | 317 | // execute the request |
318 | response = (HttpWebResponse) | 318 | response = (HttpWebResponse) |
319 | request.GetResponse(); | 319 | request.GetResponse(); |
320 | 320 | ||
321 | Stream resStream = response.GetResponseStream(); | 321 | Stream resStream = response.GetResponseStream(); |
322 | 322 | ||
323 | do | 323 | do |
324 | { | 324 | { |
325 | // fill the buffer with data | 325 | // fill the buffer with data |
326 | count = resStream.Read(buf, 0, buf.Length); | 326 | count = resStream.Read(buf, 0, buf.Length); |
327 | 327 | ||
328 | // make sure we read some data | 328 | // make sure we read some data |
329 | if (count != 0) | 329 | if (count != 0) |
330 | { | 330 | { |
331 | // translate from bytes to ASCII text | 331 | // translate from bytes to ASCII text |
332 | tempString = Encoding.UTF8.GetString(buf, 0, count); | 332 | tempString = Encoding.UTF8.GetString(buf, 0, count); |
333 | 333 | ||
334 | // continue building the string | 334 | // continue building the string |
335 | sb.Append(tempString); | 335 | sb.Append(tempString); |
336 | } | 336 | } |
337 | } while (count > 0); // any more data to read? | 337 | } while (count > 0); // any more data to read? |
338 | 338 | ||
339 | response_body = sb.ToString(); | 339 | response_body = sb.ToString(); |
340 | } | 340 | } |
341 | catch (Exception e) | 341 | catch (Exception e) |
342 | { | 342 | { |
343 | status = 499; | 343 | status = 499; |
344 | response_body = e.Message; | 344 | response_body = e.Message; |
345 | finished = true; | 345 | finished = true; |
346 | return; | 346 | return; |
347 | } | 347 | } |
348 | 348 | ||
349 | status = 200; | 349 | status = 200; |
350 | finished = true; | 350 | finished = true; |
351 | } | 351 | } |
352 | 352 | ||
353 | public void Stop() | 353 | public void Stop() |
354 | { | 354 | { |
355 | try | 355 | try |
356 | { | 356 | { |
357 | httpThread.Abort(); | 357 | httpThread.Abort(); |
358 | } | 358 | } |
359 | catch (Exception) | 359 | catch (Exception) |
360 | { | 360 | { |
361 | } | 361 | } |
362 | } | 362 | } |
363 | } | 363 | } |
364 | } \ No newline at end of file | 364 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs index a0408cd..c828ef0 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/LoadImageURL/LoadImageURLModule.cs | |||
@@ -1,191 +1,191 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net; | 31 | using System.Net; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenJPEGNet; | 34 | using OpenJPEGNet; |
35 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
36 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL | 38 | namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL |
39 | { | 39 | { |
40 | public class LoadImageURLModule : IRegionModule, IDynamicTextureRender | 40 | public class LoadImageURLModule : IRegionModule, IDynamicTextureRender |
41 | { | 41 | { |
42 | private string m_name = "LoadImageURL"; | 42 | private string m_name = "LoadImageURL"; |
43 | private Scene m_scene; | 43 | private Scene m_scene; |
44 | private IDynamicTextureManager m_textureManager; | 44 | private IDynamicTextureManager m_textureManager; |
45 | 45 | ||
46 | #region IDynamicTextureRender Members | 46 | #region IDynamicTextureRender Members |
47 | 47 | ||
48 | public string GetName() | 48 | public string GetName() |
49 | { | 49 | { |
50 | return m_name; | 50 | return m_name; |
51 | } | 51 | } |
52 | 52 | ||
53 | public string GetContentType() | 53 | public string GetContentType() |
54 | { | 54 | { |
55 | return ("image"); | 55 | return ("image"); |
56 | } | 56 | } |
57 | 57 | ||
58 | public bool SupportsAsynchronous() | 58 | public bool SupportsAsynchronous() |
59 | { | 59 | { |
60 | return true; | 60 | return true; |
61 | } | 61 | } |
62 | 62 | ||
63 | public byte[] ConvertUrl(string url, string extraParams) | 63 | public byte[] ConvertUrl(string url, string extraParams) |
64 | { | 64 | { |
65 | return null; | 65 | return null; |
66 | } | 66 | } |
67 | 67 | ||
68 | public byte[] ConvertStream(Stream data, string extraParams) | 68 | public byte[] ConvertStream(Stream data, string extraParams) |
69 | { | 69 | { |
70 | return null; | 70 | return null; |
71 | } | 71 | } |
72 | 72 | ||
73 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) | 73 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) |
74 | { | 74 | { |
75 | MakeHttpRequest(url, id); | 75 | MakeHttpRequest(url, id); |
76 | return true; | 76 | return true; |
77 | } | 77 | } |
78 | 78 | ||
79 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) | 79 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) |
80 | { | 80 | { |
81 | return false; | 81 | return false; |
82 | } | 82 | } |
83 | 83 | ||
84 | #endregion | 84 | #endregion |
85 | 85 | ||
86 | #region IRegionModule Members | 86 | #region IRegionModule Members |
87 | 87 | ||
88 | public void Initialise(Scene scene, IConfigSource config) | 88 | public void Initialise(Scene scene, IConfigSource config) |
89 | { | 89 | { |
90 | if (m_scene == null) | 90 | if (m_scene == null) |
91 | { | 91 | { |
92 | m_scene = scene; | 92 | m_scene = scene; |
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | public void PostInitialise() | 96 | public void PostInitialise() |
97 | { | 97 | { |
98 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); | 98 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); |
99 | if (m_textureManager != null) | 99 | if (m_textureManager != null) |
100 | { | 100 | { |
101 | m_textureManager.RegisterRender(GetContentType(), this); | 101 | m_textureManager.RegisterRender(GetContentType(), this); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void Close() | 105 | public void Close() |
106 | { | 106 | { |
107 | } | 107 | } |
108 | 108 | ||
109 | public string Name | 109 | public string Name |
110 | { | 110 | { |
111 | get { return m_name; } | 111 | get { return m_name; } |
112 | } | 112 | } |
113 | 113 | ||
114 | public bool IsSharedModule | 114 | public bool IsSharedModule |
115 | { | 115 | { |
116 | get { return true; } | 116 | get { return true; } |
117 | } | 117 | } |
118 | 118 | ||
119 | #endregion | 119 | #endregion |
120 | 120 | ||
121 | private void MakeHttpRequest(string url, LLUUID requestID) | 121 | private void MakeHttpRequest(string url, LLUUID requestID) |
122 | { | 122 | { |
123 | WebRequest request = HttpWebRequest.Create(url); | 123 | WebRequest request = HttpWebRequest.Create(url); |
124 | RequestState state = new RequestState((HttpWebRequest) request, requestID); | 124 | RequestState state = new RequestState((HttpWebRequest) request, requestID); |
125 | IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); | 125 | IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); |
126 | 126 | ||
127 | TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); | 127 | TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); |
128 | state.TimeOfRequest = (int) t.TotalSeconds; | 128 | state.TimeOfRequest = (int) t.TotalSeconds; |
129 | } | 129 | } |
130 | 130 | ||
131 | private void HttpRequestReturn(IAsyncResult result) | 131 | private void HttpRequestReturn(IAsyncResult result) |
132 | { | 132 | { |
133 | RequestState state = (RequestState) result.AsyncState; | 133 | RequestState state = (RequestState) result.AsyncState; |
134 | WebRequest request = (WebRequest) state.Request; | 134 | WebRequest request = (WebRequest) state.Request; |
135 | HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result); | 135 | HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result); |
136 | if (response.StatusCode == HttpStatusCode.OK) | 136 | if (response.StatusCode == HttpStatusCode.OK) |
137 | { | 137 | { |
138 | Bitmap image = new Bitmap(response.GetResponseStream()); | 138 | Bitmap image = new Bitmap(response.GetResponseStream()); |
139 | Size newsize; | 139 | Size newsize; |
140 | 140 | ||
141 | // TODO: make this a bit less hard coded | 141 | // TODO: make this a bit less hard coded |
142 | if ((image.Height < 64) && (image.Width < 64)) | 142 | if ((image.Height < 64) && (image.Width < 64)) |
143 | { | 143 | { |
144 | newsize = new Size(32, 32); | 144 | newsize = new Size(32, 32); |
145 | } | 145 | } |
146 | else if ((image.Height < 128) && (image.Width < 128)) | 146 | else if ((image.Height < 128) && (image.Width < 128)) |
147 | { | 147 | { |
148 | newsize = new Size(64, 64); | 148 | newsize = new Size(64, 64); |
149 | } | 149 | } |
150 | else if ((image.Height < 256) && (image.Width < 256)) | 150 | else if ((image.Height < 256) && (image.Width < 256)) |
151 | { | 151 | { |
152 | newsize = new Size(128, 128); | 152 | newsize = new Size(128, 128); |
153 | } | 153 | } |
154 | else if ((image.Height < 512 && image.Width < 512)) | 154 | else if ((image.Height < 512 && image.Width < 512)) |
155 | { | 155 | { |
156 | newsize = new Size(256, 256); | 156 | newsize = new Size(256, 256); |
157 | } | 157 | } |
158 | else if ((image.Height < 1024 && image.Width < 1024)) | 158 | else if ((image.Height < 1024 && image.Width < 1024)) |
159 | { | 159 | { |
160 | newsize = new Size(512, 512); | 160 | newsize = new Size(512, 512); |
161 | } | 161 | } |
162 | else | 162 | else |
163 | { | 163 | { |
164 | newsize = new Size(1024, 1024); | 164 | newsize = new Size(1024, 1024); |
165 | } | 165 | } |
166 | 166 | ||
167 | Bitmap resize = new Bitmap(image, newsize); | 167 | Bitmap resize = new Bitmap(image, newsize); |
168 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); | 168 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); |
169 | 169 | ||
170 | m_textureManager.ReturnData(state.RequestID, imageJ2000); | 170 | m_textureManager.ReturnData(state.RequestID, imageJ2000); |
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | #region Nested type: RequestState | 174 | #region Nested type: RequestState |
175 | 175 | ||
176 | public class RequestState | 176 | public class RequestState |
177 | { | 177 | { |
178 | public HttpWebRequest Request = null; | 178 | public HttpWebRequest Request = null; |
179 | public LLUUID RequestID = LLUUID.Zero; | 179 | public LLUUID RequestID = LLUUID.Zero; |
180 | public int TimeOfRequest = 0; | 180 | public int TimeOfRequest = 0; |
181 | 181 | ||
182 | public RequestState(HttpWebRequest request, LLUUID requestID) | 182 | public RequestState(HttpWebRequest request, LLUUID requestID) |
183 | { | 183 | { |
184 | Request = request; | 184 | Request = request; |
185 | RequestID = requestID; | 185 | RequestID = requestID; |
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | #endregion | 189 | #endregion |
190 | } | 190 | } |
191 | } \ No newline at end of file | 191 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs index 386c2b5..626c60f 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/VectorRender/VectorRenderModule.cs | |||
@@ -1,369 +1,369 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Drawing; | 29 | using System.Drawing; |
30 | using System.Drawing.Imaging; | 30 | using System.Drawing.Imaging; |
31 | using System.Globalization; | 31 | using System.Globalization; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Net; | 33 | using System.Net; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenJPEGNet; | 36 | using OpenJPEGNet; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | using Image=System.Drawing.Image; | 39 | using Image=System.Drawing.Image; |
40 | 40 | ||
41 | //using Cairo; | 41 | //using Cairo; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender | 43 | namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender |
44 | { | 44 | { |
45 | public class VectorRenderModule : IRegionModule, IDynamicTextureRender | 45 | public class VectorRenderModule : IRegionModule, IDynamicTextureRender |
46 | { | 46 | { |
47 | private string m_name = "VectorRenderModule"; | 47 | private string m_name = "VectorRenderModule"; |
48 | private Scene m_scene; | 48 | private Scene m_scene; |
49 | private IDynamicTextureManager m_textureManager; | 49 | private IDynamicTextureManager m_textureManager; |
50 | 50 | ||
51 | public VectorRenderModule() | 51 | public VectorRenderModule() |
52 | { | 52 | { |
53 | } | 53 | } |
54 | 54 | ||
55 | #region IDynamicTextureRender Members | 55 | #region IDynamicTextureRender Members |
56 | 56 | ||
57 | public string GetContentType() | 57 | public string GetContentType() |
58 | { | 58 | { |
59 | return ("vector"); | 59 | return ("vector"); |
60 | } | 60 | } |
61 | 61 | ||
62 | public string GetName() | 62 | public string GetName() |
63 | { | 63 | { |
64 | return m_name; | 64 | return m_name; |
65 | } | 65 | } |
66 | 66 | ||
67 | public bool SupportsAsynchronous() | 67 | public bool SupportsAsynchronous() |
68 | { | 68 | { |
69 | return true; | 69 | return true; |
70 | } | 70 | } |
71 | 71 | ||
72 | public byte[] ConvertUrl(string url, string extraParams) | 72 | public byte[] ConvertUrl(string url, string extraParams) |
73 | { | 73 | { |
74 | return null; | 74 | return null; |
75 | } | 75 | } |
76 | 76 | ||
77 | public byte[] ConvertStream(Stream data, string extraParams) | 77 | public byte[] ConvertStream(Stream data, string extraParams) |
78 | { | 78 | { |
79 | return null; | 79 | return null; |
80 | } | 80 | } |
81 | 81 | ||
82 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) | 82 | public bool AsyncConvertUrl(LLUUID id, string url, string extraParams) |
83 | { | 83 | { |
84 | return false; | 84 | return false; |
85 | } | 85 | } |
86 | 86 | ||
87 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) | 87 | public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams) |
88 | { | 88 | { |
89 | Draw(bodyData, id, extraParams); | 89 | Draw(bodyData, id, extraParams); |
90 | return true; | 90 | return true; |
91 | } | 91 | } |
92 | 92 | ||
93 | #endregion | 93 | #endregion |
94 | 94 | ||
95 | #region IRegionModule Members | 95 | #region IRegionModule Members |
96 | 96 | ||
97 | public void Initialise(Scene scene, IConfigSource config) | 97 | public void Initialise(Scene scene, IConfigSource config) |
98 | { | 98 | { |
99 | if (m_scene == null) | 99 | if (m_scene == null) |
100 | { | 100 | { |
101 | m_scene = scene; | 101 | m_scene = scene; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void PostInitialise() | 105 | public void PostInitialise() |
106 | { | 106 | { |
107 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); | 107 | m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); |
108 | if (m_textureManager != null) | 108 | if (m_textureManager != null) |
109 | { | 109 | { |
110 | m_textureManager.RegisterRender(GetContentType(), this); | 110 | m_textureManager.RegisterRender(GetContentType(), this); |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | public void Close() | 114 | public void Close() |
115 | { | 115 | { |
116 | } | 116 | } |
117 | 117 | ||
118 | public string Name | 118 | public string Name |
119 | { | 119 | { |
120 | get { return m_name; } | 120 | get { return m_name; } |
121 | } | 121 | } |
122 | 122 | ||
123 | public bool IsSharedModule | 123 | public bool IsSharedModule |
124 | { | 124 | { |
125 | get { return true; } | 125 | get { return true; } |
126 | } | 126 | } |
127 | 127 | ||
128 | #endregion | 128 | #endregion |
129 | 129 | ||
130 | private void Draw(string data, LLUUID id, string extraParams) | 130 | private void Draw(string data, LLUUID id, string extraParams) |
131 | { | 131 | { |
132 | // TODO: this is a brutal hack. extraParams should actually be parsed reasonably. | 132 | // TODO: this is a brutal hack. extraParams should actually be parsed reasonably. |
133 | int size = 256; | 133 | int size = 256; |
134 | try | 134 | try |
135 | { | 135 | { |
136 | size = Convert.ToInt32(extraParams); | 136 | size = Convert.ToInt32(extraParams); |
137 | } | 137 | } |
138 | catch (Exception e) | 138 | catch (Exception e) |
139 | { | 139 | { |
140 | //Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used | 140 | //Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used |
141 | Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString()); | 141 | Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString()); |
142 | } | 142 | } |
143 | 143 | ||
144 | if ((size < 128) || (size > 1024)) | 144 | if ((size < 128) || (size > 1024)) |
145 | size = 256; | 145 | size = 256; |
146 | 146 | ||
147 | Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb); | 147 | Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb); |
148 | 148 | ||
149 | Graphics graph = Graphics.FromImage(bitmap); | 149 | Graphics graph = Graphics.FromImage(bitmap); |
150 | 150 | ||
151 | extraParams = extraParams.ToLower(); | 151 | extraParams = extraParams.ToLower(); |
152 | int alpha = 255; | 152 | int alpha = 255; |
153 | if (extraParams == "setalpha") | 153 | if (extraParams == "setalpha") |
154 | { | 154 | { |
155 | alpha = 0; | 155 | alpha = 0; |
156 | } | 156 | } |
157 | else | 157 | else |
158 | { | 158 | { |
159 | graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size); | 159 | graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size); |
160 | } | 160 | } |
161 | 161 | ||
162 | for (int w = 0; w < bitmap.Width; w++) | 162 | for (int w = 0; w < bitmap.Width; w++) |
163 | { | 163 | { |
164 | for (int h = 0; h < bitmap.Height; h++) | 164 | for (int h = 0; h < bitmap.Height; h++) |
165 | { | 165 | { |
166 | bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); | 166 | bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); |
167 | } | 167 | } |
168 | } | 168 | } |
169 | 169 | ||
170 | 170 | ||
171 | GDIDraw(data, graph); | 171 | GDIDraw(data, graph); |
172 | 172 | ||
173 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); | 173 | byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); |
174 | m_textureManager.ReturnData(id, imageJ2000); | 174 | m_textureManager.ReturnData(id, imageJ2000); |
175 | } | 175 | } |
176 | 176 | ||
177 | /* | 177 | /* |
178 | private void CairoDraw(string data, System.Drawing.Graphics graph) | 178 | private void CairoDraw(string data, System.Drawing.Graphics graph) |
179 | { | 179 | { |
180 | using (Win32Surface draw = new Win32Surface(graph.GetHdc())) | 180 | using (Win32Surface draw = new Win32Surface(graph.GetHdc())) |
181 | { | 181 | { |
182 | Context contex = new Context(draw); | 182 | Context contex = new Context(draw); |
183 | 183 | ||
184 | contex.Antialias = Antialias.None; //fastest method but low quality | 184 | contex.Antialias = Antialias.None; //fastest method but low quality |
185 | contex.LineWidth = 7; | 185 | contex.LineWidth = 7; |
186 | char[] lineDelimiter = { ';' }; | 186 | char[] lineDelimiter = { ';' }; |
187 | char[] partsDelimiter = { ',' }; | 187 | char[] partsDelimiter = { ',' }; |
188 | string[] lines = data.Split(lineDelimiter); | 188 | string[] lines = data.Split(lineDelimiter); |
189 | 189 | ||
190 | foreach (string line in lines) | 190 | foreach (string line in lines) |
191 | { | 191 | { |
192 | string nextLine = line.Trim(); | 192 | string nextLine = line.Trim(); |
193 | 193 | ||
194 | if (nextLine.StartsWith("MoveTO")) | 194 | if (nextLine.StartsWith("MoveTO")) |
195 | { | 195 | { |
196 | float x = 0; | 196 | float x = 0; |
197 | float y = 0; | 197 | float y = 0; |
198 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); | 198 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); |
199 | contex.MoveTo(x, y); | 199 | contex.MoveTo(x, y); |
200 | } | 200 | } |
201 | else if (nextLine.StartsWith("LineTo")) | 201 | else if (nextLine.StartsWith("LineTo")) |
202 | { | 202 | { |
203 | float x = 0; | 203 | float x = 0; |
204 | float y = 0; | 204 | float y = 0; |
205 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); | 205 | GetParams(partsDelimiter, ref nextLine, ref x, ref y); |
206 | contex.LineTo(x, y); | 206 | contex.LineTo(x, y); |
207 | contex.Stroke(); | 207 | contex.Stroke(); |
208 | } | 208 | } |
209 | } | 209 | } |
210 | } | 210 | } |
211 | graph.ReleaseHdc(); | 211 | graph.ReleaseHdc(); |
212 | } | 212 | } |
213 | */ | 213 | */ |
214 | 214 | ||
215 | private void GDIDraw(string data, Graphics graph) | 215 | private void GDIDraw(string data, Graphics graph) |
216 | { | 216 | { |
217 | Point startPoint = new Point(0, 0); | 217 | Point startPoint = new Point(0, 0); |
218 | Point endPoint = new Point(0, 0); | 218 | Point endPoint = new Point(0, 0); |
219 | Pen drawPen = new Pen(Color.Black, 7); | 219 | Pen drawPen = new Pen(Color.Black, 7); |
220 | Font myFont = new Font("Times New Roman", 14); | 220 | Font myFont = new Font("Times New Roman", 14); |
221 | SolidBrush myBrush = new SolidBrush(Color.Black); | 221 | SolidBrush myBrush = new SolidBrush(Color.Black); |
222 | char[] lineDelimiter = {';'}; | 222 | char[] lineDelimiter = {';'}; |
223 | char[] partsDelimiter = {','}; | 223 | char[] partsDelimiter = {','}; |
224 | string[] lines = data.Split(lineDelimiter); | 224 | string[] lines = data.Split(lineDelimiter); |
225 | 225 | ||
226 | foreach (string line in lines) | 226 | foreach (string line in lines) |
227 | { | 227 | { |
228 | string nextLine = line.Trim(); | 228 | string nextLine = line.Trim(); |
229 | //replace with switch, or even better, do some proper parsing | 229 | //replace with switch, or even better, do some proper parsing |
230 | if (nextLine.StartsWith("MoveTo")) | 230 | if (nextLine.StartsWith("MoveTo")) |
231 | { | 231 | { |
232 | float x = 0; | 232 | float x = 0; |
233 | float y = 0; | 233 | float y = 0; |
234 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); | 234 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); |
235 | startPoint.X = (int) x; | 235 | startPoint.X = (int) x; |
236 | startPoint.Y = (int) y; | 236 | startPoint.Y = (int) y; |
237 | } | 237 | } |
238 | else if (nextLine.StartsWith("LineTo")) | 238 | else if (nextLine.StartsWith("LineTo")) |
239 | { | 239 | { |
240 | float x = 0; | 240 | float x = 0; |
241 | float y = 0; | 241 | float y = 0; |
242 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); | 242 | GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y); |
243 | endPoint.X = (int) x; | 243 | endPoint.X = (int) x; |
244 | endPoint.Y = (int) y; | 244 | endPoint.Y = (int) y; |
245 | graph.DrawLine(drawPen, startPoint, endPoint); | 245 | graph.DrawLine(drawPen, startPoint, endPoint); |
246 | startPoint.X = endPoint.X; | 246 | startPoint.X = endPoint.X; |
247 | startPoint.Y = endPoint.Y; | 247 | startPoint.Y = endPoint.Y; |
248 | } | 248 | } |
249 | else if (nextLine.StartsWith("Text")) | 249 | else if (nextLine.StartsWith("Text")) |
250 | { | 250 | { |
251 | nextLine = nextLine.Remove(0, 4); | 251 | nextLine = nextLine.Remove(0, 4); |
252 | nextLine = nextLine.Trim(); | 252 | nextLine = nextLine.Trim(); |
253 | graph.DrawString(nextLine, myFont, myBrush, startPoint); | 253 | graph.DrawString(nextLine, myFont, myBrush, startPoint); |
254 | } | 254 | } |
255 | else if (nextLine.StartsWith("Image")) | 255 | else if (nextLine.StartsWith("Image")) |
256 | { | 256 | { |
257 | float x = 0; | 257 | float x = 0; |
258 | float y = 0; | 258 | float y = 0; |
259 | GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); | 259 | GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); |
260 | endPoint.X = (int) x; | 260 | endPoint.X = (int) x; |
261 | endPoint.Y = (int) y; | 261 | endPoint.Y = (int) y; |
262 | Image image = ImageHttpRequest(nextLine); | 262 | Image image = ImageHttpRequest(nextLine); |
263 | graph.DrawImage(image, (float) startPoint.X, (float) startPoint.Y, x, y); | 263 | graph.DrawImage(image, (float) startPoint.X, (float) startPoint.Y, x, y); |
264 | startPoint.X += endPoint.X; | 264 | startPoint.X += endPoint.X; |
265 | startPoint.Y += endPoint.Y; | 265 | startPoint.Y += endPoint.Y; |
266 | } | 266 | } |
267 | else if (nextLine.StartsWith("Rectangle")) | 267 | else if (nextLine.StartsWith("Rectangle")) |
268 | { | 268 | { |
269 | float x = 0; | 269 | float x = 0; |
270 | float y = 0; | 270 | float y = 0; |
271 | GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y); | 271 | GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y); |
272 | endPoint.X = (int) x; | 272 | endPoint.X = (int) x; |
273 | endPoint.Y = (int) y; | 273 | endPoint.Y = (int) y; |
274 | graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); | 274 | graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); |
275 | startPoint.X += endPoint.X; | 275 | startPoint.X += endPoint.X; |
276 | startPoint.Y += endPoint.Y; | 276 | startPoint.Y += endPoint.Y; |
277 | } | 277 | } |
278 | else if (nextLine.StartsWith("FillRectangle")) | 278 | else if (nextLine.StartsWith("FillRectangle")) |
279 | { | 279 | { |
280 | float x = 0; | 280 | float x = 0; |
281 | float y = 0; | 281 | float y = 0; |
282 | GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y); | 282 | GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y); |
283 | endPoint.X = (int) x; | 283 | endPoint.X = (int) x; |
284 | endPoint.Y = (int) y; | 284 | endPoint.Y = (int) y; |
285 | graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); | 285 | graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); |
286 | startPoint.X += endPoint.X; | 286 | startPoint.X += endPoint.X; |
287 | startPoint.Y += endPoint.Y; | 287 | startPoint.Y += endPoint.Y; |
288 | } | 288 | } |
289 | else if (nextLine.StartsWith("Ellipse")) | 289 | else if (nextLine.StartsWith("Ellipse")) |
290 | { | 290 | { |
291 | float x = 0; | 291 | float x = 0; |
292 | float y = 0; | 292 | float y = 0; |
293 | GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y); | 293 | GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y); |
294 | endPoint.X = (int) x; | 294 | endPoint.X = (int) x; |
295 | endPoint.Y = (int) y; | 295 | endPoint.Y = (int) y; |
296 | graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); | 296 | graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); |
297 | startPoint.X += endPoint.X; | 297 | startPoint.X += endPoint.X; |
298 | startPoint.Y += endPoint.Y; | 298 | startPoint.Y += endPoint.Y; |
299 | } | 299 | } |
300 | else if (nextLine.StartsWith("FontSize")) | 300 | else if (nextLine.StartsWith("FontSize")) |
301 | { | 301 | { |
302 | nextLine = nextLine.Remove(0, 8); | 302 | nextLine = nextLine.Remove(0, 8); |
303 | nextLine = nextLine.Trim(); | 303 | nextLine = nextLine.Trim(); |
304 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); | 304 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); |
305 | myFont = new Font("Times New Roman", size); | 305 | myFont = new Font("Times New Roman", size); |
306 | } | 306 | } |
307 | else if (nextLine.StartsWith("PenSize")) | 307 | else if (nextLine.StartsWith("PenSize")) |
308 | { | 308 | { |
309 | nextLine = nextLine.Remove(0, 8); | 309 | nextLine = nextLine.Remove(0, 8); |
310 | nextLine = nextLine.Trim(); | 310 | nextLine = nextLine.Trim(); |
311 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); | 311 | float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture); |
312 | drawPen.Width = size; | 312 | drawPen.Width = size; |
313 | } | 313 | } |
314 | else if (nextLine.StartsWith("PenColour")) | 314 | else if (nextLine.StartsWith("PenColour")) |
315 | { | 315 | { |
316 | nextLine = nextLine.Remove(0, 9); | 316 | nextLine = nextLine.Remove(0, 9); |
317 | nextLine = nextLine.Trim(); | 317 | nextLine = nextLine.Trim(); |
318 | 318 | ||
319 | Color newColour = Color.FromName(nextLine); | 319 | Color newColour = Color.FromName(nextLine); |
320 | 320 | ||
321 | myBrush.Color = newColour; | 321 | myBrush.Color = newColour; |
322 | drawPen.Color = newColour; | 322 | drawPen.Color = newColour; |
323 | } | 323 | } |
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
327 | private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) | 327 | private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) |
328 | { | 328 | { |
329 | line = line.Remove(0, startLength); | 329 | line = line.Remove(0, startLength); |
330 | string[] parts = line.Split(partsDelimiter); | 330 | string[] parts = line.Split(partsDelimiter); |
331 | if (parts.Length == 2) | 331 | if (parts.Length == 2) |
332 | { | 332 | { |
333 | string xVal = parts[0].Trim(); | 333 | string xVal = parts[0].Trim(); |
334 | string yVal = parts[1].Trim(); | 334 | string yVal = parts[1].Trim(); |
335 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); | 335 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); |
336 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); | 336 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); |
337 | } | 337 | } |
338 | else if (parts.Length > 2) | 338 | else if (parts.Length > 2) |
339 | { | 339 | { |
340 | string xVal = parts[0].Trim(); | 340 | string xVal = parts[0].Trim(); |
341 | string yVal = parts[1].Trim(); | 341 | string yVal = parts[1].Trim(); |
342 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); | 342 | x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); |
343 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); | 343 | y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); |
344 | 344 | ||
345 | line = ""; | 345 | line = ""; |
346 | for (int i = 2; i < parts.Length; i++) | 346 | for (int i = 2; i < parts.Length; i++) |
347 | { | 347 | { |
348 | line = line + parts[i].Trim(); | 348 | line = line + parts[i].Trim(); |
349 | line = line + " "; | 349 | line = line + " "; |
350 | } | 350 | } |
351 | } | 351 | } |
352 | } | 352 | } |
353 | 353 | ||
354 | private Bitmap ImageHttpRequest(string url) | 354 | private Bitmap ImageHttpRequest(string url) |
355 | { | 355 | { |
356 | WebRequest request = HttpWebRequest.Create(url); | 356 | WebRequest request = HttpWebRequest.Create(url); |
357 | //Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. | 357 | //Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. |
358 | //Ckrinke Stream str = null; | 358 | //Ckrinke Stream str = null; |
359 | HttpWebResponse response = (HttpWebResponse) (request).GetResponse(); | 359 | HttpWebResponse response = (HttpWebResponse) (request).GetResponse(); |
360 | if (response.StatusCode == HttpStatusCode.OK) | 360 | if (response.StatusCode == HttpStatusCode.OK) |
361 | { | 361 | { |
362 | Bitmap image = new Bitmap(response.GetResponseStream()); | 362 | Bitmap image = new Bitmap(response.GetResponseStream()); |
363 | return image; | 363 | return image; |
364 | } | 364 | } |
365 | 365 | ||
366 | return null; | 366 | return null; |
367 | } | 367 | } |
368 | } | 368 | } |
369 | } \ No newline at end of file | 369 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs index ff3b31e..e79b2bd 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs | |||
@@ -1,585 +1,585 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | /***************************************************** | 36 | /***************************************************** |
37 | * | 37 | * |
38 | * WorldCommModule | 38 | * WorldCommModule |
39 | * | 39 | * |
40 | * | 40 | * |
41 | * Holding place for world comms - basically llListen | 41 | * Holding place for world comms - basically llListen |
42 | * function implementation. | 42 | * function implementation. |
43 | * | 43 | * |
44 | * lLListen(integer channel, string name, key id, string msg) | 44 | * lLListen(integer channel, string name, key id, string msg) |
45 | * The name, id, and msg arguments specify the filtering | 45 | * The name, id, and msg arguments specify the filtering |
46 | * criteria. You can pass the empty string | 46 | * criteria. You can pass the empty string |
47 | * (or NULL_KEY for id) for these to set a completely | 47 | * (or NULL_KEY for id) for these to set a completely |
48 | * open filter; this causes the listen() event handler to be | 48 | * open filter; this causes the listen() event handler to be |
49 | * invoked for all chat on the channel. To listen only | 49 | * invoked for all chat on the channel. To listen only |
50 | * for chat spoken by a specific object or avatar, | 50 | * for chat spoken by a specific object or avatar, |
51 | * specify the name and/or id arguments. To listen | 51 | * specify the name and/or id arguments. To listen |
52 | * only for a specific command, specify the | 52 | * only for a specific command, specify the |
53 | * (case-sensitive) msg argument. If msg is not empty, | 53 | * (case-sensitive) msg argument. If msg is not empty, |
54 | * listener will only hear strings which are exactly equal | 54 | * listener will only hear strings which are exactly equal |
55 | * to msg. You can also use all the arguments to establish | 55 | * to msg. You can also use all the arguments to establish |
56 | * the most restrictive filtering criteria. | 56 | * the most restrictive filtering criteria. |
57 | * | 57 | * |
58 | * It might be useful for each listener to maintain a message | 58 | * It might be useful for each listener to maintain a message |
59 | * digest, with a list of recent messages by UUID. This can | 59 | * digest, with a list of recent messages by UUID. This can |
60 | * be used to prevent in-world repeater loops. However, the | 60 | * be used to prevent in-world repeater loops. However, the |
61 | * linden functions do not have this capability, so for now | 61 | * linden functions do not have this capability, so for now |
62 | * thats the way it works. | 62 | * thats the way it works. |
63 | * | 63 | * |
64 | * **************************************************/ | 64 | * **************************************************/ |
65 | 65 | ||
66 | namespace OpenSim.Region.Environment.Modules.Scripting.WorldComm | 66 | namespace OpenSim.Region.Environment.Modules.Scripting.WorldComm |
67 | { | 67 | { |
68 | public class WorldCommModule : IRegionModule, IWorldComm | 68 | public class WorldCommModule : IRegionModule, IWorldComm |
69 | { | 69 | { |
70 | private object CommListLock = new object(); | 70 | private object CommListLock = new object(); |
71 | private object ListLock = new object(); | 71 | private object ListLock = new object(); |
72 | private ListenerManager m_listenerManager; | 72 | private ListenerManager m_listenerManager; |
73 | private string m_name = "WorldCommModule"; | 73 | private string m_name = "WorldCommModule"; |
74 | private Queue m_pending; | 74 | private Queue m_pending; |
75 | private Queue m_pendingQ; | 75 | private Queue m_pendingQ; |
76 | private Scene m_scene; | 76 | private Scene m_scene; |
77 | 77 | ||
78 | public WorldCommModule() | 78 | public WorldCommModule() |
79 | { | 79 | { |
80 | } | 80 | } |
81 | 81 | ||
82 | #region IRegionModule Members | 82 | #region IRegionModule Members |
83 | 83 | ||
84 | public void Initialise(Scene scene, IConfigSource config) | 84 | public void Initialise(Scene scene, IConfigSource config) |
85 | { | 85 | { |
86 | m_scene = scene; | 86 | m_scene = scene; |
87 | m_scene.RegisterModuleInterface<IWorldComm>(this); | 87 | m_scene.RegisterModuleInterface<IWorldComm>(this); |
88 | m_listenerManager = new ListenerManager(); | 88 | m_listenerManager = new ListenerManager(); |
89 | m_scene.EventManager.OnNewClient += NewClient; | 89 | m_scene.EventManager.OnNewClient += NewClient; |
90 | m_pendingQ = new Queue(); | 90 | m_pendingQ = new Queue(); |
91 | m_pending = Queue.Synchronized(m_pendingQ); | 91 | m_pending = Queue.Synchronized(m_pendingQ); |
92 | } | 92 | } |
93 | 93 | ||
94 | public void PostInitialise() | 94 | public void PostInitialise() |
95 | { | 95 | { |
96 | } | 96 | } |
97 | 97 | ||
98 | public void Close() | 98 | public void Close() |
99 | { | 99 | { |
100 | } | 100 | } |
101 | 101 | ||
102 | public string Name | 102 | public string Name |
103 | { | 103 | { |
104 | get { return m_name; } | 104 | get { return m_name; } |
105 | } | 105 | } |
106 | 106 | ||
107 | public bool IsSharedModule | 107 | public bool IsSharedModule |
108 | { | 108 | { |
109 | get { return false; } | 109 | get { return false; } |
110 | } | 110 | } |
111 | 111 | ||
112 | #endregion | 112 | #endregion |
113 | 113 | ||
114 | #region IWorldComm Members | 114 | #region IWorldComm Members |
115 | 115 | ||
116 | public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) | 116 | public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) |
117 | { | 117 | { |
118 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); | 118 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); |
119 | } | 119 | } |
120 | 120 | ||
121 | public void ListenControl(int handle, int active) | 121 | public void ListenControl(int handle, int active) |
122 | { | 122 | { |
123 | if (m_listenerManager != null) | 123 | if (m_listenerManager != null) |
124 | { | 124 | { |
125 | if (active == 1) | 125 | if (active == 1) |
126 | m_listenerManager.Activate(handle); | 126 | m_listenerManager.Activate(handle); |
127 | else if (active == 0) | 127 | else if (active == 0) |
128 | m_listenerManager.Dectivate(handle); | 128 | m_listenerManager.Dectivate(handle); |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | public void ListenRemove(int handle) | 132 | public void ListenRemove(int handle) |
133 | { | 133 | { |
134 | if (m_listenerManager != null) | 134 | if (m_listenerManager != null) |
135 | { | 135 | { |
136 | m_listenerManager.Remove(handle); | 136 | m_listenerManager.Remove(handle); |
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | public void DeleteListener(LLUUID itemID) | 140 | public void DeleteListener(LLUUID itemID) |
141 | { | 141 | { |
142 | if (m_listenerManager != null) | 142 | if (m_listenerManager != null) |
143 | { | 143 | { |
144 | m_listenerManager.DeleteListener(itemID); | 144 | m_listenerManager.DeleteListener(itemID); |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
148 | // This method scans nearby objects and determines if they are listeners, | 148 | // This method scans nearby objects and determines if they are listeners, |
149 | // and if so if this message fits the filter. If it does, then | 149 | // and if so if this message fits the filter. If it does, then |
150 | // enqueue the message for delivery to the objects listen event handler. | 150 | // enqueue the message for delivery to the objects listen event handler. |
151 | // Objects that do an llSay have their messages delivered here, and for | 151 | // Objects that do an llSay have their messages delivered here, and for |
152 | // nearby avatars, the SimChat function is used. | 152 | // nearby avatars, the SimChat function is used. |
153 | public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) | 153 | public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) |
154 | { | 154 | { |
155 | SceneObjectPart source = null; | 155 | SceneObjectPart source = null; |
156 | ScenePresence avatar = null; | 156 | ScenePresence avatar = null; |
157 | 157 | ||
158 | source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); | 158 | source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); |
159 | if (source == null) | 159 | if (source == null) |
160 | { | 160 | { |
161 | avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); | 161 | avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); |
162 | } | 162 | } |
163 | if ((avatar != null) || (source != null)) | 163 | if ((avatar != null) || (source != null)) |
164 | { | 164 | { |
165 | // Loop through the objects in the scene | 165 | // Loop through the objects in the scene |
166 | // If they are in proximity, then if they are | 166 | // If they are in proximity, then if they are |
167 | // listeners, if so add them to the pending queue | 167 | // listeners, if so add them to the pending queue |
168 | 168 | ||
169 | foreach (ListenerInfo li in m_listenerManager.GetListeners()) | 169 | foreach (ListenerInfo li in m_listenerManager.GetListeners()) |
170 | { | 170 | { |
171 | EntityBase sPart; | 171 | EntityBase sPart; |
172 | 172 | ||
173 | m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); | 173 | m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); |
174 | 174 | ||
175 | if (sPart != null) | 175 | if (sPart != null) |
176 | { | 176 | { |
177 | double dis = 0; | 177 | double dis = 0; |
178 | 178 | ||
179 | if (source != null) | 179 | if (source != null) |
180 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); | 180 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); |
181 | else | 181 | else |
182 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); | 182 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); |
183 | 183 | ||
184 | switch (type) | 184 | switch (type) |
185 | { | 185 | { |
186 | case ChatTypeEnum.Whisper: | 186 | case ChatTypeEnum.Whisper: |
187 | 187 | ||
188 | if ((dis < 10) && (dis > -10)) | 188 | if ((dis < 10) && (dis > -10)) |
189 | { | 189 | { |
190 | if (li.GetChannel() == channel) | 190 | if (li.GetChannel() == channel) |
191 | { | 191 | { |
192 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 192 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
193 | sourceItemID, sPart.UUID, channel, name, msg | 193 | sourceItemID, sPart.UUID, channel, name, msg |
194 | ); | 194 | ); |
195 | if (isListener != null) | 195 | if (isListener != null) |
196 | { | 196 | { |
197 | lock (m_pending.SyncRoot) | 197 | lock (m_pending.SyncRoot) |
198 | { | 198 | { |
199 | m_pending.Enqueue(isListener); | 199 | m_pending.Enqueue(isListener); |
200 | } | 200 | } |
201 | } | 201 | } |
202 | } | 202 | } |
203 | } | 203 | } |
204 | break; | 204 | break; |
205 | 205 | ||
206 | case ChatTypeEnum.Say: | 206 | case ChatTypeEnum.Say: |
207 | 207 | ||
208 | if ((dis < 30) && (dis > -30)) | 208 | if ((dis < 30) && (dis > -30)) |
209 | { | 209 | { |
210 | if (li.GetChannel() == channel) | 210 | if (li.GetChannel() == channel) |
211 | { | 211 | { |
212 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 212 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
213 | sourceItemID, sPart.UUID, channel, name, msg | 213 | sourceItemID, sPart.UUID, channel, name, msg |
214 | ); | 214 | ); |
215 | if (isListener != null) | 215 | if (isListener != null) |
216 | { | 216 | { |
217 | lock (m_pending.SyncRoot) | 217 | lock (m_pending.SyncRoot) |
218 | { | 218 | { |
219 | m_pending.Enqueue(isListener); | 219 | m_pending.Enqueue(isListener); |
220 | } | 220 | } |
221 | } | 221 | } |
222 | } | 222 | } |
223 | } | 223 | } |
224 | break; | 224 | break; |
225 | 225 | ||
226 | case ChatTypeEnum.Shout: | 226 | case ChatTypeEnum.Shout: |
227 | if ((dis < 100) && (dis > -100)) | 227 | if ((dis < 100) && (dis > -100)) |
228 | { | 228 | { |
229 | if (li.GetChannel() == channel) | 229 | if (li.GetChannel() == channel) |
230 | { | 230 | { |
231 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 231 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
232 | sourceItemID, sPart.UUID, channel, name, msg | 232 | sourceItemID, sPart.UUID, channel, name, msg |
233 | ); | 233 | ); |
234 | if (isListener != null) | 234 | if (isListener != null) |
235 | { | 235 | { |
236 | lock (m_pending.SyncRoot) | 236 | lock (m_pending.SyncRoot) |
237 | { | 237 | { |
238 | m_pending.Enqueue(isListener); | 238 | m_pending.Enqueue(isListener); |
239 | } | 239 | } |
240 | } | 240 | } |
241 | } | 241 | } |
242 | } | 242 | } |
243 | break; | 243 | break; |
244 | 244 | ||
245 | case ChatTypeEnum.Broadcast: | 245 | case ChatTypeEnum.Broadcast: |
246 | // Dont process if this message is from itself! | 246 | // Dont process if this message is from itself! |
247 | if (li.GetHostID().ToString().Equals(sourceItemID) || | 247 | if (li.GetHostID().ToString().Equals(sourceItemID) || |
248 | sPart.UUID.ToString().Equals(sourceItemID)) | 248 | sPart.UUID.ToString().Equals(sourceItemID)) |
249 | continue; | 249 | continue; |
250 | 250 | ||
251 | if (li.GetChannel() == channel) | 251 | if (li.GetChannel() == channel) |
252 | { | 252 | { |
253 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 253 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
254 | sourceItemID, sPart.UUID, channel, name, msg | 254 | sourceItemID, sPart.UUID, channel, name, msg |
255 | ); | 255 | ); |
256 | if (isListener != null) | 256 | if (isListener != null) |
257 | { | 257 | { |
258 | lock (m_pending.SyncRoot) | 258 | lock (m_pending.SyncRoot) |
259 | { | 259 | { |
260 | m_pending.Enqueue(isListener); | 260 | m_pending.Enqueue(isListener); |
261 | } | 261 | } |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | break; | 265 | break; |
266 | } | 266 | } |
267 | } | 267 | } |
268 | } | 268 | } |
269 | } | 269 | } |
270 | } | 270 | } |
271 | 271 | ||
272 | public bool HasMessages() | 272 | public bool HasMessages() |
273 | { | 273 | { |
274 | if (m_pending != null) | 274 | if (m_pending != null) |
275 | return (m_pending.Count > 0); | 275 | return (m_pending.Count > 0); |
276 | else | 276 | else |
277 | return false; | 277 | return false; |
278 | } | 278 | } |
279 | 279 | ||
280 | public ListenerInfo GetNextMessage() | 280 | public ListenerInfo GetNextMessage() |
281 | { | 281 | { |
282 | ListenerInfo li = null; | 282 | ListenerInfo li = null; |
283 | 283 | ||
284 | lock (m_pending.SyncRoot) | 284 | lock (m_pending.SyncRoot) |
285 | { | 285 | { |
286 | li = (ListenerInfo) m_pending.Dequeue(); | 286 | li = (ListenerInfo) m_pending.Dequeue(); |
287 | } | 287 | } |
288 | 288 | ||
289 | return li; | 289 | return li; |
290 | } | 290 | } |
291 | 291 | ||
292 | public uint PeekNextMessageLocalID() | 292 | public uint PeekNextMessageLocalID() |
293 | { | 293 | { |
294 | return ((ListenerInfo) m_pending.Peek()).GetLocalID(); | 294 | return ((ListenerInfo) m_pending.Peek()).GetLocalID(); |
295 | } | 295 | } |
296 | 296 | ||
297 | public LLUUID PeekNextMessageItemID() | 297 | public LLUUID PeekNextMessageItemID() |
298 | { | 298 | { |
299 | return ((ListenerInfo) m_pending.Peek()).GetItemID(); | 299 | return ((ListenerInfo) m_pending.Peek()).GetItemID(); |
300 | } | 300 | } |
301 | 301 | ||
302 | #endregion | 302 | #endregion |
303 | 303 | ||
304 | public void NewClient(IClientAPI client) | 304 | public void NewClient(IClientAPI client) |
305 | { | 305 | { |
306 | client.OnChatFromViewer += DeliverClientMessage; | 306 | client.OnChatFromViewer += DeliverClientMessage; |
307 | } | 307 | } |
308 | 308 | ||
309 | /******************************************************************** | 309 | /******************************************************************** |
310 | * | 310 | * |
311 | * Listener Stuff | 311 | * Listener Stuff |
312 | * | 312 | * |
313 | * *****************************************************************/ | 313 | * *****************************************************************/ |
314 | 314 | ||
315 | private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) | 315 | private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) |
316 | { | 316 | { |
317 | DeliverMessage(e.Sender.AgentId.ToString(), | 317 | DeliverMessage(e.Sender.AgentId.ToString(), |
318 | e.Type, e.Channel, | 318 | e.Type, e.Channel, |
319 | e.Sender.FirstName + " " + e.Sender.LastName, | 319 | e.Sender.FirstName + " " + e.Sender.LastName, |
320 | e.Message); | 320 | e.Message); |
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
324 | public class ListenerManager | 324 | public class ListenerManager |
325 | { | 325 | { |
326 | //private Dictionary<int, ListenerInfo> m_listeners; | 326 | //private Dictionary<int, ListenerInfo> m_listeners; |
327 | private object ListenersLock = new object(); | 327 | private object ListenersLock = new object(); |
328 | private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); | 328 | private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); |
329 | private int m_MaxListeners = 100; | 329 | private int m_MaxListeners = 100; |
330 | 330 | ||
331 | public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) | 331 | public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) |
332 | { | 332 | { |
333 | if (m_listeners.Count < m_MaxListeners) | 333 | if (m_listeners.Count < m_MaxListeners) |
334 | { | 334 | { |
335 | ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); | 335 | ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); |
336 | 336 | ||
337 | if (isListener == null) | 337 | if (isListener == null) |
338 | { | 338 | { |
339 | int newHandle = GetNewHandle(); | 339 | int newHandle = GetNewHandle(); |
340 | 340 | ||
341 | if (newHandle > -1) | 341 | if (newHandle > -1) |
342 | { | 342 | { |
343 | ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); | 343 | ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); |
344 | 344 | ||
345 | lock (m_listeners.SyncRoot) | 345 | lock (m_listeners.SyncRoot) |
346 | { | 346 | { |
347 | m_listeners.Add(newHandle, li); | 347 | m_listeners.Add(newHandle, li); |
348 | } | 348 | } |
349 | 349 | ||
350 | return newHandle; | 350 | return newHandle; |
351 | } | 351 | } |
352 | } | 352 | } |
353 | } | 353 | } |
354 | 354 | ||
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | 357 | ||
358 | public void Remove(int handle) | 358 | public void Remove(int handle) |
359 | { | 359 | { |
360 | lock (m_listeners.SyncRoot) | 360 | lock (m_listeners.SyncRoot) |
361 | { | 361 | { |
362 | m_listeners.Remove(handle); | 362 | m_listeners.Remove(handle); |
363 | } | 363 | } |
364 | } | 364 | } |
365 | 365 | ||
366 | public void DeleteListener(LLUUID itemID) | 366 | public void DeleteListener(LLUUID itemID) |
367 | { | 367 | { |
368 | ArrayList removedListeners = new ArrayList(); | 368 | ArrayList removedListeners = new ArrayList(); |
369 | 369 | ||
370 | lock (m_listeners.SyncRoot) | 370 | lock (m_listeners.SyncRoot) |
371 | { | 371 | { |
372 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); | 372 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); |
373 | while (en.MoveNext()) | 373 | while (en.MoveNext()) |
374 | { | 374 | { |
375 | ListenerInfo li = (ListenerInfo) en.Value; | 375 | ListenerInfo li = (ListenerInfo) en.Value; |
376 | if (li.GetItemID().Equals(itemID)) | 376 | if (li.GetItemID().Equals(itemID)) |
377 | { | 377 | { |
378 | removedListeners.Add(li.GetHandle()); | 378 | removedListeners.Add(li.GetHandle()); |
379 | } | 379 | } |
380 | } | 380 | } |
381 | foreach (int handle in removedListeners) | 381 | foreach (int handle in removedListeners) |
382 | { | 382 | { |
383 | m_listeners.Remove(handle); | 383 | m_listeners.Remove(handle); |
384 | } | 384 | } |
385 | } | 385 | } |
386 | } | 386 | } |
387 | 387 | ||
388 | private int GetNewHandle() | 388 | private int GetNewHandle() |
389 | { | 389 | { |
390 | for (int i = 0; i < int.MaxValue - 1; i++) | 390 | for (int i = 0; i < int.MaxValue - 1; i++) |
391 | { | 391 | { |
392 | if (!m_listeners.ContainsKey(i)) | 392 | if (!m_listeners.ContainsKey(i)) |
393 | return i; | 393 | return i; |
394 | } | 394 | } |
395 | 395 | ||
396 | return -1; | 396 | return -1; |
397 | } | 397 | } |
398 | 398 | ||
399 | public bool IsListener(LLUUID hostID) | 399 | public bool IsListener(LLUUID hostID) |
400 | { | 400 | { |
401 | foreach (ListenerInfo li in m_listeners.Values) | 401 | foreach (ListenerInfo li in m_listeners.Values) |
402 | { | 402 | { |
403 | if (li.GetHostID().Equals(hostID)) | 403 | if (li.GetHostID().Equals(hostID)) |
404 | return true; | 404 | return true; |
405 | } | 405 | } |
406 | 406 | ||
407 | return false; | 407 | return false; |
408 | } | 408 | } |
409 | 409 | ||
410 | public void Activate(int handle) | 410 | public void Activate(int handle) |
411 | { | 411 | { |
412 | if (m_listeners.ContainsKey(handle)) | 412 | if (m_listeners.ContainsKey(handle)) |
413 | { | 413 | { |
414 | lock (m_listeners.SyncRoot) | 414 | lock (m_listeners.SyncRoot) |
415 | { | 415 | { |
416 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; | 416 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; |
417 | li.Activate(); | 417 | li.Activate(); |
418 | } | 418 | } |
419 | } | 419 | } |
420 | } | 420 | } |
421 | 421 | ||
422 | public void Dectivate(int handle) | 422 | public void Dectivate(int handle) |
423 | { | 423 | { |
424 | if (m_listeners.ContainsKey(handle)) | 424 | if (m_listeners.ContainsKey(handle)) |
425 | { | 425 | { |
426 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; | 426 | ListenerInfo li = (ListenerInfo) m_listeners[handle]; |
427 | li.Deactivate(); | 427 | li.Deactivate(); |
428 | } | 428 | } |
429 | } | 429 | } |
430 | 430 | ||
431 | // Theres probably a more clever and efficient way to | 431 | // Theres probably a more clever and efficient way to |
432 | // do this, maybe with regex. | 432 | // do this, maybe with regex. |
433 | public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, | 433 | public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, |
434 | string msg) | 434 | string msg) |
435 | { | 435 | { |
436 | bool isMatch = true; | 436 | bool isMatch = true; |
437 | lock (m_listeners.SyncRoot) | 437 | lock (m_listeners.SyncRoot) |
438 | { | 438 | { |
439 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); | 439 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); |
440 | while (en.MoveNext()) | 440 | while (en.MoveNext()) |
441 | { | 441 | { |
442 | ListenerInfo li = (ListenerInfo) en.Value; | 442 | ListenerInfo li = (ListenerInfo) en.Value; |
443 | 443 | ||
444 | if (li.IsActive()) | 444 | if (li.IsActive()) |
445 | { | 445 | { |
446 | if (li.GetHostID().Equals(listenerKey)) | 446 | if (li.GetHostID().Equals(listenerKey)) |
447 | { | 447 | { |
448 | if (channel == li.GetChannel()) | 448 | if (channel == li.GetChannel()) |
449 | { | 449 | { |
450 | if ((li.GetID().ToString().Length > 0) && | 450 | if ((li.GetID().ToString().Length > 0) && |
451 | (!li.GetID().Equals(LLUUID.Zero))) | 451 | (!li.GetID().Equals(LLUUID.Zero))) |
452 | { | 452 | { |
453 | if (!li.GetID().ToString().Equals(sourceItemID)) | 453 | if (!li.GetID().ToString().Equals(sourceItemID)) |
454 | { | 454 | { |
455 | isMatch = false; | 455 | isMatch = false; |
456 | } | 456 | } |
457 | } | 457 | } |
458 | if (isMatch && (li.GetName().Length > 0)) | 458 | if (isMatch && (li.GetName().Length > 0)) |
459 | { | 459 | { |
460 | if (li.GetName().Equals(name)) | 460 | if (li.GetName().Equals(name)) |
461 | { | 461 | { |
462 | isMatch = false; | 462 | isMatch = false; |
463 | } | 463 | } |
464 | } | 464 | } |
465 | if (isMatch) | 465 | if (isMatch) |
466 | { | 466 | { |
467 | return new ListenerInfo( | 467 | return new ListenerInfo( |
468 | li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), | 468 | li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), |
469 | li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) | 469 | li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) |
470 | ); | 470 | ); |
471 | } | 471 | } |
472 | } | 472 | } |
473 | } | 473 | } |
474 | } | 474 | } |
475 | } | 475 | } |
476 | } | 476 | } |
477 | return null; | 477 | return null; |
478 | } | 478 | } |
479 | 479 | ||
480 | public ICollection GetListeners() | 480 | public ICollection GetListeners() |
481 | { | 481 | { |
482 | return m_listeners.Values; | 482 | return m_listeners.Values; |
483 | } | 483 | } |
484 | } | 484 | } |
485 | 485 | ||
486 | public class ListenerInfo | 486 | public class ListenerInfo |
487 | { | 487 | { |
488 | private bool m_active; // Listener is active or not | 488 | private bool m_active; // Listener is active or not |
489 | private int m_channel; // Channel | 489 | private int m_channel; // Channel |
490 | private int m_handle; // Assigned handle of this listener | 490 | private int m_handle; // Assigned handle of this listener |
491 | private LLUUID m_hostID; // ID of the host/scene part | 491 | private LLUUID m_hostID; // ID of the host/scene part |
492 | private LLUUID m_id; // ID to filter messages from | 492 | private LLUUID m_id; // ID to filter messages from |
493 | private LLUUID m_itemID; // ID of the host script engine | 493 | private LLUUID m_itemID; // ID of the host script engine |
494 | private uint m_localID; // Local ID from script engine | 494 | private uint m_localID; // Local ID from script engine |
495 | private string m_message; // The message | 495 | private string m_message; // The message |
496 | private string m_name; // Object name to filter messages from | 496 | private string m_name; // Object name to filter messages from |
497 | private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message | 497 | private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message |
498 | 498 | ||
499 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) | 499 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) |
500 | { | 500 | { |
501 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); | 501 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); |
502 | } | 502 | } |
503 | 503 | ||
504 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, | 504 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, |
505 | string message, LLUUID sourceItemID) | 505 | string message, LLUUID sourceItemID) |
506 | { | 506 | { |
507 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); | 507 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); |
508 | m_sourceItemID = sourceItemID; | 508 | m_sourceItemID = sourceItemID; |
509 | } | 509 | } |
510 | 510 | ||
511 | private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, | 511 | private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, |
512 | LLUUID id, string message) | 512 | LLUUID id, string message) |
513 | { | 513 | { |
514 | m_handle = handle; | 514 | m_handle = handle; |
515 | m_channel = channel; | 515 | m_channel = channel; |
516 | m_itemID = ItemID; | 516 | m_itemID = ItemID; |
517 | m_hostID = hostID; | 517 | m_hostID = hostID; |
518 | m_name = name; | 518 | m_name = name; |
519 | m_id = id; | 519 | m_id = id; |
520 | m_message = message; | 520 | m_message = message; |
521 | m_active = true; | 521 | m_active = true; |
522 | m_localID = localID; | 522 | m_localID = localID; |
523 | } | 523 | } |
524 | 524 | ||
525 | public LLUUID GetItemID() | 525 | public LLUUID GetItemID() |
526 | { | 526 | { |
527 | return m_itemID; | 527 | return m_itemID; |
528 | } | 528 | } |
529 | 529 | ||
530 | public LLUUID GetHostID() | 530 | public LLUUID GetHostID() |
531 | { | 531 | { |
532 | return m_hostID; | 532 | return m_hostID; |
533 | } | 533 | } |
534 | 534 | ||
535 | public LLUUID GetSourceItemID() | 535 | public LLUUID GetSourceItemID() |
536 | { | 536 | { |
537 | return m_sourceItemID; | 537 | return m_sourceItemID; |
538 | } | 538 | } |
539 | 539 | ||
540 | public int GetChannel() | 540 | public int GetChannel() |
541 | { | 541 | { |
542 | return m_channel; | 542 | return m_channel; |
543 | } | 543 | } |
544 | 544 | ||
545 | public uint GetLocalID() | 545 | public uint GetLocalID() |
546 | { | 546 | { |
547 | return m_localID; | 547 | return m_localID; |
548 | } | 548 | } |
549 | 549 | ||
550 | public int GetHandle() | 550 | public int GetHandle() |
551 | { | 551 | { |
552 | return m_handle; | 552 | return m_handle; |
553 | } | 553 | } |
554 | 554 | ||
555 | public string GetMessage() | 555 | public string GetMessage() |
556 | { | 556 | { |
557 | return m_message; | 557 | return m_message; |
558 | } | 558 | } |
559 | 559 | ||
560 | public string GetName() | 560 | public string GetName() |
561 | { | 561 | { |
562 | return m_name; | 562 | return m_name; |
563 | } | 563 | } |
564 | 564 | ||
565 | public bool IsActive() | 565 | public bool IsActive() |
566 | { | 566 | { |
567 | return m_active; | 567 | return m_active; |
568 | } | 568 | } |
569 | 569 | ||
570 | public void Deactivate() | 570 | public void Deactivate() |
571 | { | 571 | { |
572 | m_active = false; | 572 | m_active = false; |
573 | } | 573 | } |
574 | 574 | ||
575 | public void Activate() | 575 | public void Activate() |
576 | { | 576 | { |
577 | m_active = true; | 577 | m_active = true; |
578 | } | 578 | } |
579 | 579 | ||
580 | public LLUUID GetID() | 580 | public LLUUID GetID() |
581 | { | 581 | { |
582 | return m_id; | 582 | return m_id; |
583 | } | 583 | } |
584 | } | 584 | } |
585 | } \ No newline at end of file | 585 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs index 6ca8136..a039d42 100644 --- a/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/XMLRPC/XMLRPCModule.cs | |||
@@ -1,672 +1,672 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Threading; | 33 | using System.Threading; |
34 | using libsecondlife; | 34 | using libsecondlife; |
35 | using log4net; | 35 | using log4net; |
36 | using Nini.Config; | 36 | using Nini.Config; |
37 | using Nwc.XmlRpc; | 37 | using Nwc.XmlRpc; |
38 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Framework.Servers; | 39 | using OpenSim.Framework.Servers; |
40 | using OpenSim.Region.Environment.Interfaces; | 40 | using OpenSim.Region.Environment.Interfaces; |
41 | using OpenSim.Region.Environment.Scenes; | 41 | using OpenSim.Region.Environment.Scenes; |
42 | 42 | ||
43 | /***************************************************** | 43 | /***************************************************** |
44 | * | 44 | * |
45 | * XMLRPCModule | 45 | * XMLRPCModule |
46 | * | 46 | * |
47 | * Module for accepting incoming communications from | 47 | * Module for accepting incoming communications from |
48 | * external XMLRPC client and calling a remote data | 48 | * external XMLRPC client and calling a remote data |
49 | * procedure for a registered data channel/prim. | 49 | * procedure for a registered data channel/prim. |
50 | * | 50 | * |
51 | * | 51 | * |
52 | * 1. On module load, open a listener port | 52 | * 1. On module load, open a listener port |
53 | * 2. Attach an XMLRPC handler | 53 | * 2. Attach an XMLRPC handler |
54 | * 3. When a request is received: | 54 | * 3. When a request is received: |
55 | * 3.1 Parse into components: channel key, int, string | 55 | * 3.1 Parse into components: channel key, int, string |
56 | * 3.2 Look up registered channel listeners | 56 | * 3.2 Look up registered channel listeners |
57 | * 3.3 Call the channel (prim) remote data method | 57 | * 3.3 Call the channel (prim) remote data method |
58 | * 3.4 Capture the response (llRemoteDataReply) | 58 | * 3.4 Capture the response (llRemoteDataReply) |
59 | * 3.5 Return response to client caller | 59 | * 3.5 Return response to client caller |
60 | * 3.6 If no response from llRemoteDataReply within | 60 | * 3.6 If no response from llRemoteDataReply within |
61 | * RemoteReplyScriptTimeout, generate script timeout fault | 61 | * RemoteReplyScriptTimeout, generate script timeout fault |
62 | * | 62 | * |
63 | * Prims in script must: | 63 | * Prims in script must: |
64 | * 1. Open a remote data channel | 64 | * 1. Open a remote data channel |
65 | * 1.1 Generate a channel ID | 65 | * 1.1 Generate a channel ID |
66 | * 1.2 Register primid,channelid pair with module | 66 | * 1.2 Register primid,channelid pair with module |
67 | * 2. Implement the remote data procedure handler | 67 | * 2. Implement the remote data procedure handler |
68 | * | 68 | * |
69 | * llOpenRemoteDataChannel | 69 | * llOpenRemoteDataChannel |
70 | * llRemoteDataReply | 70 | * llRemoteDataReply |
71 | * remote_data(integer type, key channel, key messageid, string sender, integer ival, string sval) | 71 | * remote_data(integer type, key channel, key messageid, string sender, integer ival, string sval) |
72 | * llCloseRemoteDataChannel | 72 | * llCloseRemoteDataChannel |
73 | * | 73 | * |
74 | * **************************************************/ | 74 | * **************************************************/ |
75 | 75 | ||
76 | namespace OpenSim.Region.Environment.Modules.Scripting.XMLRPC | 76 | namespace OpenSim.Region.Environment.Modules.Scripting.XMLRPC |
77 | { | 77 | { |
78 | public class XMLRPCModule : IRegionModule, IXMLRPC | 78 | public class XMLRPCModule : IRegionModule, IXMLRPC |
79 | { | 79 | { |
80 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 80 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
81 | 81 | ||
82 | private string m_name = "XMLRPCModule"; | 82 | private string m_name = "XMLRPCModule"; |
83 | 83 | ||
84 | // <channel id, RPCChannelInfo> | 84 | // <channel id, RPCChannelInfo> |
85 | private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; | 85 | private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; |
86 | private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses; | 86 | private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses; |
87 | private int m_remoteDataPort = 0; | 87 | private int m_remoteDataPort = 0; |
88 | 88 | ||
89 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending; | 89 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending; |
90 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses; | 90 | private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses; |
91 | private List<Scene> m_scenes = new List<Scene>(); | 91 | private List<Scene> m_scenes = new List<Scene>(); |
92 | private int RemoteReplyScriptTimeout = 9000; | 92 | private int RemoteReplyScriptTimeout = 9000; |
93 | private int RemoteReplyScriptWait = 300; | 93 | private int RemoteReplyScriptWait = 300; |
94 | private object XMLRPCListLock = new object(); | 94 | private object XMLRPCListLock = new object(); |
95 | 95 | ||
96 | #region IRegionModule Members | 96 | #region IRegionModule Members |
97 | 97 | ||
98 | public void Initialise(Scene scene, IConfigSource config) | 98 | public void Initialise(Scene scene, IConfigSource config) |
99 | { | 99 | { |
100 | try | 100 | try |
101 | { | 101 | { |
102 | m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort); | 102 | m_remoteDataPort = config.Configs["Network"].GetInt("remoteDataPort", m_remoteDataPort); |
103 | } | 103 | } |
104 | catch (Exception) | 104 | catch (Exception) |
105 | { | 105 | { |
106 | } | 106 | } |
107 | 107 | ||
108 | if (!m_scenes.Contains(scene)) | 108 | if (!m_scenes.Contains(scene)) |
109 | { | 109 | { |
110 | m_scenes.Add(scene); | 110 | m_scenes.Add(scene); |
111 | 111 | ||
112 | scene.RegisterModuleInterface<IXMLRPC>(this); | 112 | scene.RegisterModuleInterface<IXMLRPC>(this); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | public void PostInitialise() | 116 | public void PostInitialise() |
117 | { | 117 | { |
118 | if (IsEnabled()) | 118 | if (IsEnabled()) |
119 | { | 119 | { |
120 | m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); | 120 | m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); |
121 | m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>(); | 121 | m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>(); |
122 | m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>(); | 122 | m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>(); |
123 | m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>(); | 123 | m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>(); |
124 | 124 | ||
125 | // Start http server | 125 | // Start http server |
126 | // Attach xmlrpc handlers | 126 | // Attach xmlrpc handlers |
127 | m_log.Info("[REMOTE_DATA]: " + | 127 | m_log.Info("[REMOTE_DATA]: " + |
128 | "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); | 128 | "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); |
129 | BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); | 129 | BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); |
130 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); | 130 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); |
131 | httpServer.Start(); | 131 | httpServer.Start(); |
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | public void Close() | 135 | public void Close() |
136 | { | 136 | { |
137 | } | 137 | } |
138 | 138 | ||
139 | public string Name | 139 | public string Name |
140 | { | 140 | { |
141 | get { return m_name; } | 141 | get { return m_name; } |
142 | } | 142 | } |
143 | 143 | ||
144 | public bool IsSharedModule | 144 | public bool IsSharedModule |
145 | { | 145 | { |
146 | get { return true; } | 146 | get { return true; } |
147 | } | 147 | } |
148 | 148 | ||
149 | #endregion | 149 | #endregion |
150 | 150 | ||
151 | #region IXMLRPC Members | 151 | #region IXMLRPC Members |
152 | 152 | ||
153 | public bool IsEnabled() | 153 | public bool IsEnabled() |
154 | { | 154 | { |
155 | return (m_remoteDataPort > 0); | 155 | return (m_remoteDataPort > 0); |
156 | } | 156 | } |
157 | 157 | ||
158 | /********************************************** | 158 | /********************************************** |
159 | * OpenXMLRPCChannel | 159 | * OpenXMLRPCChannel |
160 | * | 160 | * |
161 | * Generate a LLUUID channel key and add it and | 161 | * Generate a LLUUID channel key and add it and |
162 | * the prim id to dictionary <channelUUID, primUUID> | 162 | * the prim id to dictionary <channelUUID, primUUID> |
163 | * | 163 | * |
164 | * First check if there is a channel assigned for | 164 | * First check if there is a channel assigned for |
165 | * this itemID. If there is, then someone called | 165 | * this itemID. If there is, then someone called |
166 | * llOpenRemoteDataChannel twice. Just return the | 166 | * llOpenRemoteDataChannel twice. Just return the |
167 | * original channel. Other option is to delete the | 167 | * original channel. Other option is to delete the |
168 | * current channel and assign a new one. | 168 | * current channel and assign a new one. |
169 | * | 169 | * |
170 | * ********************************************/ | 170 | * ********************************************/ |
171 | 171 | ||
172 | public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID) | 172 | public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID) |
173 | { | 173 | { |
174 | LLUUID channel = new LLUUID(); | 174 | LLUUID channel = new LLUUID(); |
175 | 175 | ||
176 | //Is a dupe? | 176 | //Is a dupe? |
177 | foreach (RPCChannelInfo ci in m_openChannels.Values) | 177 | foreach (RPCChannelInfo ci in m_openChannels.Values) |
178 | { | 178 | { |
179 | if (ci.GetItemID().Equals(itemID)) | 179 | if (ci.GetItemID().Equals(itemID)) |
180 | { | 180 | { |
181 | // return the original channel ID for this item | 181 | // return the original channel ID for this item |
182 | channel = ci.GetChannelID(); | 182 | channel = ci.GetChannelID(); |
183 | break; | 183 | break; |
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | if (channel == LLUUID.Zero) | 187 | if (channel == LLUUID.Zero) |
188 | { | 188 | { |
189 | channel = LLUUID.Random(); | 189 | channel = LLUUID.Random(); |
190 | RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel); | 190 | RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel); |
191 | lock (XMLRPCListLock) | 191 | lock (XMLRPCListLock) |
192 | { | 192 | { |
193 | m_openChannels.Add(channel, rpcChanInfo); | 193 | m_openChannels.Add(channel, rpcChanInfo); |
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
197 | return channel; | 197 | return channel; |
198 | } | 198 | } |
199 | 199 | ||
200 | // Delete channels based on itemID | 200 | // Delete channels based on itemID |
201 | // for when a script is deleted | 201 | // for when a script is deleted |
202 | public void DeleteChannels(LLUUID itemID) | 202 | public void DeleteChannels(LLUUID itemID) |
203 | { | 203 | { |
204 | if (m_openChannels != null) | 204 | if (m_openChannels != null) |
205 | { | 205 | { |
206 | ArrayList tmp = new ArrayList(); | 206 | ArrayList tmp = new ArrayList(); |
207 | 207 | ||
208 | lock (XMLRPCListLock) | 208 | lock (XMLRPCListLock) |
209 | { | 209 | { |
210 | foreach (RPCChannelInfo li in m_openChannels.Values) | 210 | foreach (RPCChannelInfo li in m_openChannels.Values) |
211 | { | 211 | { |
212 | if (li.GetItemID().Equals(itemID)) | 212 | if (li.GetItemID().Equals(itemID)) |
213 | { | 213 | { |
214 | tmp.Add(itemID); | 214 | tmp.Add(itemID); |
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | IEnumerator tmpEnumerator = tmp.GetEnumerator(); | 218 | IEnumerator tmpEnumerator = tmp.GetEnumerator(); |
219 | while (tmpEnumerator.MoveNext()) | 219 | while (tmpEnumerator.MoveNext()) |
220 | m_openChannels.Remove((LLUUID) tmpEnumerator.Current); | 220 | m_openChannels.Remove((LLUUID) tmpEnumerator.Current); |
221 | } | 221 | } |
222 | } | 222 | } |
223 | } | 223 | } |
224 | 224 | ||
225 | /********************************************** | 225 | /********************************************** |
226 | * Remote Data Reply | 226 | * Remote Data Reply |
227 | * | 227 | * |
228 | * Response to RPC message | 228 | * Response to RPC message |
229 | * | 229 | * |
230 | *********************************************/ | 230 | *********************************************/ |
231 | 231 | ||
232 | public void RemoteDataReply(string channel, string message_id, string sdata, int idata) | 232 | public void RemoteDataReply(string channel, string message_id, string sdata, int idata) |
233 | { | 233 | { |
234 | RPCRequestInfo rpcInfo; | 234 | RPCRequestInfo rpcInfo; |
235 | LLUUID message_key = new LLUUID(message_id); | 235 | LLUUID message_key = new LLUUID(message_id); |
236 | 236 | ||
237 | if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo)) | 237 | if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo)) |
238 | { | 238 | { |
239 | rpcInfo.SetStrRetval(sdata); | 239 | rpcInfo.SetStrRetval(sdata); |
240 | rpcInfo.SetIntRetval(idata); | 240 | rpcInfo.SetIntRetval(idata); |
241 | rpcInfo.SetProcessed(true); | 241 | rpcInfo.SetProcessed(true); |
242 | m_rpcPendingResponses.Remove(message_key); | 242 | m_rpcPendingResponses.Remove(message_key); |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | /********************************************** | 246 | /********************************************** |
247 | * CloseXMLRPCChannel | 247 | * CloseXMLRPCChannel |
248 | * | 248 | * |
249 | * Remove channel from dictionary | 249 | * Remove channel from dictionary |
250 | * | 250 | * |
251 | *********************************************/ | 251 | *********************************************/ |
252 | 252 | ||
253 | public void CloseXMLRPCChannel(LLUUID channelKey) | 253 | public void CloseXMLRPCChannel(LLUUID channelKey) |
254 | { | 254 | { |
255 | if (m_openChannels.ContainsKey(channelKey)) | 255 | if (m_openChannels.ContainsKey(channelKey)) |
256 | m_openChannels.Remove(channelKey); | 256 | m_openChannels.Remove(channelKey); |
257 | } | 257 | } |
258 | 258 | ||
259 | 259 | ||
260 | public bool hasRequests() | 260 | public bool hasRequests() |
261 | { | 261 | { |
262 | lock (XMLRPCListLock) | 262 | lock (XMLRPCListLock) |
263 | { | 263 | { |
264 | if (m_rpcPending != null) | 264 | if (m_rpcPending != null) |
265 | return (m_rpcPending.Count > 0); | 265 | return (m_rpcPending.Count > 0); |
266 | else | 266 | else |
267 | return false; | 267 | return false; |
268 | } | 268 | } |
269 | } | 269 | } |
270 | 270 | ||
271 | public RPCRequestInfo GetNextCompletedRequest() | 271 | public RPCRequestInfo GetNextCompletedRequest() |
272 | { | 272 | { |
273 | if (m_rpcPending != null) | 273 | if (m_rpcPending != null) |
274 | { | 274 | { |
275 | lock (XMLRPCListLock) | 275 | lock (XMLRPCListLock) |
276 | { | 276 | { |
277 | foreach (LLUUID luid in m_rpcPending.Keys) | 277 | foreach (LLUUID luid in m_rpcPending.Keys) |
278 | { | 278 | { |
279 | RPCRequestInfo tmpReq; | 279 | RPCRequestInfo tmpReq; |
280 | 280 | ||
281 | if (m_rpcPending.TryGetValue(luid, out tmpReq)) | 281 | if (m_rpcPending.TryGetValue(luid, out tmpReq)) |
282 | { | 282 | { |
283 | if (!tmpReq.IsProcessed()) return tmpReq; | 283 | if (!tmpReq.IsProcessed()) return tmpReq; |
284 | } | 284 | } |
285 | } | 285 | } |
286 | } | 286 | } |
287 | } | 287 | } |
288 | return null; | 288 | return null; |
289 | } | 289 | } |
290 | 290 | ||
291 | public void RemoveCompletedRequest(LLUUID id) | 291 | public void RemoveCompletedRequest(LLUUID id) |
292 | { | 292 | { |
293 | lock (XMLRPCListLock) | 293 | lock (XMLRPCListLock) |
294 | { | 294 | { |
295 | RPCRequestInfo tmp; | 295 | RPCRequestInfo tmp; |
296 | if (m_rpcPending.TryGetValue(id, out tmp)) | 296 | if (m_rpcPending.TryGetValue(id, out tmp)) |
297 | { | 297 | { |
298 | m_rpcPending.Remove(id); | 298 | m_rpcPending.Remove(id); |
299 | m_rpcPendingResponses.Add(id, tmp); | 299 | m_rpcPendingResponses.Add(id, tmp); |
300 | } | 300 | } |
301 | else | 301 | else |
302 | { | 302 | { |
303 | Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST"); | 303 | Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST"); |
304 | } | 304 | } |
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
308 | public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) | 308 | public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) |
309 | { | 309 | { |
310 | SendRemoteDataRequest req = new SendRemoteDataRequest( | 310 | SendRemoteDataRequest req = new SendRemoteDataRequest( |
311 | localID, itemID, channel, dest, idata, sdata | 311 | localID, itemID, channel, dest, idata, sdata |
312 | ); | 312 | ); |
313 | m_pendingSRDResponses.Add(req.GetReqID(), req); | 313 | m_pendingSRDResponses.Add(req.GetReqID(), req); |
314 | return req.process(); | 314 | return req.process(); |
315 | } | 315 | } |
316 | 316 | ||
317 | public SendRemoteDataRequest GetNextCompletedSRDRequest() | 317 | public SendRemoteDataRequest GetNextCompletedSRDRequest() |
318 | { | 318 | { |
319 | if (m_pendingSRDResponses != null) | 319 | if (m_pendingSRDResponses != null) |
320 | { | 320 | { |
321 | lock (XMLRPCListLock) | 321 | lock (XMLRPCListLock) |
322 | { | 322 | { |
323 | foreach (LLUUID luid in m_pendingSRDResponses.Keys) | 323 | foreach (LLUUID luid in m_pendingSRDResponses.Keys) |
324 | { | 324 | { |
325 | SendRemoteDataRequest tmpReq; | 325 | SendRemoteDataRequest tmpReq; |
326 | 326 | ||
327 | if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq)) | 327 | if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq)) |
328 | { | 328 | { |
329 | if (tmpReq.finished) | 329 | if (tmpReq.finished) |
330 | return tmpReq; | 330 | return tmpReq; |
331 | } | 331 | } |
332 | } | 332 | } |
333 | } | 333 | } |
334 | } | 334 | } |
335 | return null; | 335 | return null; |
336 | } | 336 | } |
337 | 337 | ||
338 | public void RemoveCompletedSRDRequest(LLUUID id) | 338 | public void RemoveCompletedSRDRequest(LLUUID id) |
339 | { | 339 | { |
340 | lock (XMLRPCListLock) | 340 | lock (XMLRPCListLock) |
341 | { | 341 | { |
342 | SendRemoteDataRequest tmpReq; | 342 | SendRemoteDataRequest tmpReq; |
343 | if (m_pendingSRDResponses.TryGetValue(id, out tmpReq)) | 343 | if (m_pendingSRDResponses.TryGetValue(id, out tmpReq)) |
344 | { | 344 | { |
345 | m_pendingSRDResponses.Remove(id); | 345 | m_pendingSRDResponses.Remove(id); |
346 | } | 346 | } |
347 | } | 347 | } |
348 | } | 348 | } |
349 | 349 | ||
350 | public void CancelSRDRequests(LLUUID itemID) | 350 | public void CancelSRDRequests(LLUUID itemID) |
351 | { | 351 | { |
352 | if (m_pendingSRDResponses != null) | 352 | if (m_pendingSRDResponses != null) |
353 | { | 353 | { |
354 | lock (XMLRPCListLock) | 354 | lock (XMLRPCListLock) |
355 | { | 355 | { |
356 | foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values) | 356 | foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values) |
357 | { | 357 | { |
358 | if (li.m_itemID.Equals(itemID)) | 358 | if (li.m_itemID.Equals(itemID)) |
359 | m_pendingSRDResponses.Remove(li.GetReqID()); | 359 | m_pendingSRDResponses.Remove(li.GetReqID()); |
360 | } | 360 | } |
361 | } | 361 | } |
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
365 | #endregion | 365 | #endregion |
366 | 366 | ||
367 | public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request) | 367 | public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request) |
368 | { | 368 | { |
369 | XmlRpcResponse response = new XmlRpcResponse(); | 369 | XmlRpcResponse response = new XmlRpcResponse(); |
370 | 370 | ||
371 | Hashtable requestData = (Hashtable) request.Params[0]; | 371 | Hashtable requestData = (Hashtable) request.Params[0]; |
372 | bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && | 372 | bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && |
373 | requestData.Contains("StringValue")); | 373 | requestData.Contains("StringValue")); |
374 | 374 | ||
375 | if (GoodXML) | 375 | if (GoodXML) |
376 | { | 376 | { |
377 | LLUUID channel = new LLUUID((string) requestData["Channel"]); | 377 | LLUUID channel = new LLUUID((string) requestData["Channel"]); |
378 | RPCChannelInfo rpcChanInfo; | 378 | RPCChannelInfo rpcChanInfo; |
379 | if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) | 379 | if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) |
380 | { | 380 | { |
381 | string intVal = (string) requestData["IntValue"]; | 381 | string intVal = (string) requestData["IntValue"]; |
382 | string strVal = (string) requestData["StringValue"]; | 382 | string strVal = (string) requestData["StringValue"]; |
383 | 383 | ||
384 | RPCRequestInfo rpcInfo; | 384 | RPCRequestInfo rpcInfo; |
385 | 385 | ||
386 | lock (XMLRPCListLock) | 386 | lock (XMLRPCListLock) |
387 | { | 387 | { |
388 | rpcInfo = | 388 | rpcInfo = |
389 | new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, | 389 | new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, |
390 | intVal); | 390 | intVal); |
391 | m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo); | 391 | m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo); |
392 | } | 392 | } |
393 | 393 | ||
394 | int timeoutCtr = 0; | 394 | int timeoutCtr = 0; |
395 | 395 | ||
396 | while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout)) | 396 | while (!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout)) |
397 | { | 397 | { |
398 | Thread.Sleep(RemoteReplyScriptWait); | 398 | Thread.Sleep(RemoteReplyScriptWait); |
399 | timeoutCtr += RemoteReplyScriptWait; | 399 | timeoutCtr += RemoteReplyScriptWait; |
400 | } | 400 | } |
401 | if (rpcInfo.IsProcessed()) | 401 | if (rpcInfo.IsProcessed()) |
402 | { | 402 | { |
403 | Hashtable param = new Hashtable(); | 403 | Hashtable param = new Hashtable(); |
404 | param["StringValue"] = rpcInfo.GetStrRetval(); | 404 | param["StringValue"] = rpcInfo.GetStrRetval(); |
405 | param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval()); | 405 | param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval()); |
406 | 406 | ||
407 | ArrayList parameters = new ArrayList(); | 407 | ArrayList parameters = new ArrayList(); |
408 | parameters.Add(param); | 408 | parameters.Add(param); |
409 | 409 | ||
410 | response.Value = parameters; | 410 | response.Value = parameters; |
411 | rpcInfo = null; | 411 | rpcInfo = null; |
412 | } | 412 | } |
413 | else | 413 | else |
414 | { | 414 | { |
415 | response.SetFault(-1, "Script timeout"); | 415 | response.SetFault(-1, "Script timeout"); |
416 | rpcInfo = null; | 416 | rpcInfo = null; |
417 | } | 417 | } |
418 | } | 418 | } |
419 | else | 419 | else |
420 | { | 420 | { |
421 | response.SetFault(-1, "Invalid channel"); | 421 | response.SetFault(-1, "Invalid channel"); |
422 | } | 422 | } |
423 | } | 423 | } |
424 | 424 | ||
425 | return response; | 425 | return response; |
426 | } | 426 | } |
427 | } | 427 | } |
428 | 428 | ||
429 | public class RPCRequestInfo | 429 | public class RPCRequestInfo |
430 | { | 430 | { |
431 | private LLUUID m_ChannelKey; | 431 | private LLUUID m_ChannelKey; |
432 | private string m_IntVal; | 432 | private string m_IntVal; |
433 | private LLUUID m_ItemID; | 433 | private LLUUID m_ItemID; |
434 | private uint m_localID; | 434 | private uint m_localID; |
435 | private LLUUID m_MessageID; | 435 | private LLUUID m_MessageID; |
436 | private bool m_processed; | 436 | private bool m_processed; |
437 | private int m_respInt; | 437 | private int m_respInt; |
438 | private string m_respStr; | 438 | private string m_respStr; |
439 | private string m_StrVal; | 439 | private string m_StrVal; |
440 | 440 | ||
441 | public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal) | 441 | public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal) |
442 | { | 442 | { |
443 | m_localID = localID; | 443 | m_localID = localID; |
444 | m_StrVal = strVal; | 444 | m_StrVal = strVal; |
445 | m_IntVal = intVal; | 445 | m_IntVal = intVal; |
446 | m_ItemID = itemID; | 446 | m_ItemID = itemID; |
447 | m_ChannelKey = channelKey; | 447 | m_ChannelKey = channelKey; |
448 | m_MessageID = LLUUID.Random(); | 448 | m_MessageID = LLUUID.Random(); |
449 | m_processed = false; | 449 | m_processed = false; |
450 | m_respStr = String.Empty; | 450 | m_respStr = String.Empty; |
451 | m_respInt = 0; | 451 | m_respInt = 0; |
452 | } | 452 | } |
453 | 453 | ||
454 | public bool IsProcessed() | 454 | public bool IsProcessed() |
455 | { | 455 | { |
456 | return m_processed; | 456 | return m_processed; |
457 | } | 457 | } |
458 | 458 | ||
459 | public LLUUID GetChannelKey() | 459 | public LLUUID GetChannelKey() |
460 | { | 460 | { |
461 | return m_ChannelKey; | 461 | return m_ChannelKey; |
462 | } | 462 | } |
463 | 463 | ||
464 | public void SetProcessed(bool processed) | 464 | public void SetProcessed(bool processed) |
465 | { | 465 | { |
466 | m_processed = processed; | 466 | m_processed = processed; |
467 | } | 467 | } |
468 | 468 | ||
469 | public void SetStrRetval(string resp) | 469 | public void SetStrRetval(string resp) |
470 | { | 470 | { |
471 | m_respStr = resp; | 471 | m_respStr = resp; |
472 | } | 472 | } |
473 | 473 | ||
474 | public string GetStrRetval() | 474 | public string GetStrRetval() |
475 | { | 475 | { |
476 | return m_respStr; | 476 | return m_respStr; |
477 | } | 477 | } |
478 | 478 | ||
479 | public void SetIntRetval(int resp) | 479 | public void SetIntRetval(int resp) |
480 | { | 480 | { |
481 | m_respInt = resp; | 481 | m_respInt = resp; |
482 | } | 482 | } |
483 | 483 | ||
484 | public int GetIntRetval() | 484 | public int GetIntRetval() |
485 | { | 485 | { |
486 | return m_respInt; | 486 | return m_respInt; |
487 | } | 487 | } |
488 | 488 | ||
489 | public uint GetLocalID() | 489 | public uint GetLocalID() |
490 | { | 490 | { |
491 | return m_localID; | 491 | return m_localID; |
492 | } | 492 | } |
493 | 493 | ||
494 | public LLUUID GetItemID() | 494 | public LLUUID GetItemID() |
495 | { | 495 | { |
496 | return m_ItemID; | 496 | return m_ItemID; |
497 | } | 497 | } |
498 | 498 | ||
499 | public string GetStrVal() | 499 | public string GetStrVal() |
500 | { | 500 | { |
501 | return m_StrVal; | 501 | return m_StrVal; |
502 | } | 502 | } |
503 | 503 | ||
504 | public int GetIntValue() | 504 | public int GetIntValue() |
505 | { | 505 | { |
506 | return int.Parse(m_IntVal); | 506 | return int.Parse(m_IntVal); |
507 | } | 507 | } |
508 | 508 | ||
509 | public LLUUID GetMessageID() | 509 | public LLUUID GetMessageID() |
510 | { | 510 | { |
511 | return m_MessageID; | 511 | return m_MessageID; |
512 | } | 512 | } |
513 | } | 513 | } |
514 | 514 | ||
515 | public class RPCChannelInfo | 515 | public class RPCChannelInfo |
516 | { | 516 | { |
517 | private LLUUID m_ChannelKey; | 517 | private LLUUID m_ChannelKey; |
518 | private LLUUID m_itemID; | 518 | private LLUUID m_itemID; |
519 | private uint m_localID; | 519 | private uint m_localID; |
520 | 520 | ||
521 | public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID) | 521 | public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID) |
522 | { | 522 | { |
523 | m_ChannelKey = channelID; | 523 | m_ChannelKey = channelID; |
524 | m_localID = localID; | 524 | m_localID = localID; |
525 | m_itemID = itemID; | 525 | m_itemID = itemID; |
526 | } | 526 | } |
527 | 527 | ||
528 | public LLUUID GetItemID() | 528 | public LLUUID GetItemID() |
529 | { | 529 | { |
530 | return m_itemID; | 530 | return m_itemID; |
531 | } | 531 | } |
532 | 532 | ||
533 | public LLUUID GetChannelID() | 533 | public LLUUID GetChannelID() |
534 | { | 534 | { |
535 | return m_ChannelKey; | 535 | return m_ChannelKey; |
536 | } | 536 | } |
537 | 537 | ||
538 | public uint GetLocalID() | 538 | public uint GetLocalID() |
539 | { | 539 | { |
540 | return m_localID; | 540 | return m_localID; |
541 | } | 541 | } |
542 | } | 542 | } |
543 | 543 | ||
544 | public class SendRemoteDataRequest | 544 | public class SendRemoteDataRequest |
545 | { | 545 | { |
546 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 546 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
547 | public string channel; | 547 | public string channel; |
548 | public string destURL; | 548 | public string destURL; |
549 | public bool finished; | 549 | public bool finished; |
550 | private Thread httpThread; | 550 | private Thread httpThread; |
551 | public int idata; | 551 | public int idata; |
552 | public LLUUID m_itemID; | 552 | public LLUUID m_itemID; |
553 | public uint m_localID; | 553 | public uint m_localID; |
554 | public LLUUID reqID; | 554 | public LLUUID reqID; |
555 | public XmlRpcRequest request; | 555 | public XmlRpcRequest request; |
556 | public int response_idata; | 556 | public int response_idata; |
557 | public string response_sdata; | 557 | public string response_sdata; |
558 | public string sdata; | 558 | public string sdata; |
559 | 559 | ||
560 | public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) | 560 | public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata) |
561 | { | 561 | { |
562 | this.channel = channel; | 562 | this.channel = channel; |
563 | destURL = dest; | 563 | destURL = dest; |
564 | this.idata = idata; | 564 | this.idata = idata; |
565 | this.sdata = sdata; | 565 | this.sdata = sdata; |
566 | m_itemID = itemID; | 566 | m_itemID = itemID; |
567 | m_localID = localID; | 567 | m_localID = localID; |
568 | 568 | ||
569 | reqID = LLUUID.Random(); | 569 | reqID = LLUUID.Random(); |
570 | } | 570 | } |
571 | 571 | ||
572 | public LLUUID process() | 572 | public LLUUID process() |
573 | { | 573 | { |
574 | httpThread = new Thread(SendRequest); | 574 | httpThread = new Thread(SendRequest); |
575 | httpThread.Name = "HttpRequestThread"; | 575 | httpThread.Name = "HttpRequestThread"; |
576 | httpThread.Priority = ThreadPriority.BelowNormal; | 576 | httpThread.Priority = ThreadPriority.BelowNormal; |
577 | httpThread.IsBackground = true; | 577 | httpThread.IsBackground = true; |
578 | finished = false; | 578 | finished = false; |
579 | httpThread.Start(); | 579 | httpThread.Start(); |
580 | ThreadTracker.Add(httpThread); | 580 | ThreadTracker.Add(httpThread); |
581 | 581 | ||
582 | return reqID; | 582 | return reqID; |
583 | } | 583 | } |
584 | 584 | ||
585 | /* | 585 | /* |
586 | * TODO: More work on the response codes. Right now | 586 | * TODO: More work on the response codes. Right now |
587 | * returning 200 for success or 499 for exception | 587 | * returning 200 for success or 499 for exception |
588 | */ | 588 | */ |
589 | 589 | ||
590 | public void SendRequest() | 590 | public void SendRequest() |
591 | { | 591 | { |
592 | Hashtable param = new Hashtable(); | 592 | Hashtable param = new Hashtable(); |
593 | 593 | ||
594 | // Check if channel is an LLUUID | 594 | // Check if channel is an LLUUID |
595 | // if not, use as method name | 595 | // if not, use as method name |
596 | LLUUID parseUID; | 596 | LLUUID parseUID; |
597 | string mName = "llRemoteData"; | 597 | string mName = "llRemoteData"; |
598 | if ((channel != null) && (channel != "")) | 598 | if ((channel != null) && (channel != "")) |
599 | if (!LLUUID.TryParse(channel, out parseUID)) | 599 | if (!LLUUID.TryParse(channel, out parseUID)) |
600 | mName = channel; | 600 | mName = channel; |
601 | else | 601 | else |
602 | param["Channel"] = channel; | 602 | param["Channel"] = channel; |
603 | 603 | ||
604 | param["StringValue"] = sdata; | 604 | param["StringValue"] = sdata; |
605 | param["IntValue"] = Convert.ToString(idata); | 605 | param["IntValue"] = Convert.ToString(idata); |
606 | 606 | ||
607 | ArrayList parameters = new ArrayList(); | 607 | ArrayList parameters = new ArrayList(); |
608 | parameters.Add(param); | 608 | parameters.Add(param); |
609 | XmlRpcRequest req = new XmlRpcRequest(mName, parameters); | 609 | XmlRpcRequest req = new XmlRpcRequest(mName, parameters); |
610 | try | 610 | try |
611 | { | 611 | { |
612 | XmlRpcResponse resp = req.Send(destURL, 30000); | 612 | XmlRpcResponse resp = req.Send(destURL, 30000); |
613 | if (resp != null) | 613 | if (resp != null) |
614 | { | 614 | { |
615 | Hashtable respParms; | 615 | Hashtable respParms; |
616 | if (resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) | 616 | if (resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) |
617 | { | 617 | { |
618 | respParms = (Hashtable) resp.Value; | 618 | respParms = (Hashtable) resp.Value; |
619 | } | 619 | } |
620 | else | 620 | else |
621 | { | 621 | { |
622 | ArrayList respData = (ArrayList) resp.Value; | 622 | ArrayList respData = (ArrayList) resp.Value; |
623 | respParms = (Hashtable) respData[0]; | 623 | respParms = (Hashtable) respData[0]; |
624 | } | 624 | } |
625 | if (respParms != null) | 625 | if (respParms != null) |
626 | { | 626 | { |
627 | if (respParms.Contains("StringValue")) | 627 | if (respParms.Contains("StringValue")) |
628 | { | 628 | { |
629 | sdata = (string) respParms["StringValue"]; | 629 | sdata = (string) respParms["StringValue"]; |
630 | } | 630 | } |
631 | if (respParms.Contains("IntValue")) | 631 | if (respParms.Contains("IntValue")) |
632 | { | 632 | { |
633 | idata = Convert.ToInt32((string) respParms["IntValue"]); | 633 | idata = Convert.ToInt32((string) respParms["IntValue"]); |
634 | } | 634 | } |
635 | if (respParms.Contains("faultString")) | 635 | if (respParms.Contains("faultString")) |
636 | { | 636 | { |
637 | sdata = (string) respParms["faultString"]; | 637 | sdata = (string) respParms["faultString"]; |
638 | } | 638 | } |
639 | if (respParms.Contains("faultCode")) | 639 | if (respParms.Contains("faultCode")) |
640 | { | 640 | { |
641 | idata = Convert.ToInt32(respParms["faultCode"]); | 641 | idata = Convert.ToInt32(respParms["faultCode"]); |
642 | } | 642 | } |
643 | } | 643 | } |
644 | } | 644 | } |
645 | } | 645 | } |
646 | catch (WebException we) | 646 | catch (WebException we) |
647 | { | 647 | { |
648 | sdata = we.Message; | 648 | sdata = we.Message; |
649 | m_log.Warn("[SendRemoteDataRequest]: Request failed"); | 649 | m_log.Warn("[SendRemoteDataRequest]: Request failed"); |
650 | m_log.Warn(we.StackTrace); | 650 | m_log.Warn(we.StackTrace); |
651 | } | 651 | } |
652 | 652 | ||
653 | finished = true; | 653 | finished = true; |
654 | } | 654 | } |
655 | 655 | ||
656 | public void Stop() | 656 | public void Stop() |
657 | { | 657 | { |
658 | try | 658 | try |
659 | { | 659 | { |
660 | httpThread.Abort(); | 660 | httpThread.Abort(); |
661 | } | 661 | } |
662 | catch (Exception) | 662 | catch (Exception) |
663 | { | 663 | { |
664 | } | 664 | } |
665 | } | 665 | } |
666 | 666 | ||
667 | public LLUUID GetReqID() | 667 | public LLUUID GetReqID() |
668 | { | 668 | { |
669 | return reqID; | 669 | return reqID; |
670 | } | 670 | } |
671 | } | 671 | } |
672 | } \ No newline at end of file | 672 | } \ No newline at end of file |