diff options
author | Diva Canto | 2013-06-08 11:01:20 -0700 |
---|---|---|
committer | Diva Canto | 2013-06-08 11:01:20 -0700 |
commit | 4e2e69bd250524710c4026f457141fc72adf70ac (patch) | |
tree | 981a2a5e11a93f8efdea0834b1c9ff9105c03061 | |
parent | Groups V2 -- fix mantis #6666 (diff) | |
parent | Catch exception triggered by incoming avatars using legacy profiles (diff) | |
download | opensim-SC-4e2e69bd250524710c4026f457141fc72adf70ac.zip opensim-SC-4e2e69bd250524710c4026f457141fc72adf70ac.tar.gz opensim-SC-4e2e69bd250524710c4026f457141fc72adf70ac.tar.bz2 opensim-SC-4e2e69bd250524710c4026f457141fc72adf70ac.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
13 files changed, 1231 insertions, 241 deletions
diff --git a/OpenSim/Data/SQLite/Resources/UserProfiles.migrations b/OpenSim/Data/SQLite/Resources/UserProfiles.migrations new file mode 100644 index 0000000..16581f6 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/UserProfiles.migrations | |||
@@ -0,0 +1,90 @@ | |||
1 | :VERSION 1 # ------------------------------- | ||
2 | |||
3 | begin; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS classifieds ( | ||
6 | classifieduuid char(36) NOT NULL PRIMARY KEY, | ||
7 | creatoruuid char(36) NOT NULL, | ||
8 | creationdate int(20) NOT NULL, | ||
9 | expirationdate int(20) NOT NULL, | ||
10 | category varchar(20) NOT NULL, | ||
11 | name varchar(255) NOT NULL, | ||
12 | description text NOT NULL, | ||
13 | parceluuid char(36) NOT NULL, | ||
14 | parentestate int(11) NOT NULL, | ||
15 | snapshotuuid char(36) NOT NULL, | ||
16 | simname varchar(255) NOT NULL, | ||
17 | posglobal varchar(255) NOT NULL, | ||
18 | parcelname varchar(255) NOT NULL, | ||
19 | classifiedflags int(8) NOT NULL, | ||
20 | priceforlisting int(5) NOT NULL | ||
21 | ); | ||
22 | |||
23 | commit; | ||
24 | |||
25 | begin; | ||
26 | |||
27 | CREATE TABLE IF NOT EXISTS usernotes ( | ||
28 | useruuid varchar(36) NOT NULL, | ||
29 | targetuuid varchar(36) NOT NULL, | ||
30 | notes text NOT NULL, | ||
31 | UNIQUE (useruuid,targetuuid) ON CONFLICT REPLACE | ||
32 | ); | ||
33 | |||
34 | commit; | ||
35 | |||
36 | begin; | ||
37 | |||
38 | CREATE TABLE IF NOT EXISTS userpicks ( | ||
39 | pickuuid varchar(36) NOT NULL PRIMARY KEY, | ||
40 | creatoruuid varchar(36) NOT NULL, | ||
41 | toppick int NOT NULL, | ||
42 | parceluuid varchar(36) NOT NULL, | ||
43 | name varchar(255) NOT NULL, | ||
44 | description text NOT NULL, | ||
45 | snapshotuuid varchar(36) NOT NULL, | ||
46 | user varchar(255) NOT NULL, | ||
47 | originalname varchar(255) NOT NULL, | ||
48 | simname varchar(255) NOT NULL, | ||
49 | posglobal varchar(255) NOT NULL, | ||
50 | sortorder int(2) NOT NULL, | ||
51 | enabled int NOT NULL | ||
52 | ); | ||
53 | |||
54 | commit; | ||
55 | |||
56 | begin; | ||
57 | |||
58 | CREATE TABLE IF NOT EXISTS userprofile ( | ||
59 | useruuid varchar(36) NOT NULL PRIMARY KEY, | ||
60 | profilePartner varchar(36) NOT NULL, | ||
61 | profileAllowPublish binary(1) NOT NULL, | ||
62 | profileMaturePublish binary(1) NOT NULL, | ||
63 | profileURL varchar(255) NOT NULL, | ||
64 | profileWantToMask int(3) NOT NULL, | ||
65 | profileWantToText text NOT NULL, | ||
66 | profileSkillsMask int(3) NOT NULL, | ||
67 | profileSkillsText text NOT NULL, | ||
68 | profileLanguages text NOT NULL, | ||
69 | profileImage varchar(36) NOT NULL, | ||
70 | profileAboutText text NOT NULL, | ||
71 | profileFirstImage varchar(36) NOT NULL, | ||
72 | profileFirstText text NOT NULL | ||
73 | ); | ||
74 | |||
75 | commit; | ||
76 | |||
77 | :VERSION 2 # ------------------------------- | ||
78 | |||
79 | begin; | ||
80 | |||
81 | CREATE TABLE IF NOT EXISTS userdata ( | ||
82 | UserId char(36) NOT NULL, | ||
83 | TagId varchar(64) NOT NULL, | ||
84 | DataKey varchar(255), | ||
85 | DataVal varchar(255), | ||
86 | PRIMARY KEY (UserId,TagId) | ||
87 | ); | ||
88 | |||
89 | commit; | ||
90 | |||
diff --git a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs new file mode 100644 index 0000000..cc1dac1 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs | |||
@@ -0,0 +1,904 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | #if CSharpSqlite | ||
34 | using Community.CsharpSqlite.Sqlite; | ||
35 | #else | ||
36 | using Mono.Data.Sqlite; | ||
37 | #endif | ||
38 | using OpenMetaverse; | ||
39 | using OpenMetaverse.StructuredData; | ||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | |||
43 | namespace OpenSim.Data.SQLite | ||
44 | { | ||
45 | public class SQLiteUserProfilesData: IProfilesData | ||
46 | { | ||
47 | private static readonly ILog m_log = | ||
48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private SqliteConnection m_connection; | ||
51 | private string m_connectionString; | ||
52 | |||
53 | private FieldInfo[] m_Fields; | ||
54 | private Dictionary<string, FieldInfo> m_FieldMap = | ||
55 | new Dictionary<string, FieldInfo>(); | ||
56 | |||
57 | protected virtual Assembly Assembly | ||
58 | { | ||
59 | get { return GetType().Assembly; } | ||
60 | } | ||
61 | |||
62 | public SQLiteUserProfilesData() | ||
63 | { | ||
64 | } | ||
65 | |||
66 | public SQLiteUserProfilesData(string connectionString) | ||
67 | { | ||
68 | Initialise(connectionString); | ||
69 | } | ||
70 | |||
71 | public void Initialise(string connectionString) | ||
72 | { | ||
73 | if (Util.IsWindows()) | ||
74 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
75 | |||
76 | m_connectionString = connectionString; | ||
77 | |||
78 | m_log.Info("[PROFILES_DATA]: Sqlite - connecting: "+m_connectionString); | ||
79 | |||
80 | m_connection = new SqliteConnection(m_connectionString); | ||
81 | m_connection.Open(); | ||
82 | |||
83 | Migration m = new Migration(m_connection, Assembly, "UserProfiles"); | ||
84 | m.Update(); | ||
85 | } | ||
86 | |||
87 | private string[] FieldList | ||
88 | { | ||
89 | get { return new List<string>(m_FieldMap.Keys).ToArray(); } | ||
90 | } | ||
91 | |||
92 | #region IProfilesData implementation | ||
93 | public OSDArray GetClassifiedRecords(UUID creatorId) | ||
94 | { | ||
95 | OSDArray data = new OSDArray(); | ||
96 | string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = :Id"; | ||
97 | IDataReader reader = null; | ||
98 | |||
99 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
100 | { | ||
101 | cmd.CommandText = query; | ||
102 | cmd.Parameters.AddWithValue(":Id", creatorId); | ||
103 | reader = cmd.ExecuteReader(); | ||
104 | } | ||
105 | |||
106 | while (reader.Read()) | ||
107 | { | ||
108 | OSDMap n = new OSDMap(); | ||
109 | UUID Id = UUID.Zero; | ||
110 | string Name = null; | ||
111 | try | ||
112 | { | ||
113 | UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id); | ||
114 | Name = Convert.ToString(reader["name"]); | ||
115 | } | ||
116 | catch (Exception e) | ||
117 | { | ||
118 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
119 | ": UserAccount exception {0}", e.Message); | ||
120 | } | ||
121 | n.Add("classifieduuid", OSD.FromUUID(Id)); | ||
122 | n.Add("name", OSD.FromString(Name)); | ||
123 | data.Add(n); | ||
124 | } | ||
125 | |||
126 | reader.Close(); | ||
127 | |||
128 | return data; | ||
129 | } | ||
130 | public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) | ||
131 | { | ||
132 | string query = string.Empty; | ||
133 | |||
134 | query += "INSERT OR REPLACE INTO classifieds ("; | ||
135 | query += "`classifieduuid`,"; | ||
136 | query += "`creatoruuid`,"; | ||
137 | query += "`creationdate`,"; | ||
138 | query += "`expirationdate`,"; | ||
139 | query += "`category`,"; | ||
140 | query += "`name`,"; | ||
141 | query += "`description`,"; | ||
142 | query += "`parceluuid`,"; | ||
143 | query += "`parentestate`,"; | ||
144 | query += "`snapshotuuid`,"; | ||
145 | query += "`simname`,"; | ||
146 | query += "`posglobal`,"; | ||
147 | query += "`parcelname`,"; | ||
148 | query += "`classifiedflags`,"; | ||
149 | query += "`priceforlisting`) "; | ||
150 | query += "VALUES ("; | ||
151 | query += ":ClassifiedId,"; | ||
152 | query += ":CreatorId,"; | ||
153 | query += ":CreatedDate,"; | ||
154 | query += ":ExpirationDate,"; | ||
155 | query += ":Category,"; | ||
156 | query += ":Name,"; | ||
157 | query += ":Description,"; | ||
158 | query += ":ParcelId,"; | ||
159 | query += ":ParentEstate,"; | ||
160 | query += ":SnapshotId,"; | ||
161 | query += ":SimName,"; | ||
162 | query += ":GlobalPos,"; | ||
163 | query += ":ParcelName,"; | ||
164 | query += ":Flags,"; | ||
165 | query += ":ListingPrice ) "; | ||
166 | |||
167 | if(string.IsNullOrEmpty(ad.ParcelName)) | ||
168 | ad.ParcelName = "Unknown"; | ||
169 | if(ad.ParcelId == null) | ||
170 | ad.ParcelId = UUID.Zero; | ||
171 | if(string.IsNullOrEmpty(ad.Description)) | ||
172 | ad.Description = "No Description"; | ||
173 | |||
174 | DateTime epoch = new DateTime(1970, 1, 1); | ||
175 | DateTime now = DateTime.Now; | ||
176 | TimeSpan epochnow = now - epoch; | ||
177 | TimeSpan duration; | ||
178 | DateTime expiration; | ||
179 | TimeSpan epochexp; | ||
180 | |||
181 | if(ad.Flags == 2) | ||
182 | { | ||
183 | duration = new TimeSpan(7,0,0,0); | ||
184 | expiration = now.Add(duration); | ||
185 | epochexp = expiration - epoch; | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | duration = new TimeSpan(365,0,0,0); | ||
190 | expiration = now.Add(duration); | ||
191 | epochexp = expiration - epoch; | ||
192 | } | ||
193 | ad.CreationDate = (int)epochnow.TotalSeconds; | ||
194 | ad.ExpirationDate = (int)epochexp.TotalSeconds; | ||
195 | |||
196 | try { | ||
197 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
198 | { | ||
199 | cmd.CommandText = query; | ||
200 | cmd.Parameters.AddWithValue(":ClassifiedId", ad.ClassifiedId.ToString()); | ||
201 | cmd.Parameters.AddWithValue(":CreatorId", ad.CreatorId.ToString()); | ||
202 | cmd.Parameters.AddWithValue(":CreatedDate", ad.CreationDate.ToString()); | ||
203 | cmd.Parameters.AddWithValue(":ExpirationDate", ad.ExpirationDate.ToString()); | ||
204 | cmd.Parameters.AddWithValue(":Category", ad.Category.ToString()); | ||
205 | cmd.Parameters.AddWithValue(":Name", ad.Name.ToString()); | ||
206 | cmd.Parameters.AddWithValue(":Description", ad.Description.ToString()); | ||
207 | cmd.Parameters.AddWithValue(":ParcelId", ad.ParcelId.ToString()); | ||
208 | cmd.Parameters.AddWithValue(":ParentEstate", ad.ParentEstate.ToString()); | ||
209 | cmd.Parameters.AddWithValue(":SnapshotId", ad.SnapshotId.ToString ()); | ||
210 | cmd.Parameters.AddWithValue(":SimName", ad.SimName.ToString()); | ||
211 | cmd.Parameters.AddWithValue(":GlobalPos", ad.GlobalPos.ToString()); | ||
212 | cmd.Parameters.AddWithValue(":ParcelName", ad.ParcelName.ToString()); | ||
213 | cmd.Parameters.AddWithValue(":Flags", ad.Flags.ToString()); | ||
214 | cmd.Parameters.AddWithValue(":ListingPrice", ad.Price.ToString ()); | ||
215 | |||
216 | cmd.ExecuteNonQuery(); | ||
217 | } | ||
218 | } | ||
219 | catch (Exception e) | ||
220 | { | ||
221 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
222 | ": ClassifiedesUpdate exception {0}", e.Message); | ||
223 | result = e.Message; | ||
224 | return false; | ||
225 | } | ||
226 | return true; | ||
227 | } | ||
228 | public bool DeleteClassifiedRecord(UUID recordId) | ||
229 | { | ||
230 | string query = string.Empty; | ||
231 | |||
232 | query += "DELETE FROM classifieds WHERE "; | ||
233 | query += "classifieduuid = :ClasifiedId"; | ||
234 | |||
235 | try | ||
236 | { | ||
237 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
238 | { | ||
239 | cmd.CommandText = query; | ||
240 | cmd.Parameters.AddWithValue(":ClassifiedId", recordId.ToString()); | ||
241 | |||
242 | cmd.ExecuteNonQuery(); | ||
243 | } | ||
244 | } | ||
245 | catch (Exception e) | ||
246 | { | ||
247 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
248 | ": DeleteClassifiedRecord exception {0}", e.Message); | ||
249 | return false; | ||
250 | } | ||
251 | return true; | ||
252 | } | ||
253 | |||
254 | public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) | ||
255 | { | ||
256 | IDataReader reader = null; | ||
257 | string query = string.Empty; | ||
258 | |||
259 | query += "SELECT * FROM classifieds WHERE "; | ||
260 | query += "classifieduuid = :AdId"; | ||
261 | |||
262 | try | ||
263 | { | ||
264 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
265 | { | ||
266 | cmd.CommandText = query; | ||
267 | cmd.Parameters.AddWithValue(":AdId", ad.ClassifiedId.ToString()); | ||
268 | |||
269 | using (reader = cmd.ExecuteReader()) | ||
270 | { | ||
271 | if(reader.Read ()) | ||
272 | { | ||
273 | ad.CreatorId = new UUID(reader["creatoruuid"].ToString()); | ||
274 | ad.ParcelId = new UUID(reader["parceluuid"].ToString ()); | ||
275 | ad.SnapshotId = new UUID(reader["snapshotuuid"].ToString ()); | ||
276 | ad.CreationDate = Convert.ToInt32(reader["creationdate"]); | ||
277 | ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]); | ||
278 | ad.ParentEstate = Convert.ToInt32(reader["parentestate"]); | ||
279 | ad.Flags = (byte) Convert.ToUInt32(reader["classifiedflags"]); | ||
280 | ad.Category = Convert.ToInt32(reader["category"]); | ||
281 | ad.Price = Convert.ToInt16(reader["priceforlisting"]); | ||
282 | ad.Name = reader["name"].ToString(); | ||
283 | ad.Description = reader["description"].ToString(); | ||
284 | ad.SimName = reader["simname"].ToString(); | ||
285 | ad.GlobalPos = reader["posglobal"].ToString(); | ||
286 | ad.ParcelName = reader["parcelname"].ToString(); | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | catch (Exception e) | ||
292 | { | ||
293 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
294 | ": GetPickInfo exception {0}", e.Message); | ||
295 | } | ||
296 | return true; | ||
297 | } | ||
298 | |||
299 | public OSDArray GetAvatarPicks(UUID avatarId) | ||
300 | { | ||
301 | IDataReader reader = null; | ||
302 | string query = string.Empty; | ||
303 | |||
304 | query += "SELECT `pickuuid`,`name` FROM userpicks WHERE "; | ||
305 | query += "creatoruuid = :Id"; | ||
306 | OSDArray data = new OSDArray(); | ||
307 | |||
308 | try | ||
309 | { | ||
310 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
311 | { | ||
312 | cmd.CommandText = query; | ||
313 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
314 | |||
315 | using (reader = cmd.ExecuteReader()) | ||
316 | { | ||
317 | while (reader.Read()) | ||
318 | { | ||
319 | OSDMap record = new OSDMap(); | ||
320 | |||
321 | record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"])); | ||
322 | record.Add("name",OSD.FromString((string)reader["name"])); | ||
323 | data.Add(record); | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | catch (Exception e) | ||
329 | { | ||
330 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
331 | ": GetAvatarPicks exception {0}", e.Message); | ||
332 | } | ||
333 | return data; | ||
334 | } | ||
335 | public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) | ||
336 | { | ||
337 | IDataReader reader = null; | ||
338 | string query = string.Empty; | ||
339 | UserProfilePick pick = new UserProfilePick(); | ||
340 | |||
341 | query += "SELECT * FROM userpicks WHERE "; | ||
342 | query += "creatoruuid = :CreatorId AND "; | ||
343 | query += "pickuuid = :PickId"; | ||
344 | |||
345 | try | ||
346 | { | ||
347 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
348 | { | ||
349 | cmd.CommandText = query; | ||
350 | cmd.Parameters.AddWithValue(":CreatorId", avatarId.ToString()); | ||
351 | cmd.Parameters.AddWithValue(":PickId", pickId.ToString()); | ||
352 | |||
353 | using (reader = cmd.ExecuteReader()) | ||
354 | { | ||
355 | |||
356 | while (reader.Read()) | ||
357 | { | ||
358 | string description = (string)reader["description"]; | ||
359 | |||
360 | if (string.IsNullOrEmpty(description)) | ||
361 | description = "No description given."; | ||
362 | |||
363 | UUID.TryParse((string)reader["pickuuid"], out pick.PickId); | ||
364 | UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId); | ||
365 | UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId); | ||
366 | UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId); | ||
367 | pick.GlobalPos = (string)reader["posglobal"]; | ||
368 | bool.TryParse((string)reader["toppick"].ToString(), out pick.TopPick); | ||
369 | bool.TryParse((string)reader["enabled"].ToString(), out pick.Enabled); | ||
370 | pick.Name = (string)reader["name"]; | ||
371 | pick.Desc = description; | ||
372 | pick.User = (string)reader["user"]; | ||
373 | pick.OriginalName = (string)reader["originalname"]; | ||
374 | pick.SimName = (string)reader["simname"]; | ||
375 | pick.SortOrder = (int)reader["sortorder"]; | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | catch (Exception e) | ||
381 | { | ||
382 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
383 | ": GetPickInfo exception {0}", e.Message); | ||
384 | } | ||
385 | return pick; | ||
386 | } | ||
387 | |||
388 | public bool UpdatePicksRecord(UserProfilePick pick) | ||
389 | { | ||
390 | string query = string.Empty; | ||
391 | |||
392 | query += "INSERT OR REPLACE INTO userpicks ("; | ||
393 | query += "pickuuid, "; | ||
394 | query += "creatoruuid, "; | ||
395 | query += "toppick, "; | ||
396 | query += "parceluuid, "; | ||
397 | query += "name, "; | ||
398 | query += "description, "; | ||
399 | query += "snapshotuuid, "; | ||
400 | query += "user, "; | ||
401 | query += "originalname, "; | ||
402 | query += "simname, "; | ||
403 | query += "posglobal, "; | ||
404 | query += "sortorder, "; | ||
405 | query += "enabled ) "; | ||
406 | query += "VALUES ("; | ||
407 | query += ":PickId,"; | ||
408 | query += ":CreatorId,"; | ||
409 | query += ":TopPick,"; | ||
410 | query += ":ParcelId,"; | ||
411 | query += ":Name,"; | ||
412 | query += ":Desc,"; | ||
413 | query += ":SnapshotId,"; | ||
414 | query += ":User,"; | ||
415 | query += ":Original,"; | ||
416 | query += ":SimName,"; | ||
417 | query += ":GlobalPos,"; | ||
418 | query += ":SortOrder,"; | ||
419 | query += ":Enabled) "; | ||
420 | |||
421 | try | ||
422 | { | ||
423 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
424 | { | ||
425 | int top_pick; | ||
426 | int.TryParse(pick.TopPick.ToString(), out top_pick); | ||
427 | int enabled; | ||
428 | int.TryParse(pick.Enabled.ToString(), out enabled); | ||
429 | |||
430 | cmd.CommandText = query; | ||
431 | cmd.Parameters.AddWithValue(":PickId", pick.PickId.ToString()); | ||
432 | cmd.Parameters.AddWithValue(":CreatorId", pick.CreatorId.ToString()); | ||
433 | cmd.Parameters.AddWithValue(":TopPick", top_pick); | ||
434 | cmd.Parameters.AddWithValue(":ParcelId", pick.ParcelId.ToString()); | ||
435 | cmd.Parameters.AddWithValue(":Name", pick.Name.ToString()); | ||
436 | cmd.Parameters.AddWithValue(":Desc", pick.Desc.ToString()); | ||
437 | cmd.Parameters.AddWithValue(":SnapshotId", pick.SnapshotId.ToString()); | ||
438 | cmd.Parameters.AddWithValue(":User", pick.User.ToString()); | ||
439 | cmd.Parameters.AddWithValue(":Original", pick.OriginalName.ToString()); | ||
440 | cmd.Parameters.AddWithValue(":SimName",pick.SimName.ToString()); | ||
441 | cmd.Parameters.AddWithValue(":GlobalPos", pick.GlobalPos); | ||
442 | cmd.Parameters.AddWithValue(":SortOrder", pick.SortOrder.ToString ()); | ||
443 | cmd.Parameters.AddWithValue(":Enabled", enabled); | ||
444 | |||
445 | cmd.ExecuteNonQuery(); | ||
446 | } | ||
447 | } | ||
448 | catch (Exception e) | ||
449 | { | ||
450 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
451 | ": UpdateAvatarNotes exception {0}", e.Message); | ||
452 | return false; | ||
453 | } | ||
454 | return true; | ||
455 | } | ||
456 | |||
457 | public bool DeletePicksRecord(UUID pickId) | ||
458 | { | ||
459 | string query = string.Empty; | ||
460 | |||
461 | query += "DELETE FROM userpicks WHERE "; | ||
462 | query += "pickuuid = :PickId"; | ||
463 | |||
464 | try | ||
465 | { | ||
466 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
467 | { | ||
468 | cmd.CommandText = query; | ||
469 | cmd.Parameters.AddWithValue(":PickId", pickId.ToString()); | ||
470 | cmd.ExecuteNonQuery(); | ||
471 | } | ||
472 | } | ||
473 | catch (Exception e) | ||
474 | { | ||
475 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
476 | ": DeleteUserPickRecord exception {0}", e.Message); | ||
477 | return false; | ||
478 | } | ||
479 | return true; | ||
480 | } | ||
481 | |||
482 | public bool GetAvatarNotes(ref UserProfileNotes notes) | ||
483 | { | ||
484 | IDataReader reader = null; | ||
485 | string query = string.Empty; | ||
486 | |||
487 | query += "SELECT `notes` FROM usernotes WHERE "; | ||
488 | query += "useruuid = :Id AND "; | ||
489 | query += "targetuuid = :TargetId"; | ||
490 | OSDArray data = new OSDArray(); | ||
491 | |||
492 | try | ||
493 | { | ||
494 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
495 | { | ||
496 | cmd.CommandText = query; | ||
497 | cmd.Parameters.AddWithValue(":Id", notes.UserId.ToString()); | ||
498 | cmd.Parameters.AddWithValue(":TargetId", notes.TargetId.ToString()); | ||
499 | |||
500 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
501 | { | ||
502 | while (reader.Read()) | ||
503 | { | ||
504 | notes.Notes = OSD.FromString((string)reader["notes"]); | ||
505 | } | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | catch (Exception e) | ||
510 | { | ||
511 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
512 | ": GetAvatarNotes exception {0}", e.Message); | ||
513 | } | ||
514 | return true; | ||
515 | } | ||
516 | |||
517 | public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) | ||
518 | { | ||
519 | string query = string.Empty; | ||
520 | bool remove; | ||
521 | |||
522 | if(string.IsNullOrEmpty(note.Notes)) | ||
523 | { | ||
524 | remove = true; | ||
525 | query += "DELETE FROM usernotes WHERE "; | ||
526 | query += "useruuid=:UserId AND "; | ||
527 | query += "targetuuid=:TargetId"; | ||
528 | } | ||
529 | else | ||
530 | { | ||
531 | remove = false; | ||
532 | query += "INSERT OR REPLACE INTO usernotes VALUES ( "; | ||
533 | query += ":UserId,"; | ||
534 | query += ":TargetId,"; | ||
535 | query += ":Notes )"; | ||
536 | } | ||
537 | |||
538 | try | ||
539 | { | ||
540 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
541 | { | ||
542 | cmd.CommandText = query; | ||
543 | |||
544 | if(!remove) | ||
545 | cmd.Parameters.AddWithValue(":Notes", note.Notes); | ||
546 | cmd.Parameters.AddWithValue(":TargetId", note.TargetId.ToString ()); | ||
547 | cmd.Parameters.AddWithValue(":UserId", note.UserId.ToString()); | ||
548 | |||
549 | cmd.ExecuteNonQuery(); | ||
550 | } | ||
551 | } | ||
552 | catch (Exception e) | ||
553 | { | ||
554 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
555 | ": UpdateAvatarNotes exception {0}", e.Message); | ||
556 | return false; | ||
557 | } | ||
558 | return true; | ||
559 | } | ||
560 | |||
561 | public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) | ||
562 | { | ||
563 | IDataReader reader = null; | ||
564 | string query = string.Empty; | ||
565 | |||
566 | query += "SELECT * FROM userprofile WHERE "; | ||
567 | query += "useruuid = :Id"; | ||
568 | |||
569 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
570 | { | ||
571 | cmd.CommandText = query; | ||
572 | cmd.Parameters.AddWithValue(":Id", props.UserId.ToString()); | ||
573 | |||
574 | |||
575 | try | ||
576 | { | ||
577 | reader = cmd.ExecuteReader(); | ||
578 | } | ||
579 | catch(Exception e) | ||
580 | { | ||
581 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
582 | ": GetAvatarProperties exception {0}", e.Message); | ||
583 | result = e.Message; | ||
584 | return false; | ||
585 | } | ||
586 | if(reader != null && reader.Read()) | ||
587 | { | ||
588 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
589 | ": Getting data for {0}.", props.UserId); | ||
590 | |||
591 | props.WebUrl = (string)reader["profileURL"]; | ||
592 | UUID.TryParse((string)reader["profileImage"], out props.ImageId); | ||
593 | props.AboutText = (string)reader["profileAboutText"]; | ||
594 | UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId); | ||
595 | props.FirstLifeText = (string)reader["profileFirstText"]; | ||
596 | UUID.TryParse((string)reader["profilePartner"], out props.PartnerId); | ||
597 | props.WantToMask = (int)reader["profileWantToMask"]; | ||
598 | props.WantToText = (string)reader["profileWantToText"]; | ||
599 | props.SkillsMask = (int)reader["profileSkillsMask"]; | ||
600 | props.SkillsText = (string)reader["profileSkillsText"]; | ||
601 | props.Language = (string)reader["profileLanguages"]; | ||
602 | } | ||
603 | else | ||
604 | { | ||
605 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
606 | ": No data for {0}", props.UserId); | ||
607 | |||
608 | props.WebUrl = string.Empty; | ||
609 | props.ImageId = UUID.Zero; | ||
610 | props.AboutText = string.Empty; | ||
611 | props.FirstLifeImageId = UUID.Zero; | ||
612 | props.FirstLifeText = string.Empty; | ||
613 | props.PartnerId = UUID.Zero; | ||
614 | props.WantToMask = 0; | ||
615 | props.WantToText = string.Empty; | ||
616 | props.SkillsMask = 0; | ||
617 | props.SkillsText = string.Empty; | ||
618 | props.Language = string.Empty; | ||
619 | props.PublishProfile = false; | ||
620 | props.PublishMature = false; | ||
621 | |||
622 | query = "INSERT INTO userprofile ("; | ||
623 | query += "useruuid, "; | ||
624 | query += "profilePartner, "; | ||
625 | query += "profileAllowPublish, "; | ||
626 | query += "profileMaturePublish, "; | ||
627 | query += "profileURL, "; | ||
628 | query += "profileWantToMask, "; | ||
629 | query += "profileWantToText, "; | ||
630 | query += "profileSkillsMask, "; | ||
631 | query += "profileSkillsText, "; | ||
632 | query += "profileLanguages, "; | ||
633 | query += "profileImage, "; | ||
634 | query += "profileAboutText, "; | ||
635 | query += "profileFirstImage, "; | ||
636 | query += "profileFirstText) VALUES ("; | ||
637 | query += ":userId, "; | ||
638 | query += ":profilePartner, "; | ||
639 | query += ":profileAllowPublish, "; | ||
640 | query += ":profileMaturePublish, "; | ||
641 | query += ":profileURL, "; | ||
642 | query += ":profileWantToMask, "; | ||
643 | query += ":profileWantToText, "; | ||
644 | query += ":profileSkillsMask, "; | ||
645 | query += ":profileSkillsText, "; | ||
646 | query += ":profileLanguages, "; | ||
647 | query += ":profileImage, "; | ||
648 | query += ":profileAboutText, "; | ||
649 | query += ":profileFirstImage, "; | ||
650 | query += ":profileFirstText)"; | ||
651 | |||
652 | using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) | ||
653 | { | ||
654 | put.CommandText = query; | ||
655 | put.Parameters.AddWithValue(":userId", props.UserId.ToString()); | ||
656 | put.Parameters.AddWithValue(":profilePartner", props.PartnerId.ToString()); | ||
657 | put.Parameters.AddWithValue(":profileAllowPublish", props.PublishProfile); | ||
658 | put.Parameters.AddWithValue(":profileMaturePublish", props.PublishMature); | ||
659 | put.Parameters.AddWithValue(":profileURL", props.WebUrl); | ||
660 | put.Parameters.AddWithValue(":profileWantToMask", props.WantToMask); | ||
661 | put.Parameters.AddWithValue(":profileWantToText", props.WantToText); | ||
662 | put.Parameters.AddWithValue(":profileSkillsMask", props.SkillsMask); | ||
663 | put.Parameters.AddWithValue(":profileSkillsText", props.SkillsText); | ||
664 | put.Parameters.AddWithValue(":profileLanguages", props.Language); | ||
665 | put.Parameters.AddWithValue(":profileImage", props.ImageId.ToString()); | ||
666 | put.Parameters.AddWithValue(":profileAboutText", props.AboutText); | ||
667 | put.Parameters.AddWithValue(":profileFirstImage", props.FirstLifeImageId.ToString()); | ||
668 | put.Parameters.AddWithValue(":profileFirstText", props.FirstLifeText); | ||
669 | |||
670 | put.ExecuteNonQuery(); | ||
671 | } | ||
672 | } | ||
673 | } | ||
674 | return true; | ||
675 | } | ||
676 | |||
677 | public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) | ||
678 | { | ||
679 | string query = string.Empty; | ||
680 | |||
681 | query += "UPDATE userprofile SET "; | ||
682 | query += "profilePartner=:profilePartner, "; | ||
683 | query += "profileURL=:profileURL, "; | ||
684 | query += "profileImage=:image, "; | ||
685 | query += "profileAboutText=:abouttext,"; | ||
686 | query += "profileFirstImage=:firstlifeimage,"; | ||
687 | query += "profileFirstText=:firstlifetext "; | ||
688 | query += "WHERE useruuid=:uuid"; | ||
689 | |||
690 | try | ||
691 | { | ||
692 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
693 | { | ||
694 | cmd.CommandText = query; | ||
695 | cmd.Parameters.AddWithValue(":profileURL", props.WebUrl); | ||
696 | cmd.Parameters.AddWithValue(":profilePartner", props.PartnerId.ToString()); | ||
697 | cmd.Parameters.AddWithValue(":image", props.ImageId.ToString()); | ||
698 | cmd.Parameters.AddWithValue(":abouttext", props.AboutText); | ||
699 | cmd.Parameters.AddWithValue(":firstlifeimage", props.FirstLifeImageId.ToString()); | ||
700 | cmd.Parameters.AddWithValue(":firstlifetext", props.FirstLifeText); | ||
701 | cmd.Parameters.AddWithValue(":uuid", props.UserId.ToString()); | ||
702 | |||
703 | cmd.ExecuteNonQuery(); | ||
704 | } | ||
705 | } | ||
706 | catch (Exception e) | ||
707 | { | ||
708 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
709 | ": AgentPropertiesUpdate exception {0}", e.Message); | ||
710 | |||
711 | return false; | ||
712 | } | ||
713 | return true; | ||
714 | } | ||
715 | |||
716 | public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) | ||
717 | { | ||
718 | string query = string.Empty; | ||
719 | |||
720 | query += "UPDATE userprofile SET "; | ||
721 | query += "profileWantToMask=:WantMask, "; | ||
722 | query += "profileWantToText=:WantText,"; | ||
723 | query += "profileSkillsMask=:SkillsMask,"; | ||
724 | query += "profileSkillsText=:SkillsText, "; | ||
725 | query += "profileLanguages=:Languages "; | ||
726 | query += "WHERE useruuid=:uuid"; | ||
727 | |||
728 | try | ||
729 | { | ||
730 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
731 | { | ||
732 | cmd.CommandText = query; | ||
733 | cmd.Parameters.AddWithValue(":WantMask", up.WantToMask); | ||
734 | cmd.Parameters.AddWithValue(":WantText", up.WantToText); | ||
735 | cmd.Parameters.AddWithValue(":SkillsMask", up.SkillsMask); | ||
736 | cmd.Parameters.AddWithValue(":SkillsText", up.SkillsText); | ||
737 | cmd.Parameters.AddWithValue(":Languages", up.Language); | ||
738 | cmd.Parameters.AddWithValue(":uuid", up.UserId.ToString()); | ||
739 | |||
740 | cmd.ExecuteNonQuery(); | ||
741 | } | ||
742 | } | ||
743 | catch (Exception e) | ||
744 | { | ||
745 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
746 | ": AgentInterestsUpdate exception {0}", e.Message); | ||
747 | result = e.Message; | ||
748 | return false; | ||
749 | } | ||
750 | return true; | ||
751 | } | ||
752 | public bool GetUserAppData(ref UserAppData props, ref string result) | ||
753 | { | ||
754 | IDataReader reader = null; | ||
755 | string query = string.Empty; | ||
756 | |||
757 | query += "SELECT * FROM `userdata` WHERE "; | ||
758 | query += "UserId = :Id AND "; | ||
759 | query += "TagId = :TagId"; | ||
760 | |||
761 | try | ||
762 | { | ||
763 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
764 | { | ||
765 | cmd.CommandText = query; | ||
766 | cmd.Parameters.AddWithValue(":Id", props.UserId.ToString()); | ||
767 | cmd.Parameters.AddWithValue (":TagId", props.TagId.ToString()); | ||
768 | |||
769 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
770 | { | ||
771 | if(reader.Read()) | ||
772 | { | ||
773 | props.DataKey = (string)reader["DataKey"]; | ||
774 | props.DataVal = (string)reader["DataVal"]; | ||
775 | } | ||
776 | else | ||
777 | { | ||
778 | query += "INSERT INTO userdata VALUES ( "; | ||
779 | query += ":UserId,"; | ||
780 | query += ":TagId,"; | ||
781 | query += ":DataKey,"; | ||
782 | query += ":DataVal) "; | ||
783 | |||
784 | using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) | ||
785 | { | ||
786 | put.Parameters.AddWithValue(":Id", props.UserId.ToString()); | ||
787 | put.Parameters.AddWithValue(":TagId", props.TagId.ToString()); | ||
788 | put.Parameters.AddWithValue(":DataKey", props.DataKey.ToString()); | ||
789 | put.Parameters.AddWithValue(":DataVal", props.DataVal.ToString()); | ||
790 | |||
791 | put.ExecuteNonQuery(); | ||
792 | } | ||
793 | } | ||
794 | } | ||
795 | } | ||
796 | } | ||
797 | catch (Exception e) | ||
798 | { | ||
799 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
800 | ": Requst application data exception {0}", e.Message); | ||
801 | result = e.Message; | ||
802 | return false; | ||
803 | } | ||
804 | return true; | ||
805 | } | ||
806 | public bool SetUserAppData(UserAppData props, ref string result) | ||
807 | { | ||
808 | string query = string.Empty; | ||
809 | |||
810 | query += "UPDATE userdata SET "; | ||
811 | query += "TagId = :TagId, "; | ||
812 | query += "DataKey = :DataKey, "; | ||
813 | query += "DataVal = :DataVal WHERE "; | ||
814 | query += "UserId = :UserId AND "; | ||
815 | query += "TagId = :TagId"; | ||
816 | |||
817 | try | ||
818 | { | ||
819 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
820 | { | ||
821 | cmd.CommandText = query; | ||
822 | cmd.Parameters.AddWithValue(":UserId", props.UserId.ToString()); | ||
823 | cmd.Parameters.AddWithValue(":TagId", props.TagId.ToString ()); | ||
824 | cmd.Parameters.AddWithValue(":DataKey", props.DataKey.ToString ()); | ||
825 | cmd.Parameters.AddWithValue(":DataVal", props.DataKey.ToString ()); | ||
826 | |||
827 | cmd.ExecuteNonQuery(); | ||
828 | } | ||
829 | } | ||
830 | catch (Exception e) | ||
831 | { | ||
832 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
833 | ": SetUserData exception {0}", e.Message); | ||
834 | return false; | ||
835 | } | ||
836 | return true; | ||
837 | } | ||
838 | public OSDArray GetUserImageAssets(UUID avatarId) | ||
839 | { | ||
840 | IDataReader reader = null; | ||
841 | OSDArray data = new OSDArray(); | ||
842 | string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = :Id"; | ||
843 | |||
844 | // Get classified image assets | ||
845 | |||
846 | |||
847 | try | ||
848 | { | ||
849 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
850 | { | ||
851 | cmd.CommandText = query; | ||
852 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
853 | |||
854 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
855 | { | ||
856 | while(reader.Read()) | ||
857 | { | ||
858 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString())); | ||
859 | } | ||
860 | } | ||
861 | } | ||
862 | |||
863 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
864 | { | ||
865 | cmd.CommandText = query; | ||
866 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
867 | |||
868 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
869 | { | ||
870 | if(reader.Read()) | ||
871 | { | ||
872 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString ())); | ||
873 | } | ||
874 | } | ||
875 | } | ||
876 | |||
877 | query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = :Id"; | ||
878 | |||
879 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
880 | { | ||
881 | cmd.CommandText = query; | ||
882 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
883 | |||
884 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
885 | { | ||
886 | if(reader.Read()) | ||
887 | { | ||
888 | data.Add(new OSDString((string)reader["profileImage"].ToString ())); | ||
889 | data.Add(new OSDString((string)reader["profileFirstImage"].ToString ())); | ||
890 | } | ||
891 | } | ||
892 | } | ||
893 | } | ||
894 | catch (Exception e) | ||
895 | { | ||
896 | m_log.DebugFormat("[PROFILES_DATA]" + | ||
897 | ": GetAvatarNotes exception {0}", e.Message); | ||
898 | } | ||
899 | return data; | ||
900 | } | ||
901 | #endregion | ||
902 | } | ||
903 | } | ||
904 | |||
diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 27edd4b..3e3c2b3 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs | |||
@@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console | |||
234 | string uri = "/ReadResponses/" + sessionID.ToString() + "/"; | 234 | string uri = "/ReadResponses/" + sessionID.ToString() + "/"; |
235 | 235 | ||
236 | m_Server.AddPollServiceHTTPHandler( | 236 | m_Server.AddPollServiceHTTPHandler( |
237 | uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID)); | 237 | uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout |
238 | 238 | ||
239 | XmlDocument xmldoc = new XmlDocument(); | 239 | XmlDocument xmldoc = new XmlDocument(); |
240 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, | 240 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, |
@@ -425,7 +425,7 @@ namespace OpenSim.Framework.Console | |||
425 | return false; | 425 | return false; |
426 | } | 426 | } |
427 | 427 | ||
428 | private Hashtable GetEvents(UUID RequestID, UUID sessionID, string request) | 428 | private Hashtable GetEvents(UUID RequestID, UUID sessionID) |
429 | { | 429 | { |
430 | ConsoleConnection c = null; | 430 | ConsoleConnection c = null; |
431 | 431 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 96a030b..eb7c578 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -1805,7 +1805,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1805 | 1805 | ||
1806 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events | 1806 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events |
1807 | m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000); | 1807 | m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000); |
1808 | m_PollServiceManager.Start(); | ||
1809 | HTTPDRunning = true; | 1808 | HTTPDRunning = true; |
1810 | 1809 | ||
1811 | //HttpListenerContext context; | 1810 | //HttpListenerContext context; |
@@ -1856,7 +1855,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1856 | HTTPDRunning = false; | 1855 | HTTPDRunning = false; |
1857 | try | 1856 | try |
1858 | { | 1857 | { |
1859 | m_PollServiceManager.Stop(); | 1858 | // m_PollServiceManager.Stop(); |
1860 | 1859 | ||
1861 | m_httpListener2.ExceptionThrown -= httpServerException; | 1860 | m_httpListener2.ExceptionThrown -= httpServerException; |
1862 | //m_httpListener2.DisconnectHandler = null; | 1861 | //m_httpListener2.DisconnectHandler = null; |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 3089351..3079a7e 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs | |||
@@ -34,7 +34,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
34 | public delegate void RequestMethod(UUID requestID, Hashtable request); | 34 | public delegate void RequestMethod(UUID requestID, Hashtable request); |
35 | public delegate bool HasEventsMethod(UUID requestID, UUID pId); | 35 | public delegate bool HasEventsMethod(UUID requestID, UUID pId); |
36 | 36 | ||
37 | public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId, string request); | 37 | public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId); |
38 | 38 | ||
39 | public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); | 39 | public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); |
40 | 40 | ||
@@ -45,17 +45,28 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
45 | public NoEventsMethod NoEvents; | 45 | public NoEventsMethod NoEvents; |
46 | public RequestMethod Request; | 46 | public RequestMethod Request; |
47 | public UUID Id; | 47 | public UUID Id; |
48 | public int TimeOutms; | ||
49 | public EventType Type; | ||
50 | |||
51 | public enum EventType : int | ||
52 | { | ||
53 | Normal = 0, | ||
54 | LslHttp = 1, | ||
55 | Inventory = 2 | ||
56 | } | ||
48 | 57 | ||
49 | public PollServiceEventArgs( | 58 | public PollServiceEventArgs( |
50 | RequestMethod pRequest, | 59 | RequestMethod pRequest, |
51 | HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, | 60 | HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, |
52 | UUID pId) | 61 | UUID pId, int pTimeOutms) |
53 | { | 62 | { |
54 | Request = pRequest; | 63 | Request = pRequest; |
55 | HasEvents = pHasEvents; | 64 | HasEvents = pHasEvents; |
56 | GetEvents = pGetEvents; | 65 | GetEvents = pGetEvents; |
57 | NoEvents = pNoEvents; | 66 | NoEvents = pNoEvents; |
58 | Id = pId; | 67 | Id = pId; |
68 | TimeOutms = pTimeOutms; | ||
69 | Type = EventType.Normal; | ||
59 | } | 70 | } |
60 | } | 71 | } |
61 | } \ No newline at end of file | 72 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 3e84c55..a5380c1 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -33,53 +33,56 @@ using log4net; | |||
33 | using HttpServer; | 33 | using HttpServer; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Monitoring; | 35 | using OpenSim.Framework.Monitoring; |
36 | using Amib.Threading; | ||
37 | using System.IO; | ||
38 | using System.Text; | ||
39 | using System.Collections.Generic; | ||
36 | 40 | ||
37 | namespace OpenSim.Framework.Servers.HttpServer | 41 | namespace OpenSim.Framework.Servers.HttpServer |
38 | { | 42 | { |
39 | public class PollServiceRequestManager | 43 | public class PollServiceRequestManager |
40 | { | 44 | { |
41 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 46 | ||
43 | private readonly BaseHttpServer m_server; | 47 | private readonly BaseHttpServer m_server; |
44 | private static Queue m_requests = Queue.Synchronized(new Queue()); | 48 | |
49 | private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); | ||
50 | private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); | ||
51 | private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>(); | ||
52 | |||
45 | private uint m_WorkerThreadCount = 0; | 53 | private uint m_WorkerThreadCount = 0; |
46 | private Thread[] m_workerThreads; | 54 | private Thread[] m_workerThreads; |
47 | private PollServiceWorkerThread[] m_PollServiceWorkerThreads; | 55 | private Thread m_retrysThread; |
48 | private volatile bool m_running = true; | 56 | |
49 | private int m_pollTimeout; | 57 | private bool m_running = true; |
58 | private int slowCount = 0; | ||
59 | |||
60 | private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2); | ||
61 | |||
62 | // private int m_timeout = 1000; // increase timeout 250; now use the event one | ||
50 | 63 | ||
51 | public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) | 64 | public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) |
52 | { | 65 | { |
53 | m_server = pSrv; | 66 | m_server = pSrv; |
54 | m_WorkerThreadCount = pWorkerThreadCount; | 67 | m_WorkerThreadCount = pWorkerThreadCount; |
55 | m_pollTimeout = pTimeout; | ||
56 | } | ||
57 | |||
58 | public void Start() | ||
59 | { | ||
60 | m_running = true; | ||
61 | m_workerThreads = new Thread[m_WorkerThreadCount]; | 68 | m_workerThreads = new Thread[m_WorkerThreadCount]; |
62 | m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount]; | ||
63 | 69 | ||
64 | //startup worker threads | 70 | //startup worker threads |
65 | for (uint i = 0; i < m_WorkerThreadCount; i++) | 71 | for (uint i = 0; i < m_WorkerThreadCount; i++) |
66 | { | 72 | { |
67 | m_PollServiceWorkerThreads[i] = new PollServiceWorkerThread(m_server, m_pollTimeout); | ||
68 | m_PollServiceWorkerThreads[i].ReQueue += ReQueueEvent; | ||
69 | |||
70 | m_workerThreads[i] | 73 | m_workerThreads[i] |
71 | = Watchdog.StartThread( | 74 | = Watchdog.StartThread( |
72 | m_PollServiceWorkerThreads[i].ThreadStart, | 75 | PoolWorkerJob, |
73 | String.Format("PollServiceWorkerThread{0}", i), | 76 | String.Format("PollServiceWorkerThread{0}", i), |
74 | ThreadPriority.Normal, | 77 | ThreadPriority.Normal, |
75 | false, | 78 | false, |
76 | true, | 79 | false, |
77 | null, | 80 | null, |
78 | int.MaxValue); | 81 | int.MaxValue); |
79 | } | 82 | } |
80 | 83 | ||
81 | Watchdog.StartThread( | 84 | m_retrysThread = Watchdog.StartThread( |
82 | this.ThreadStart, | 85 | this.CheckRetries, |
83 | "PollServiceWatcherThread", | 86 | "PollServiceWatcherThread", |
84 | ThreadPriority.Normal, | 87 | ThreadPriority.Normal, |
85 | false, | 88 | false, |
@@ -88,78 +91,211 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
88 | 1000 * 60 * 10); | 91 | 1000 * 60 * 10); |
89 | } | 92 | } |
90 | 93 | ||
91 | internal void ReQueueEvent(PollServiceHttpRequest req) | 94 | |
95 | private void ReQueueEvent(PollServiceHttpRequest req) | ||
92 | { | 96 | { |
93 | // Do accounting stuff here | 97 | if (m_running) |
94 | Enqueue(req); | 98 | { |
99 | lock (m_retryRequests) | ||
100 | m_retryRequests.Enqueue(req); | ||
101 | } | ||
95 | } | 102 | } |
96 | 103 | ||
97 | public void Enqueue(PollServiceHttpRequest req) | 104 | public void Enqueue(PollServiceHttpRequest req) |
98 | { | 105 | { |
99 | lock (m_requests) | 106 | if (m_running) |
100 | m_requests.Enqueue(req); | 107 | { |
108 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal) | ||
109 | { | ||
110 | m_requests.Enqueue(req); | ||
111 | } | ||
112 | else | ||
113 | { | ||
114 | lock (m_slowRequests) | ||
115 | m_slowRequests.Enqueue(req); | ||
116 | } | ||
117 | } | ||
101 | } | 118 | } |
102 | 119 | ||
103 | public void ThreadStart() | 120 | private void CheckRetries() |
104 | { | 121 | { |
105 | while (m_running) | 122 | while (m_running) |
106 | { | 123 | { |
124 | Thread.Sleep(100); // let the world move .. back to faster rate | ||
107 | Watchdog.UpdateThread(); | 125 | Watchdog.UpdateThread(); |
108 | ProcessQueuedRequests(); | 126 | lock (m_retryRequests) |
109 | Thread.Sleep(1000); | 127 | { |
128 | while (m_retryRequests.Count > 0 && m_running) | ||
129 | m_requests.Enqueue(m_retryRequests.Dequeue()); | ||
130 | } | ||
131 | slowCount++; | ||
132 | if (slowCount >= 10) | ||
133 | { | ||
134 | slowCount = 0; | ||
135 | |||
136 | lock (m_slowRequests) | ||
137 | { | ||
138 | while (m_slowRequests.Count > 0 && m_running) | ||
139 | m_requests.Enqueue(m_slowRequests.Dequeue()); | ||
140 | } | ||
141 | } | ||
110 | } | 142 | } |
111 | } | 143 | } |
112 | 144 | ||
113 | private void ProcessQueuedRequests() | 145 | ~PollServiceRequestManager() |
114 | { | 146 | { |
115 | lock (m_requests) | 147 | m_running = false; |
148 | // m_timeout = -10000; // cause all to expire | ||
149 | Thread.Sleep(1000); // let the world move | ||
150 | |||
151 | foreach (Thread t in m_workerThreads) | ||
152 | Watchdog.AbortThread(t.ManagedThreadId); | ||
153 | |||
154 | try | ||
155 | { | ||
156 | foreach (PollServiceHttpRequest req in m_retryRequests) | ||
157 | { | ||
158 | DoHTTPGruntWork(m_server,req, | ||
159 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
160 | } | ||
161 | } | ||
162 | catch | ||
163 | { | ||
164 | } | ||
165 | |||
166 | PollServiceHttpRequest wreq; | ||
167 | m_retryRequests.Clear(); | ||
168 | |||
169 | lock (m_slowRequests) | ||
116 | { | 170 | { |
117 | if (m_requests.Count == 0) | 171 | while (m_slowRequests.Count > 0 && m_running) |
118 | return; | 172 | m_requests.Enqueue(m_slowRequests.Dequeue()); |
173 | } | ||
119 | 174 | ||
120 | // m_log.DebugFormat("[POLL SERVICE REQUEST MANAGER]: Processing {0} requests", m_requests.Count); | 175 | while (m_requests.Count() > 0) |
176 | { | ||
177 | try | ||
178 | { | ||
179 | wreq = m_requests.Dequeue(0); | ||
180 | DoHTTPGruntWork(m_server,wreq, | ||
181 | wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id)); | ||
182 | } | ||
183 | catch | ||
184 | { | ||
185 | } | ||
186 | } | ||
121 | 187 | ||
122 | int reqperthread = (int) (m_requests.Count/m_WorkerThreadCount) + 1; | 188 | m_requests.Clear(); |
189 | } | ||
123 | 190 | ||
124 | // For Each WorkerThread | 191 | // work threads |
125 | for (int tc = 0; tc < m_WorkerThreadCount && m_requests.Count > 0; tc++) | 192 | |
193 | private void PoolWorkerJob() | ||
194 | { | ||
195 | while (m_running) | ||
196 | { | ||
197 | PollServiceHttpRequest req = m_requests.Dequeue(5000); | ||
198 | |||
199 | Watchdog.UpdateThread(); | ||
200 | if (req != null) | ||
126 | { | 201 | { |
127 | //Loop over number of requests each thread handles. | 202 | try |
128 | for (int i = 0; i < reqperthread && m_requests.Count > 0; i++) | ||
129 | { | 203 | { |
130 | try | 204 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) |
131 | { | 205 | { |
132 | m_PollServiceWorkerThreads[tc].Enqueue((PollServiceHttpRequest)m_requests.Dequeue()); | 206 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); |
207 | |||
208 | if (responsedata == null) | ||
209 | continue; | ||
210 | |||
211 | if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue | ||
212 | { | ||
213 | try | ||
214 | { | ||
215 | DoHTTPGruntWork(m_server, req, responsedata); | ||
216 | } | ||
217 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | ||
218 | { | ||
219 | // Ignore it, no need to reply | ||
220 | } | ||
221 | } | ||
222 | else | ||
223 | { | ||
224 | m_threadPool.QueueWorkItem(x => | ||
225 | { | ||
226 | try | ||
227 | { | ||
228 | DoHTTPGruntWork(m_server, req, responsedata); | ||
229 | } | ||
230 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | ||
231 | { | ||
232 | // Ignore it, no need to reply | ||
233 | } | ||
234 | |||
235 | return null; | ||
236 | }, null); | ||
237 | } | ||
133 | } | 238 | } |
134 | catch (InvalidOperationException) | 239 | else |
135 | { | 240 | { |
136 | // The queue is empty, we did our calculations wrong! | 241 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) |
137 | return; | 242 | { |
243 | DoHTTPGruntWork(m_server, req, | ||
244 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
245 | } | ||
246 | else | ||
247 | { | ||
248 | ReQueueEvent(req); | ||
249 | } | ||
138 | } | 250 | } |
139 | 251 | } | |
252 | catch (Exception e) | ||
253 | { | ||
254 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); | ||
140 | } | 255 | } |
141 | } | 256 | } |
142 | } | 257 | } |
143 | |||
144 | } | 258 | } |
145 | 259 | ||
146 | public void Stop() | 260 | // DoHTTPGruntWork changed, not sending response |
261 | // do the same work around as core | ||
262 | |||
263 | internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata) | ||
147 | { | 264 | { |
148 | m_running = false; | 265 | OSHttpResponse response |
266 | = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext); | ||
149 | 267 | ||
150 | foreach (object o in m_requests) | 268 | byte[] buffer = server.DoHTTPGruntWork(responsedata, response); |
151 | { | ||
152 | PollServiceHttpRequest req = (PollServiceHttpRequest) o; | ||
153 | PollServiceWorkerThread.DoHTTPGruntWork( | ||
154 | m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
155 | } | ||
156 | 269 | ||
157 | m_requests.Clear(); | 270 | response.SendChunked = false; |
271 | response.ContentLength64 = buffer.Length; | ||
272 | response.ContentEncoding = Encoding.UTF8; | ||
158 | 273 | ||
159 | foreach (Thread t in m_workerThreads) | 274 | try |
275 | { | ||
276 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
277 | } | ||
278 | catch (Exception ex) | ||
160 | { | 279 | { |
161 | t.Abort(); | 280 | m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex)); |
281 | } | ||
282 | finally | ||
283 | { | ||
284 | //response.OutputStream.Close(); | ||
285 | try | ||
286 | { | ||
287 | response.OutputStream.Flush(); | ||
288 | response.Send(); | ||
289 | |||
290 | //if (!response.KeepAlive && response.ReuseContext) | ||
291 | // response.FreeContext(); | ||
292 | } | ||
293 | catch (Exception e) | ||
294 | { | ||
295 | m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e)); | ||
296 | } | ||
162 | } | 297 | } |
163 | } | 298 | } |
164 | } | 299 | } |
165 | } \ No newline at end of file | 300 | } |
301 | |||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs deleted file mode 100644 index 5adbcd1..0000000 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Text; | ||
33 | using HttpServer; | ||
34 | using OpenMetaverse; | ||
35 | using System.Reflection; | ||
36 | using log4net; | ||
37 | using OpenSim.Framework.Monitoring; | ||
38 | |||
39 | namespace OpenSim.Framework.Servers.HttpServer | ||
40 | { | ||
41 | public delegate void ReQueuePollServiceItem(PollServiceHttpRequest req); | ||
42 | |||
43 | public class PollServiceWorkerThread | ||
44 | { | ||
45 | private static readonly ILog m_log = | ||
46 | LogManager.GetLogger( | ||
47 | MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | public event ReQueuePollServiceItem ReQueue; | ||
50 | |||
51 | private readonly BaseHttpServer m_server; | ||
52 | private BlockingQueue<PollServiceHttpRequest> m_request; | ||
53 | private bool m_running = true; | ||
54 | private int m_timeout = 250; | ||
55 | |||
56 | public PollServiceWorkerThread(BaseHttpServer pSrv, int pTimeout) | ||
57 | { | ||
58 | m_request = new BlockingQueue<PollServiceHttpRequest>(); | ||
59 | m_server = pSrv; | ||
60 | m_timeout = pTimeout; | ||
61 | } | ||
62 | |||
63 | public void ThreadStart() | ||
64 | { | ||
65 | Run(); | ||
66 | } | ||
67 | |||
68 | public void Run() | ||
69 | { | ||
70 | while (m_running) | ||
71 | { | ||
72 | PollServiceHttpRequest req = m_request.Dequeue(); | ||
73 | |||
74 | Watchdog.UpdateThread(); | ||
75 | |||
76 | try | ||
77 | { | ||
78 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) | ||
79 | { | ||
80 | StreamReader str; | ||
81 | try | ||
82 | { | ||
83 | str = new StreamReader(req.Request.Body); | ||
84 | } | ||
85 | catch (System.ArgumentException) | ||
86 | { | ||
87 | // Stream was not readable means a child agent | ||
88 | // was closed due to logout, leaving the | ||
89 | // Event Queue request orphaned. | ||
90 | continue; | ||
91 | } | ||
92 | |||
93 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); | ||
94 | DoHTTPGruntWork(m_server, req, responsedata); | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | if ((Environment.TickCount - req.RequestTime) > m_timeout) | ||
99 | { | ||
100 | DoHTTPGruntWork( | ||
101 | m_server, | ||
102 | req, | ||
103 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
104 | } | ||
105 | else | ||
106 | { | ||
107 | ReQueuePollServiceItem reQueueItem = ReQueue; | ||
108 | if (reQueueItem != null) | ||
109 | reQueueItem(req); | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | catch (Exception e) | ||
114 | { | ||
115 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
120 | internal void Enqueue(PollServiceHttpRequest pPollServiceHttpRequest) | ||
121 | { | ||
122 | m_request.Enqueue(pPollServiceHttpRequest); | ||
123 | } | ||
124 | |||
125 | /// <summary> | ||
126 | /// FIXME: This should be part of BaseHttpServer | ||
127 | /// </summary> | ||
128 | internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata) | ||
129 | { | ||
130 | OSHttpResponse response | ||
131 | = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext); | ||
132 | |||
133 | byte[] buffer = server.DoHTTPGruntWork(responsedata, response); | ||
134 | |||
135 | response.SendChunked = false; | ||
136 | response.ContentLength64 = buffer.Length; | ||
137 | response.ContentEncoding = Encoding.UTF8; | ||
138 | |||
139 | try | ||
140 | { | ||
141 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
142 | } | ||
143 | catch (Exception ex) | ||
144 | { | ||
145 | m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex)); | ||
146 | } | ||
147 | finally | ||
148 | { | ||
149 | //response.OutputStream.Close(); | ||
150 | try | ||
151 | { | ||
152 | response.OutputStream.Flush(); | ||
153 | response.Send(); | ||
154 | |||
155 | //if (!response.KeepAlive && response.ReuseContext) | ||
156 | // response.FreeContext(); | ||
157 | } | ||
158 | catch (Exception e) | ||
159 | { | ||
160 | m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e)); | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index c7d4283..e73a04a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -376,7 +376,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
376 | // TODO: Add EventQueueGet name/description for diagnostics | 376 | // TODO: Add EventQueueGet name/description for diagnostics |
377 | MainServer.Instance.AddPollServiceHTTPHandler( | 377 | MainServer.Instance.AddPollServiceHTTPHandler( |
378 | eventQueueGetPath, | 378 | eventQueueGetPath, |
379 | new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); | 379 | new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 40000)); |
380 | 380 | ||
381 | // m_log.DebugFormat( | 381 | // m_log.DebugFormat( |
382 | // "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", | 382 | // "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", |
@@ -418,7 +418,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
418 | } | 418 | } |
419 | } | 419 | } |
420 | 420 | ||
421 | public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) | 421 | public Hashtable GetEvents(UUID requestID, UUID pAgentId) |
422 | { | 422 | { |
423 | if (DebugLevel >= 2) | 423 | if (DebugLevel >= 2) |
424 | m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); | 424 | m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 2586cf0..d1afff2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -181,12 +181,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
181 | private Scene m_scene; | 181 | private Scene m_scene; |
182 | 182 | ||
183 | public PollServiceInventoryEventArgs(Scene scene, UUID pId) : | 183 | public PollServiceInventoryEventArgs(Scene scene, UUID pId) : |
184 | base(null, null, null, null, pId) | 184 | base(null, null, null, null, pId, int.MaxValue) |
185 | { | 185 | { |
186 | m_scene = scene; | 186 | m_scene = scene; |
187 | 187 | ||
188 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; | 188 | HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; |
189 | GetEvents = (x, y, z) => | 189 | GetEvents = (x, y) => |
190 | { | 190 | { |
191 | lock (responses) | 191 | lock (responses) |
192 | { | 192 | { |
@@ -316,6 +316,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
316 | // Register this as a poll service | 316 | // Register this as a poll service |
317 | PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID); | 317 | PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID); |
318 | 318 | ||
319 | args.Type = PollServiceEventArgs.EventType.Inventory; | ||
319 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); | 320 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); |
320 | 321 | ||
321 | string hostName = m_scene.RegionInfo.ExternalHostName; | 322 | string hostName = m_scene.RegionInfo.ExternalHostName; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index bf24030..2bb24ae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | |||
@@ -57,6 +57,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile | |||
57 | 57 | ||
58 | public void Initialise(IConfigSource config) | 58 | public void Initialise(IConfigSource config) |
59 | { | 59 | { |
60 | if(config.Configs["UserProfiles"] != null) | ||
61 | return; | ||
62 | |||
60 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); | 63 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); |
61 | m_Enabled = true; | 64 | m_Enabled = true; |
62 | } | 65 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index a97c9b4..322addd 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | |||
@@ -130,6 +130,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
130 | 130 | ||
131 | if (profileConfig == null) | 131 | if (profileConfig == null) |
132 | { | 132 | { |
133 | m_log.Debug("[PROFILES]: UserProfiles disabled, no configuration"); | ||
133 | Enabled = false; | 134 | Enabled = false; |
134 | return; | 135 | return; |
135 | } | 136 | } |
@@ -1316,7 +1317,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
1316 | Stream rstream = webResponse.GetResponseStream(); | 1317 | Stream rstream = webResponse.GetResponseStream(); |
1317 | 1318 | ||
1318 | OSDMap response = new OSDMap(); | 1319 | OSDMap response = new OSDMap(); |
1319 | response = (OSDMap)OSDParser.DeserializeJson(rstream); | 1320 | try |
1321 | { | ||
1322 | response = (OSDMap)OSDParser.DeserializeJson(rstream); | ||
1323 | } | ||
1324 | catch (Exception e) | ||
1325 | { | ||
1326 | m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); | ||
1327 | return false; | ||
1328 | } | ||
1329 | |||
1320 | if(response.ContainsKey("error")) | 1330 | if(response.ContainsKey("error")) |
1321 | { | 1331 | { |
1322 | data = response["error"]; | 1332 | data = response["error"]; |
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index c9cd412..def8162 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | |||
@@ -235,9 +235,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
235 | 235 | ||
236 | string uri = "/lslhttp/" + urlcode.ToString() + "/"; | 236 | string uri = "/lslhttp/" + urlcode.ToString() + "/"; |
237 | 237 | ||
238 | m_HttpServer.AddPollServiceHTTPHandler( | 238 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); |
239 | uri, | 239 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
240 | new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); | 240 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); |
241 | 241 | ||
242 | m_log.DebugFormat( | 242 | m_log.DebugFormat( |
243 | "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", | 243 | "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", |
@@ -280,9 +280,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
280 | 280 | ||
281 | string uri = "/lslhttps/" + urlcode.ToString() + "/"; | 281 | string uri = "/lslhttps/" + urlcode.ToString() + "/"; |
282 | 282 | ||
283 | m_HttpsServer.AddPollServiceHTTPHandler( | 283 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); |
284 | uri, | 284 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
285 | new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); | 285 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); |
286 | 286 | ||
287 | m_log.DebugFormat( | 287 | m_log.DebugFormat( |
288 | "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", | 288 | "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", |
@@ -516,7 +516,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
516 | } | 516 | } |
517 | } | 517 | } |
518 | 518 | ||
519 | private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) | 519 | private Hashtable GetEvents(UUID requestID, UUID sessionID) |
520 | { | 520 | { |
521 | Hashtable response; | 521 | Hashtable response; |
522 | 522 | ||
@@ -668,4 +668,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
668 | ScriptRemoved(itemID); | 668 | ScriptRemoved(itemID); |
669 | } | 669 | } |
670 | } | 670 | } |
671 | } \ No newline at end of file | 671 | } |
diff --git a/prebuild.xml b/prebuild.xml index 5531558..88db6ed 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -191,6 +191,7 @@ | |||
191 | <Reference name="XMLRPC" path="../../../../bin/"/> | 191 | <Reference name="XMLRPC" path="../../../../bin/"/> |
192 | <Reference name="log4net" path="../../../../bin/"/> | 192 | <Reference name="log4net" path="../../../../bin/"/> |
193 | <Reference name="HttpServer_OpenSim" path="../../../../bin/"/> | 193 | <Reference name="HttpServer_OpenSim" path="../../../../bin/"/> |
194 | <Reference name="SmartThreadPool"/> | ||
194 | 195 | ||
195 | <Files> | 196 | <Files> |
196 | <Match pattern="*.cs" recurse="true"> | 197 | <Match pattern="*.cs" recurse="true"> |