aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2011-06-09 02:05:04 +0100
committerMelanie2011-06-09 02:05:04 +0100
commit326c46ba70cea70ddfe4aef9a6b73edff63e126a (patch)
tree5e76347b0d77f58717d8e5e4f3b8787ff01a18d7 /OpenSim
parentMake the last otem in a list created with llCSV2List findable (diff)
parentConsistency fix on the last commit. (diff)
downloadopensim-SC-326c46ba70cea70ddfe4aef9a6b73edff63e126a.zip
opensim-SC-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.gz
opensim-SC-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.bz2
opensim-SC-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.xz
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/IFriendsData.cs4
-rw-r--r--OpenSim/Data/MSSQL/MSSQLEstateData.cs203
-rw-r--r--OpenSim/Data/MSSQL/MSSQLFriendsData.cs10
-rw-r--r--OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs24
-rw-r--r--OpenSim/Data/MSSQL/MSSQLMigration.cs32
-rw-r--r--OpenSim/Data/MSSQL/MSSQLRegionData.cs1
-rw-r--r--OpenSim/Data/MSSQL/MSSQLSimulationData.cs513
-rw-r--r--OpenSim/Data/MSSQL/MSSQLXInventoryData.cs32
-rw-r--r--OpenSim/Data/MSSQL/Resources/Avatar.migrations24
-rw-r--r--OpenSim/Data/MSSQL/Resources/GridUserStore.migrations46
-rw-r--r--OpenSim/Data/MSSQL/Resources/RegionStore.migrations2
-rw-r--r--OpenSim/Data/MySQL/MySQLFriendsData.cs14
-rw-r--r--OpenSim/Data/MySQL/Resources/FriendsStore.migrations7
-rw-r--r--OpenSim/Data/Null/NullFriendsData.cs18
-rw-r--r--OpenSim/Data/SQLite/SQLiteFriendsData.cs12
-rw-r--r--OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs2
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs1
-rw-r--r--OpenSim/Framework/AssetBase.cs6
-rw-r--r--OpenSim/Framework/AssetLandmark.cs3
-rw-r--r--OpenSim/Framework/IClientAPI.cs16
-rw-r--r--OpenSim/Framework/Util.cs63
-rw-r--r--OpenSim/Region/Application/Application.cs4
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs45
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs355
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs628
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs350
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs82
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs244
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs173
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs57
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs34
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs84
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs112
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs23
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs41
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs83
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs3
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs402
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs30
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs110
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs32
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs161
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs139
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs756
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs193
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs366
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs206
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs375
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs163
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs317
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs167
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs94
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs270
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs104
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/README52
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs216
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs92
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs3
-rw-r--r--OpenSim/Server/Base/ServerUtils.cs11
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendServerConnector.cs6
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs65
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs71
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs320
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs243
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs219
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs53
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs206
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs323
-rw-r--r--OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs131
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs25
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs27
-rw-r--r--OpenSim/Services/FreeswitchService/FreeswitchService.cs8
-rw-r--r--OpenSim/Services/Friends/FriendsService.cs38
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs11
-rw-r--r--OpenSim/Services/HypergridService/HGInstantMessageService.cs349
-rw-r--r--OpenSim/Services/HypergridService/HGInventoryService.cs2
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs252
-rw-r--r--OpenSim/Services/Interfaces/IFriendsService.cs4
-rw-r--r--OpenSim/Services/Interfaces/IHypergridServices.cs (renamed from OpenSim/Services/Interfaces/IGatekeeperService.cs)25
-rw-r--r--OpenSim/Services/InventoryService/InventoryService.cs8
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs10
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs14
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs48
-rw-r--r--OpenSim/Tests/Clients/InstantMessage/IMClient.cs75
-rw-r--r--OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs11
-rw-r--r--OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs94
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs2
103 files changed, 6258 insertions, 4229 deletions
diff --git a/OpenSim/Data/IFriendsData.cs b/OpenSim/Data/IFriendsData.cs
index 1f1a031..3fdf87b 100644
--- a/OpenSim/Data/IFriendsData.cs
+++ b/OpenSim/Data/IFriendsData.cs
@@ -34,7 +34,7 @@ namespace OpenSim.Data
34{ 34{
35 public class FriendsData 35 public class FriendsData
36 { 36 {
37 public UUID PrincipalID; 37 public string PrincipalID;
38 public string Friend; 38 public string Friend;
39 public Dictionary<string, string> Data; 39 public Dictionary<string, string> Data;
40 } 40 }
@@ -46,6 +46,8 @@ namespace OpenSim.Data
46 { 46 {
47 bool Store(FriendsData data); 47 bool Store(FriendsData data);
48 bool Delete(UUID ownerID, string friend); 48 bool Delete(UUID ownerID, string friend);
49 bool Delete(string ownerID, string friend);
49 FriendsData[] GetFriends(UUID principalID); 50 FriendsData[] GetFriends(UUID principalID);
51 FriendsData[] GetFriends(string principalID);
50 } 52 }
51} 53}
diff --git a/OpenSim/Data/MSSQL/MSSQLEstateData.cs b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
index d10ebe4..9c54e77 100644
--- a/OpenSim/Data/MSSQL/MSSQLEstateData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLEstateData.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
41 { 41 {
42 private const string _migrationStore = "EstateStore"; 42 private const string _migrationStore = "EstateStore";
43 43
44 private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 private MSSQLManager _Database; 46 private MSSQLManager _Database;
47 private string m_connectionString; 47 private string m_connectionString;
@@ -72,7 +72,12 @@ namespace OpenSim.Data.MSSQL
72 } 72 }
73 73
74 //Migration settings 74 //Migration settings
75 _Database.CheckMigration(_migrationStore); 75 using (SqlConnection conn = new SqlConnection(m_connectionString))
76 {
77 conn.Open();
78 Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
79 m.Update();
80 }
76 81
77 //Interesting way to get parameters! Maybe implement that also with other types 82 //Interesting way to get parameters! Maybe implement that also with other types
78 Type t = typeof(EstateSettings); 83 Type t = typeof(EstateSettings);
@@ -112,19 +117,19 @@ namespace OpenSim.Data.MSSQL
112 { 117 {
113 FieldInfo f = _FieldMap[name]; 118 FieldInfo f = _FieldMap[name];
114 object v = reader[name]; 119 object v = reader[name];
115 if (f.FieldType == typeof(bool) ) 120 if (f.FieldType == typeof(bool))
116 { 121 {
117 f.SetValue(es, Convert.ToInt32(v) != 0); 122 f.SetValue(es, Convert.ToInt32(v) != 0);
118 } 123 }
119 else if (f.FieldType == typeof(UUID) ) 124 else if (f.FieldType == typeof(UUID))
120 { 125 {
121 f.SetValue(es, new UUID((Guid)v)); // uuid); 126 f.SetValue(es, new UUID((Guid)v)); // uuid);
122 } 127 }
123 else if (f.FieldType == typeof(string)) 128 else if (f.FieldType == typeof(string))
124 { 129 {
125 f.SetValue(es, v.ToString()); 130 f.SetValue(es, v.ToString());
126 } 131 }
127 else if (f.FieldType == typeof(UInt32)) 132 else if (f.FieldType == typeof(UInt32))
128 { 133 {
129 f.SetValue(es, Convert.ToUInt32(v)); 134 f.SetValue(es, Convert.ToUInt32(v));
130 } 135 }
@@ -186,7 +191,7 @@ namespace OpenSim.Data.MSSQL
186 } 191 }
187 catch (Exception e) 192 catch (Exception e)
188 { 193 {
189 _Log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e); 194 m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
190 } 195 }
191 } 196 }
192 197
@@ -310,12 +315,12 @@ namespace OpenSim.Data.MSSQL
310 conn.Open(); 315 conn.Open();
311 using (SqlCommand cmd = conn.CreateCommand()) 316 using (SqlCommand cmd = conn.CreateCommand())
312 { 317 {
313 cmd.CommandText = "delete from estateban where EstateID = @EstateID"; 318 cmd.CommandText = "delete from estateban where EstateID = @EstateID";
314 cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID); 319 cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
315 cmd.ExecuteNonQuery(); 320 cmd.ExecuteNonQuery();
316 321
317 //Insert after 322 //Insert after
318 cmd.CommandText = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )"; 323 cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )";
319 cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty); 324 cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
320 foreach (EstateBan b in es.EstateBans) 325 foreach (EstateBan b in es.EstateBans)
321 { 326 {
@@ -350,43 +355,195 @@ namespace OpenSim.Data.MSSQL
350 355
351 public EstateSettings LoadEstateSettings(int estateID) 356 public EstateSettings LoadEstateSettings(int estateID)
352 { 357 {
353 // TODO: Implementation! 358 EstateSettings es = new EstateSettings();
354 return new EstateSettings(); 359 string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
360 using (SqlConnection conn = new SqlConnection(m_connectionString))
361 {
362 conn.Open();
363 using (SqlCommand cmd = new SqlCommand(sql, conn))
364 {
365 cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
366 using (SqlDataReader reader = cmd.ExecuteReader())
367 {
368 if (reader.Read())
369 {
370 foreach (string name in FieldList)
371 {
372 FieldInfo f = _FieldMap[name];
373 object v = reader[name];
374 if (f.FieldType == typeof(bool))
375 {
376 f.SetValue(es, Convert.ToInt32(v) != 0);
377 }
378 else if (f.FieldType == typeof(UUID))
379 {
380 f.SetValue(es, new UUID((Guid)v)); // uuid);
381 }
382 else if (f.FieldType == typeof(string))
383 {
384 f.SetValue(es, v.ToString());
385 }
386 else if (f.FieldType == typeof(UInt32))
387 {
388 f.SetValue(es, Convert.ToUInt32(v));
389 }
390 else if (f.FieldType == typeof(Single))
391 {
392 f.SetValue(es, Convert.ToSingle(v));
393 }
394 else
395 f.SetValue(es, v);
396 }
397 }
398
399 }
400 }
401 }
402 LoadBanList(es);
403
404 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
405 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
406 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
407
408 //Set event
409 es.OnSave += StoreEstateSettings;
410 return es;
411
355 } 412 }
356 413
357 public List<EstateSettings> LoadEstateSettingsAll() 414 public List<EstateSettings> LoadEstateSettingsAll()
358 { 415 {
359 // TODO: Implementation! 416 List<EstateSettings> allEstateSettings = new List<EstateSettings>();
360 return new List<EstateSettings>(); 417
418 List<int> allEstateIds = GetEstatesAll();
419
420 foreach (int estateId in allEstateIds)
421 allEstateSettings.Add(LoadEstateSettings(estateId));
422
423 return allEstateSettings;
361 } 424 }
362 425
363 public List<int> GetEstates(string search) 426 public List<int> GetEstates(string search)
364 { 427 {
365 // TODO: Implementation! 428 List<int> result = new List<int>();
366 return new List<int>(); 429 string sql = "select estateID from estate_settings where EstateName = @EstateName";
430 using (SqlConnection conn = new SqlConnection(m_connectionString))
431 {
432 conn.Open();
433 using (SqlCommand cmd = new SqlCommand(sql, conn))
434 {
435 cmd.Parameters.AddWithValue("@EstateName", search);
436
437 using (IDataReader reader = cmd.ExecuteReader())
438 {
439 while (reader.Read())
440 {
441 result.Add(Convert.ToInt32(reader["EstateID"]));
442 }
443 reader.Close();
444 }
445 }
446 }
447
448 return result;
367 } 449 }
368 450
369 public List<int> GetEstatesAll() 451 public List<int> GetEstatesAll()
370 { 452 {
371 // TODO: Implementation! 453 List<int> result = new List<int>();
372 return new List<int>(); 454 string sql = "select estateID from estate_settings";
455 using (SqlConnection conn = new SqlConnection(m_connectionString))
456 {
457 conn.Open();
458 using (SqlCommand cmd = new SqlCommand(sql, conn))
459 {
460 using (IDataReader reader = cmd.ExecuteReader())
461 {
462 while (reader.Read())
463 {
464 result.Add(Convert.ToInt32(reader["EstateID"]));
465 }
466 reader.Close();
467 }
468 }
469 }
470
471 return result;
373 } 472 }
374 473
375 public List<int> GetEstatesByOwner(UUID ownerID) 474 public List<int> GetEstatesByOwner(UUID ownerID)
376 { 475 {
377 return new List<int>(); 476 List<int> result = new List<int>();
477 string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
478 using (SqlConnection conn = new SqlConnection(m_connectionString))
479 {
480 conn.Open();
481 using (SqlCommand cmd = new SqlCommand(sql, conn))
482 {
483 cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
484
485 using (IDataReader reader = cmd.ExecuteReader())
486 {
487 while (reader.Read())
488 {
489 result.Add(Convert.ToInt32(reader["EstateID"]));
490 }
491 reader.Close();
492 }
493 }
494 }
495
496 return result;
378 } 497 }
379 498
380 public bool LinkRegion(UUID regionID, int estateID) 499 public bool LinkRegion(UUID regionID, int estateID)
381 { 500 {
382 // TODO: Implementation! 501 string sql = "insert into estate_map values (@RegionID, @EstateID)";
502 using (SqlConnection conn = new SqlConnection(m_connectionString))
503 {
504 conn.Open();
505 try
506 {
507 using (SqlCommand cmd = new SqlCommand(sql, conn))
508 {
509 cmd.Parameters.AddWithValue("@RegionID", regionID);
510 cmd.Parameters.AddWithValue("@EstateID", estateID);
511
512 int ret = cmd.ExecuteNonQuery();
513 return (ret != 0);
514 }
515 }
516 catch (Exception ex)
517 {
518 m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
519 }
520 }
383 return false; 521 return false;
384 } 522 }
385 523
386 public List<UUID> GetRegions(int estateID) 524 public List<UUID> GetRegions(int estateID)
387 { 525 {
388 // TODO: Implementation! 526 List<UUID> result = new List<UUID>();
389 return new List<UUID>(); 527 string sql = "select RegionID from estate_map where EstateID = @EstateID";
528 using (SqlConnection conn = new SqlConnection(m_connectionString))
529 {
530 conn.Open();
531 using (SqlCommand cmd = new SqlCommand(sql, conn))
532 {
533 cmd.Parameters.AddWithValue("@EstateID", estateID);
534
535 using (IDataReader reader = cmd.ExecuteReader())
536 {
537 while (reader.Read())
538 {
539 result.Add(DBGuid.FromDB(reader["RegionID"]));
540 }
541 reader.Close();
542 }
543 }
544 }
545
546 return result;
390 } 547 }
391 548
392 public bool DeleteEstate(int estateID) 549 public bool DeleteEstate(int estateID)
diff --git a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
index af4fd9b..09dde5e 100644
--- a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
@@ -52,6 +52,11 @@ namespace OpenSim.Data.MSSQL
52 52
53 public bool Delete(UUID principalID, string friend) 53 public bool Delete(UUID principalID, string friend)
54 { 54 {
55 return Delete(principalID.ToString(), friend);
56 }
57
58 public bool Delete(string principalID, string friend)
59 {
55 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 60 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
56 using (SqlCommand cmd = new SqlCommand()) 61 using (SqlCommand cmd = new SqlCommand())
57 { 62 {
@@ -68,6 +73,11 @@ namespace OpenSim.Data.MSSQL
68 73
69 public FriendsData[] GetFriends(UUID principalID) 74 public FriendsData[] GetFriends(UUID principalID)
70 { 75 {
76 return GetFriends(principalID.ToString());
77 }
78
79 public FriendsData[] GetFriends(string principalID)
80 {
71 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 81 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
72 using (SqlCommand cmd = new SqlCommand()) 82 using (SqlCommand cmd = new SqlCommand())
73 { 83 {
diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
index 6e695ce..8f471c4 100644
--- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
+++ b/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
@@ -168,14 +168,13 @@ namespace OpenSim.Data.MSSQL
168 168
169 protected T[] DoQuery(SqlCommand cmd) 169 protected T[] DoQuery(SqlCommand cmd)
170 { 170 {
171 List<T> result = new List<T>();
171 using (SqlDataReader reader = cmd.ExecuteReader()) 172 using (SqlDataReader reader = cmd.ExecuteReader())
172 { 173 {
173 if (reader == null) 174 if (reader == null)
174 return new T[0]; 175 return new T[0];
175 176
176 CheckColumnNames(reader); 177 CheckColumnNames(reader);
177
178 List<T> result = new List<T>();
179 178
180 while (reader.Read()) 179 while (reader.Read())
181 { 180 {
@@ -262,6 +261,15 @@ namespace OpenSim.Data.MSSQL
262 { 261 {
263 names.Add(fi.Name); 262 names.Add(fi.Name);
264 values.Add("@" + fi.Name); 263 values.Add("@" + fi.Name);
264 // Temporarily return more information about what field is unexpectedly null for
265 // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
266 // InventoryTransferModule or we may be required to substitute a DBNull here.
267 if (fi.GetValue(row) == null)
268 throw new NullReferenceException(
269 string.Format(
270 "[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
271 fi.Name, row));
272
265 if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name)) 273 if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
266 { 274 {
267 constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString())); 275 constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
@@ -358,12 +366,18 @@ namespace OpenSim.Data.MSSQL
358 366
359 string where = String.Join(" AND ", terms.ToArray()); 367 string where = String.Join(" AND ", terms.ToArray());
360 368
361 string query = String.Format("DELETE * FROM {0} WHERE {1}", m_Realm, where); 369 string query = String.Format("DELETE FROM {0} WHERE {1}", m_Realm, where);
362 370
363 cmd.Connection = conn; 371 cmd.Connection = conn;
364 cmd.CommandText = query; 372 cmd.CommandText = query;
365 conn.Open(); 373 conn.Open();
366 return cmd.ExecuteNonQuery() > 0; 374
375 if (cmd.ExecuteNonQuery() > 0)
376 {
377 //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
378 return true;
379 }
380 return false;
367 } 381 }
368 } 382 }
369 } 383 }
diff --git a/OpenSim/Data/MSSQL/MSSQLMigration.cs b/OpenSim/Data/MSSQL/MSSQLMigration.cs
index cd395b8..1aa96c7 100644
--- a/OpenSim/Data/MSSQL/MSSQLMigration.cs
+++ b/OpenSim/Data/MSSQL/MSSQLMigration.cs
@@ -29,16 +29,19 @@ using System;
29using System.Data; 29using System.Data;
30using System.Data.Common; 30using System.Data.Common;
31using System.Reflection; 31using System.Reflection;
32using System.Data.SqlClient;
32 33
33namespace OpenSim.Data.MSSQL 34namespace OpenSim.Data.MSSQL
34{ 35{
35 public class MSSQLMigration : Migration 36 public class MSSQLMigration : Migration
36 { 37 {
37 public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type) 38 public MSSQLMigration(DbConnection conn, Assembly assem, string type)
39 : base(conn, assem, type)
38 { 40 {
39 } 41 }
40 42
41 public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type) 43 public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
44 : base(conn, assem, subtype, type)
42 { 45 {
43 } 46 }
44 47
@@ -67,5 +70,30 @@ namespace OpenSim.Data.MSSQL
67 } 70 }
68 return version; 71 return version;
69 } 72 }
73
74 protected override void ExecuteScript(DbConnection conn, string[] script)
75 {
76 if (!(conn is SqlConnection))
77 {
78 base.ExecuteScript(conn, script);
79 return;
80 }
81
82 foreach (string sql in script)
83 {
84 try
85 {
86 using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
87 {
88 cmd.ExecuteNonQuery();
89 }
90 }
91 catch (Exception ex)
92 {
93 throw new Exception(sql);
94
95 }
96 }
97 }
70 } 98 }
71} 99}
diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs
index cdf8ec0..3ae87c3 100644
--- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs
@@ -70,6 +70,7 @@ namespace OpenSim.Data.MSSQL
70 string sql = "select * from ["+m_Realm+"] where regionName like @regionName"; 70 string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
71 if (scopeID != UUID.Zero) 71 if (scopeID != UUID.Zero)
72 sql += " and ScopeID = @scopeID"; 72 sql += " and ScopeID = @scopeID";
73 sql += " order by regionName";
73 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 74 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
74 using (SqlCommand cmd = new SqlCommand(sql, conn)) 75 using (SqlCommand cmd = new SqlCommand(sql, conn))
75 { 76 {
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
index 5155e56..78f80e1 100644
--- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs
@@ -55,6 +55,10 @@ namespace OpenSim.Data.MSSQL
55 /// </summary> 55 /// </summary>
56 private MSSQLManager _Database; 56 private MSSQLManager _Database;
57 private string m_connectionString; 57 private string m_connectionString;
58 protected virtual Assembly Assembly
59 {
60 get { return GetType().Assembly; }
61 }
58 62
59 public MSSQLSimulationData() 63 public MSSQLSimulationData()
60 { 64 {
@@ -74,9 +78,28 @@ namespace OpenSim.Data.MSSQL
74 m_connectionString = connectionString; 78 m_connectionString = connectionString;
75 _Database = new MSSQLManager(connectionString); 79 _Database = new MSSQLManager(connectionString);
76 80
81 using (SqlConnection conn = new SqlConnection(connectionString))
82 {
83 conn.Open();
84 //New Migration settings
85 Migration m = new Migration(conn, Assembly, "RegionStore");
86 m.Update();
77 87
78 //Migration settings 88 // Clean dropped attachments
79 _Database.CheckMigration(_migrationStore); 89 //
90 try
91 {
92 using (SqlCommand cmd = conn.CreateCommand())
93 {
94 cmd.CommandText = "delete from prims where prims.UUID in (select UUID from primshapes where PCode = 9 and State <> 0); delete from primshapes where PCode = 9 and State <> 0";
95 cmd.ExecuteNonQuery();
96 }
97 }
98 catch (Exception ex)
99 {
100 _Log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
101 }
102 }
80 } 103 }
81 104
82 /// <summary> 105 /// <summary>
@@ -214,7 +237,7 @@ namespace OpenSim.Data.MSSQL
214 { 237 {
215 command.Parameters.Clear(); 238 command.Parameters.Clear();
216 command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID)); 239 command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
217 240
218 List<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); 241 List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
219 242
220 using (SqlDataReader reader = command.ExecuteReader()) 243 using (SqlDataReader reader = command.ExecuteReader())
@@ -241,6 +264,14 @@ namespace OpenSim.Data.MSSQL
241 /// <param name="regionUUID"></param> 264 /// <param name="regionUUID"></param>
242 public void StoreObject(SceneObjectGroup obj, UUID regionUUID) 265 public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
243 { 266 {
267 uint flags = obj.RootPart.GetEffectiveObjectFlags();
268 // Eligibility check
269 //
270 if ((flags & (uint)PrimFlags.Temporary) != 0)
271 return;
272 if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
273 return;
274
244 _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length); 275 _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length);
245 276
246 using (SqlConnection conn = new SqlConnection(m_connectionString)) 277 using (SqlConnection conn = new SqlConnection(m_connectionString))
@@ -700,16 +731,470 @@ VALUES
700 } 731 }
701 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) 732 public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
702 { 733 {
703 //This connector doesn't support the windlight module yet 734 RegionLightShareData nWP = new RegionLightShareData();
704 //Return default LL windlight settings 735 nWP.OnSave += StoreRegionWindlightSettings;
705 return new RegionLightShareData(); 736 string sql = "select * from [regionwindlight] where region_id = @regionID";
737 using (SqlConnection conn = new SqlConnection(m_connectionString))
738 using (SqlCommand cmd = new SqlCommand(sql, conn))
739 {
740 cmd.Parameters.Add(_Database.CreateParameter("@regionID", regionUUID));
741 conn.Open();
742 using (SqlDataReader result = cmd.ExecuteReader())
743 {
744 if (!result.Read())
745 {
746 //No result, so store our default windlight profile and return it
747 nWP.regionID = regionUUID;
748 StoreRegionWindlightSettings(nWP);
749 return nWP;
750 }
751 else
752 {
753 nWP.regionID = DBGuid.FromDB(result["region_id"]);
754 nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
755 nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
756 nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
757 nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
758 nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
759 nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
760 nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
761 nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
762 nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
763 nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
764 nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
765 nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
766 nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
767 nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
768 nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
769 nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
770 nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
771 UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
772 nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
773 nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
774 nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
775 nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
776 nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
777 nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
778 nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
779 nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
780 nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
781 nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
782 nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
783 nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
784 nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
785 nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
786 nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
787 nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
788 nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
789 nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
790 nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
791 nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
792 nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
793 nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
794 nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
795 nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
796 nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
797 nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
798 nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
799 nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
800 nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
801 nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
802 nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
803 nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
804 nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
805 nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
806 nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
807 nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
808 nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
809 nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
810 nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
811 nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
812 nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
813 nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
814 nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
815 nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
816 nWP.valid = true;
817 }
818 }
819 }
820 return nWP;
706 } 821 }
822
707 public void RemoveRegionWindlightSettings(UUID regionID) 823 public void RemoveRegionWindlightSettings(UUID regionID)
708 { 824 {
825 string sql = "delete from [regionwindlight] where region_id = @region_id";
826 using (SqlConnection conn = new SqlConnection(m_connectionString))
827 using (SqlCommand cmd = new SqlCommand(sql, conn))
828 {
829 conn.Open();
830 cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionID));
831 cmd.ExecuteNonQuery();
832 }
709 } 833 }
834
710 public void StoreRegionWindlightSettings(RegionLightShareData wl) 835 public void StoreRegionWindlightSettings(RegionLightShareData wl)
711 { 836 {
712 //This connector doesn't support the windlight module yet 837 string sql = "select count (region_id) from regionwindlight where region_id = @region_id";
838 bool exists = false;
839 using (SqlConnection conn = new SqlConnection(m_connectionString))
840 {
841 conn.Open();
842 using (SqlCommand cmd = new SqlCommand(sql, conn))
843 {
844 cmd.Parameters.Add(_Database.CreateParameter("@region_id", wl.regionID));
845 exists = (int)cmd.ExecuteScalar() > 0;
846 }
847 }
848 if (exists)
849 {
850 RemoveRegionWindlightSettings(wl.regionID);
851 }
852
853 // sql insert
854 sql = @"INSERT INTO [regionwindlight]
855 ([region_id]
856 ,[water_color_r]
857 ,[water_color_g]
858 ,[water_color_b]
859 ,[water_fog_density_exponent]
860 ,[underwater_fog_modifier]
861 ,[reflection_wavelet_scale_1]
862 ,[reflection_wavelet_scale_2]
863 ,[reflection_wavelet_scale_3]
864 ,[fresnel_scale]
865 ,[fresnel_offset]
866 ,[refract_scale_above]
867 ,[refract_scale_below]
868 ,[blur_multiplier]
869 ,[big_wave_direction_x]
870 ,[big_wave_direction_y]
871 ,[little_wave_direction_x]
872 ,[little_wave_direction_y]
873 ,[normal_map_texture]
874 ,[horizon_r]
875 ,[horizon_g]
876 ,[horizon_b]
877 ,[horizon_i]
878 ,[haze_horizon]
879 ,[blue_density_r]
880 ,[blue_density_g]
881 ,[blue_density_b]
882 ,[blue_density_i]
883 ,[haze_density]
884 ,[density_multiplier]
885 ,[distance_multiplier]
886 ,[max_altitude]
887 ,[sun_moon_color_r]
888 ,[sun_moon_color_g]
889 ,[sun_moon_color_b]
890 ,[sun_moon_color_i]
891 ,[sun_moon_position]
892 ,[ambient_r]
893 ,[ambient_g]
894 ,[ambient_b]
895 ,[ambient_i]
896 ,[east_angle]
897 ,[sun_glow_focus]
898 ,[sun_glow_size]
899 ,[scene_gamma]
900 ,[star_brightness]
901 ,[cloud_color_r]
902 ,[cloud_color_g]
903 ,[cloud_color_b]
904 ,[cloud_color_i]
905 ,[cloud_x]
906 ,[cloud_y]
907 ,[cloud_density]
908 ,[cloud_coverage]
909 ,[cloud_scale]
910 ,[cloud_detail_x]
911 ,[cloud_detail_y]
912 ,[cloud_detail_density]
913 ,[cloud_scroll_x]
914 ,[cloud_scroll_x_lock]
915 ,[cloud_scroll_y]
916 ,[cloud_scroll_y_lock]
917 ,[draw_classic_clouds])
918 VALUES
919 (@region_id
920 ,@water_color_r
921 ,@water_color_g
922 ,@water_color_b
923 ,@water_fog_density_exponent
924 ,@underwater_fog_modifier
925 ,@reflection_wavelet_scale_1
926 ,@reflection_wavelet_scale_2
927 ,@reflection_wavelet_scale_3
928 ,@fresnel_scale
929 ,@fresnel_offset
930 ,@refract_scale_above
931 ,@refract_scale_below
932 ,@blur_multiplier
933 ,@big_wave_direction_x
934 ,@big_wave_direction_y
935 ,@little_wave_direction_x
936 ,@little_wave_direction_y
937 ,@normal_map_texture
938 ,@horizon_r
939 ,@horizon_g
940 ,@horizon_b
941 ,@horizon_i
942 ,@haze_horizon
943 ,@blue_density_r
944 ,@blue_density_g
945 ,@blue_density_b
946 ,@blue_density_i
947 ,@haze_density
948 ,@density_multiplier
949 ,@distance_multiplier
950 ,@max_altitude
951 ,@sun_moon_color_r
952 ,@sun_moon_color_g
953 ,@sun_moon_color_b
954 ,@sun_moon_color_i
955 ,@sun_moon_position
956 ,@ambient_r
957 ,@ambient_g
958 ,@ambient_b
959 ,@ambient_i
960 ,@east_angle
961 ,@sun_glow_focus
962 ,@sun_glow_size
963 ,@scene_gamma
964 ,@star_brightness
965 ,@cloud_color_r
966 ,@cloud_color_g
967 ,@cloud_color_b
968 ,@cloud_color_i
969 ,@cloud_x
970 ,@cloud_y
971 ,@cloud_density
972 ,@cloud_coverage
973 ,@cloud_scale
974 ,@cloud_detail_x
975 ,@cloud_detail_y
976 ,@cloud_detail_density
977 ,@cloud_scroll_x
978 ,@cloud_scroll_x_lock
979 ,@cloud_scroll_y
980 ,@cloud_scroll_y_lock
981 ,@draw_classic_clouds)";
982 using (SqlConnection conn = new SqlConnection(m_connectionString))
983 {
984 conn.Open();
985 using (SqlCommand cmd = new SqlCommand(sql, conn))
986 {
987 cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID));
988 cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X));
989 cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y));
990 cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z));
991 cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent));
992 cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier));
993 cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X));
994 cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y));
995 cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z));
996 cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale));
997 cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset));
998 cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove));
999 cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow));
1000 cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier));
1001 cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X));
1002 cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y));
1003 cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X));
1004 cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y));
1005 cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture));
1006 cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X));
1007 cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y));
1008 cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z));
1009 cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W));
1010 cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon));
1011 cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X));
1012 cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y));
1013 cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z));
1014 cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W));
1015 cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity));
1016 cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier));
1017 cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier));
1018 cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude));
1019 cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X));
1020 cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y));
1021 cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z));
1022 cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W));
1023 cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition));
1024 cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X));
1025 cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y));
1026 cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z));
1027 cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W));
1028 cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle));
1029 cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus));
1030 cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize));
1031 cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma));
1032 cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness));
1033 cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X));
1034 cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y));
1035 cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z));
1036 cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W));
1037 cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X));
1038 cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y));
1039 cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z));
1040 cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage));
1041 cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale));
1042 cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X));
1043 cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y));
1044 cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z));
1045 cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX));
1046 cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock));
1047 cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY));
1048 cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock));
1049 cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds));
1050
1051 cmd.ExecuteNonQuery();
1052 }
1053 }
1054 #region update
1055 // }
1056 // else
1057 // {
1058 // // sql update
1059 // sql = @"UPDATE [OpenSim].[dbo].[regionwindlight]
1060 // SET [region_id] = @region_id
1061 // ,[water_color_r] = @water_color_r
1062 // ,[water_color_g] = @water_color_g
1063 // ,[water_color_b] = @water_color_b
1064 // ,[water_fog_density_exponent] = @water_fog_density_exponent
1065 // ,[underwater_fog_modifier] = @underwater_fog_modifier
1066 // ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1
1067 // ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2
1068 // ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3
1069 // ,[fresnel_scale] = @fresnel_scale
1070 // ,[fresnel_offset] = @fresnel_offset
1071 // ,[refract_scale_above] = @refract_scale_above
1072 // ,[refract_scale_below] = @refract_scale_below
1073 // ,[blur_multiplier] = @blur_multiplier
1074 // ,[big_wave_direction_x] = @big_wave_direction_x
1075 // ,[big_wave_direction_y] = @big_wave_direction_y
1076 // ,[little_wave_direction_x] = @little_wave_direction_x
1077 // ,[little_wave_direction_y] = @little_wave_direction_y
1078 // ,[normal_map_texture] = @normal_map_texture
1079 // ,[horizon_r] = @horizon_r
1080 // ,[horizon_g] = @horizon_g
1081 // ,[horizon_b] = @horizon_b
1082 // ,[horizon_i] = @horizon_i
1083 // ,[haze_horizon] = @haze_horizon
1084 // ,[blue_density_r] = @blue_density_r
1085 // ,[blue_density_g] = @blue_density_g
1086 // ,[blue_density_b] = @blue_density_b
1087 // ,[blue_density_i] = @blue_density_i
1088 // ,[haze_density] = @haze_density
1089 // ,[density_multiplier] = @density_multiplier
1090 // ,[distance_multiplier] = @distance_multiplier
1091 // ,[max_altitude] = @max_altitude
1092 // ,[sun_moon_color_r] = @sun_moon_color_r
1093 // ,[sun_moon_color_g] = @sun_moon_color_g
1094 // ,[sun_moon_color_b] = @sun_moon_color_b
1095 // ,[sun_moon_color_i] = @sun_moon_color_i
1096 // ,[sun_moon_position] = @sun_moon_position
1097 // ,[ambient_r] = @ambient_r
1098 // ,[ambient_g] = @ambient_g
1099 // ,[ambient_b] = @ambient_b
1100 // ,[ambient_i] = @ambient_i
1101 // ,[east_angle] = @east_angle
1102 // ,[sun_glow_focus] = @sun_glow_focus
1103 // ,[sun_glow_size] = @sun_glow_size
1104 // ,[scene_gamma] = @scene_gamma
1105 // ,[star_brightness] = @star_brightness
1106 // ,[cloud_color_r] = @cloud_color_r
1107 // ,[cloud_color_g] = @cloud_color_g
1108 // ,[cloud_color_b] = @cloud_color_b
1109 // ,[cloud_color_i] = @cloud_color_i
1110 // ,[cloud_x] = @cloud_x
1111 // ,[cloud_y] = @cloud_y
1112 // ,[cloud_density] = @cloud_density
1113 // ,[cloud_coverage] = @cloud_coverage
1114 // ,[cloud_scale] = @cloud_scale
1115 // ,[cloud_detail_x] = @cloud_detail_x
1116 // ,[cloud_detail_y] = @cloud_detail_y
1117 // ,[cloud_detail_density] = @cloud_detail_density
1118 // ,[cloud_scroll_x] = @cloud_scroll_x
1119 // ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock
1120 // ,[cloud_scroll_y] = @cloud_scroll_y
1121 // ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock
1122 // ,[draw_classic_clouds] = @draw_classic_clouds
1123 // WHERE region_id = @region_id";
1124 // using (SqlConnection conn = new SqlConnection(m_connectionString))
1125 // {
1126 // conn.Open();
1127 // using (SqlCommand cmd = new SqlCommand(sql, conn))
1128 // {
1129 // cmd.Parameters.AddWithValue("region_id", wl.regionID);
1130 // cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
1131 // cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
1132 // cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
1133 // cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
1134 // cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
1135 // cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
1136 // cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
1137 // cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
1138 // cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
1139 // cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
1140 // cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
1141 // cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
1142 // cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
1143 // cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
1144 // cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
1145 // cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
1146 // cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
1147 // cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
1148 // cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
1149 // cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
1150 // cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
1151 // cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
1152 // cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
1153 // cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
1154 // cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
1155 // cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
1156 // cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
1157 // cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
1158 // cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
1159 // cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
1160 // cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
1161 // cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
1162 // cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
1163 // cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
1164 // cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
1165 // cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
1166 // cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
1167 // cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
1168 // cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
1169 // cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
1170 // cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
1171 // cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
1172 // cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
1173 // cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
1174 // cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
1175 // cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
1176 // cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
1177 // cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
1178 // cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
1179 // cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
1180 // cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
1181 // cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
1182 // cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
1183 // cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
1184 // cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
1185 // cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
1186 // cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
1187 // cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
1188 // cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
1189 // cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
1190 // cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
1191 // cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
1192
1193 // cmd.ExecuteNonQuery();
1194 // }
1195 // }
1196 // }
1197 #endregion
713 } 1198 }
714 /// <summary> 1199 /// <summary>
715 /// Loads the settings of a region. 1200 /// Loads the settings of a region.
@@ -1136,7 +1621,7 @@ VALUES
1136 if (Convert.ToInt16(primRow["PassTouches"]) != 0) 1621 if (Convert.ToInt16(primRow["PassTouches"]) != 0)
1137 prim.PassTouches = true; 1622 prim.PassTouches = true;
1138 prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]); 1623 prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
1139 1624
1140 if (!(primRow["MediaURL"] is System.DBNull)) 1625 if (!(primRow["MediaURL"] is System.DBNull))
1141 prim.MediaUrl = (string)primRow["MediaURL"]; 1626 prim.MediaUrl = (string)primRow["MediaURL"];
1142 1627
@@ -1192,11 +1677,11 @@ VALUES
1192 { 1677 {
1193 } 1678 }
1194 1679
1195 if (!(shapeRow["Media"] is System.DBNull) ) 1680 if (!(shapeRow["Media"] is System.DBNull))
1196 { 1681 {
1197 baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]); 1682 baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
1198 } 1683 }
1199 1684
1200 1685
1201 return baseShape; 1686 return baseShape;
1202 } 1687 }
@@ -1576,15 +2061,15 @@ VALUES
1576 parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams)); 2061 parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
1577 parameters.Add(_Database.CreateParameter("State", s.State)); 2062 parameters.Add(_Database.CreateParameter("State", s.State));
1578 2063
1579 if(null == s.Media ) 2064 if (null == s.Media)
1580 { 2065 {
1581 parameters.Add(_Database.CreateParameter("Media", DBNull.Value)); 2066 parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
1582 } 2067 }
1583 else 2068 else
1584 { 2069 {
1585 parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml())); 2070 parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
1586 } 2071 }
1587 2072
1588 2073
1589 return parameters.ToArray(); 2074 return parameters.ToArray();
1590 } 2075 }
diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
index dc35a2e..1f6994d 100644
--- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
@@ -66,11 +66,18 @@ namespace OpenSim.Data.MSSQL
66 66
67 public bool StoreFolder(XInventoryFolder folder) 67 public bool StoreFolder(XInventoryFolder folder)
68 { 68 {
69 if (folder.folderName.Length > 64)
70 folder.folderName = folder.folderName.Substring(0, 64);
69 return m_Folders.Store(folder); 71 return m_Folders.Store(folder);
70 } 72 }
71 73
72 public bool StoreItem(XInventoryItem item) 74 public bool StoreItem(XInventoryItem item)
73 { 75 {
76 if (item.inventoryName.Length > 64)
77 item.inventoryName = item.inventoryName.Substring(0, 64);
78 if (item.inventoryDescription.Length > 128)
79 item.inventoryDescription = item.inventoryDescription.Substring(0, 128);
80
74 return m_Items.Store(item); 81 return m_Items.Store(item);
75 } 82 }
76 83
@@ -78,7 +85,6 @@ namespace OpenSim.Data.MSSQL
78 { 85 {
79 return m_Folders.Delete(field, val); 86 return m_Folders.Delete(field, val);
80 } 87 }
81
82 public bool DeleteFolders(string[] fields, string[] vals) 88 public bool DeleteFolders(string[] fields, string[] vals)
83 { 89 {
84 return m_Folders.Delete(fields, vals); 90 return m_Folders.Delete(fields, vals);
@@ -88,12 +94,10 @@ namespace OpenSim.Data.MSSQL
88 { 94 {
89 return m_Items.Delete(field, val); 95 return m_Items.Delete(field, val);
90 } 96 }
91
92 public bool DeleteItems(string[] fields, string[] vals) 97 public bool DeleteItems(string[] fields, string[] vals)
93 { 98 {
94 return m_Items.Delete(fields, vals); 99 return m_Items.Delete(fields, vals);
95 } 100 }
96
97 public bool MoveItem(string id, string newParent) 101 public bool MoveItem(string id, string newParent)
98 { 102 {
99 return m_Items.MoveItem(id, newParent); 103 return m_Items.MoveItem(id, newParent);
@@ -172,5 +176,27 @@ namespace OpenSim.Data.MSSQL
172 176
173 } 177 }
174 } 178 }
179 public override bool Store(XInventoryItem item)
180 {
181 if (!base.Store(item))
182 return false;
183 string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
184 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
185 using (SqlCommand cmd = new SqlCommand(sql, conn))
186 {
187 conn.Open();
188
189 cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString());
190 try
191 {
192 cmd.ExecuteNonQuery();
193 }
194 catch (Exception e)
195 {
196 return false;
197 }
198 }
199 return true;
200 }
175 } 201 }
176} 202}
diff --git a/OpenSim/Data/MSSQL/Resources/Avatar.migrations b/OpenSim/Data/MSSQL/Resources/Avatar.migrations
index 5364153..61f7b56 100644
--- a/OpenSim/Data/MSSQL/Resources/Avatar.migrations
+++ b/OpenSim/Data/MSSQL/Resources/Avatar.migrations
@@ -37,4 +37,28 @@ EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
37 37
38COMMIT 38COMMIT
39 39
40:VERSION 3
41
42BEGIN TRANSACTION
43
44CREATE TABLE dbo.Tmp_Avatars
45 (
46 PrincipalID uniqueidentifier NOT NULL,
47 [Name] varchar(32) NOT NULL,
48 Value text NOT NULL DEFAULT '',
49 PRIMARY KEY CLUSTERED
50(
51 [PrincipalID] ASC, [Name] ASC
52)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
53) ON [PRIMARY]
54 TEXTIMAGE_ON [PRIMARY]
55
56IF EXISTS(SELECT * FROM dbo.Avatars)
57 EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
58 SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
59
60DROP TABLE dbo.Avatars
61
62EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
63COMMIT
40 64
diff --git a/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations b/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations
index 7a7cecd..ecd3f4d 100644
--- a/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations
@@ -17,3 +17,49 @@ CREATE TABLE "GridUser" (
17) 17)
18 18
19COMMIT 19COMMIT
20
21:VERSION 2 # --------------------------
22
23BEGIN TRANSACTION
24
25CREATE TABLE [GridUser_tmp] (
26 [UserID] VARCHAR(255) NOT NULL,
27 [HomeRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
28 [HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
29 [HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
30 [LastRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
31 [LastPosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
32 [LastLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
33 [Online] CHAR(5) NOT NULL DEFAULT 'false',
34 [Login] CHAR(16) NOT NULL DEFAULT '0',
35 [Logout] CHAR(16) NOT NULL DEFAULT '0',
36
37 PRIMARY KEY CLUSTERED
38 (
39 [UserID] ASC
40 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
41 ) ON [PRIMARY]
42
43COMMIT
44
45IF EXISTS(SELECT * FROM dbo.GridUser)
46 EXEC('INSERT INTO dbo.GridUser_tmp ([UserID]
47 ,[HomeRegionID]
48 ,[HomePosition]
49 ,[HomeLookAt]
50 ,[LastRegionID]
51 ,[LastPosition]
52 ,[LastLookAt]
53 ,[Online]
54 ,[Login]
55 ,[Logout])
56 SELECT CONVERT(varchar(36), [HomeRegionID]), [HomePosition] ,[HomeLookAt] , CONVERT(varchar(36),[LastRegionID])
57 ,[LastPosition]
58 ,[LastLookAt]
59 ,[Online]
60 ,[Login]
61 ,[Logout] FROM dbo.GridUser WITH (HOLDLOCK TABLOCKX)')
62
63DROP TABLE dbo.GridUser
64
65EXECUTE sp_rename N'dbo.GridUser_tmp', N'GridUser', 'OBJECT' \ No newline at end of file
diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
index 340b63d..3995e6c 100644
--- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations
@@ -1003,7 +1003,7 @@ CREATE TABLE "regionwindlight" (
1003 PRIMARY KEY ("region_id") 1003 PRIMARY KEY ("region_id")
1004) 1004)
1005 1005
1006COMMIT TRANSACTION 1006COMMIT
1007 1007
1008:VERSION 26 1008:VERSION 26
1009 1009
diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs
index 663fad6..130ba5e 100644
--- a/OpenSim/Data/MySQL/MySQLFriendsData.cs
+++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs
@@ -44,6 +44,11 @@ namespace OpenSim.Data.MySQL
44 44
45 public bool Delete(UUID principalID, string friend) 45 public bool Delete(UUID principalID, string friend)
46 { 46 {
47 return Delete(principalID.ToString(), friend);
48 }
49
50 public bool Delete(string principalID, string friend)
51 {
47 MySqlCommand cmd = new MySqlCommand(); 52 MySqlCommand cmd = new MySqlCommand();
48 53
49 cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm); 54 cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
@@ -64,5 +69,14 @@ namespace OpenSim.Data.MySQL
64 69
65 return DoQuery(cmd); 70 return DoQuery(cmd);
66 } 71 }
72
73 public FriendsData[] GetFriends(string principalID)
74 {
75 MySqlCommand cmd = new MySqlCommand();
76
77 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
78 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
79 return DoQuery(cmd);
80 }
67 } 81 }
68} 82}
diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
index ce713bd..7848e49 100644
--- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
@@ -21,5 +21,12 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf
21 21
22COMMIT; 22COMMIT;
23 23
24:VERSION 3 # -------------------------
24 25
26BEGIN;
27
28ALTER TABLE `Friends` DROP PRIMARY KEY;
29ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36));
30ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
25 31
32COMMIT;
diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs
index e7f7fd3..d90788a 100644
--- a/OpenSim/Data/Null/NullFriendsData.cs
+++ b/OpenSim/Data/Null/NullFriendsData.cs
@@ -42,6 +42,11 @@ namespace OpenSim.Data.Null
42 { 42 {
43 } 43 }
44 44
45 public FriendsData[] GetFriends(UUID principalID)
46 {
47 return GetFriends(principalID.ToString());
48 }
49
45 /// <summary> 50 /// <summary>
46 /// Tries to implement the Get [] semantics, but it cuts corners. 51 /// Tries to implement the Get [] semantics, but it cuts corners.
47 /// Specifically, it gets all friendships even if they weren't accepted yet. 52 /// Specifically, it gets all friendships even if they weren't accepted yet.
@@ -49,11 +54,11 @@ namespace OpenSim.Data.Null
49 /// <param name="fields"></param> 54 /// <param name="fields"></param>
50 /// <param name="values"></param> 55 /// <param name="values"></param>
51 /// <returns></returns> 56 /// <returns></returns>
52 public FriendsData[] GetFriends(UUID userID) 57 public FriendsData[] GetFriends(string userID)
53 { 58 {
54 List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata) 59 List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
55 { 60 {
56 return fdata.PrincipalID == userID; 61 return fdata.PrincipalID == userID.ToString();
57 }); 62 });
58 63
59 if (lst != null) 64 if (lst != null)
@@ -72,9 +77,14 @@ namespace OpenSim.Data.Null
72 return true; 77 return true;
73 } 78 }
74 79
75 public bool Delete(UUID userID, string friendID) 80 public bool Delete(UUID principalID, string friend)
81 {
82 return Delete(principalID.ToString(), friend);
83 }
84
85 public bool Delete(string userID, string friendID)
76 { 86 {
77 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; }); 87 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
78 if (lst != null) 88 if (lst != null)
79 { 89 {
80 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); 90 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs
index 4bfd228..b14c348 100644
--- a/OpenSim/Data/SQLite/SQLiteFriendsData.cs
+++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs
@@ -46,7 +46,12 @@ namespace OpenSim.Data.SQLite
46 { 46 {
47 } 47 }
48 48
49 public FriendsData[] GetFriends(UUID userID) 49 public FriendsData[] GetFriends(UUID principalID)
50 {
51 return GetFriends(principalID.ToString());
52 }
53
54 public FriendsData[] GetFriends(string userID)
50 { 55 {
51 SqliteCommand cmd = new SqliteCommand(); 56 SqliteCommand cmd = new SqliteCommand();
52 57
@@ -59,6 +64,11 @@ namespace OpenSim.Data.SQLite
59 64
60 public bool Delete(UUID principalID, string friend) 65 public bool Delete(UUID principalID, string friend)
61 { 66 {
67 return Delete(principalID.ToString(), friend);
68 }
69
70 public bool Delete(string principalID, string friend)
71 {
62 SqliteCommand cmd = new SqliteCommand(); 72 SqliteCommand cmd = new SqliteCommand();
63 73
64 cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm); 74 cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
index 3fb2d3f..0d7ae1f 100644
--- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
+++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
@@ -280,7 +280,7 @@ namespace OpenSim.Data.SQLite
280 280
281 string where = String.Join(" and ", terms.ToArray()); 281 string where = String.Join(" and ", terms.ToArray());
282 282
283 string query = String.Format("delete * from {0} where {1}", m_Realm, where); 283 string query = String.Format("delete from {0} where {1}", m_Realm, where);
284 284
285 cmd.CommandText = query; 285 cmd.CommandText = query;
286 286
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs
index dbd47d3..125910e 100644
--- a/OpenSim/Framework/AgentCircuitData.cs
+++ b/OpenSim/Framework/AgentCircuitData.cs
@@ -345,6 +345,7 @@ namespace OpenSim.Framework
345 } 345 }
346 } 346 }
347 } 347 }
348
348 } 349 }
349 350
350 351
diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs
index 98fa846..8e24f91 100644
--- a/OpenSim/Framework/AssetBase.cs
+++ b/OpenSim/Framework/AssetBase.cs
@@ -223,6 +223,12 @@ namespace OpenSim.Framework
223 set { m_metadata.Temporary = value; } 223 set { m_metadata.Temporary = value; }
224 } 224 }
225 225
226 public string CreatorID
227 {
228 get { return m_metadata.CreatorID; }
229 set { m_metadata.CreatorID = value; }
230 }
231
226 public AssetFlags Flags 232 public AssetFlags Flags
227 { 233 {
228 get { return m_metadata.Flags; } 234 get { return m_metadata.Flags; }
diff --git a/OpenSim/Framework/AssetLandmark.cs b/OpenSim/Framework/AssetLandmark.cs
index f433235..103f756 100644
--- a/OpenSim/Framework/AssetLandmark.cs
+++ b/OpenSim/Framework/AssetLandmark.cs
@@ -35,6 +35,7 @@ namespace OpenSim.Framework
35 public Vector3 Position; 35 public Vector3 Position;
36 public ulong RegionHandle; 36 public ulong RegionHandle;
37 public UUID RegionID; 37 public UUID RegionID;
38 public string Gatekeeper = string.Empty;
38 public int Version; 39 public int Version;
39 40
40 public AssetLandmark(AssetBase a) 41 public AssetLandmark(AssetBase a)
@@ -51,6 +52,8 @@ namespace OpenSim.Framework
51 string[] parts = temp.Split('\n'); 52 string[] parts = temp.Split('\n');
52 int.TryParse(parts[0].Substring(17, 1), out Version); 53 int.TryParse(parts[0].Substring(17, 1), out Version);
53 UUID.TryParse(parts[1].Substring(10, 36), out RegionID); 54 UUID.TryParse(parts[1].Substring(10, 36), out RegionID);
55 if (parts.Length >= 5)
56 Gatekeeper = parts[4].Replace("gatekeeper ", "");
54 // The position is a vector with spaces as separators ("10.3 32.5 43"). 57 // The position is a vector with spaces as separators ("10.3 32.5 43").
55 // Parse each scalar separately to take into account the system's culture setting. 58 // Parse each scalar separately to take into account the system's culture setting.
56 string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' '); 59 string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' ');
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 3cf5f32..31a45e2 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Framework
83 IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags); 83 IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags);
84 84
85 public delegate void TeleportLandmarkRequest( 85 public delegate void TeleportLandmarkRequest(
86 IClientAPI remoteClient, UUID regionID, Vector3 position); 86 IClientAPI remoteClient, AssetLandmark lm);
87 87
88 public delegate void DisconnectUser(); 88 public delegate void DisconnectUser();
89 89
@@ -1165,7 +1165,19 @@ namespace OpenSim.Framework
1165 void SendAgentAlertMessage(string message, bool modal); 1165 void SendAgentAlertMessage(string message, bool modal);
1166 void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url); 1166 void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url);
1167 1167
1168 void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, 1168 /// <summary>
1169 /// Open a dialog box on the client.
1170 /// </summary>
1171 /// <param name="objectname"></param>
1172 /// <param name="objectID"></param>
1173 /// <param name="ownerID">/param>
1174 /// <param name="ownerFirstName"></param>
1175 /// <param name="ownerLastName"></param>
1176 /// <param name="msg"></param>
1177 /// <param name="textureID"></param>
1178 /// <param name="ch"></param>
1179 /// <param name="buttonlabels"></param>
1180 void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
1169 string[] buttonlabels); 1181 string[] buttonlabels);
1170 1182
1171 bool AddMoney(int debit); 1183 bool AddMoney(int debit);
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 366a38f..5ace351 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1706,5 +1706,68 @@ namespace OpenSim.Framework
1706 return (T)Enum.Parse(typeof(T), value); ; 1706 return (T)Enum.Parse(typeof(T), value); ;
1707 } 1707 }
1708 #endregion 1708 #endregion
1709
1710 #region Universal User Identifiers
1711 /// <summary>
1712 /// </summary>
1713 /// <param name="value">uuid[;endpoint[;name]]</param>
1714 /// <param name="uuid"></param>
1715 /// <param name="url"></param>
1716 /// <param name="firstname"></param>
1717 /// <param name="lastname"></param>
1718 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
1719 {
1720 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
1721
1722 string[] parts = value.Split(';');
1723 if (parts.Length >= 1)
1724 if (!UUID.TryParse(parts[0], out uuid))
1725 return false;
1726
1727 if (parts.Length >= 2)
1728 url = parts[1];
1729
1730 if (parts.Length >= 3)
1731 {
1732 string[] name = parts[2].Split();
1733 if (name.Length == 2)
1734 {
1735 firstname = name[0];
1736 lastname = name[1];
1737 }
1738 }
1739 if (parts.Length >= 4)
1740 secret = parts[3];
1741
1742 return true;
1743 }
1744
1745 /// <summary>
1746 ///
1747 /// </summary>
1748 /// <param name="acircuit"></param>
1749 /// <returns>uuid[;endpoint[;name]]</returns>
1750 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
1751 {
1752 if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
1753 {
1754 string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
1755 if (!agentsURI.EndsWith("/"))
1756 agentsURI += "/";
1757
1758 // This is ugly, but there's no other way, given that the name is changed
1759 // in the agent circuit data for foreigners
1760 if (acircuit.lastname.Contains("@"))
1761 {
1762 string[] parts = acircuit.firstname.Split(new char[] { '.' });
1763 if (parts.Length == 2)
1764 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
1765 }
1766 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
1767 }
1768 else
1769 return acircuit.AgentID.ToString();
1770 }
1771 #endregion
1709 } 1772 }
1710} 1773}
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 7e320e6..3b261e7 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -231,6 +231,8 @@ namespace OpenSim
231 configSource.Alias.AddAlias("Off", false); 231 configSource.Alias.AddAlias("Off", false);
232 configSource.Alias.AddAlias("True", true); 232 configSource.Alias.AddAlias("True", true);
233 configSource.Alias.AddAlias("False", false); 233 configSource.Alias.AddAlias("False", false);
234 configSource.Alias.AddAlias("Yes", true);
235 configSource.Alias.AddAlias("No", false);
234 236
235 configSource.AddSwitch("Startup", "background"); 237 configSource.AddSwitch("Startup", "background");
236 configSource.AddSwitch("Startup", "inifile"); 238 configSource.AddSwitch("Startup", "inifile");
@@ -239,6 +241,8 @@ namespace OpenSim
239 configSource.AddSwitch("Startup", "physics"); 241 configSource.AddSwitch("Startup", "physics");
240 configSource.AddSwitch("Startup", "gui"); 242 configSource.AddSwitch("Startup", "gui");
241 configSource.AddSwitch("Startup", "console"); 243 configSource.AddSwitch("Startup", "console");
244 configSource.AddSwitch("Startup", "save_crashes");
245 configSource.AddSwitch("Startup", "crash_dir");
242 246
243 configSource.AddConfig("StandAlone"); 247 configSource.AddConfig("StandAlone");
244 configSource.AddConfig("Network"); 248 configSource.AddConfig("Network");
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 503123e..04a68ae 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -918,7 +918,7 @@ namespace OpenSim
918 918
919 if (regInfo.EstateSettings.EstateID == 0) // No record at all 919 if (regInfo.EstateSettings.EstateID == 0) // No record at all
920 { 920 {
921 MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName); 921 m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
922 922
923 List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll(); 923 List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
924 List<string> estateNames = new List<string>(); 924 List<string> estateNames = new List<string>();
@@ -929,7 +929,7 @@ namespace OpenSim
929 { 929 {
930 if (estates.Count == 0) 930 if (estates.Count == 0)
931 { 931 {
932 MainConsole.Instance.Output("No existing estates found. You must create a new one."); 932 m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
933 933
934 if (CreateEstate(regInfo, estateNames)) 934 if (CreateEstate(regInfo, estateNames))
935 break; 935 break;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 05e6d27..eed8878 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1476,6 +1476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1476 money.MoneyData.TransactionSuccess = success; 1476 money.MoneyData.TransactionSuccess = success;
1477 money.MoneyData.Description = description; 1477 money.MoneyData.Description = description;
1478 money.MoneyData.MoneyBalance = balance; 1478 money.MoneyData.MoneyBalance = balance;
1479 money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
1479 OutPacket(money, ThrottleOutPacketType.Task); 1480 OutPacket(money, ThrottleOutPacketType.Task);
1480 } 1481 }
1481 1482
@@ -2231,7 +2232,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2231 OutPacket(loadURL, ThrottleOutPacketType.Task); 2232 OutPacket(loadURL, ThrottleOutPacketType.Task);
2232 } 2233 }
2233 2234
2234 public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 2235 public void SendDialog(
2236 string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
2237 UUID textureID, int ch, string[] buttonlabels)
2235 { 2238 {
2236 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); 2239 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
2237 dialog.Data.ObjectID = objectID; 2240 dialog.Data.ObjectID = objectID;
@@ -2249,6 +2252,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2249 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); 2252 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
2250 } 2253 }
2251 dialog.Buttons = buttons; 2254 dialog.Buttons = buttons;
2255
2256 dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
2257 dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
2258 dialog.OwnerData[0].OwnerID = ownerID;
2259
2252 OutPacket(dialog, ThrottleOutPacketType.Task); 2260 OutPacket(dialog, ThrottleOutPacketType.Task);
2253 } 2261 }
2254 2262
@@ -2320,8 +2328,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2320 OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff; 2328 OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
2321 } 2329 }
2322 2330
2323
2324
2325 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage); 2331 SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
2326 viewertime.TimeInfo.SunDirection = Position; 2332 viewertime.TimeInfo.SunDirection = Position;
2327 viewertime.TimeInfo.SunAngVelocity = Velocity; 2333 viewertime.TimeInfo.SunAngVelocity = Velocity;
@@ -8358,16 +8364,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8358 AssetLandmark lm; 8364 AssetLandmark lm;
8359 if (lmid != UUID.Zero) 8365 if (lmid != UUID.Zero)
8360 { 8366 {
8367
8361 //AssetBase lma = m_assetCache.GetAsset(lmid, false); 8368 //AssetBase lma = m_assetCache.GetAsset(lmid, false);
8362 AssetBase lma = m_assetService.Get(lmid.ToString()); 8369 AssetBase lma = m_assetService.Get(lmid.ToString());
8363 8370
8364 if (lma == null) 8371 if (lma == null)
8365 { 8372 {
8366 // Failed to find landmark 8373 // Failed to find landmark
8367 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); 8374
8368 tpCancel.Info.SessionID = tpReq.Info.SessionID; 8375 // Let's try to search in the user's home asset server
8369 tpCancel.Info.AgentID = tpReq.Info.AgentID; 8376 lma = FindAssetInUserAssetServer(lmid.ToString());
8370 OutPacket(tpCancel, ThrottleOutPacketType.Task); 8377
8378 if (lma == null)
8379 {
8380 // Really doesn't exist
8381 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
8382 tpCancel.Info.SessionID = tpReq.Info.SessionID;
8383 tpCancel.Info.AgentID = tpReq.Info.AgentID;
8384 OutPacket(tpCancel, ThrottleOutPacketType.Task);
8385 }
8371 } 8386 }
8372 8387
8373 try 8388 try
@@ -8398,13 +8413,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8398 TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; 8413 TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
8399 if (handlerTeleportLandmarkRequest != null) 8414 if (handlerTeleportLandmarkRequest != null)
8400 { 8415 {
8401 handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); 8416 handlerTeleportLandmarkRequest(this, lm);
8402 } 8417 }
8403 else 8418 else
8404 { 8419 {
8405 //no event handler so cancel request 8420 //no event handler so cancel request
8406
8407
8408 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel); 8421 TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
8409 tpCancel.Info.AgentID = tpReq.Info.AgentID; 8422 tpCancel.Info.AgentID = tpReq.Info.AgentID;
8410 tpCancel.Info.SessionID = tpReq.Info.SessionID; 8423 tpCancel.Info.SessionID = tpReq.Info.SessionID;
@@ -8414,6 +8427,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8414 return true; 8427 return true;
8415 } 8428 }
8416 8429
8430 private AssetBase FindAssetInUserAssetServer(string id)
8431 {
8432 AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
8433 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
8434 {
8435 string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
8436 return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
8437 }
8438
8439 return null;
8440 }
8441
8417 private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack) 8442 private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
8418 { 8443 {
8419 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; 8444 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index ded8743..8a16582 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
124 124
125 ScenePresence sp = m_scene.GetScenePresence(avatarID); 125 ScenePresence sp = m_scene.GetScenePresence(avatarID);
126 if (sp != null) 126 if (sp != null)
127 sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); 127 sp.ControllingClient.SendDialog(
128 objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
128 } 129 }
129 130
130 public void SendUrlToUser( 131 public void SendUrlToUser(
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 0cd05e3..c8167c5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
49{ 49{
50 public class FriendsModule : ISharedRegionModule, IFriendsModule 50 public class FriendsModule : ISharedRegionModule, IFriendsModule
51 { 51 {
52 protected bool m_Enabled = false;
53
52 protected class UserFriendData 54 protected class UserFriendData
53 { 55 {
54 public UUID PrincipalID; 56 public UUID PrincipalID;
@@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
67 } 69 }
68 } 70 }
69 71
70 private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; 72 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
71 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
72 74
73 protected List<Scene> m_Scenes = new List<Scene>(); 75 protected List<Scene> m_Scenes = new List<Scene>();
@@ -130,8 +132,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
130 } 132 }
131 } 133 }
132 134
135 #region ISharedRegionModule
133 public void Initialise(IConfigSource config) 136 public void Initialise(IConfigSource config)
134 { 137 {
138 IConfig moduleConfig = config.Configs["Modules"];
139 if (moduleConfig != null)
140 {
141 string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
142 if (name == Name)
143 {
144 InitModule(config);
145
146 m_Enabled = true;
147 m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
148 }
149 }
150 }
151
152 protected void InitModule(IConfigSource config)
153 {
135 IConfig friendsConfig = config.Configs["Friends"]; 154 IConfig friendsConfig = config.Configs["Friends"];
136 if (friendsConfig != null) 155 if (friendsConfig != null)
137 { 156 {
@@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
153 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); 172 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
154 throw new Exception("Connector load error"); 173 throw new Exception("Connector load error");
155 } 174 }
156
157 } 175 }
158 176
159 public void PostInitialise() 177 public void PostInitialise()
@@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
164 { 182 {
165 } 183 }
166 184
167 public void AddRegion(Scene scene) 185 public virtual void AddRegion(Scene scene)
168 { 186 {
187 if (!m_Enabled)
188 return;
189 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
190
169 m_Scenes.Add(scene); 191 m_Scenes.Add(scene);
170 scene.RegisterModuleInterface<IFriendsModule>(this); 192 scene.RegisterModuleInterface<IFriendsModule>(this);
171 193
@@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
181 203
182 public void RemoveRegion(Scene scene) 204 public void RemoveRegion(Scene scene)
183 { 205 {
206 if (!m_Enabled)
207 return;
208
184 m_Scenes.Remove(scene); 209 m_Scenes.Remove(scene);
185 } 210 }
186 211
187 public string Name 212 public virtual string Name
188 { 213 {
189 get { return "FriendsModule"; } 214 get { return "FriendsModule"; }
190 } 215 }
@@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
194 get { return null; } 219 get { return null; }
195 } 220 }
196 221
197 public uint GetFriendPerms(UUID principalID, UUID friendID) 222 #endregion
223
224 public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
198 { 225 {
199 FriendInfo[] friends = GetFriends(principalID); 226 FriendInfo[] friends = GetFriends(principalID);
200 foreach (FriendInfo fi in friends) 227 FriendInfo finfo = GetFriend(friends, friendID);
228 if (finfo != null)
201 { 229 {
202 if (fi.Friend == friendID.ToString()) 230 return (uint)finfo.TheirFlags;
203 return (uint)fi.TheirFlags;
204 } 231 }
205 232
206 return 0; 233 return 0;
@@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
214 client.OnTerminateFriendship += OnTerminateFriendship; 241 client.OnTerminateFriendship += OnTerminateFriendship;
215 client.OnGrantUserRights += OnGrantUserRights; 242 client.OnGrantUserRights += OnGrantUserRights;
216 243
217 // Asynchronously fetch the friends list or increment the refcount for the existing 244 Util.FireAndForget(delegate { FetchFriendslist(client); });
218 // friends list 245 }
219 Util.FireAndForget( 246
220 delegate(object o) 247 /// Fetch the friends list or increment the refcount for the existing
248 /// friends list
249 /// Returns true if the list was fetched, false if it wasn't
250 protected virtual bool FetchFriendslist(IClientAPI client)
251 {
252 UUID agentID = client.AgentId;
253 lock (m_Friends)
254 {
255 UserFriendData friendsData;
256 if (m_Friends.TryGetValue(agentID, out friendsData))
221 { 257 {
222 lock (m_Friends) 258 friendsData.Refcount++;
223 { 259 return false;
224 UserFriendData friendsData; 260 }
225 if (m_Friends.TryGetValue(client.AgentId, out friendsData)) 261 else
226 { 262 {
227 friendsData.Refcount++; 263 friendsData = new UserFriendData();
228 } 264 friendsData.PrincipalID = agentID;
229 else 265 friendsData.Friends = GetFriendsFromService(client);
230 { 266 friendsData.Refcount = 1;
231 friendsData = new UserFriendData();
232 friendsData.PrincipalID = client.AgentId;
233 friendsData.Friends = FriendsService.GetFriends(client.AgentId);
234 friendsData.Refcount = 1;
235 267
236 m_Friends[client.AgentId] = friendsData; 268 m_Friends[agentID] = friendsData;
237 } 269 return true;
238 }
239 } 270 }
240 ); 271 }
241 } 272 }
242 273
243 private void OnClientClosed(UUID agentID, Scene scene) 274 private void OnClientClosed(UUID agentID, Scene scene)
@@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
263 294
264 private void OnMakeRootAgent(ScenePresence sp) 295 private void OnMakeRootAgent(ScenePresence sp)
265 { 296 {
266 UUID agentID = sp.ControllingClient.AgentId; 297 RefetchFriends(sp.ControllingClient);
267 UpdateFriendsCache(agentID);
268 } 298 }
269 299
270 private void OnClientLogin(IClientAPI client) 300 private void OnClientLogin(IClientAPI client)
271 { 301 {
272 UUID agentID = client.AgentId; 302 UUID agentID = client.AgentId;
273 303
304 //m_log.DebugFormat("[XXX]: OnClientLogin!");
274 // Inform the friends that this user is online 305 // Inform the friends that this user is online
275 StatusChange(agentID, true); 306 StatusChange(agentID, true);
276 307
@@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
279 m_NeedsListOfFriends.Add(agentID); 310 m_NeedsListOfFriends.Add(agentID);
280 } 311 }
281 312
282 public void SendFriendsOnlineIfNeeded(IClientAPI client) 313 public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
283 { 314 {
284 UUID agentID = client.AgentId; 315 UUID agentID = client.AgentId;
285 316
@@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
287 lock (m_NeedsListOfFriends) 318 lock (m_NeedsListOfFriends)
288 { 319 {
289 if (!m_NeedsListOfFriends.Remove(agentID)) 320 if (!m_NeedsListOfFriends.Remove(agentID))
290 return; 321 return false;
291 } 322 }
292 323
293 // Send the friends online 324 // Send the friends online
@@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
313 foreach (string fid in outstanding) 344 foreach (string fid in outstanding)
314 { 345 {
315 UUID fromAgentID; 346 UUID fromAgentID;
316 if (!UUID.TryParse(fid, out fromAgentID)) 347 string firstname = "Unknown", lastname = "User";
348 if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
349 {
350 m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
317 continue; 351 continue;
318 352 }
319 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
320 353
321 PresenceInfo presence = null; 354 PresenceInfo presence = null;
322 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); 355 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
@@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
326 im.offline = 0; 359 im.offline = 0;
327 360
328 im.fromAgentID = fromAgentID.Guid; 361 im.fromAgentID = fromAgentID.Guid;
329 im.fromAgentName = account.FirstName + " " + account.LastName; 362 im.fromAgentName = firstname + " " + lastname;
330 im.offline = (byte)((presence == null) ? 1 : 0); 363 im.offline = (byte)((presence == null) ? 1 : 0);
331 im.imSessionID = im.fromAgentID; 364 im.imSessionID = im.fromAgentID;
365 im.message = FriendshipMessage(fid);
332 366
333 // Finally 367 // Finally
334 LocalFriendshipOffered(agentID, im); 368 LocalFriendshipOffered(agentID, im);
335 } 369 }
370
371 return true;
372 }
373
374 protected virtual string FriendshipMessage(string friendID)
375 {
376 return "Will you be my friend?";
377 }
378
379 protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
380 {
381 first = "Unknown"; last = "User";
382 if (!UUID.TryParse(fid, out agentID))
383 return false;
384
385 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
386 if (account != null)
387 {
388 first = account.FirstName;
389 last = account.LastName;
390 }
391
392 return true;
336 } 393 }
337 394
338 List<UUID> GetOnlineFriends(UUID userID) 395 List<UUID> GetOnlineFriends(UUID userID)
@@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
348 } 405 }
349 406
350 if (friendList.Count > 0) 407 if (friendList.Count > 0)
351 { 408 GetOnlineFriends(userID, friendList, online);
352 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
353 foreach (PresenceInfo pi in presence)
354 {
355 UUID presenceID;
356 if (UUID.TryParse(pi.UserID, out presenceID))
357 online.Add(presenceID);
358 }
359 }
360 409
361 return online; 410 return online;
362 } 411 }
363 412
413 protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
414 {
415 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
416 foreach (PresenceInfo pi in presence)
417 {
418 UUID presenceID;
419 if (UUID.TryParse(pi.UserID, out presenceID))
420 online.Add(presenceID);
421 }
422 }
423
364 /// <summary> 424 /// <summary>
365 /// Find the client for a ID 425 /// Find the client for a ID
366 /// </summary> 426 /// </summary>
@@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
415 Util.FireAndForget( 475 Util.FireAndForget(
416 delegate 476 delegate
417 { 477 {
418 foreach (FriendInfo fi in friendList) 478 m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
419 { 479 // Notify about this user status
420 //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); 480 StatusNotify(friendList, agentID, online);
421 // Notify about this user status
422 StatusNotify(fi, agentID, online);
423 }
424 } 481 }
425 ); 482 );
426 } 483 }
427 } 484 }
428 485
429 private void StatusNotify(FriendInfo friend, UUID userID, bool online) 486 protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
430 { 487 {
431 UUID friendID; 488 foreach (FriendInfo friend in friendList)
432 if (UUID.TryParse(friend.Friend, out friendID))
433 { 489 {
434 // Try local 490 UUID friendID;
435 if (LocalStatusNotification(userID, friendID, online)) 491 if (UUID.TryParse(friend.Friend, out friendID))
436 return;
437
438 // The friend is not here [as root]. Let's forward.
439 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
440 if (friendSessions != null && friendSessions.Length > 0)
441 { 492 {
442 PresenceInfo friendSession = null; 493 // Try local
443 foreach (PresenceInfo pinfo in friendSessions) 494 if (LocalStatusNotification(userID, friendID, online))
444 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad 495 return;
445 {
446 friendSession = pinfo;
447 break;
448 }
449 496
450 if (friendSession != null) 497 // The friend is not here [as root]. Let's forward.
498 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
499 if (friendSessions != null && friendSessions.Length > 0)
451 { 500 {
452 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 501 PresenceInfo friendSession = null;
453 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); 502 foreach (PresenceInfo pinfo in friendSessions)
454 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); 503 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
504 {
505 friendSession = pinfo;
506 break;
507 }
508
509 if (friendSession != null)
510 {
511 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
512 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
513 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
514 }
455 } 515 }
456 }
457 516
458 // Friend is not online. Ignore. 517 // Friend is not online. Ignore.
459 } 518 }
460 else 519 else
461 { 520 {
462 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); 521 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
522 }
463 } 523 }
464 } 524 }
465 525
@@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
475 535
476 // This user wants to be friends with the other user. 536 // This user wants to be friends with the other user.
477 // Let's add the relation backwards, in case the other is not online 537 // Let's add the relation backwards, in case the other is not online
478 FriendsService.StoreFriend(friendID, principalID.ToString(), 0); 538 StoreBackwards(friendID, principalID);
479 539
480 // Now let's ask the other user to be friends with this user 540 // Now let's ask the other user to be friends with this user
481 ForwardFriendshipOffer(principalID, friendID, im); 541 ForwardFriendshipOffer(principalID, friendID, im);
@@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
487 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 547 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
488 // We stick this agent's ID as imSession, so that it's directly available on the receiving end 548 // We stick this agent's ID as imSession, so that it's directly available on the receiving end
489 im.imSessionID = im.fromAgentID; 549 im.imSessionID = im.fromAgentID;
550 im.fromAgentName = GetFriendshipRequesterName(agentID);
490 551
491 // Try the local sim 552 // Try the local sim
492 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
493 im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
494
495 if (LocalFriendshipOffered(friendID, im)) 553 if (LocalFriendshipOffered(friendID, im))
496 return; 554 return;
497 555
@@ -509,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
509 // If the prospective friend is not online, he'll get the message upon login. 567 // If the prospective friend is not online, he'll get the message upon login.
510 } 568 }
511 569
570 protected virtual string GetFriendshipRequesterName(UUID agentID)
571 {
572 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
573 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
574 }
575
512 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 576 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
513 { 577 {
514 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID); 578 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
515 579
516 FriendsService.StoreFriend(agentID, friendID.ToString(), 1); 580 StoreFriendships(agentID, friendID);
517 FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
518 581
519 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>(); 582 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
520 if (ccm != null) 583 if (ccm != null)
@@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
523 } 586 }
524 587
525 // Update the local cache 588 // Update the local cache
526 UpdateFriendsCache(agentID); 589 RefetchFriends(client);
527 590
528 // 591 //
529 // Notify the friend 592 // Notify the friend
@@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
554 { 617 {
555 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); 618 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
556 619
557 FriendsService.Delete(agentID, friendID.ToString()); 620 DeleteFriendship(agentID, friendID);
558 FriendsService.Delete(friendID, agentID.ToString());
559 621
560 // 622 //
561 // Notify the friend 623 // Notify the friend
@@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
582 644
583 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) 645 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
584 { 646 {
585 FriendsService.Delete(agentID, exfriendID.ToString()); 647 if (!DeleteFriendship(agentID, exfriendID))
586 FriendsService.Delete(exfriendID, agentID.ToString()); 648 client.SendAlertMessage("Unable to terminate friendship on this sim.");
587 649
588 // Update local cache 650 // Update local cache
589 UpdateFriendsCache(agentID); 651 RefetchFriends(client);
590 652
591 client.SendTerminateFriend(exfriendID); 653 client.SendTerminateFriend(exfriendID);
592 654
@@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
612 674
613 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 675 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
614 { 676 {
677 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
678
615 FriendInfo[] friends = GetFriends(remoteClient.AgentId); 679 FriendInfo[] friends = GetFriends(remoteClient.AgentId);
616 if (friends.Length == 0) 680 if (friends.Length == 0)
681 {
617 return; 682 return;
683 }
618 684
619 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
620 // Let's find the friend in this user's friend list 685 // Let's find the friend in this user's friend list
621 FriendInfo friend = null; 686 FriendInfo friend = GetFriend(friends, target);
622 foreach (FriendInfo fi in friends)
623 {
624 if (fi.Friend == target.ToString())
625 friend = fi;
626 }
627 687
628 if (friend != null) // Found it 688 if (friend != null) // Found it
629 { 689 {
630 // Store it on the DB 690 // Store it on the DB
631 FriendsService.StoreFriend(requester, target.ToString(), rights); 691 if (!StoreRights(requester, target, rights))
692 {
693 remoteClient.SendAlertMessage("Unable to grant rights.");
694 return;
695 }
632 696
633 // Store it in the local cache 697 // Store it in the local cache
634 int myFlags = friend.MyFlags; 698 int myFlags = friend.MyFlags;
@@ -658,6 +722,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
658 } 722 }
659 } 723 }
660 } 724 }
725 else
726 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
727 }
728
729 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
730 {
731 foreach (FriendInfo fi in friends)
732 {
733 if (fi.Friend == friendID.ToString())
734 return fi;
735 }
736 return null;
661 } 737 }
662 738
663 #region Local 739 #region Local
@@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
693 769
694 770
695 // Update the local cache 771 // Update the local cache
696 UpdateFriendsCache(friendID); 772 RefetchFriends(friendClient);
697 773
698 // we're done 774 // we're done
699 return true; 775 return true;
@@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
726 // the friend in this sim as root agent 802 // the friend in this sim as root agent
727 friendClient.SendTerminateFriend(exfriendID); 803 friendClient.SendTerminateFriend(exfriendID);
728 // update local cache 804 // update local cache
729 UpdateFriendsCache(exfriendID); 805 RefetchFriends(friendClient);
730 // we're done 806 // we're done
731 return true; 807 return true;
732 } 808 }
@@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
756 } 832 }
757 833
758 // Update local cache 834 // Update local cache
759 lock (m_Friends) 835 UpdateLocalCache(userID, friendID, rights);
760 {
761 FriendInfo[] friends = GetFriends(friendID);
762 foreach (FriendInfo finfo in friends)
763 {
764 if (finfo.Friend == userID.ToString())
765 finfo.TheirFlags = rights;
766 }
767 }
768 836
769 return true; 837 return true;
770 } 838 }
@@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
775 843
776 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online) 844 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
777 { 845 {
846 m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
778 IClientAPI friendClient = LocateClientObject(friendID); 847 IClientAPI friendClient = LocateClientObject(friendID);
779 if (friendClient != null) 848 if (friendClient != null)
780 { 849 {
781 //m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
782 // the friend in this sim as root agent 850 // the friend in this sim as root agent
783 if (online) 851 if (online)
784 friendClient.SendAgentOnline(new UUID[] { userID }); 852 friendClient.SendAgentOnline(new UUID[] { userID });
@@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
793 861
794 #endregion 862 #endregion
795 863
796 private FriendInfo[] GetFriends(UUID agentID) 864 #region Get / Set friends in several flavours
865 /// <summary>
866 /// Get friends from local cache only
867 /// </summary>
868 /// <param name="agentID"></param>
869 /// <returns></returns>
870 protected FriendInfo[] GetFriends(UUID agentID)
797 { 871 {
798 UserFriendData friendsData; 872 UserFriendData friendsData;
799 873
@@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
806 return EMPTY_FRIENDS; 880 return EMPTY_FRIENDS;
807 } 881 }
808 882
809 private void UpdateFriendsCache(UUID agentID) 883 /// <summary>
884 /// Update loca cache only
885 /// </summary>
886 /// <param name="userID"></param>
887 /// <param name="friendID"></param>
888 /// <param name="rights"></param>
889 protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
890 {
891 // Update local cache
892 lock (m_Friends)
893 {
894 FriendInfo[] friends = GetFriends(friendID);
895 FriendInfo finfo = GetFriend(friends, userID);
896 finfo.TheirFlags = rights;
897 }
898 }
899
900 protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
901 {
902 return FriendsService.GetFriends(client.AgentId);
903 }
904
905 private void RefetchFriends(IClientAPI client)
810 { 906 {
907 UUID agentID = client.AgentId;
811 lock (m_Friends) 908 lock (m_Friends)
812 { 909 {
813 UserFriendData friendsData; 910 UserFriendData friendsData;
814 if (m_Friends.TryGetValue(agentID, out friendsData)) 911 if (m_Friends.TryGetValue(agentID, out friendsData))
815 friendsData.Friends = FriendsService.GetFriends(agentID); 912 friendsData.Friends = GetFriendsFromService(client);
816 } 913 }
817 } 914 }
915
916 protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
917 {
918 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
919 return true;
920 }
921
922 protected virtual void StoreBackwards(UUID friendID, UUID agentID)
923 {
924 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
925 }
926
927 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
928 {
929 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
930 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
931 }
932
933 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
934 {
935 FriendsService.Delete(agentID, exfriendID.ToString());
936 FriendsService.Delete(exfriendID, agentID.ToString());
937 return true;
938 }
939
940 #endregion
818 } 941 }
819} 942}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
new file mode 100644
index 0000000..b9d6719
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -0,0 +1,628 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45
46namespace OpenSim.Region.CoreModules.Avatar.Friends
47{
48 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 #region ISharedRegionModule
53 public override string Name
54 {
55 get { return "HGFriendsModule"; }
56 }
57
58 public override void AddRegion(Scene scene)
59 {
60 if (!m_Enabled)
61 return;
62
63 base.AddRegion(scene);
64 scene.RegisterModuleInterface<IFriendsSimConnector>(this);
65 }
66
67 #endregion
68
69 #region IFriendsSimConnector
70
71 /// <summary>
72 /// Notify the user that the friend's status changed
73 /// </summary>
74 /// <param name="userID">user to be notified</param>
75 /// <param name="friendID">friend whose status changed</param>
76 /// <param name="online">status</param>
77 /// <returns></returns>
78 public bool StatusNotify(UUID friendID, UUID userID, bool online)
79 {
80 return LocalStatusNotification(friendID, userID, online);
81 }
82
83 #endregion
84
85 protected override bool FetchFriendslist(IClientAPI client)
86 {
87 if (base.FetchFriendslist(client))
88 {
89 UUID agentID = client.AgentId;
90 // we do this only for the root agent
91 if (m_Friends[agentID].Refcount == 1)
92 {
93 // We need to preload the user management cache with the names
94 // of foreign friends, just like we do with SOPs' creators
95 foreach (FriendInfo finfo in m_Friends[agentID].Friends)
96 {
97 if (finfo.TheirFlags != -1)
98 {
99 UUID id;
100 if (!UUID.TryParse(finfo.Friend, out id))
101 {
102 string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
103 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
104 {
105 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
106 uMan.AddUser(id, url + ";" + first + " " + last);
107 }
108 }
109 }
110 }
111 return true;
112 }
113 }
114 return false;
115 }
116
117 public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
118 {
119 if (base.SendFriendsOnlineIfNeeded(client))
120 {
121 AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
122 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
123 {
124 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
125 if (account == null) // foreign
126 {
127 FriendInfo[] friends = GetFriends(client.AgentId);
128 foreach (FriendInfo f in friends)
129 {
130 client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
131 }
132 }
133 }
134 }
135 return false;
136 }
137
138 protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
139 {
140 List<string> fList = new List<string>();
141 foreach (string s in friendList)
142 fList.Add(s.Substring(0, 36));
143
144 PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
145 foreach (PresenceInfo pi in presence)
146 {
147 UUID presenceID;
148 if (UUID.TryParse(pi.UserID, out presenceID))
149 online.Add(presenceID);
150 }
151 }
152
153 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
154 //{
155 // // Let's single out the UUIs
156 // List<string> localFriends = new List<string>();
157 // List<string> foreignFriends = new List<string>();
158 // string tmp = string.Empty;
159
160 // foreach (string s in friendList)
161 // {
162 // UUID id;
163 // if (UUID.TryParse(s, out id))
164 // localFriends.Add(s);
165 // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
166 // {
167 // foreignFriends.Add(s);
168 // // add it here too, who knows maybe the foreign friends happens to be on this grid
169 // localFriends.Add(id.ToString());
170 // }
171 // }
172
173 // // OK, see who's present on this grid
174 // List<string> toBeRemoved = new List<string>();
175 // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
176 // foreach (PresenceInfo pi in presence)
177 // {
178 // UUID presenceID;
179 // if (UUID.TryParse(pi.UserID, out presenceID))
180 // {
181 // online.Add(presenceID);
182 // foreach (string s in foreignFriends)
183 // if (s.StartsWith(pi.UserID))
184 // toBeRemoved.Add(s);
185 // }
186 // }
187
188 // foreach (string s in toBeRemoved)
189 // foreignFriends.Remove(s);
190
191 // // OK, let's send this up the stack, and leave a closure here
192 // // collecting online friends in other grids
193 // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
194
195 //}
196
197 private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
198 {
199 // let's divide the friends on a per-domain basis
200 Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
201 foreach (string friend in foreignFriends)
202 {
203 UUID friendID;
204 if (!UUID.TryParse(friend, out friendID))
205 {
206 // it's a foreign friend
207 string url = string.Empty, tmp = string.Empty;
208 if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
209 {
210 if (!friendsPerDomain.ContainsKey(url))
211 friendsPerDomain[url] = new List<string>();
212 friendsPerDomain[url].Add(friend);
213 }
214 }
215 }
216
217 // Now, call those worlds
218
219 foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
220 {
221 List<string> ids = new List<string>();
222 foreach (string f in kvp.Value)
223 ids.Add(f);
224 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
225 List<UUID> online = uConn.GetOnlineFriends(userID, ids);
226 // Finally send the notifications to the user
227 // this whole process may take a while, so let's check at every
228 // iteration that the user is still here
229 IClientAPI client = LocateClientObject(userID);
230 if (client != null)
231 client.SendAgentOnline(online.ToArray());
232 else
233 break;
234 }
235
236 }
237
238 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
239 {
240 // First, let's divide the friends on a per-domain basis
241 Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
242 foreach (FriendInfo friend in friendList)
243 {
244 UUID friendID;
245 if (UUID.TryParse(friend.Friend, out friendID))
246 {
247 if (!friendsPerDomain.ContainsKey("local"))
248 friendsPerDomain["local"] = new List<FriendInfo>();
249 friendsPerDomain["local"].Add(friend);
250 }
251 else
252 {
253 // it's a foreign friend
254 string url = string.Empty, tmp = string.Empty;
255 if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
256 {
257 // Let's try our luck in the local sim. Who knows, maybe it's here
258 if (LocalStatusNotification(userID, friendID, online))
259 continue;
260
261 if (!friendsPerDomain.ContainsKey(url))
262 friendsPerDomain[url] = new List<FriendInfo>();
263 friendsPerDomain[url].Add(friend);
264 }
265 }
266 }
267
268 // For the local friends, just call the base method
269 // Let's do this first of all
270 if (friendsPerDomain.ContainsKey("local"))
271 base.StatusNotify(friendsPerDomain["local"], userID, online);
272
273 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
274 {
275 if (kvp.Key != "local")
276 {
277 // For the others, call the user agent service
278 List<string> ids = new List<string>();
279 foreach (FriendInfo f in kvp.Value)
280 ids.Add(f.Friend);
281 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
282 List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
283 // need to debug this here
284 if (online)
285 {
286 IClientAPI client = LocateClientObject(userID);
287 if (client != null)
288 client.SendAgentOnline(friendsOnline.ToArray());
289 }
290 }
291 }
292 }
293
294 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
295 {
296 first = "Unknown"; last = "User";
297 if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
298 return true;
299
300 // fid is not a UUID...
301 string url = string.Empty, tmp = string.Empty;
302 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
303 {
304 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
305 userMan.AddUser(agentID, url + ";" + first + " " + last);
306
307 try // our best
308 {
309 string[] parts = userMan.GetUserName(agentID).Split();
310 first = parts[0];
311 last = parts[1];
312 }
313 catch { }
314 return true;
315 }
316 return false;
317 }
318
319 protected override string GetFriendshipRequesterName(UUID agentID)
320 {
321 // For the time being we assume that HG friendship requests can only happen
322 // when avies are on the same region.
323 IClientAPI client = LocateClientObject(agentID);
324 if (client != null)
325 return client.FirstName + " " + client.LastName;
326 else
327 return base.GetFriendshipRequesterName(agentID);
328 }
329
330 protected override string FriendshipMessage(string friendID)
331 {
332 UUID id;
333 if (UUID.TryParse(friendID, out id))
334 return base.FriendshipMessage(friendID);
335
336 return "Please confirm this friendship you made while you were away.";
337 }
338
339 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
340 {
341 foreach (FriendInfo fi in friends)
342 {
343 if (fi.Friend.StartsWith(friendID.ToString()))
344 return fi;
345 }
346 return null;
347 }
348
349
350 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
351 {
352 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
353 if (account1 != null)
354 return base.GetFriendsFromService(client);
355
356 FriendInfo[] finfos = new FriendInfo[0];
357 // Foreigner
358 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
359 if (agentClientCircuit != null)
360 {
361 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
362
363 finfos = FriendsService.GetFriends(agentUUI);
364 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
365 }
366 return finfos;
367 }
368
369 protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
370 {
371 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
372 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
373 // Are they both local users?
374 if (account1 != null && account2 != null)
375 {
376 // local grid users
377 return base.StoreRights(agentID, friendID, rights);
378 }
379
380 if (account1 != null) // agent is local, friend is foreigner
381 {
382 FriendInfo[] finfos = GetFriends(agentID);
383 FriendInfo finfo = GetFriend(finfos, friendID);
384 if (finfo != null)
385 {
386 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
387 return true;
388 }
389 }
390
391 if (account2 != null) // agent is foreigner, friend is local
392 {
393 string agentUUI = GetUUI(friendID, agentID);
394 if (agentUUI != string.Empty)
395 {
396 FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
397 return true;
398 }
399 }
400
401 return false;
402
403 }
404
405 protected override void StoreBackwards(UUID friendID, UUID agentID)
406 {
407 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
408 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
409 // Are they both local users?
410 if (account1 != null && account2 != null)
411 {
412 // local grid users
413 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
414 base.StoreBackwards(friendID, agentID);
415 return;
416 }
417
418 // no provision for this temporary friendship state
419 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
420 }
421
422 protected override void StoreFriendships(UUID agentID, UUID friendID)
423 {
424 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
425 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
426 // Are they both local users?
427 if (agentAccount != null && friendAccount != null)
428 {
429 // local grid users
430 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
431 base.StoreFriendships(agentID, friendID);
432 return;
433 }
434
435 // ok, at least one of them is foreigner, let's get their data
436 IClientAPI agentClient = LocateClientObject(agentID);
437 IClientAPI friendClient = LocateClientObject(friendID);
438 AgentCircuitData agentClientCircuit = null;
439 AgentCircuitData friendClientCircuit = null;
440 string agentUUI = string.Empty;
441 string friendUUI = string.Empty;
442 string agentFriendService = string.Empty;
443 string friendFriendService = string.Empty;
444
445 if (agentClient != null)
446 {
447 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
448 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
449 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
450 }
451 if (friendClient != null)
452 {
453 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
454 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
455 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
456 }
457
458 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
459 agentUUI, friendUUI, agentFriendService, friendFriendService);
460
461 // Generate a random 8-character hex number that will sign this friendship
462 string secret = UUID.Random().ToString().Substring(0, 8);
463
464 if (agentAccount != null) // agent is local, 'friend' is foreigner
465 {
466 // This may happen when the agent returned home, in which case the friend is not there
467 // We need to look for its information in the friends list itself
468 bool confirming = false;
469 if (friendUUI == string.Empty)
470 {
471 FriendInfo[] finfos = GetFriends(agentID);
472 foreach (FriendInfo finfo in finfos)
473 {
474 if (finfo.TheirFlags == -1)
475 {
476 if (finfo.Friend.StartsWith(friendID.ToString()))
477 {
478 friendUUI = finfo.Friend;
479 confirming = true;
480 }
481 }
482 }
483 }
484
485 // If it's confirming the friendship, we already have the full friendUUI with the secret
486 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
487
488 // store in the local friends service a reference to the foreign friend
489 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
490 // and also the converse
491 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
492
493 if (!confirming && friendClientCircuit != null)
494 {
495 // store in the foreign friends service a reference to the local agent
496 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
497 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
498 }
499 }
500 else if (friendAccount != null) // 'friend' is local, agent is foreigner
501 {
502 // store in the local friends service a reference to the foreign agent
503 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
504 // and also the converse
505 FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
506
507 if (agentClientCircuit != null)
508 {
509 // store in the foreign friends service a reference to the local agent
510 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
511 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
512 }
513 }
514 else // They're both foreigners!
515 {
516 HGFriendsServicesConnector friendsConn;
517 if (agentClientCircuit != null)
518 {
519 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
520 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
521 }
522 if (friendClientCircuit != null)
523 {
524 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
525 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
526 }
527 }
528 // my brain hurts now
529 }
530
531 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
532 {
533 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
534 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
535 // Are they both local users?
536 if (agentAccount != null && friendAccount != null)
537 {
538 // local grid users
539 return base.DeleteFriendship(agentID, exfriendID);
540 }
541
542 // ok, at least one of them is foreigner, let's get their data
543 string agentUUI = string.Empty;
544 string friendUUI = string.Empty;
545
546 if (agentAccount != null) // agent is local, 'friend' is foreigner
547 {
548 // We need to look for its information in the friends list itself
549 FriendInfo[] finfos = GetFriends(agentID);
550 FriendInfo finfo = GetFriend(finfos, exfriendID);
551 if (finfo != null)
552 {
553 friendUUI = finfo.Friend;
554
555 // delete in the local friends service the reference to the foreign friend
556 FriendsService.Delete(agentID, friendUUI);
557 // and also the converse
558 FriendsService.Delete(friendUUI, agentID.ToString());
559
560 // notify the exfriend's service
561 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
562
563 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
564 return true;
565 }
566 }
567 else if (friendAccount != null) // agent is foreigner, 'friend' is local
568 {
569 agentUUI = GetUUI(exfriendID, agentID);
570
571 if (agentUUI != string.Empty)
572 {
573 // delete in the local friends service the reference to the foreign agent
574 FriendsService.Delete(exfriendID, agentUUI);
575 // and also the converse
576 FriendsService.Delete(agentUUI, exfriendID.ToString());
577
578 // notify the agent's service?
579 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
580
581 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
582 return true;
583 }
584 }
585 //else They're both foreigners! Can't handle this
586
587 return false;
588 }
589
590 private string GetUUI(UUID localUser, UUID foreignUser)
591 {
592 // Let's see if the user is here by any chance
593 FriendInfo[] finfos = GetFriends(localUser);
594 if (finfos != EMPTY_FRIENDS) // friend is here, cool
595 {
596 FriendInfo finfo = GetFriend(finfos, foreignUser);
597 if (finfo != null)
598 {
599 return finfo.Friend;
600 }
601 }
602 else // user is not currently on this sim, need to get from the service
603 {
604 finfos = FriendsService.GetFriends(localUser);
605 foreach (FriendInfo finfo in finfos)
606 {
607 if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
608 {
609 return finfo.Friend;
610 }
611 }
612 }
613 return string.Empty;
614 }
615
616 private void Delete(UUID foreignUser, UUID localUser, string uui)
617 {
618 UUID id;
619 string url = string.Empty, secret = string.Empty, tmp = string.Empty;
620 if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
621 {
622 m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
623 HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
624 friendConn.DeleteFriendship(foreignUser, localUser, secret);
625 }
626 }
627 }
628}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
new file mode 100644
index 0000000..7753c25
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -0,0 +1,350 @@
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 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42using OpenSim.Services.Interfaces;
43using OpenSim.Services.Connectors.InstantMessage;
44using OpenSim.Services.Connectors.Hypergrid;
45using OpenSim.Server.Handlers.Hypergrid;
46
47namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 protected bool m_Enabled = false;
55 protected List<Scene> m_Scenes = new List<Scene>();
56
57 protected IInstantMessage m_IMService;
58 protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
59
60 public event UndeliveredMessage OnUndeliveredMessage;
61
62 IUserManagement m_uMan;
63 IUserManagement UserManagementModule
64 {
65 get
66 {
67 if (m_uMan == null)
68 m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
69 return m_uMan;
70 }
71 }
72
73 public virtual void Initialise(IConfigSource config)
74 {
75 IConfig cnf = config.Configs["Messaging"];
76 if (cnf != null && cnf.GetString(
77 "MessageTransferModule", "MessageTransferModule") != Name)
78 {
79 m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
80 return;
81 }
82
83 InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
84 m_IMService = imServer.GetService();
85 m_Enabled = true;
86 }
87
88 public virtual void AddRegion(Scene scene)
89 {
90 if (!m_Enabled)
91 return;
92
93 lock (m_Scenes)
94 {
95 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
96 scene.RegisterModuleInterface<IMessageTransferModule>(this);
97 m_Scenes.Add(scene);
98 }
99 }
100
101 public virtual void PostInitialise()
102 {
103 if (!m_Enabled)
104 return;
105
106 }
107
108 public virtual void RegionLoaded(Scene scene)
109 {
110 }
111
112 public virtual void RemoveRegion(Scene scene)
113 {
114 if (!m_Enabled)
115 return;
116
117 lock (m_Scenes)
118 {
119 m_Scenes.Remove(scene);
120 }
121 }
122
123 public virtual void Close()
124 {
125 }
126
127 public virtual string Name
128 {
129 get { return "HGMessageTransferModule"; }
130 }
131
132 public virtual Type ReplaceableInterface
133 {
134 get { return null; }
135 }
136
137 public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
138 {
139 UUID toAgentID = new UUID(im.toAgentID);
140
141 // Try root avatar only first
142 foreach (Scene scene in m_Scenes)
143 {
144 if (scene.Entities.ContainsKey(toAgentID) &&
145 scene.Entities[toAgentID] is ScenePresence)
146 {
147// m_log.DebugFormat(
148// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
149// toAgentID.ToString(), scene.RegionInfo.RegionName);
150
151 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
152 if (!user.IsChildAgent)
153 {
154 // Local message
155// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
156 user.ControllingClient.SendInstantMessage(im);
157
158 // Message sent
159 result(true);
160 return;
161 }
162 }
163 }
164
165 // try child avatar second
166 foreach (Scene scene in m_Scenes)
167 {
168// m_log.DebugFormat(
169// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
170
171 if (scene.Entities.ContainsKey(toAgentID) &&
172 scene.Entities[toAgentID] is ScenePresence)
173 {
174 // Local message
175 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
176
177// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
178 user.ControllingClient.SendInstantMessage(im);
179
180 // Message sent
181 result(true);
182 return;
183 }
184 }
185
186// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
187 // Is the user a local user?
188 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
189 string url = string.Empty;
190 bool foreigner = false;
191 if (account == null) // foreign user
192 {
193 url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
194 foreigner = true;
195 }
196
197 Util.FireAndForget(delegate
198 {
199 bool success = false;
200 if (foreigner && url == string.Empty) // we don't know about this user
201 {
202 string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
203 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
204 if (recipientUUI != string.Empty)
205 {
206 UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
207 if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
208 {
209 success = m_IMService.OutgoingInstantMessage(im, u, true);
210 if (success)
211 UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
212 }
213 }
214 }
215 else
216 success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
217
218 if (!success && !foreigner)
219 HandleUndeliveredMessage(im, result);
220 else
221 result(success);
222 });
223
224 return;
225 }
226
227 protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
228 {
229 bool successful = false;
230 foreach (Scene scene in m_Scenes)
231 {
232 if (scene.Entities.ContainsKey(toAgentID) &&
233 scene.Entities[toAgentID] is ScenePresence)
234 {
235 ScenePresence user =
236 (ScenePresence)scene.Entities[toAgentID];
237
238 if (!user.IsChildAgent)
239 {
240 scene.EventManager.TriggerIncomingInstantMessage(gim);
241 successful = true;
242 }
243 }
244 }
245 if (!successful)
246 {
247 // If the message can't be delivered to an agent, it
248 // is likely to be a group IM. On a group IM, the
249 // imSessionID = toAgentID = group id. Raise the
250 // unhandled IM event to give the groups module
251 // a chance to pick it up. We raise that in a random
252 // scene, since the groups module is shared.
253 //
254 m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
255 }
256
257 return successful;
258 }
259
260 protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
261 {
262 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
263
264 // If this event has handlers, then an IM from an agent will be
265 // considered delivered. This will suppress the error message.
266 //
267 if (handlerUndeliveredMessage != null)
268 {
269 handlerUndeliveredMessage(im);
270 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
271 result(true);
272 else
273 result(false);
274 return;
275 }
276
277 //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
278 result(false);
279 }
280
281 private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
282 {
283 // Let's call back the fromAgent's user agent service
284 // Maybe that service knows about the toAgent
285 IClientAPI client = LocateClientObject(fromAgent);
286 if (client != null)
287 {
288 AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
289 if (circuit != null)
290 {
291 if (circuit.ServiceURLs.ContainsKey("HomeURI"))
292 {
293 string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
294 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
295 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
296 return uasConn.GetUUI(fromAgent, toAgent);
297 }
298 }
299 }
300
301 return string.Empty;
302 }
303
304
305 /// <summary>
306 /// Find the scene for an agent
307 /// </summary>
308 private Scene GetClientScene(UUID agentId)
309 {
310 lock (m_Scenes)
311 {
312 foreach (Scene scene in m_Scenes)
313 {
314 ScenePresence presence = scene.GetScenePresence(agentId);
315 if (presence != null && !presence.IsChildAgent)
316 return scene;
317 }
318 }
319
320 return null;
321 }
322
323 /// <summary>
324 /// Find the client for a ID
325 /// </summary>
326 public IClientAPI LocateClientObject(UUID agentID)
327 {
328 Scene scene = GetClientScene(agentID);
329 if (scene != null)
330 {
331 ScenePresence presence = scene.GetScenePresence(agentID);
332 if (presence != null)
333 return presence.ControllingClient;
334 }
335
336 return null;
337 }
338
339 #region IInstantMessageSimConnector
340 public bool SendInstantMessage(GridInstantMessage im)
341 {
342 //m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
343 UUID agentID = new UUID(im.toAgentID);
344 return SendIMToScene(im, agentID);
345 }
346 #endregion
347
348
349 }
350}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 47e34dc..0d90a15 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
149 149
150 /// <summary> 150 /// <summary>
151 /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder. 151 /// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
152 /// 152 /// </summary>
153 /// <remarks>
153 /// This method does not handle paths that contain multiple delimitors 154 /// This method does not handle paths that contain multiple delimitors
154 /// 155 ///
155 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 156 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
156 /// XPath like expression 157 /// XPath like expression
157 /// 158 ///
158 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 159 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
159 /// </summary> 160 /// </remarks>
160 /// 161 ///
161 /// <param name="inventoryService"> 162 /// <param name="inventoryService">
162 /// Inventory service to query 163 /// Inventory service to query
@@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
178 179
179 return FindItemByPath(inventoryService, rootFolder, path); 180 return FindItemByPath(inventoryService, rootFolder, path);
180 } 181 }
181 182
182 /// <summary> 183 /// <summary>
183 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. 184 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
184 /// 185 /// </summary>
185 /// This method does not handle paths that contain multiple delimitors 186 /// <remarks>
187 /// This method does not handle paths that contain multiple delimiters
186 /// 188 ///
187 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 189 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
188 /// XPath like expression 190 /// XPath like expression
189 /// 191 ///
190 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 192 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
191 /// </summary> 193 /// </remarks>
192 /// 194 ///
193 /// <param name="inventoryService"> 195 /// <param name="inventoryService">Inventory service to query</param>
194 /// Inventory service to query 196 /// <param name="startFolder">The folder from which the path starts</param>
195 /// </param> 197 /// <param name="path">The path to the required item.</param>
196 /// <param name="startFolder">
197 /// The folder from which the path starts
198 /// </param>
199 /// <param name="path">
200 /// <param name="path">
201 /// The path to the required item.
202 /// </param>
203 /// <returns>null if the item is not found</returns> 198 /// <returns>null if the item is not found</returns>
204 public static InventoryItemBase FindItemByPath( 199 public static InventoryItemBase FindItemByPath(
205 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 200 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
206 { 201 {
202 List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
203
204 if (foundItems.Count != 0)
205 return foundItems[0];
206 else
207 return null;
208 }
209
210 public static List<InventoryItemBase> FindItemsByPath(
211 IInventoryService inventoryService, UUID userId, string path)
212 {
213 InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
214
215 if (null == rootFolder)
216 return new List<InventoryItemBase>();
217
218 return FindItemsByPath(inventoryService, rootFolder, path);
219 }
220
221 /// <summary>
222 /// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
223 /// </summary>
224 /// <remarks>
225 /// This method does not handle paths that contain multiple delimiters
226 ///
227 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
228 /// XPath like expression
229 ///
230 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
231 /// </remarks>
232 ///
233 /// <param name="inventoryService">Inventory service to query</param>
234 /// <param name="startFolder">The folder from which the path starts</param>
235 /// <param name="path">The path to the required item.</param>
236 /// <returns>The items that were found with this path. An empty list if no items were found.</returns>
237 public static List<InventoryItemBase> FindItemsByPath(
238 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
239 {
240 List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
241
207 // If the path isn't just / then trim any starting extraneous slashes 242 // If the path isn't just / then trim any starting extraneous slashes
208 path = path.TrimStart(new char[] { PATH_DELIMITER }); 243 path = path.TrimStart(new char[] { PATH_DELIMITER });
209 244
@@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
215 if (components.Length == 1) 250 if (components.Length == 1)
216 { 251 {
217// m_log.DebugFormat( 252// m_log.DebugFormat(
218// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", 253// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
219// components[0], startFolder.Name, startFolder.ID); 254// components[0], startFolder.Name, startFolder.ID);
220 255
221 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 256 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
222 257
223// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count); 258// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
224 259
225 foreach (InventoryItemBase item in items) 260 foreach (InventoryItemBase item in items)
@@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
227// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID); 262// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
228 263
229 if (item.Name == components[0]) 264 if (item.Name == components[0])
230 return item; 265 foundItems.Add(item);
231 } 266 }
232 } 267 }
233 else 268 else
234 { 269 {
235// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); 270// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
236 271
237 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 272 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
238 273
239 foreach (InventoryFolderBase folder in contents.Folders) 274 foreach (InventoryFolderBase folder in contents.Folders)
240 { 275 {
241 if (folder.Name == components[0]) 276 if (folder.Name == components[0])
242 return FindItemByPath(inventoryService, folder, components[1]); 277 foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
243 } 278 }
244 } 279 }
245 280
246 // We didn't find an item or intermediate folder with the given name 281 return foundItems;
247 return null;
248 } 282 }
249 283
250 /// <summary> 284 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index e043caa..93657a8 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -154,7 +154,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); 154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
155 m_archiveWriter.WriteFile(filename, serialization); 155 m_archiveWriter.WriteFile(filename, serialization);
156 156
157 if (SaveAssets) 157 AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
158
159 // Don't chase down link asset items as they actually point to their target item IDs rather than an asset
160 if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
158 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); 161 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
159 } 162 }
160 163
@@ -246,10 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
246 249
247 // The path may point to an item instead 250 // The path may point to an item instead
248 if (inventoryFolder == null) 251 if (inventoryFolder == null)
249 {
250 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); 252 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
251 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
252 }
253 253
254 if (null == inventoryFolder && null == inventoryItem) 254 if (null == inventoryFolder && null == inventoryItem)
255 { 255 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
new file mode 100644
index 0000000..c82cfd2
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -0,0 +1,244 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using Mono.Addins;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Connectors.Hypergrid;
40
41using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42
43namespace OpenSim.Region.CoreModules.Avatar.Lure
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class HGLureModule : ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private readonly List<Scene> m_scenes = new List<Scene>();
52
53 private IMessageTransferModule m_TransferModule = null;
54 private bool m_Enabled = false;
55
56 private string m_ThisGridURL;
57
58 private ExpiringCache<UUID, GridInstantMessage> m_PendingLures = new ExpiringCache<UUID, GridInstantMessage>();
59
60 public void Initialise(IConfigSource config)
61 {
62 if (config.Configs["Messaging"] != null)
63 {
64 if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule")
65 {
66 m_Enabled = true;
67
68 m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty);
69 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
70 }
71 }
72 }
73
74 public void AddRegion(Scene scene)
75 {
76 if (!m_Enabled)
77 return;
78
79 lock (m_scenes)
80 {
81 m_scenes.Add(scene);
82 scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage;
83 scene.EventManager.OnNewClient += OnNewClient;
84 }
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91
92 if (m_TransferModule == null)
93 {
94 m_TransferModule =
95 scene.RequestModuleInterface<IMessageTransferModule>();
96
97 if (m_TransferModule == null)
98 {
99 m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!");
100
101 m_Enabled = false;
102 m_scenes.Clear();
103 scene.EventManager.OnNewClient -= OnNewClient;
104 scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
105 }
106 }
107
108 }
109
110 public void RemoveRegion(Scene scene)
111 {
112 if (!m_Enabled)
113 return;
114
115 lock (m_scenes)
116 {
117 m_scenes.Remove(scene);
118 scene.EventManager.OnNewClient -= OnNewClient;
119 scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
120 }
121 }
122
123 void OnNewClient(IClientAPI client)
124 {
125 client.OnInstantMessage += OnInstantMessage;
126 client.OnStartLure += OnStartLure;
127 client.OnTeleportLureRequest += OnTeleportLureRequest;
128 }
129
130 public void PostInitialise()
131 {
132 }
133
134 public void Close()
135 {
136 }
137
138 public string Name
139 {
140 get { return "HGLureModule"; }
141 }
142
143 public Type ReplaceableInterface
144 {
145 get { return null; }
146 }
147
148 void OnInstantMessage(IClientAPI client, GridInstantMessage im)
149 {
150 }
151
152 void OnIncomingInstantMessage(GridInstantMessage im)
153 {
154 if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
155 {
156 UUID sessionID = new UUID(im.imSessionID);
157 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
158 m_PendingLures.Add(sessionID, im, 7200); // 2 hours
159
160 // Forward. We do this, because the IM module explicitly rejects
161 // IMs of this type
162 if (m_TransferModule != null)
163 m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
164
165 }
166 }
167
168 public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
169 {
170 if (!(client.Scene is Scene))
171 return;
172
173 Scene scene = (Scene)(client.Scene);
174 ScenePresence presence = scene.GetScenePresence(client.AgentId);
175
176 message += "@" + m_ThisGridURL;
177
178 m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
179
180 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
181 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, UUID.Random(), false, presence.AbsolutePosition,
184 new Byte[0]);
185 m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
186
187 if (m_TransferModule != null)
188 {
189 m_TransferModule.SendInstantMessage(m,
190 delegate(bool success) { });
191 }
192 }
193
194 public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
195 {
196 if (!(client.Scene is Scene))
197 return;
198
199 Scene scene = (Scene)(client.Scene);
200
201 GridInstantMessage im = null;
202 if (m_PendingLures.TryGetValue(lureID, out im))
203 {
204 m_PendingLures.Remove(lureID);
205 Lure(client, teleportFlags, im);
206 }
207 else
208 m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
209
210 }
211
212 private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im)
213 {
214 Scene scene = (Scene)(client.Scene);
215 GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID));
216 if (region != null)
217 scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags);
218 else // we don't have that region here. Check if it's HG
219 {
220 string[] parts = im.message.Split(new char[] { '@' });
221 if (parts.Length > 1)
222 {
223 string url = parts[parts.Length - 1]; // the last part
224 if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'}))
225 {
226 m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position);
227 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
228 GridRegion gatekeeper = new GridRegion();
229 gatekeeper.ServerURI = url;
230 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID));
231 if (finalDestination != null)
232 {
233 ScenePresence sp = scene.GetScenePresence(client.AgentId);
234 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
235 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
236 if (transferMod != null && sp != null && eq != null)
237 transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
238 }
239 }
240 }
241 }
242 }
243 }
244}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index a12b57a..dcfdf8f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
45 private readonly List<Scene> m_scenes = new List<Scene>(); 45 private readonly List<Scene> m_scenes = new List<Scene>();
46 46
47 private IMessageTransferModule m_TransferModule = null; 47 private IMessageTransferModule m_TransferModule = null;
48 private bool m_Enabled = true; 48 private bool m_Enabled = false;
49 49
50 public void Initialise(IConfigSource config) 50 public void Initialise(IConfigSource config)
51 { 51 {
52 if (config.Configs["Messaging"] != null) 52 if (config.Configs["Messaging"] != null)
53 { 53 {
54 if (config.Configs["Messaging"].GetString( 54 if (config.Configs["Messaging"].GetString(
55 "LureModule", "LureModule") != 55 "LureModule", "LureModule") ==
56 "LureModule") 56 "LureModule")
57 m_Enabled = false; 57 {
58 m_Enabled = true;
59 m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
60 }
58 } 61 }
59 } 62 }
60 63
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
74 77
75 public void RegionLoaded(Scene scene) 78 public void RegionLoaded(Scene scene)
76 { 79 {
80 if (!m_Enabled)
81 return;
82
77 if (m_TransferModule == null) 83 if (m_TransferModule == null)
78 { 84 {
79 m_TransferModule = 85 m_TransferModule =
@@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
96 102
97 public void RemoveRegion(Scene scene) 103 public void RemoveRegion(Scene scene)
98 { 104 {
105 if (!m_Enabled)
106 return;
107
99 lock (m_scenes) 108 lock (m_scenes)
100 { 109 {
101 m_scenes.Remove(scene); 110 m_scenes.Remove(scene);
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
new file mode 100644
index 0000000..079e1b6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -0,0 +1,173 @@
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 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Globalization;
31using System.Reflection;
32
33using OpenMetaverse;
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37
38using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Region.CoreModules.Avatar.Profile
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class BasicProfileModule : ISharedRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //
51 // Module vars
52 //
53 private List<Scene> m_Scenes = new List<Scene>();
54 private bool m_Enabled = false;
55
56 #region ISharedRegionModule
57
58 public void Initialise(IConfigSource config)
59 {
60 if (config.Configs["Profile"] != null)
61 {
62 if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
63 return;
64 }
65
66 m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
67 m_Enabled = true;
68
69 }
70
71 public void AddRegion(Scene scene)
72 {
73 if (!m_Enabled)
74 return;
75
76 lock (m_Scenes)
77 {
78 if (!m_Scenes.Contains(scene))
79 {
80 m_Scenes.Add(scene);
81 // Hook up events
82 scene.EventManager.OnNewClient += OnNewClient;
83 }
84 }
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91 }
92
93 public void RemoveRegion(Scene scene)
94 {
95 if (!m_Enabled)
96 return;
97
98 lock (m_Scenes)
99 {
100 m_Scenes.Remove(scene);
101 }
102 }
103
104 public void PostInitialise()
105 {
106 }
107
108 public void Close()
109 {
110 }
111
112 public string Name
113 {
114 get { return "BasicProfileModule"; }
115 }
116
117 public Type ReplaceableInterface
118 {
119 get { return null; }
120 }
121
122 #endregion
123
124 /// New Client Event Handler
125 private void OnNewClient(IClientAPI client)
126 {
127 //Profile
128 client.OnRequestAvatarProperties += RequestAvatarProperties;
129 }
130
131 public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
132 {
133 IScene s = remoteClient.Scene;
134 if (!(s is Scene))
135 return;
136
137 Scene scene = (Scene)s;
138
139 string profileUrl = String.Empty;
140 string aboutText = String.Empty;
141 string firstLifeAboutText = String.Empty;
142 UUID image = UUID.Zero;
143 UUID firstLifeImage = UUID.Zero;
144 UUID partner = UUID.Zero;
145 uint wantMask = 0;
146 string wantText = String.Empty;
147 uint skillsMask = 0;
148 string skillsText = String.Empty;
149 string languages = String.Empty;
150
151 Byte[] charterMember = Utils.StringToBytes("Avatar");
152
153 profileUrl = "No profile data";
154 aboutText = string.Empty;
155 firstLifeAboutText = string.Empty;
156 image = UUID.Zero;
157 firstLifeImage = UUID.Zero;
158 partner = UUID.Zero;
159
160 remoteClient.SendAvatarProperties(avatarID, aboutText,
161 Util.ToDateTime(0).ToString(
162 "M/d/yyyy", CultureInfo.InvariantCulture),
163 charterMember, firstLifeAboutText,
164 (uint)(0 & 0xff),
165 firstLifeImage, image, profileUrl, partner);
166
167 //Viewer expects interest data when it asks for properties.
168 remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
169 skillsMask, skillsText, languages);
170 }
171
172 }
173} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 1fb346e..02efcd8 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
52 52
53 protected bool m_Enabled = false; 53 protected bool m_Enabled = false;
54 protected Scene m_aScene; 54 protected Scene m_aScene;
55 protected List<Scene> m_Scenes = new List<Scene>();
55 protected List<UUID> m_agentsInTransit; 56 protected List<UUID> m_agentsInTransit;
56 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = 57 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
57 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 58 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
@@ -96,13 +97,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
96 if (m_aScene == null) 97 if (m_aScene == null)
97 m_aScene = scene; 98 m_aScene = scene;
98 99
100 m_Scenes.Add(scene);
99 scene.RegisterModuleInterface<IEntityTransferModule>(this); 101 scene.RegisterModuleInterface<IEntityTransferModule>(this);
100 scene.EventManager.OnNewClient += OnNewClient; 102 scene.EventManager.OnNewClient += OnNewClient;
101 } 103 }
102 104
103 protected virtual void OnNewClient(IClientAPI client) 105 protected virtual void OnNewClient(IClientAPI client)
104 { 106 {
105 client.OnTeleportHomeRequest += TeleportHomeFired; 107 client.OnTeleportHomeRequest += TriggerTeleportHome;
108 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
106 } 109 }
107 110
108 public virtual void Close() 111 public virtual void Close()
@@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
118 return; 121 return;
119 if (scene == m_aScene) 122 if (scene == m_aScene)
120 m_aScene = null; 123 m_aScene = null;
124
125 m_Scenes.Remove(scene);
121 } 126 }
122 127
123 public virtual void RegionLoaded(Scene scene) 128 public virtual void RegionLoaded(Scene scene)
@@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
127 132
128 } 133 }
129 134
130
131 #endregion 135 #endregion
132 136
133 #region Agent Teleports 137 #region Agent Teleports
@@ -249,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
249 } 253 }
250 } 254 }
251 255
252 protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) 256 public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
253 { 257 {
254 if (reg == null || finalDestination == null) 258 if (reg == null || finalDestination == null)
255 { 259 {
@@ -557,9 +561,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
557 561
558 #endregion 562 #endregion
559 563
564 #region Landmark Teleport
565 /// <summary>
566 /// Tries to teleport agent to landmark.
567 /// </summary>
568 /// <param name="remoteClient"></param>
569 /// <param name="regionHandle"></param>
570 /// <param name="position"></param>
571 public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
572 {
573 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
574
575 if (info == null)
576 {
577 // can't find the region: Tell viewer and abort
578 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
579 return;
580 }
581 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
582 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
583 }
584
585 #endregion
586
560 #region Teleport Home 587 #region Teleport Home
561 588
562 public void TeleportHomeFired(UUID id, IClientAPI client) 589 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
563 { 590 {
564 TeleportHome(id, client); 591 TeleportHome(id, client);
565 } 592 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 1ccbcfd..d6ef5df 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
86 86
87 protected override void OnNewClient(IClientAPI client) 87 protected override void OnNewClient(IClientAPI client)
88 { 88 {
89 client.OnTeleportHomeRequest += TeleportHomeFired; 89 client.OnTeleportHomeRequest += TriggerTeleportHome;
90 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
90 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 91 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
91 } 92 }
92 93
@@ -178,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
178 return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); 179 return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
179 } 180 }
180 181
181 public void TeleportHomeFired(UUID id, IClientAPI client) 182 public void TriggerTeleportHome(UUID id, IClientAPI client)
182 { 183 {
183 TeleportHome(id, client); 184 TeleportHome(id, client);
184 } 185 }
@@ -233,6 +234,58 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
233 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); 234 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
234 return true; 235 return true;
235 } 236 }
237
238 /// <summary>
239 /// Tries to teleport agent to landmark.
240 /// </summary>
241 /// <param name="remoteClient"></param>
242 /// <param name="regionHandle"></param>
243 /// <param name="position"></param>
244 public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
245 {
246 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
247 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
248 if (lm.Gatekeeper == string.Empty)
249 {
250 base.RequestTeleportLandmark(remoteClient, lm);
251 return;
252 }
253
254 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
255
256 // Local region?
257 if (info != null)
258 {
259 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
260 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
261 return;
262 }
263 else
264 {
265 // Foreign region
266 Scene scene = (Scene)(remoteClient.Scene);
267 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
268 GridRegion gatekeeper = new GridRegion();
269 gatekeeper.ServerURI = lm.Gatekeeper;
270 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
271 if (finalDestination != null)
272 {
273 ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
274 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
275 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
276 if (transferMod != null && sp != null && eq != null)
277 transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
278 Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
279 }
280
281 }
282
283 // can't find the region: Tell viewer and abort
284 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
285
286 }
287
288
236 #endregion 289 #endregion
237 290
238 #region IUserAgentVerificationModule 291 #region IUserAgentVerificationModule
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 52791cb..49d484b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
56 56
57 private string m_ProfileServerURI; 57 private string m_ProfileServerURI;
58 private bool m_OutboundPermission; 58 private bool m_OutboundPermission;
59 private string m_ThisGatekeeper;
59 60
60// private bool m_Initialized = false; 61// private bool m_Initialized = false;
61 62
@@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
85 { 86 {
86 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 87 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
87 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 88 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
89 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
88 } 90 }
89 else 91 else
90 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 92 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@@ -110,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
110 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) 112 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
111 { 113 {
112 string userAssetServer = string.Empty; 114 string userAssetServer = string.Empty;
113 if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission) 115 if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
114 { 116 {
115 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); 117 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
116 } 118 }
@@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
119 #endregion 121 #endregion
120 122
121 #region Overrides of Basic Inventory Access methods 123 #region Overrides of Basic Inventory Access methods
124
125 protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
126 {
127 UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID);
128 if (account == null)
129 prefix = "HG ";
130 else
131 prefix = string.Empty;
132 suffix = " @ " + m_ThisGatekeeper;
133 Vector3 pos = presence.AbsolutePosition;
134 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
135 presence.Scene.RegionInfo.RegionID,
136 pos.X, pos.Y, pos.Z,
137 presence.RegionHandle,
138 m_ThisGatekeeper);
139 }
140
141
122 /// 142 ///
123 /// CapsUpdateInventoryItemAsset 143 /// CapsUpdateInventoryItemAsset
124 /// 144 ///
@@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
180 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) 200 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
181 { 201 {
182 string userAssetServer = string.Empty; 202 string userAssetServer = string.Empty;
183 if (IsForeignUser(sender, out userAssetServer)) 203 if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
184 m_assMapper.Get(item.AssetID, sender, userAssetServer); 204 m_assMapper.Get(item.AssetID, sender, userAssetServer);
185 205
186 if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission) 206 if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
187 m_assMapper.Post(item.AssetID, receiver, userAssetServer); 207 m_assMapper.Post(item.AssetID, receiver, userAssetServer);
188 } 208 }
189 209
@@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
203 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 223 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
204 { 224 {
205 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 225 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
206 assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true; 226 assetServerURL = assetServerURL.Trim(new char[] { '/' });
207 } 227 }
208 } 228 }
229 else
230 {
231 assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
232 assetServerURL = assetServerURL.Trim(new char[] { '/' });
233 }
234 return true;
209 } 235 }
210 236
211 return false; 237 return false;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 184b223..7bad814 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Xml; 31using System.Xml;
32using System.Reflection; 32using System.Reflection;
33using System.Text;
33using System.Threading; 34using System.Threading;
34 35
35using OpenSim.Framework; 36using OpenSim.Framework;
@@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
128 129
129 protected virtual void OnNewClient(IClientAPI client) 130 protected virtual void OnNewClient(IClientAPI client)
130 { 131 {
131 132 client.OnCreateNewInventoryItem += CreateNewInventoryItem;
132 } 133 }
133 134
134 public virtual void Close() 135 public virtual void Close()
@@ -157,6 +158,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
157 #region Inventory Access 158 #region Inventory Access
158 159
159 /// <summary> 160 /// <summary>
161 /// Create a new inventory item. Called when the client creates a new item directly within their
162 /// inventory (e.g. by selecting a context inventory menu option).
163 /// </summary>
164 /// <param name="remoteClient"></param>
165 /// <param name="transactionID"></param>
166 /// <param name="folderID"></param>
167 /// <param name="callbackID"></param>
168 /// <param name="description"></param>
169 /// <param name="name"></param>
170 /// <param name="invType"></param>
171 /// <param name="type"></param>
172 /// <param name="wearableType"></param>
173 /// <param name="nextOwnerMask"></param>
174 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
175 uint callbackID, string description, string name, sbyte invType,
176 sbyte assetType,
177 byte wearableType, uint nextOwnerMask, int creationDate)
178 {
179 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
180
181 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
182 return;
183
184 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
185 InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
186
187 if (folder == null || folder.Owner != remoteClient.AgentId)
188 return;
189
190 if (transactionID == UUID.Zero)
191 {
192 ScenePresence presence;
193 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
194 {
195 byte[] data = null;
196
197 if (invType == (sbyte)InventoryType.Landmark && presence != null)
198 {
199 string suffix = string.Empty, prefix = string.Empty;
200 string strdata = GenerateLandmark(presence, out prefix, out suffix);
201 data = Encoding.ASCII.GetBytes(strdata);
202 name = prefix + name;
203 description += suffix;
204 }
205
206 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
207 m_Scene.AssetService.Store(asset);
208
209 m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
210 }
211 else
212 {
213 m_log.ErrorFormat(
214 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
215 remoteClient.AgentId);
216 }
217 }
218 else
219 {
220 IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
221 if (agentTransactions != null)
222 {
223 agentTransactions.HandleItemCreationFromTransaction(
224 remoteClient, transactionID, folderID, callbackID, description,
225 name, invType, assetType, wearableType, nextOwnerMask);
226 }
227 }
228 }
229
230 protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
231 {
232 prefix = string.Empty;
233 suffix = string.Empty;
234 Vector3 pos = presence.AbsolutePosition;
235 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
236 presence.Scene.RegionInfo.RegionID,
237 pos.X, pos.Y, pos.Z,
238 presence.RegionHandle);
239 }
240
241 /// <summary>
160 /// Capability originating call to update the asset of an item in an agent's inventory 242 /// Capability originating call to update the asset of an item in an agent's inventory
161 /// </summary> 243 /// </summary>
162 /// <param name="remoteClient"></param> 244 /// <param name="remoteClient"></param>
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 4cc6905..ae4336c 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -30,11 +30,13 @@ using System.IO;
30using System.Reflection; 30using System.Reflection;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console;
33 34
34using OpenSim.Region.Framework; 35using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39using OpenSim.Services.Connectors.Hypergrid;
38 40
39using OpenMetaverse; 41using OpenMetaverse;
40using log4net; 42using log4net;
@@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
47 public UUID Id; 49 public UUID Id;
48 public string FirstName; 50 public string FirstName;
49 public string LastName; 51 public string LastName;
50 public string ProfileURL; 52 public string HomeURL;
53 public Dictionary<string, object> ServerURLs;
51 } 54 }
52 55
53 public class UserManagementModule : ISharedRegionModule, IUserManagement 56 public class UserManagementModule : ISharedRegionModule, IUserManagement
@@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
78 // } 81 // }
79 // } 82 // }
80 //} 83 //}
84 MainConsole.Instance.Commands.AddCommand("grid", true,
85 "show user-names",
86 "show user-names",
87 "Show the bindings between user UUIDs and user names",
88 String.Empty,
89 HandleShowUsers);
90
91
81 } 92 }
82 93
83 public bool IsSharedModule 94 public bool IsSharedModule
@@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
101 112
102 scene.RegisterModuleInterface<IUserManagement>(this); 113 scene.RegisterModuleInterface<IUserManagement>(this);
103 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); 114 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
115 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
104 } 116 }
105 117
106 public void RemoveRegion(Scene scene) 118 public void RemoveRegion(Scene scene)
@@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
109 m_Scenes.Remove(scene); 121 m_Scenes.Remove(scene);
110 } 122 }
111 123
112 public void RegionLoaded(Scene scene) 124 public void RegionLoaded(Scene s)
113 { 125 {
114 } 126 }
115 127
116 public void PostInitialise() 128 public void PostInitialise()
117 { 129 {
118 foreach (Scene s in m_Scenes)
119 {
120 // let's sniff all the user names referenced by objects in the scene
121 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
122 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
123 }
124 } 130 }
125 131
126 public void Close() 132 public void Close()
@@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
134 140
135 #region Event Handlers 141 #region Event Handlers
136 142
143 void EventManager_OnPrimsLoaded(Scene s)
144 {
145 // let's sniff all the user names referenced by objects in the scene
146 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
147 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
148 }
149
150
137 void EventManager_OnNewClient(IClientAPI client) 151 void EventManager_OnNewClient(IClientAPI client)
138 { 152 {
139 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); 153 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
@@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
150 string[] names = GetUserNames(uuid); 164 string[] names = GetUserNames(uuid);
151 if (names.Length == 2) 165 if (names.Length == 2)
152 { 166 {
167 //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
153 remote_client.SendNameReply(uuid, names[0], names[1]); 168 remote_client.SendNameReply(uuid, names[0], names[1]);
154 } 169 }
155 170
@@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
210 225
211 public string GetUserName(UUID uuid) 226 public string GetUserName(UUID uuid)
212 { 227 {
228 //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
213 string[] names = GetUserNames(uuid); 229 string[] names = GetUserNames(uuid);
214 if (names.Length == 2) 230 if (names.Length == 2)
215 { 231 {
@@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
222 return "(hippos)"; 238 return "(hippos)";
223 } 239 }
224 240
241 public string GetUserHomeURL(UUID userID)
242 {
243 if (m_UserCache.ContainsKey(userID))
244 return m_UserCache[userID].HomeURL;
245
246 return string.Empty;
247 }
248
249 public string GetUserServerURL(UUID userID, string serverType)
250 {
251 if (m_UserCache.ContainsKey(userID))
252 {
253 UserData userdata = m_UserCache[userID];
254 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
255 return userdata.ServerURLs[serverType].ToString();
256
257 if (userdata.HomeURL != string.Empty)
258 {
259 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
260 userdata.ServerURLs = uConn.GetServerURLs(userID);
261 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
262 return userdata.ServerURLs[serverType].ToString();
263 }
264 }
265
266 return string.Empty;
267 }
268
269 public string GetUserUUI(UUID userID)
270 {
271 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
272 if (account != null)
273 return userID.ToString();
274
275 if (m_UserCache.ContainsKey(userID))
276 {
277 UserData ud = m_UserCache[userID];
278 string homeURL = ud.HomeURL;
279 string first = ud.FirstName, last = ud.LastName;
280 if (ud.LastName.StartsWith("@"))
281 {
282 string[] parts = ud.FirstName.Split('.');
283 if (parts.Length >= 2)
284 {
285 first = parts[0];
286 last = parts[1];
287 }
288 return userID + ";" + homeURL + ";" + first + " " + last;
289 }
290 }
291
292 return userID.ToString();
293 }
294
225 public void AddUser(UUID id, string creatorData) 295 public void AddUser(UUID id, string creatorData)
226 { 296 {
227 if (m_UserCache.ContainsKey(id)) 297 if (m_UserCache.ContainsKey(id))
@@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
247 string[] parts = creatorData.Split(';'); 317 string[] parts = creatorData.Split(';');
248 if (parts.Length >= 1) 318 if (parts.Length >= 1)
249 { 319 {
250 user.ProfileURL = parts[0]; 320 user.HomeURL = parts[0];
251 try 321 try
252 { 322 {
253 Uri uri = new Uri(parts[0]); 323 Uri uri = new Uri(parts[0]);
254 user.LastName = "@" + uri.Authority; 324 user.LastName = "@" + uri.Authority;
255 } 325 }
256 catch 326 catch (UriFormatException)
257 { 327 {
258 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); 328 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
259 user.LastName = "@unknown"; 329 user.LastName = "@unknown";
@@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
272 lock (m_UserCache) 342 lock (m_UserCache)
273 m_UserCache[id] = user; 343 m_UserCache[id] = user;
274 344
275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); 345 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
276 } 346 }
277 347
278 public void AddUser(UUID uuid, string first, string last, string profileURL) 348 public void AddUser(UUID uuid, string first, string last, string profileURL)
@@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
311 //} 381 //}
312 382
313 #endregion IUserManagement 383 #endregion IUserManagement
384
385 private void HandleShowUsers(string module, string[] cmd)
386 {
387 if (m_UserCache.Count == 0)
388 {
389 MainConsole.Instance.Output("No users not found");
390 return;
391 }
392
393 MainConsole.Instance.Output("UUID User Name");
394 MainConsole.Instance.Output("-----------------------------------------------------------------------------");
395 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
396 {
397 MainConsole.Instance.Output(String.Format("{0} {1} {2}",
398 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
399 }
400 return;
401 }
402
403
314 } 404 }
315} 405}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 5ab334f..f066f83 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using log4net; 31using log4net;
@@ -67,9 +68,26 @@ namespace OpenSim.Region.CoreModules.Hypergrid
67 68
68 foreach (GridRegion r in regions) 69 foreach (GridRegion r in regions)
69 { 70 {
70 MapBlockData block = new MapBlockData(); 71 uint x = 0, y = 0;
71 MapBlockFromGridRegion(block, r); 72 long handle = 0;
72 mapBlocks.Add(block); 73 if (r.RegionSecret != null && r.RegionSecret != string.Empty)
74 {
75 if (long.TryParse(r.RegionSecret, out handle))
76 {
77 Utils.LongToUInts((ulong)handle, out x, out y);
78 x = x / Constants.RegionSize;
79 y = y / Constants.RegionSize;
80 }
81 }
82
83 if (handle == 0 ||
84 // Check the distance from the current region
85 (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096))
86 {
87 MapBlockData block = new MapBlockData();
88 MapBlockFromGridRegion(block, r);
89 mapBlocks.Add(block);
90 }
73 } 91 }
74 92
75 // Different from super 93 // Different from super
@@ -77,6 +95,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
77 // 95 //
78 96
79 remoteClient.SendMapBlock(mapBlocks, 0); 97 remoteClient.SendMapBlock(mapBlocks, 0);
98
80 } 99 }
81 100
82 101
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index 8a6735f..e22fd38 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -24,6 +24,7 @@
24 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> 24 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
25 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" /> 25 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
26 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" /> 26 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
27 <RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
27 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" /> 28 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
28 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" /> 29 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
29 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" /> 30 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index d2343c9..a5b5637 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -113,8 +113,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
113 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); 113 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
114 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); 114 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
115 115
116 new UserAgentServerConnector(m_Config, MainServer.Instance); 116 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
117 new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
117 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); 118 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
119 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
118 } 120 }
119 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); 121 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
120 } 122 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 3f63db3..698fd56 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
58 58
59 private List<Scene> m_Scenes = new List<Scene>(); 59 private List<Scene> m_Scenes = new List<Scene>();
60 60
61 protected IUserManagement m_UserManagement;
62 protected IUserManagement UserManagementModule
63 {
64 get
65 {
66 if (m_UserManagement == null)
67 m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
68 return m_UserManagement;
69 }
70 }
71
61 public Type ReplaceableInterface 72 public Type ReplaceableInterface
62 { 73 {
63 get { return null; } 74 get { return null; }
@@ -207,6 +218,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
207 } 218 }
208 } 219 }
209 } 220 }
221 if (sp == null)
222 {
223 inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
224 if (inventoryURL != null && inventoryURL != string.Empty)
225 {
226 inventoryURL = inventoryURL.Trim(new char[] { '/' });
227 m_InventoryURLs.Add(userID, inventoryURL);
228 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
229 }
230
231 }
232
210 } 233 }
211 } 234 }
212 235
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 5da1656..eb00de8 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
230 /// <param name="asset"></param> 230 /// <param name="asset"></param>
231 public void AssetRequestCallback(string id, object sender, AssetBase asset) 231 public void AssetRequestCallback(string id, object sender, AssetBase asset)
232 { 232 {
233 Culture.SetCurrentCulture();
234
233 try 235 try
234 { 236 {
235 lock (this) 237 lock (this)
@@ -289,6 +291,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
289 /// </summary> 291 /// </summary>
290 protected void PerformAssetsRequestCallback(object o) 292 protected void PerformAssetsRequestCallback(object o)
291 { 293 {
294 Culture.SetCurrentCulture();
295
292 try 296 try
293 { 297 {
294 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); 298 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index a098ff6..43b37c7 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
548 548
549 // libomv will moan about PrimFlags.ObjectYouOfficer being 549 // libomv will moan about PrimFlags.ObjectYouOfficer being
550 // deprecated 550 // deprecated
551 #pragma warning disable 0612 551#pragma warning disable 0612
552 objflags &= (uint) 552 objflags &= (uint)
553 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object 553 ~(PrimFlags.ObjectCopy | // Tells client you can copy the object
554 PrimFlags.ObjectModify | // tells client you can modify the object 554 PrimFlags.ObjectModify | // tells client you can modify the object
555 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) 555 PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
556 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it 556 PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
557 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object 557 PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
558 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object 558 PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
559 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object 559 PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
560 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set 560 PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
561 ); 561 );
562 #pragma warning restore 0612 562#pragma warning restore 0612
563 563
564 // Creating the three ObjectFlags options for this method to choose from. 564 // Creating the three ObjectFlags options for this method to choose from.
565 // Customize the OwnerMask 565 // Customize the OwnerMask
@@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
576 576
577 if (m_bypassPermissions) 577 if (m_bypassPermissions)
578 return objectOwnerMask; 578 return objectOwnerMask;
579 579
580 // Object owners should be able to edit their own content 580 // Object owners should be able to edit their own content
581 if (user == objectOwner) 581 if (user == objectOwner)
582 return objectOwnerMask; 582 return objectOwnerMask;
583 583
584 if (IsFriendWithPerms(user, objectOwner)) 584 if (IsFriendWithPerms(user, objectOwner))
585 {
585 return objectOwnerMask; 586 return objectOwnerMask;
586 587 }
587 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set 588 // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
588 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) 589 if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
590 {
589 return objectOwnerMask; 591 return objectOwnerMask;
592 }
590 593
591 // Admin should be able to edit anything in the sim (including admin objects) 594 // Admin should be able to edit anything in the sim (including admin objects)
592 if (IsAdministrator(user)) 595 if (IsAdministrator(user))
596 {
593 return objectOwnerMask; 597 return objectOwnerMask;
594 598 }
599
595 // Users should be able to edit what is over their land. 600 // Users should be able to edit what is over their land.
596 Vector3 taskPos = task.AbsolutePosition; 601 Vector3 taskPos = task.AbsolutePosition;
597 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); 602 ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
@@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
599 { 604 {
600 // Admin objects should not be editable by the above 605 // Admin objects should not be editable by the above
601 if (!IsAdministrator(objectOwner)) 606 if (!IsAdministrator(objectOwner))
607 {
602 return objectOwnerMask; 608 return objectOwnerMask;
609 }
603 } 610 }
604 611
605 // Group permissions 612 // Group permissions
606 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) 613 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
607 return objectGroupMask | objectEveryoneMask; 614 return objectGroupMask | objectEveryoneMask;
608 615
609 return objectEveryoneMask; 616 return objectEveryoneMask;
610 } 617 }
611 618
@@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
673 // 680 //
674 // Nobody but the object owner can set permissions on an object 681 // Nobody but the object owner can set permissions on an object
675 // 682 //
676
677 if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) 683 if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
678 { 684 {
679 return false; 685 return false;
@@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
704 // Return immediately, so that the administrator can shares group objects 710 // Return immediately, so that the administrator can shares group objects
705 return true; 711 return true;
706 } 712 }
713
714 // Friends with benefits should be able to edit the objects too
715 if (IsFriendWithPerms(currentUser, objectOwner))
716 // Return immediately, so that the administrator can share objects with friends
717 return true;
707 718
708 // Users should be able to edit what is over their land. 719 // Users should be able to edit what is over their land.
709 ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); 720 ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index cd40c5d..3f6f359 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
208 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", 208 //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
209 // path, param, agentID.ToString()); 209 // path, param, agentID.ToString());
210 210
211 // this is here because CAPS map requests work even beyond the 10,000 limit. 211 // There is a major hack going on in this method. The viewer doesn't request
212 ScenePresence avatarPresence = null; 212 // map blocks (RequestMapBlocks) above 4096. That means that if we don't hack,
213 213 // grids above that cell don't have a map at all. So, here's the hack: we wait
214 m_scene.TryGetScenePresence(agentID, out avatarPresence); 214 // for this CAP request to come, and we inject the map blocks at this point.
215 215 // In a normal scenario, this request simply sends back the MapLayer (the blue color).
216 if (avatarPresence != null) 216 // In the hacked scenario, it also sends the map blocks via UDP.
217 //
218 // 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is
219 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
220
221 if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096)
217 { 222 {
218 bool lookup = false; 223 ScenePresence avatarPresence = null;
219 224
220 lock (cachedMapBlocks) 225 m_scene.TryGetScenePresence(agentID, out avatarPresence);
221 {
222 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
223 {
224 List<MapBlockData> mapBlocks;
225 226
226 mapBlocks = cachedMapBlocks; 227 if (avatarPresence != null)
227 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
228 }
229 else
230 {
231 lookup = true;
232 }
233 }
234 if (lookup)
235 { 228 {
236 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 229 bool lookup = false;
237 230
238 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 231 lock (cachedMapBlocks)
239 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
240 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
241 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
242 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
243 foreach (GridRegion r in regions)
244 { 232 {
245 MapBlockData block = new MapBlockData(); 233 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
246 MapBlockFromGridRegion(block, r); 234 {
247 mapBlocks.Add(block); 235 List<MapBlockData> mapBlocks;
236
237 mapBlocks = cachedMapBlocks;
238 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
239 }
240 else
241 {
242 lookup = true;
243 }
248 } 244 }
249 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 245 if (lookup)
246 {
247 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
248
249 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
250 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
251 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
252 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
253 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
254 foreach (GridRegion r in regions)
255 {
256 MapBlockData block = new MapBlockData();
257 MapBlockFromGridRegion(block, r);
258 mapBlocks.Add(block);
259 }
260 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
250 261
251 lock (cachedMapBlocks) 262 lock (cachedMapBlocks)
252 cachedMapBlocks = mapBlocks; 263 cachedMapBlocks = mapBlocks;
253 264
254 cachedTime = Util.UnixTimeSinceEpoch(); 265 cachedTime = Util.UnixTimeSinceEpoch();
266 }
255 } 267 }
256 } 268 }
269
257 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 270 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
258 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 271 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
259 return mapResponse.ToString(); 272 return mapResponse.ToString();
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index b3bdff3..cdce36e 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -540,7 +540,7 @@ namespace OpenSim.Region.Examples.SimpleModule
540 { 540 {
541 } 541 }
542 542
543 public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 543 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
544 { 544 {
545 } 545 }
546 546
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 3eb38b8..c38ecd9 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -42,6 +42,9 @@ namespace OpenSim.Region.Framework.Interfaces
42 42
43 bool TeleportHome(UUID id, IClientAPI client); 43 bool TeleportHome(UUID id, IClientAPI client);
44 44
45 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
46 Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq);
47
45 bool Cross(ScenePresence agent, bool isFlying); 48 bool Cross(ScenePresence agent, bool isFlying);
46 49
47 void AgentArrivedAtDestination(UUID agent); 50 void AgentArrivedAtDestination(UUID agent);
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index 0ff7dee..d4a6857 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -34,6 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
34 public interface IFriendsModule 34 public interface IFriendsModule
35 { 35 {
36 uint GetFriendPerms(UUID PrincipalID, UUID FriendID); 36 uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
37 void SendFriendsOnlineIfNeeded(IClientAPI client); 37 bool SendFriendsOnlineIfNeeded(IClientAPI client);
38 } 38 }
39} 39}
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 2904ee8..5d30aa8 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -8,6 +8,9 @@ namespace OpenSim.Region.Framework.Interfaces
8 public interface IUserManagement 8 public interface IUserManagement
9 { 9 {
10 string GetUserName(UUID uuid); 10 string GetUserName(UUID uuid);
11 string GetUserHomeURL(UUID uuid);
12 string GetUserUUI(UUID uuid);
13 string GetUserServerURL(UUID uuid, string serverType);
11 void AddUser(UUID uuid, string userData); 14 void AddUser(UUID uuid, string userData);
12 void AddUser(UUID uuid, string firstName, string lastName, string profileURL); 15 void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
13 } 16 }
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index d326141..3ec4e59 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -393,6 +393,12 @@ namespace OpenSim.Region.Framework.Scenes
393 public delegate void RegionUp(GridRegion region); 393 public delegate void RegionUp(GridRegion region);
394 public event RegionUp OnRegionUp; 394 public event RegionUp OnRegionUp;
395 395
396 public delegate void LoginsEnabled(string regionName);
397 public event LoginsEnabled OnLoginsEnabled;
398
399 public delegate void PrimsLoaded(Scene s);
400 public event PrimsLoaded OnPrimsLoaded;
401
396 public class MoneyTransferArgs : EventArgs 402 public class MoneyTransferArgs : EventArgs
397 { 403 {
398 public UUID sender; 404 public UUID sender;
@@ -2242,5 +2248,47 @@ namespace OpenSim.Region.Framework.Scenes
2242 } 2248 }
2243 } 2249 }
2244 } 2250 }
2251
2252 public void TriggerLoginsEnabled (string regionName)
2253 {
2254 LoginsEnabled handler = OnLoginsEnabled;
2255
2256 if ( handler != null)
2257 {
2258 foreach (LoginsEnabled d in handler.GetInvocationList())
2259 {
2260 try
2261 {
2262 d(regionName);
2263 }
2264 catch (Exception e)
2265 {
2266 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for LoginsEnabled failed - continuing {0} - {1}",
2267 e.Message, e.StackTrace);
2268 }
2269 }
2270 }
2271 }
2272
2273 public void TriggerPrimsLoaded(Scene s)
2274 {
2275 PrimsLoaded handler = OnPrimsLoaded;
2276
2277 if (handler != null)
2278 {
2279 foreach (PrimsLoaded d in handler.GetInvocationList())
2280 {
2281 try
2282 {
2283 d(s);
2284 }
2285 catch (Exception e)
2286 {
2287 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for PrimsLoaded failed - continuing {0} - {1}",
2288 e.Message, e.StackTrace);
2289 }
2290 }
2291 }
2292 }
2245 } 2293 }
2246} 2294}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0b92818..c04bbb4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -408,192 +408,198 @@ namespace OpenSim.Region.Framework.Scenes
408 InventoryItemBase item = new InventoryItemBase(itemId, senderId); 408 InventoryItemBase item = new InventoryItemBase(itemId, senderId);
409 item = InventoryService.GetItem(item); 409 item = InventoryService.GetItem(item);
410 410
411 if ((item != null) && (item.Owner == senderId)) 411 if (item == null)
412 { 412 {
413 IUserManagement uman = RequestModuleInterface<IUserManagement>(); 413 m_log.WarnFormat(
414 if (uman != null) 414 "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient);
415 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); 415 return null;
416 }
416 417
417 if (!Permissions.BypassPermissions()) 418 if (item.Owner != senderId)
418 { 419 {
419 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 420 m_log.WarnFormat(
420 return null; 421 "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}",
421 } 422 item.Name, item.ID, recipient, senderId, item.Owner);
423 return null;
424 }
425
426 IUserManagement uman = RequestModuleInterface<IUserManagement>();
427 if (uman != null)
428 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
429
430 if (!Permissions.BypassPermissions())
431 {
432 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
433 return null;
434 }
422 435
423 // Insert a copy of the item into the recipient 436 // Insert a copy of the item into the recipient
424 InventoryItemBase itemCopy = new InventoryItemBase(); 437 InventoryItemBase itemCopy = new InventoryItemBase();
425 itemCopy.Owner = recipient; 438 itemCopy.Owner = recipient;
426 itemCopy.CreatorId = item.CreatorId; 439 itemCopy.CreatorId = item.CreatorId;
427 itemCopy.CreatorData = item.CreatorData; 440 itemCopy.CreatorData = item.CreatorData;
428 itemCopy.ID = UUID.Random(); 441 itemCopy.ID = UUID.Random();
429 itemCopy.AssetID = item.AssetID; 442 itemCopy.AssetID = item.AssetID;
430 itemCopy.Description = item.Description; 443 itemCopy.Description = item.Description;
431 itemCopy.Name = item.Name; 444 itemCopy.Name = item.Name;
432 itemCopy.AssetType = item.AssetType; 445 itemCopy.AssetType = item.AssetType;
433 itemCopy.InvType = item.InvType; 446 itemCopy.InvType = item.InvType;
434 itemCopy.Folder = recipientFolderId; 447 itemCopy.Folder = recipientFolderId;
435 448
436 if (Permissions.PropagatePermissions() && recipient != senderId) 449 if (Permissions.PropagatePermissions() && recipient != senderId)
450 {
451 // Trying to do this right this time. This is evil. If
452 // you believe in Good, go elsewhere. Vampires and other
453 // evil creatores only beyond this point. You have been
454 // warned.
455
456 // We're going to mask a lot of things by the next perms
457 // Tweak the next perms to be nicer to our data
458 //
459 // In this mask, all the bits we do NOT want to mess
460 // with are set. These are:
461 //
462 // Transfer
463 // Copy
464 // Modufy
465 uint permsMask = ~ ((uint)PermissionMask.Copy |
466 (uint)PermissionMask.Transfer |
467 (uint)PermissionMask.Modify);
468
469 // Now, reduce the next perms to the mask bits
470 // relevant to the operation
471 uint nextPerms = permsMask | (item.NextPermissions &
472 ((uint)PermissionMask.Copy |
473 (uint)PermissionMask.Transfer |
474 (uint)PermissionMask.Modify));
475
476 // nextPerms now has all bits set, except for the actual
477 // next permission bits.
478
479 // This checks for no mod, no copy, no trans.
480 // This indicates an error or messed up item. Do it like
481 // SL and assume trans
482 if (nextPerms == permsMask)
483 nextPerms |= (uint)PermissionMask.Transfer;
484
485 // Inventory owner perms are the logical AND of the
486 // folded perms and the root prim perms, however, if
487 // the root prim is mod, the inventory perms will be
488 // mod. This happens on "take" and is of little concern
489 // here, save for preventing escalation
490
491 // This hack ensures that items previously permalocked
492 // get unlocked when they're passed or rezzed
493 uint basePerms = item.BasePermissions |
494 (uint)PermissionMask.Move;
495 uint ownerPerms = item.CurrentPermissions;
496
497 // If this is an object, root prim perms may be more
498 // permissive than folded perms. Use folded perms as
499 // a mask
500 if (item.InvType == (int)InventoryType.Object)
437 { 501 {
438 // Trying to do this right this time. This is evil. If 502 // Create a safe mask for the current perms
439 // you believe in Good, go elsewhere. Vampires and other 503 uint foldedPerms = (item.CurrentPermissions & 7) << 13;
440 // evil creatores only beyond this point. You have been 504 foldedPerms |= permsMask;
441 // warned. 505
442 506 bool isRootMod = (item.CurrentPermissions &
443 // We're going to mask a lot of things by the next perms 507 (uint)PermissionMask.Modify) != 0 ?
444 // Tweak the next perms to be nicer to our data 508 true : false;
445 // 509
446 // In this mask, all the bits we do NOT want to mess 510 // Mask the owner perms to the folded perms
447 // with are set. These are: 511 ownerPerms &= foldedPerms;
448 // 512 basePerms &= foldedPerms;
449 // Transfer 513
450 // Copy 514 // If the root was mod, let the mask reflect that
451 // Modufy 515 // We also need to adjust the base here, because
452 uint permsMask = ~ ((uint)PermissionMask.Copy | 516 // we should be able to edit in-inventory perms
453 (uint)PermissionMask.Transfer | 517 // for the root prim, if it's mod.
454 (uint)PermissionMask.Modify); 518 if (isRootMod)
455
456 // Now, reduce the next perms to the mask bits
457 // relevant to the operation
458 uint nextPerms = permsMask | (item.NextPermissions &
459 ((uint)PermissionMask.Copy |
460 (uint)PermissionMask.Transfer |
461 (uint)PermissionMask.Modify));
462
463 // nextPerms now has all bits set, except for the actual
464 // next permission bits.
465
466 // This checks for no mod, no copy, no trans.
467 // This indicates an error or messed up item. Do it like
468 // SL and assume trans
469 if (nextPerms == permsMask)
470 nextPerms |= (uint)PermissionMask.Transfer;
471
472 // Inventory owner perms are the logical AND of the
473 // folded perms and the root prim perms, however, if
474 // the root prim is mod, the inventory perms will be
475 // mod. This happens on "take" and is of little concern
476 // here, save for preventing escalation
477
478 // This hack ensures that items previously permalocked
479 // get unlocked when they're passed or rezzed
480 uint basePerms = item.BasePermissions |
481 (uint)PermissionMask.Move;
482 uint ownerPerms = item.CurrentPermissions;
483
484 // If this is an object, root prim perms may be more
485 // permissive than folded perms. Use folded perms as
486 // a mask
487 if (item.InvType == (int)InventoryType.Object)
488 { 519 {
489 // Create a safe mask for the current perms 520 ownerPerms |= (uint)PermissionMask.Modify;
490 uint foldedPerms = (item.CurrentPermissions & 7) << 13; 521 basePerms |= (uint)PermissionMask.Modify;
491 foldedPerms |= permsMask;
492
493 bool isRootMod = (item.CurrentPermissions &
494 (uint)PermissionMask.Modify) != 0 ?
495 true : false;
496
497 // Mask the owner perms to the folded perms
498 ownerPerms &= foldedPerms;
499 basePerms &= foldedPerms;
500
501 // If the root was mod, let the mask reflect that
502 // We also need to adjust the base here, because
503 // we should be able to edit in-inventory perms
504 // for the root prim, if it's mod.
505 if (isRootMod)
506 {
507 ownerPerms |= (uint)PermissionMask.Modify;
508 basePerms |= (uint)PermissionMask.Modify;
509 }
510 } 522 }
523 }
511 524
512 // These will be applied to the root prim at next rez. 525 // These will be applied to the root prim at next rez.
513 // The slam bit (bit 3) and folded permission (bits 0-2) 526 // The slam bit (bit 3) and folded permission (bits 0-2)
514 // are preserved due to the above mangling 527 // are preserved due to the above mangling
515 ownerPerms &= nextPerms; 528 ownerPerms &= nextPerms;
516 529
517 // Mask the base permissions. This is a conservative 530 // Mask the base permissions. This is a conservative
518 // approach altering only the three main perms 531 // approach altering only the three main perms
519 basePerms &= nextPerms; 532 basePerms &= nextPerms;
520 533
521 // Assign to the actual item. Make sure the slam bit is 534 // Assign to the actual item. Make sure the slam bit is
522 // set, if it wasn't set before. 535 // set, if it wasn't set before.
523 itemCopy.BasePermissions = basePerms; 536 itemCopy.BasePermissions = basePerms;
524 itemCopy.CurrentPermissions = ownerPerms; 537 itemCopy.CurrentPermissions = ownerPerms;
525 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; 538 itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
526 539
527 itemCopy.NextPermissions = item.NextPermissions; 540 itemCopy.NextPermissions = item.NextPermissions;
528 541
529 // This preserves "everyone can move" 542 // This preserves "everyone can move"
530 itemCopy.EveryOnePermissions = item.EveryOnePermissions & 543 itemCopy.EveryOnePermissions = item.EveryOnePermissions &
531 nextPerms; 544 nextPerms;
532 545
533 // Intentionally killing "share with group" here, as 546 // Intentionally killing "share with group" here, as
534 // the recipient will not have the group this is 547 // the recipient will not have the group this is
535 // set to 548 // set to
536 itemCopy.GroupPermissions = 0; 549 itemCopy.GroupPermissions = 0;
537 } 550 }
538 else 551 else
552 {
553 itemCopy.CurrentPermissions = item.CurrentPermissions;
554 itemCopy.NextPermissions = item.NextPermissions;
555 itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
556 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
557 itemCopy.BasePermissions = item.BasePermissions;
558 }
559
560 if (itemCopy.Folder == UUID.Zero)
561 {
562 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
563
564 if (folder != null)
539 { 565 {
540 itemCopy.CurrentPermissions = item.CurrentPermissions; 566 itemCopy.Folder = folder.ID;
541 itemCopy.NextPermissions = item.NextPermissions;
542 itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
543 itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
544 itemCopy.BasePermissions = item.BasePermissions;
545 } 567 }
546 568 else
547 if (itemCopy.Folder == UUID.Zero)
548 { 569 {
549 InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); 570 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
550 571
551 if (folder != null) 572 if (root != null)
552 { 573 itemCopy.Folder = root.ID;
553 itemCopy.Folder = folder.ID;
554 }
555 else 574 else
556 { 575 return null; // No destination
557 InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
558
559 if (root != null)
560 itemCopy.Folder = root.ID;
561 else
562 return null; // No destination
563 }
564 } 576 }
577 }
565 578
566 itemCopy.GroupID = UUID.Zero; 579 itemCopy.GroupID = UUID.Zero;
567 itemCopy.GroupOwned = false; 580 itemCopy.GroupOwned = false;
568 itemCopy.Flags = item.Flags; 581 itemCopy.Flags = item.Flags;
569 itemCopy.SalePrice = item.SalePrice; 582 itemCopy.SalePrice = item.SalePrice;
570 itemCopy.SaleType = item.SaleType; 583 itemCopy.SaleType = item.SaleType;
571 584
572 if (AddInventoryItem(itemCopy)) 585 if (AddInventoryItem(itemCopy))
573 { 586 {
574 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 587 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
575 if (invAccess != null) 588 if (invAccess != null)
576 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); 589 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
577 } 590 }
578 591
579 if (!Permissions.BypassPermissions()) 592 if (!Permissions.BypassPermissions())
593 {
594 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
580 { 595 {
581 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 596 List<UUID> items = new List<UUID>();
582 { 597 items.Add(itemId);
583 List<UUID> items = new List<UUID>(); 598 InventoryService.DeleteItems(senderId, items);
584 items.Add(itemId);
585 InventoryService.DeleteItems(senderId, items);
586 }
587 } 599 }
588
589 return itemCopy;
590 }
591 else
592 {
593 m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
594 return null;
595 } 600 }
596 601
602 return itemCopy;
597 } 603 }
598 604
599 /// <summary> 605 /// <summary>
@@ -781,7 +787,7 @@ namespace OpenSim.Region.Framework.Scenes
781 /// <param name="asset"></param> 787 /// <param name="asset"></param>
782 /// <param name="invType"></param> 788 /// <param name="invType"></param>
783 /// <param name="nextOwnerMask"></param> 789 /// <param name="nextOwnerMask"></param>
784 private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, 790 public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
785 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) 791 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
786 { 792 {
787 CreateNewInventoryItem( 793 CreateNewInventoryItem(
@@ -836,78 +842,6 @@ namespace OpenSim.Region.Framework.Scenes
836 } 842 }
837 843
838 /// <summary> 844 /// <summary>
839 /// Create a new inventory item. Called when the client creates a new item directly within their
840 /// inventory (e.g. by selecting a context inventory menu option).
841 /// </summary>
842 /// <param name="remoteClient"></param>
843 /// <param name="transactionID"></param>
844 /// <param name="folderID"></param>
845 /// <param name="callbackID"></param>
846 /// <param name="description"></param>
847 /// <param name="name"></param>
848 /// <param name="invType"></param>
849 /// <param name="type"></param>
850 /// <param name="wearableType"></param>
851 /// <param name="nextOwnerMask"></param>
852 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
853 uint callbackID, string description, string name, sbyte invType,
854 sbyte assetType,
855 byte wearableType, uint nextOwnerMask, int creationDate)
856 {
857 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
858
859 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
860 return;
861
862 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
863 InventoryFolderBase folder = InventoryService.GetFolder(f);
864
865 if (folder == null || folder.Owner != remoteClient.AgentId)
866 return;
867
868 if (transactionID == UUID.Zero)
869 {
870 ScenePresence presence;
871 if (TryGetScenePresence(remoteClient.AgentId, out presence))
872 {
873 byte[] data = null;
874
875 if (invType == (sbyte)InventoryType.Landmark && presence != null)
876 {
877 Vector3 pos = presence.AbsolutePosition;
878 string strdata = String.Format(
879 "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
880 presence.Scene.RegionInfo.RegionID,
881 pos.X, pos.Y, pos.Z,
882 presence.RegionHandle);
883 data = Encoding.ASCII.GetBytes(strdata);
884 }
885
886 AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
887 AssetService.Store(asset);
888
889 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
890 }
891 else
892 {
893 m_log.ErrorFormat(
894 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
895 remoteClient.AgentId);
896 }
897 }
898 else
899 {
900 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
901 if (agentTransactions != null)
902 {
903 agentTransactions.HandleItemCreationFromTransaction(
904 remoteClient, transactionID, folderID, callbackID, description,
905 name, invType, assetType, wearableType, nextOwnerMask);
906 }
907 }
908 }
909
910 /// <summary>
911 /// Link an inventory item to an existing item. 845 /// Link an inventory item to an existing item.
912 /// </summary> 846 /// </summary>
913 /// <remarks> 847 /// <remarks>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 254ad05..1575e50 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -95,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
95 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
96 public bool m_seeIntoBannedRegion = false; 96 public bool m_seeIntoBannedRegion = false;
97 public int MaxUndoCount = 5; 97 public int MaxUndoCount = 5;
98 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
99 public bool LoginLock = false;
98 public bool LoginsDisabled = true; 100 public bool LoginsDisabled = true;
101 public bool StartDisabled = false;
99 public bool LoadingPrims; 102 public bool LoadingPrims;
100 public IXfer XferManager; 103 public IXfer XferManager;
101 104
@@ -1399,10 +1402,26 @@ namespace OpenSim.Region.Framework.Scenes
1399 IConfig startupConfig = m_config.Configs["Startup"]; 1402 IConfig startupConfig = m_config.Configs["Startup"];
1400 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1403 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1401 { 1404 {
1405 // This handles a case of a region having no scripts for the RegionReady module
1406 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1407 {
1408 // need to be able to tell these have changed in RegionReady
1409 LoginLock = false;
1410 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1411 }
1402 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1412 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1403 LoginsDisabled = false; 1413 // For RegionReady lockouts
1414 if( LoginLock == false)
1415 {
1416 LoginsDisabled = false;
1417 }
1404 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); 1418 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1405 } 1419 }
1420 else
1421 {
1422 StartDisabled = true;
1423 LoginsDisabled = true;
1424 }
1406 } 1425 }
1407 } 1426 }
1408 catch (NotImplementedException) 1427 catch (NotImplementedException)
@@ -1765,6 +1784,7 @@ namespace OpenSim.Region.Framework.Scenes
1765 1784
1766 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); 1785 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
1767 LoadingPrims = false; 1786 LoadingPrims = false;
1787 EventManager.TriggerPrimsLoaded(this);
1768 } 1788 }
1769 1789
1770 1790
@@ -1930,6 +1950,10 @@ namespace OpenSim.Region.Framework.Scenes
1930 sceneObject.SetGroup(groupID, null); 1950 sceneObject.SetGroup(groupID, null);
1931 } 1951 }
1932 1952
1953 IUserManagement uman = RequestModuleInterface<IUserManagement>();
1954 if (uman != null)
1955 sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
1956
1933 sceneObject.ScheduleGroupForFullUpdate(); 1957 sceneObject.ScheduleGroupForFullUpdate();
1934 1958
1935 return sceneObject; 1959 return sceneObject;
@@ -2658,6 +2682,10 @@ namespace OpenSim.Region.Framework.Scenes
2658 if (TryGetScenePresence(client.AgentId, out presence)) 2682 if (TryGetScenePresence(client.AgentId, out presence))
2659 { 2683 {
2660 m_LastLogin = Util.EnvironmentTickCount(); 2684 m_LastLogin = Util.EnvironmentTickCount();
2685
2686 // Cache the user's name
2687 CacheUserName(aCircuit);
2688
2661 EventManager.TriggerOnNewClient(client); 2689 EventManager.TriggerOnNewClient(client);
2662 if (vialogin) 2690 if (vialogin)
2663 { 2691 {
@@ -2671,6 +2699,28 @@ namespace OpenSim.Region.Framework.Scenes
2671 } 2699 }
2672 } 2700 }
2673 2701
2702 private void CacheUserName(AgentCircuitData aCircuit)
2703 {
2704 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
2705 if (uMan != null)
2706 {
2707 string homeURL = string.Empty;
2708 string first = aCircuit.firstname, last = aCircuit.lastname;
2709 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
2710 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2711 if (aCircuit.lastname.StartsWith("@"))
2712 {
2713 string[] parts = aCircuit.firstname.Split('.');
2714 if (parts.Length >= 2)
2715 {
2716 first = parts[0];
2717 last = parts[1];
2718 }
2719 }
2720 uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
2721 }
2722 }
2723
2674 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) 2724 private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
2675 { 2725 {
2676 vialogin = false; 2726 vialogin = false;
@@ -2813,7 +2863,7 @@ namespace OpenSim.Region.Framework.Scenes
2813 2863
2814 public virtual void SubscribeToClientInventoryEvents(IClientAPI client) 2864 public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
2815 { 2865 {
2816 client.OnCreateNewInventoryItem += CreateNewInventoryItem; 2866
2817 client.OnLinkInventoryItem += HandleLinkInventoryItem; 2867 client.OnLinkInventoryItem += HandleLinkInventoryItem;
2818 client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder; 2868 client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
2819 client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder; 2869 client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
@@ -2837,7 +2887,6 @@ namespace OpenSim.Region.Framework.Scenes
2837 public virtual void SubscribeToClientTeleportEvents(IClientAPI client) 2887 public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
2838 { 2888 {
2839 client.OnTeleportLocationRequest += RequestTeleportLocation; 2889 client.OnTeleportLocationRequest += RequestTeleportLocation;
2840 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
2841 } 2890 }
2842 2891
2843 public virtual void SubscribeToClientScriptEvents(IClientAPI client) 2892 public virtual void SubscribeToClientScriptEvents(IClientAPI client)
@@ -2941,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2941 2990
2942 public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) 2991 public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
2943 { 2992 {
2944 client.OnCreateNewInventoryItem -= CreateNewInventoryItem; 2993
2945 client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder; 2994 client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
2946 client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder; 2995 client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
2947 client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!! 2996 client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
@@ -2963,7 +3012,7 @@ namespace OpenSim.Region.Framework.Scenes
2963 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) 3012 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
2964 { 3013 {
2965 client.OnTeleportLocationRequest -= RequestTeleportLocation; 3014 client.OnTeleportLocationRequest -= RequestTeleportLocation;
2966 client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; 3015 //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
2967 //client.OnTeleportHomeRequest -= TeleportClientHome; 3016 //client.OnTeleportHomeRequest -= TeleportClientHome;
2968 } 3017 }
2969 3018
@@ -4064,26 +4113,6 @@ namespace OpenSim.Region.Framework.Scenes
4064 } 4113 }
4065 } 4114 }
4066 4115
4067 /// <summary>
4068 /// Tries to teleport agent to landmark.
4069 /// </summary>
4070 /// <param name="remoteClient"></param>
4071 /// <param name="regionHandle"></param>
4072 /// <param name="position"></param>
4073 public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
4074 {
4075 GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID);
4076
4077 if (info == null)
4078 {
4079 // can't find the region: Tell viewer and abort
4080 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
4081 return;
4082 }
4083
4084 RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
4085 }
4086
4087 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 4116 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4088 { 4117 {
4089 if (m_teleportModule != null) 4118 if (m_teleportModule != null)
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 95ded7f..5c284b9 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -121,7 +121,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
121 } 121 }
122 } 122 }
123 123
124
125 /// <summary> 124 /// <summary>
126 /// Serialize a scene object to the original xml format 125 /// Serialize a scene object to the original xml format
127 /// </summary> 126 /// </summary>
@@ -572,7 +571,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
572 571
573 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader) 572 private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
574 { 573 {
575 obj.Shape = ReadShape(reader, "Shape"); 574 bool errors = false;
575 obj.Shape = ReadShape(reader, "Shape", out errors);
576
577 if (errors)
578 m_log.DebugFormat(
579 "[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
580 obj.Name, obj.UUID);
576 } 581 }
577 582
578 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) 583 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
@@ -1479,7 +1484,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1479 } 1484 }
1480 catch (Exception e) 1485 catch (Exception e)
1481 { 1486 {
1482 m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing {0}: {1}", nodeName, e); 1487 m_log.DebugFormat(
1488 "[SceneObjectSerializer]: exception while parsing {0} in object {1} {2}: {3}{4}",
1489 obj.Name, obj.UUID, nodeName, e.Message, e.StackTrace);
1483 if (reader.NodeType == XmlNodeType.EndElement) 1490 if (reader.NodeType == XmlNodeType.EndElement)
1484 reader.Read(); 1491 reader.Read();
1485 } 1492 }
@@ -1531,8 +1538,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1531 return tinv; 1538 return tinv;
1532 } 1539 }
1533 1540
1534 static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name) 1541 /// <summary>
1542 /// Read a shape from xml input
1543 /// </summary>
1544 /// <param name="reader"></param>
1545 /// <param name="name">The name of the xml element containing the shape</param>
1546 /// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
1547 /// <returns>The shape parsed</returns>
1548 static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
1535 { 1549 {
1550 errors = false;
1551
1536 PrimitiveBaseShape shape = new PrimitiveBaseShape(); 1552 PrimitiveBaseShape shape = new PrimitiveBaseShape();
1537 1553
1538 reader.ReadStartElement(name, String.Empty); // Shape 1554 reader.ReadStartElement(name, String.Empty); // Shape
@@ -1551,7 +1567,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1551 } 1567 }
1552 catch (Exception e) 1568 catch (Exception e)
1553 { 1569 {
1554 m_log.DebugFormat("[SceneObjectSerializer]: exception while parsing Shape {0}: {1}", nodeName, e); 1570 errors = true;
1571 m_log.DebugFormat(
1572 "[SceneObjectSerializer]: exception while parsing Shape property {0}: {1}{2}",
1573 nodeName, e.Message, e.StackTrace);
1574
1555 if (reader.NodeType == XmlNodeType.EndElement) 1575 if (reader.NodeType == XmlNodeType.EndElement)
1556 reader.Read(); 1576 reader.Read();
1557 } 1577 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
new file mode 100644
index 0000000..abca792
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -0,0 +1,110 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenMetaverse.Assets;
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
44using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49
50namespace OpenSim.Region.Framework.Tests
51{
52 [TestFixture]
53 public class UserInventoryTests
54 {
55 [Test]
56 public void TestGiveInventoryItem()
57 {
58 TestHelper.InMethod();
59// log4net.Config.XmlConfigurator.Configure();
60
61 Scene scene = SceneSetupHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
65
66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID);
67
68 InventoryItemBase retrievedItem1
69 = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1");
70
71 Assert.That(retrievedItem1, Is.Not.Null);
72
73 // Try giving back the freshly received item
74 scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID);
75
76 List<InventoryItemBase> reretrievedItems
77 = UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1");
78
79 Assert.That(reretrievedItems.Count, Is.EqualTo(2));
80 }
81
82 [Test]
83 public void TestGiveInventoryFolder()
84 {
85 TestHelper.InMethod();
86// log4net.Config.XmlConfigurator.Configure();
87
88 Scene scene = SceneSetupHelpers.SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001);
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002);
91 InventoryFolderBase folder1
92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
93
94 scene.GiveInventoryFolder(user2.PrincipalID, user1.PrincipalID, folder1.ID, UUID.Zero);
95
96 InventoryFolderBase retrievedFolder1
97 = UserInventoryHelpers.GetInventoryFolder(scene.InventoryService, user2.PrincipalID, "folder1");
98
99 Assert.That(retrievedFolder1, Is.Not.Null);
100
101 // Try giving back the freshly received folder
102 scene.GiveInventoryFolder(user1.PrincipalID, user2.PrincipalID, retrievedFolder1.ID, UUID.Zero);
103
104 List<InventoryFolderBase> reretrievedFolders
105 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, "folder1");
106
107 Assert.That(reretrievedFolders.Count, Is.EqualTo(2));
108 }
109 }
110} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 07af201..4045507 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1183,7 +1183,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1183 IRC_SendChannelPrivmsg(objectname,url); 1183 IRC_SendChannelPrivmsg(objectname,url);
1184 } 1184 }
1185 1185
1186 public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 1186 public void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
1187 { 1187 {
1188 1188
1189 } 1189 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 1c791b9..630fcab 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -1223,6 +1223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1223 1223
1224 /// <summary> 1224 /// <summary>
1225 /// Get a list of groups memberships for the agent that are marked "ListInProfile" 1225 /// Get a list of groups memberships for the agent that are marked "ListInProfile"
1226 /// (unless that agent has a godLike aspect, in which case get all groups)
1226 /// </summary> 1227 /// </summary>
1227 /// <param name="dataForAgentID"></param> 1228 /// <param name="dataForAgentID"></param>
1228 /// <returns></returns> 1229 /// <returns></returns>
@@ -1231,20 +1232,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1231 List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); 1232 List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID);
1232 GroupMembershipData[] membershipArray; 1233 GroupMembershipData[] membershipArray;
1233 1234
1234 if (requestingClient.AgentId != dataForAgentID) 1235 // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for
1235 { 1236 // those with a GodLike aspect.
1236 Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership) 1237 Scene cScene = (Scene)requestingClient.Scene;
1237 { 1238 bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId);
1238 return membership.ListInProfile;
1239 };
1240 1239
1241 membershipArray = membershipData.FindAll(showInProfile).ToArray(); 1240 if (isGod)
1242 }
1243 else
1244 { 1241 {
1245 membershipArray = membershipData.ToArray(); 1242 membershipArray = membershipData.ToArray();
1246 } 1243 }
1244 else
1245 {
1246 if (requestingClient.AgentId != dataForAgentID)
1247 {
1248 Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
1249 {
1250 return membership.ListInProfile;
1251 };
1247 1252
1253 membershipArray = membershipData.FindAll(showInProfile).ToArray();
1254 }
1255 else
1256 {
1257 membershipArray = membershipData.ToArray();
1258 }
1259 }
1260
1248 if (m_debugEnabled) 1261 if (m_debugEnabled)
1249 { 1262 {
1250 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); 1263 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
@@ -1257,6 +1270,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1257 return membershipArray; 1270 return membershipArray;
1258 } 1271 }
1259 1272
1273
1260 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) 1274 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
1261 { 1275 {
1262 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1276 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs
deleted file mode 100644
index 4a402bf..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs
+++ /dev/null
@@ -1,161 +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#region Header
29
30// AuraMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PM 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class AuraMetaEntity : PointMetaEntity
56 {
57 #region Constructors
58
59 //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency.
60 public AuraMetaEntity(Scene scene, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
61 : base(scene, groupPos, transparency)
62 {
63 SetAura(color, scale);
64 }
65
66 public AuraMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
67 : base(scene, uuid, groupPos, transparency)
68 {
69 SetAura(color, scale);
70 }
71
72 #endregion Constructors
73
74 #region Private Methods
75
76 private float Average(Vector3 values)
77 {
78 return (values.X + values.Y + values.Z)/3f;
79 }
80
81 #endregion Private Methods
82
83 #region Public Methods
84
85 public void SetAura(Vector3 color, Vector3 scale)
86 {
87 SetAura(color, Average(scale) * 2.0f);
88 }
89
90 public void SetAura(Vector3 color, float radius)
91 {
92 SceneObjectPart From = m_Entity.RootPart;
93
94 //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius);
95 float burstRadius = 0.1f;
96 Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None;
97 float age = 1.5f;
98 float burstRate = 0.4f;
99 if (radius >= 8.0f)
100 {
101 //float sizeOfObject = radius / 2.0f;
102 burstRadius = (radius - 8.0f)/3f;
103 burstRate = 1.5f;
104 radius = 7.99f;
105 patternFlags = Primitive.ParticleSystem.SourcePattern.Explode;
106 age = 4.0f;
107 }
108 SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags);
109 }
110
111 public void SetAura(SceneObjectPart From, Vector3 color, float radius, float burstRadius, float age, float burstRate, Primitive.ParticleSystem.SourcePattern patternFlags)
112 {
113 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
114 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
115 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
116 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
117 // Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
118 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
119 prules.PartStartColor.G = color.Y;
120 prules.PartStartColor.B = color.Z;
121 prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency
122 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
123 prules.PartEndColor.G = color.Y;
124 prules.PartEndColor.B = color.Z;
125 prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency
126 /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE
127 prules.PartStartScaleY = 0.5f;
128 prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE
129 prules.PartEndScaleY = 0.5f;
130 */
131 prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE
132 prules.PartStartScaleY = radius;
133 prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE
134 prules.PartEndScaleY = radius;
135 prules.PartMaxAge = age; //PSYS_PART_MAX_AGE
136 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
137 prules.PartAcceleration.Y = 0.0f;
138 prules.PartAcceleration.Z = 0.0f;
139 prules.Pattern = patternFlags; //PSYS_SRC_PATTERN
140 //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
141 prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE
142 prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT
143 //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS
144 prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS
145 prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN
146 prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX
147 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
148 //prules.Target = To; //PSYS_SRC_TARGET_KEY
149 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
150 prules.AngularVelocity.Y = 0.0f;
151 prules.AngularVelocity.Z = 0.0f;
152 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
153 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
154
155 prules.CRC = 1; //activates the particle system??
156 From.AddNewParticleSystem(prules);
157 }
158
159 #endregion Public Methods
160 }
161}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs
deleted file mode 100644
index 6966de0..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs
+++ /dev/null
@@ -1,139 +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#region Header
29
30// BeamMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PM 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class BeamMetaEntity : PointMetaEntity
56 {
57 #region Constructors
58
59 public BeamMetaEntity(Scene scene, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
60 : base(scene, groupPos, transparency)
61 {
62 SetBeamToUUID(To, color);
63 }
64
65 public BeamMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
66 : base(scene, uuid, groupPos, transparency)
67 {
68 SetBeamToUUID(To, color);
69 }
70
71 #endregion Constructors
72
73 #region Public Methods
74
75 public void SetBeamToUUID(SceneObjectPart To, Vector3 color)
76 {
77 SceneObjectPart From = m_Entity.RootPart;
78 //Scale size of particles to distance objects are apart (for better visibility)
79 Vector3 FromPos = From.GetWorldPosition();
80 Vector3 ToPos = From.GetWorldPosition();
81 // UUID toUUID = To.UUID;
82 float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) +
83 Math.Pow(FromPos.X-ToPos.Y, 2) +
84 Math.Pow(FromPos.X-ToPos.Z, 2)
85 )
86 );
87 //float rate = (float) (distance/4f);
88 float rate = 0.5f;
89 float scale = (float) (distance/128f);
90 float speed = (float) (2.0f - distance/128f);
91
92 SetBeamToUUID(From, To, color, rate, scale, speed);
93 }
94
95 public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, Vector3 color, float rate, float scale, float speed)
96 {
97 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
98 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
99 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
100 prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
101 Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
102 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
103 prules.PartStartColor.G = color.Y;
104 prules.PartStartColor.B = color.Z;
105 prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency
106 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
107 prules.PartEndColor.G = color.Y;
108 prules.PartEndColor.B = color.Z;
109 prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency
110 prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE
111 prules.PartStartScaleY = scale;
112 prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE
113 prules.PartEndScaleY = scale;
114 prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE
115 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
116 prules.PartAcceleration.Y = 0.0f;
117 prules.PartAcceleration.Z = 0.0f;
118 //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN
119 //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
120 prules.BurstRate = rate; //PSYS_SRC_BURST_RATE
121 prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT
122 prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS
123 prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN
124 prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX
125 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
126 prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY
127 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
128 prules.AngularVelocity.Y = 0.0f;
129 prules.AngularVelocity.Z = 0.0f;
130 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
131 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
132
133 prules.CRC = 1; //activates the particle system??
134 From.AddNewParticleSystem(prules);
135 }
136
137 #endregion Public Methods
138 }
139}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs
deleted file mode 100644
index 8d6c41d..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs
+++ /dev/null
@@ -1,756 +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#region Header
29
30// CMController.cs
31// User: bongiojp
32//
33
34#endregion Header
35
36using System;
37using System.Collections;
38using System.Collections.Generic;
39using System.Diagnostics;
40using System.Threading;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 /// <summary>
55 /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread,
56 /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system.
57 /// </summary>
58 public class CMController
59 {
60 #region Static Fields
61
62 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
63
64 /// <value>
65 /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
66 /// </value>
67 private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
68
69 #endregion Static Fields
70
71 #region Fields
72
73 //bool init = false;
74 int m_channel = -1;
75
76 /// <value>
77 /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
78 /// </value>
79 IEstateModule m_estateModule = null;
80
81 //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
82 CMModel m_model = null;
83
84 /// <value>
85 /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
86 /// </value>
87 Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
88 State m_state = State.NONE;
89 CMView m_view = null;
90
91 #endregion Fields
92
93 #region Constructors
94
95 /// <summary>
96 /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
97 /// </summary>
98 /// <param name="model">
99 /// <see cref="CMModel"/>
100 /// </param>
101 /// <param name="view">
102 /// <see cref="CMView"/>
103 /// </param>
104 /// <param name="scene">
105 /// The first scene to keep track of. <see cref="Scene"/>
106 /// </param>
107 /// <param name="channel">
108 /// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
109 /// </param>
110 public CMController(CMModel model, CMView view, Scene scene, int channel)
111 {
112 m_model = model; m_view = view; m_channel = channel;
113 RegisterNewRegion(scene);
114 Initialize(model, view, scene, channel);
115 }
116
117 #endregion Constructors
118
119 #region Private Methods
120
121 //------------------------------------------------ EVENTS ----------------------------------------------------//
122// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
123// {
124// }
125
126 /// <summary>
127 /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
128 /// </summary>
129 private SceneObjectGroup GetGroupByPrim(uint localID)
130 {
131 foreach (Object currScene in m_sceneList.Values)
132 {
133 foreach (EntityBase ent in ((Scene)currScene).GetEntities())
134 {
135 if (ent is SceneObjectGroup)
136 {
137 if (((SceneObjectGroup)ent).HasChildPrim(localID))
138 return (SceneObjectGroup)ent;
139 }
140 }
141 }
142 return null;
143 }
144
145 private void Initialize(CMModel model, CMView view, Scene scene, int channel)
146 {
147 lock (this)
148 {
149 m_estateModule = scene.RequestModuleInterface<IEstateModule>();
150 Watchdog.StartThread(MainLoop, "Content Management", ThreadPriority.Normal, true);
151 m_state = State.NONE;
152 }
153 }
154
155 /// <summary>
156 /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
157 /// </summary>
158 private void MainLoop()
159 {
160 try
161 {
162 CMModel model = m_model; CMView view = m_view; int channel = m_channel;
163 Work currentJob = new Work();
164 while (true)
165 {
166 currentJob = m_WorkQueue.Dequeue();
167 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
168 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
169 switch (currentJob.Type)
170 {
171 case WorkType.NONE:
172 break;
173 case WorkType.OBJECTATTRIBUTECHANGE:
174 ObjectAttributeChanged(model, view, currentJob.LocalId);
175 break;
176 case WorkType.PRIMITIVEADDED:
177 PrimitiveAdded(model, view, currentJob);
178 break;
179 case WorkType.OBJECTDUPLICATED:
180 ObjectDuplicated(model, view, currentJob.LocalId);
181 break;
182 case WorkType.OBJECTKILLED:
183 ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
184 break;
185 case WorkType.UNDODID:
186 UndoDid(model, view, currentJob.UUID);
187 break;
188 case WorkType.NEWCLIENT:
189 NewClient(view, (IClientAPI) currentJob.Data1);
190 break;
191 case WorkType.SIMCHAT:
192 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
193 SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
194 break;
195 default:
196 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
197 break;
198 }
199
200 Watchdog.UpdateThread();
201 }
202 }
203 catch (Exception e)
204 {
205 // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
206 m_log.ErrorFormat(
207 "[CONTENT MANAGEMENT]: Content management thread terminating with exception. PLEASE REBOOT YOUR SIM - CONTENT MANAGEMENT WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
208 e);
209 }
210
211 Watchdog.RemoveThread();
212 }
213
214 /// <summary>
215 /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
216 /// </summary>
217 private void NewClient(CMView view, IClientAPI client)
218 {
219 if ((m_state & State.SHOWING_CHANGES) > 0)
220 view.SendMetaEntitiesToNewClient(client);
221 }
222
223 /// <summary>
224 /// Only called by the MainLoop.
225 /// </summary>
226 private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
227 {
228 SceneObjectGroup group = null;
229 if ((m_state & State.SHOWING_CHANGES) > 0)
230 {
231 group = GetGroupByPrim(LocalId);
232 if (group != null)
233 {
234 view.DisplayAuras(model.UpdateNormalEntityEffects(group)); //Might be a normal entity (green aura)
235 m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
236 }
237 }
238 }
239
240 /// <summary>
241 /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
242 /// </summary>
243 private void ObjectDuplicated(CMModel model, CMView view, uint localId)
244 {
245 if ((m_state & State.SHOWING_CHANGES) > 0)
246 view.DisplayAuras(model.CheckForNewEntitiesMissingAuras(GetGroupByPrim(localId).Scene));
247 }
248
249 /// <summary>
250 /// Only called by the MainLoop.
251 /// </summary>
252 private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
253 {
254 if ((m_state & State.SHOWING_CHANGES) > 0)
255 {
256 view.RemoveOrUpdateDeletedEntity(group);
257 model.RemoveOrUpdateDeletedEntity(group);
258 }
259 }
260
261 /// <summary>
262 /// Only called by the MainLoop.
263 /// </summary>
264 private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
265 {
266 if ((m_state & State.SHOWING_CHANGES) > 0)
267 {
268 foreach (Object scene in m_sceneList.Values)
269 m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
270 }
271 }
272
273 /// <summary>
274 /// Only called by the MainLoop.
275 /// </summary>
276 private void UndoDid(CMModel model, CMView view, UUID uuid)
277 {
278 if ((m_state & State.SHOWING_CHANGES) > 0)
279 {
280 ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
281 if (ent != null)
282 view.DisplayEntity(ent);
283 }
284 }
285
286 #endregion Private Methods
287
288 #region Protected Methods
289
290 protected void GroupBeingDeleted(SceneObjectGroup group)
291 {
292 m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
293 Work moreWork = new Work();
294 moreWork.Type = WorkType.OBJECTKILLED;
295 moreWork.Data1 = group.Copy();
296 m_WorkQueue.Enqueue(moreWork);
297 }
298
299 protected void ObjectDuplicated(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID)
300 {
301 Work moreWork = new Work();
302 moreWork.Type = WorkType.OBJECTDUPLICATED;
303 moreWork.LocalId = localID;
304 m_WorkQueue.Enqueue(moreWork);
305 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
306 }
307
308 protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
309 UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
310 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
311 {
312 Work moreWork = new Work();
313 moreWork.Type = WorkType.OBJECTDUPLICATED;
314 moreWork.LocalId = localID;
315 m_WorkQueue.Enqueue(moreWork);
316 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
317 }
318
319 protected void OnNewClient(IClientAPI client)
320 {
321 Work moreWork = new Work();
322 moreWork.Type = WorkType.NEWCLIENT;
323 moreWork.Data1 = client;
324 m_WorkQueue.Enqueue(moreWork);
325 m_log.Debug("[CONTENT MANAGEMENT] new client");
326 }
327
328 protected void OnUnDid(IClientAPI remoteClient, UUID primId)
329 {
330 Work moreWork = new Work();
331 moreWork.Type = WorkType.UNDODID;
332 moreWork.UUID = primId;
333 m_WorkQueue.Enqueue(moreWork);
334 m_log.Debug("[CONTENT MANAGEMENT] undid");
335 }
336
337 /// <summary>
338 /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
339 /// </summary>
340 protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity(Hashtable sceneList, Scene scene)
341 {
342 int somethingAddedToList = 1;
343 System.Collections.Generic.List<Scene> newList = new List<Scene>();
344 newList.Add(scene);
345
346 if (!sceneList.ContainsValue(scene))
347 {
348 foreach (Object sceneObj in sceneList)
349 newList.Add((Scene) sceneObj);
350 return newList;
351 }
352
353 while (somethingAddedToList > 0)
354 {
355 somethingAddedToList = 0;
356 for (int i = 0; i < newList.Count; i++)
357 {
358 foreach (Object sceneObj in sceneList.Values)
359 {
360 if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (!newList.Contains((Scene)sceneObj)))
361 {
362 newList.Add((Scene)sceneObj);
363 somethingAddedToList++;
364 }
365 }
366 }
367 }
368
369 foreach (Object sceneObj in sceneList.Values)
370 if (!newList.Contains((Scene)sceneObj))
371 newList.Add((Scene)sceneObj);
372
373 return newList;
374 }
375
376 //This is stupid, the same information is contained in the first and second argument
377 protected void SimChatSent(Object x, OSChatMessage e)
378 {
379 m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
380 m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
381 Work moreWork = new Work();
382 moreWork.Type = WorkType.SIMCHAT;
383 moreWork.Data1 = e;
384 m_WorkQueue.Enqueue(moreWork);
385 }
386
387 /// <summary>
388 /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
389 /// </summary>
390 protected void StartManaging(IClientAPI client)
391 {
392 m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
393 // client.OnChatFromClient += SimChatSent;
394 //init = true;
395
396 OnNewClient(client);
397
398 m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
399 client.OnUpdatePrimScale += UpdateSingleScale;
400 client.OnUpdatePrimGroupScale += UpdateMultipleScale;
401 client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
402 client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
403 client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
404 client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
405 client.OnAddPrim += UpdateNewParts;
406 client.OnObjectDuplicate += ObjectDuplicated;
407 client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
408 client.OnUndo += OnUnDid;
409 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
410 }
411
412 /// <summary>
413 ///
414 /// </summary>
415 protected void StopManaging(UUID clientUUID)
416 {
417 foreach (Object sceneobj in m_sceneList.Values)
418 {
419 ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
420 if (presence != null)
421 {
422 IClientAPI client = presence.ControllingClient;
423 m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
424 // client.OnChatFromViewer -= SimChatSent;
425
426 m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
427 client.OnUpdatePrimScale -= UpdateSingleScale;
428 client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
429 client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
430 client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
431 client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
432 client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
433 client.OnAddPrim -= UpdateNewParts;
434 client.OnObjectDuplicate -= ObjectDuplicated;
435 client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
436 client.OnUndo -= OnUnDid;
437 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
438 return;
439 }
440 }
441 }
442
443 protected void UpdateMultiplePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
444 {
445 Work moreWork = new Work();
446 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
447 moreWork.LocalId = localID;
448 m_WorkQueue.Enqueue(moreWork);
449 m_log.Debug("[CONTENT MANAGEMENT] pos");
450 }
451
452 protected void UpdateMultipleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
453 {
454 Work moreWork = new Work();
455 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
456 moreWork.LocalId = localID;
457 m_WorkQueue.Enqueue(moreWork);
458 m_log.Debug("[CONTENT MANAGEMENT] rot");
459 }
460
461 protected void UpdateMultipleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
462 {
463 Work moreWork = new Work();
464 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
465 moreWork.LocalId = localID;
466 m_WorkQueue.Enqueue(moreWork);
467 m_log.Debug("[CONTENT MANAGEMENT]scale");
468 }
469
470 protected void UpdateNewParts(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
471 byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
472 byte RayEndIsIntersection)
473 {
474 Work moreWork = new Work();
475 moreWork.Type = WorkType.PRIMITIVEADDED;
476 moreWork.UUID = ownerID;
477 m_WorkQueue.Enqueue(moreWork);
478 m_log.Debug("[CONTENT MANAGEMENT] new parts");
479 }
480
481 protected void UpdateSinglePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
482 {
483 Work moreWork = new Work();
484 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
485 moreWork.LocalId = localID;
486 m_WorkQueue.Enqueue(moreWork);
487 m_log.Debug("[CONTENT MANAGEMENT] move");
488 }
489
490 /// <summary>
491 ///
492 /// </summary>
493 protected void UpdateSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
494 {
495 Work moreWork = new Work();
496 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
497 moreWork.LocalId = localID;
498 m_WorkQueue.Enqueue(moreWork);
499 m_log.Debug("[CONTENT MANAGEMENT] rot");
500 }
501
502 protected void UpdateSingleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
503 {
504 Work moreWork = new Work();
505 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
506 moreWork.LocalId = localID;
507 m_WorkQueue.Enqueue(moreWork);
508 m_log.Debug("[CONTENT MANAGEMENT] scale");
509 }
510
511 /// <summary>
512 /// Only called from within the SimChat method.
513 /// </summary>
514 protected void commit(string message, Scene scene, CMModel model, CMView view)
515 {
516 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
517
518 string[] args = message.Split(new char[] {' '});
519
520 char[] logMessage = {' '};
521 if (args.Length > 1)
522 {
523 logMessage = new char[message.Length - (args[0].Length)];
524 message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
525 }
526
527 m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
528 foreach (Scene currScene in proximitySceneList)
529 {
530 model.CommitRegion(currScene, new String(logMessage));
531 view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
532 }
533
534 view.SendSimChatMessage(scene, "Successfully saved all regions.");
535 m_state |= State.DIRTY;
536
537 if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
538 {
539 view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
540 //Hide objects from users and Forget about them
541 view.HideAllMetaEntities();
542 view.HideAllAuras();
543 model.DeleteAllMetaObjects();
544
545 //Recreate them from backend files
546 foreach (Scene currScene in proximitySceneList)
547 {
548 model.UpdateCMEntities(currScene);
549 view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
550 }
551
552 //Display new objects to users1
553 view.DisplayRecentChanges();
554 view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
555 m_state &= ~(State.DIRTY);
556 m_state |= State.SHOWING_CHANGES;
557 }
558 }
559
560 /// <summary>
561 /// Only called from within the SimChat method.
562 /// </summary>
563 protected void diffmode(Scene scene, CMModel model, CMView view)
564 {
565 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
566
567 if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
568 {
569 view.SendSimChatMessage(scene, "Hiding all meta objects.");
570 view.HideAllMetaEntities();
571 view.HideAllAuras();
572 view.SendSimChatMessage(scene, "Diff-mode = OFF");
573
574 m_state &= ~State.SHOWING_CHANGES;
575 return;
576 }
577 else // TURN ON
578 {
579 if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
580 {
581 view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
582 //Hide objects from users and Forget about them
583 view.HideAllMetaEntities();
584 view.HideAllAuras();
585 model.DeleteAllMetaObjects();
586 //Recreate them from backend files
587 foreach (Object currScene in m_sceneList.Values)
588 model.UpdateCMEntities((Scene) currScene);
589 }
590 else if ((m_state & State.DIRTY) != 0) {
591 view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
592 foreach (Scene currScene in proximitySceneList)
593 model.UpdateCMEntities(currScene);
594 }
595
596 view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
597 foreach (Scene currScene in proximitySceneList)
598 model.CheckForNewEntitiesMissingAuras(currScene);
599 view.DisplayRecentChanges();
600
601 view.SendSimChatMessage(scene, "Diff-mode = ON");
602 m_state |= State.SHOWING_CHANGES;
603 m_state &= ~State.DIRTY;
604 }
605 }
606
607 /// <summary>
608 /// Only called from within the SimChat method. Hides all auras and meta entities,
609 /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
610 /// then lets the view update the clients of the new objects.
611 /// </summary>
612 protected void rollback(Scene scene, CMModel model, CMView view)
613 {
614 if ((m_state & State.SHOWING_CHANGES) > 0)
615 {
616 view.HideAllAuras();
617 view.HideAllMetaEntities();
618 }
619
620 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
621 foreach (Scene currScene in proximitySceneList)
622 model.RollbackRegion(currScene);
623
624 if ((m_state & State.DIRTY) != 0)
625 {
626 model.DeleteAllMetaObjects();
627 foreach (Scene currScene in proximitySceneList)
628 model.UpdateCMEntities(currScene);
629 }
630
631 if ((m_state & State.SHOWING_CHANGES) > 0)
632 view.DisplayRecentChanges();
633 }
634
635 #endregion Protected Methods
636
637 #region Public Methods
638
639 /// <summary>
640 /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
641 /// </summary>
642 /// <param name="scene">
643 /// A <see cref="Scene"/>
644 /// </param>
645 public void RegisterNewRegion(Scene scene)
646 {
647 m_sceneList.Add(scene.RegionInfo.RegionID, scene);
648
649 m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
650 m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
651
652 scene.EventManager.OnNewClient += StartManaging;
653 scene.EventManager.OnChatFromClient += SimChatSent;
654 scene.EventManager.OnRemovePresence += StopManaging;
655 // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
656 scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
657 }
658
659 /// <summary>
660 /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
661 /// </summary>
662 public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
663 {
664 if (e.Channel != channel)
665 return;
666 if (e.Sender == null)
667 return;
668
669 m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
670
671 IClientAPI client = e.Sender;
672 Scene scene = (Scene) e.Scene;
673 string message = e.Message;
674 string[] args = e.Message.Split(new char[] {' '});
675
676 ScenePresence avatar = scene.GetScenePresence(client.AgentId);
677
678 if (!(m_estateModule.IsManager(avatar.UUID)))
679 {
680 m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
681 view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
682 return;
683 }
684
685 switch (args[0])
686 {
687 case "ci":
688 case "commit":
689 commit(message, scene, model, view);
690 break;
691 case "dm":
692 case "diff-mode":
693 diffmode(scene, model, view);
694 break;
695 case "rb":
696 case "rollback":
697 rollback(scene, model, view);
698 break;
699 case "help":
700 m_view.DisplayHelpMenu(scene);
701 break;
702 default:
703 view.SendSimChatMessage(scene, "Command not found: " + args[0]);
704 break;
705 }
706 }
707
708 #endregion Public Methods
709
710 #region Other
711
712 /// <value>
713 /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk.
714 /// </value>
715 [Flags]
716 private enum State
717 {
718 NONE = 0,
719 DIRTY = 1, // The meta entities may not correctly represent the last revision.
720 SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
721 }
722
723 /// <value>
724 /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
725 /// </value>
726 private struct Work
727 {
728 #region Fields
729
730 public Object Data1; //Just space for holding data.
731 public Object Data2; //Just more space for holding data.
732 public uint LocalId; //Convenient
733 public WorkType Type;
734 public UUID UUID; //Convenient
735
736 #endregion Fields
737 }
738
739 /// <value>
740 /// Identifies what the data in struct Work should be used for.
741 /// </value>
742 private enum WorkType
743 {
744 NONE,
745 OBJECTATTRIBUTECHANGE,
746 PRIMITIVEADDED,
747 OBJECTDUPLICATED,
748 OBJECTKILLED,
749 UNDODID,
750 NEWCLIENT,
751 SIMCHAT
752 }
753
754 #endregion Other
755 }
756}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
deleted file mode 100644
index 7f64ebd..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
+++ /dev/null
@@ -1,193 +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#region Header
29
30// CMEntityCollection.cs created with MonoDevelop
31// User: bongiojp at 10:09 AM 7/7/2008
32//
33// Creates, Deletes, Stores ContentManagementEntities
34//
35
36#endregion Header
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41using System.Threading;
42
43using OpenMetaverse;
44
45using Nini.Config;
46
47using OpenSim;
48using OpenSim.Framework;
49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.Framework.Scenes;
51using OpenSim.Region.Physics.Manager;
52
53using log4net;
54
55namespace OpenSim.Region.OptionalModules.ContentManagement
56{
57 public class CMEntityCollection
58 {
59 #region Fields
60
61 // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
62 // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or
63 // old versions of deleted SceneObjectGroups will be stored in this hash table.
64 // The UUID keys are from the SceneObjectGroup RootPart UUIDs
65 protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //UUID to ContentManagementEntity
66
67 // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable
68 // The UUID keys are from the SceneObjectPart that they are supposed to be on.
69 protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //UUID to AuraMetaEntity
70
71 #endregion Fields
72
73 #region Constructors
74
75 public CMEntityCollection()
76 {
77 }
78
79 #endregion Constructors
80
81 #region Public Properties
82
83 public Hashtable Auras
84 {
85 get {return m_NewlyCreatedEntityAura; }
86 }
87
88 public Hashtable Entities
89 {
90 get { return m_CMEntityHash; }
91 }
92
93 #endregion Public Properties
94
95 #region Public Methods
96
97 public bool AddAura(ContentManagementEntity aura)
98 {
99 if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID))
100 return false;
101 m_NewlyCreatedEntityAura.Add(aura.UUID, aura);
102 return true;
103 }
104
105 public bool AddEntity(ContentManagementEntity ent)
106 {
107 if (m_CMEntityHash.ContainsKey(ent.UUID))
108 return false;
109 m_CMEntityHash.Add(ent.UUID, ent);
110 return true;
111 }
112
113 // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
114 public System.Collections.ArrayList CheckForMissingEntities(EntityBase[] currList)
115 {
116 System.Collections.ArrayList missingList = new System.Collections.ArrayList();
117 SceneObjectGroup temp = null;
118 foreach (EntityBase currObj in currList)
119 {
120 if (!(currObj is SceneObjectGroup))
121 continue;
122 temp = (SceneObjectGroup) currObj;
123
124 if (m_CMEntityHash.ContainsKey(temp.UUID))
125 {
126 foreach (SceneObjectPart part in temp.Parts)
127 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
128 missingList.Add(part);
129 }
130 else //Entire group is missing from revision. (and is a new part in region)
131 {
132 foreach (SceneObjectPart part in temp.Parts)
133 missingList.Add(part);
134 }
135 }
136 return missingList;
137 }
138
139 public void ClearAll()
140 {
141 m_CMEntityHash.Clear();
142 m_NewlyCreatedEntityAura.Clear();
143 }
144
145 // Old uuid and new sceneobjectgroup
146 public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
147 {
148 AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
149 part.GetWorldPosition(),
150 MetaEntity.TRANSLUCENT,
151 new Vector3(0,254,0),
152 part.Scale
153 );
154 m_NewlyCreatedEntityAura.Add(part.UUID, ent);
155 return ent;
156 }
157
158 // Old uuid and new sceneobjectgroup
159 public ContentManagementEntity CreateNewEntity(SceneObjectGroup group)
160 {
161 ContentManagementEntity ent = new ContentManagementEntity(group, false);
162 m_CMEntityHash.Add(group.UUID, ent);
163 return ent;
164 }
165
166 public ContentManagementEntity CreateNewEntity(String xml, Scene scene)
167 {
168 ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false);
169 if (ent == null)
170 return null;
171 m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent);
172 return ent;
173 }
174
175 public bool RemoveEntity(UUID uuid)
176 {
177 if (!m_CMEntityHash.ContainsKey(uuid))
178 return false;
179 m_CMEntityHash.Remove(uuid);
180 return true;
181 }
182
183 public bool RemoveNewlyCreatedEntityAura(UUID uuid)
184 {
185 if (!m_NewlyCreatedEntityAura.ContainsKey(uuid))
186 return false;
187 m_NewlyCreatedEntityAura.Remove(uuid);
188 return true;
189 }
190
191 #endregion Public Methods
192 }
193}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
deleted file mode 100644
index 84c7f29..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
+++ /dev/null
@@ -1,366 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Diagnostics;
32
33using OpenMetaverse;
34
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Region.Physics.Manager;
41
42using log4net;
43
44namespace OpenSim.Region.OptionalModules.ContentManagement
45{
46 public class CMModel
47 {
48 #region Static Fields
49
50 static float TimeToUpdate = 0;
51 static float TimeToConvertXml = 0;
52 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
53
54 #endregion Static Fields
55
56 #region Fields
57
58 /// <value>
59 /// The class that contains all auras and metaentities used in the CMS.
60 /// </value>
61 CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
62 IContentDatabase m_database = null;
63
64 #endregion Fields
65
66 #region Constructors
67
68 public CMModel()
69 {
70 }
71
72 #endregion Constructors
73
74 #region Public Properties
75
76 public CMEntityCollection MetaEntityCollection
77 {
78 get { return m_MetaEntityCollection; }
79 }
80
81 #endregion Public Properties
82
83 #region Public Methods
84
85 /// <summary>
86 /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity
87 /// it is a new part that must have a green aura (for diff mode).
88 /// Returns list of ContentManagementEntities
89 /// </summary>
90 public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
91 {
92 ArrayList missingList = null;
93 ArrayList newList = new ArrayList();
94
95 m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
96
97 //Check if the current scene has groups not included in the current list of MetaEntities
98 //If so, then the current scene's parts that are new should be marked green.
99 missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
100
101 foreach (Object missingPart in missingList)
102 {
103 if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
104 continue;
105 newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
106 }
107 m_log.Info("Number of missing objects found: " + newList.Count);
108 return newList;
109 }
110
111 /// <summary>
112 /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
113 /// </summary>
114 public void CommitRegion(Scene scene, String logMessage)
115 {
116 m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
117 m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
118 m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName);
119 }
120
121 public void DeleteAllMetaObjects()
122 {
123 m_MetaEntityCollection.ClearAll();
124 }
125
126 public ContentManagementEntity FindMetaEntityAffectedByUndo(UUID uuid)
127 {
128 ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
129 return ent;
130 }
131
132 //-------------------------------- HELPERS --------------------------------------------------------------------//
133 public ContentManagementEntity GetMetaGroupByPrim(UUID uuid)
134 {
135 foreach (Object ent in m_MetaEntityCollection.Entities.Values)
136 {
137 if (((ContentManagementEntity)ent).HasChildPrim(uuid))
138 return (ContentManagementEntity)ent;
139 }
140 return null;
141 }
142
143 public void Initialise(string database)
144 {
145 if (database == "FileSystemDatabase")
146 m_database = new FileSystemDatabase();
147 else if (database == "GitDatabase")
148 m_database = new GitDatabase();
149 }
150
151 public void InitialiseDatabase(Scene scene, string dir)
152 {
153 m_database.Initialise(scene, dir);
154 }
155
156 /// <summary>
157 /// Should be called just once to finish initializing the database.
158 /// </summary>
159 public void PostInitialise()
160 {
161 m_database.PostInitialise();
162 }
163
164 /// <summary>
165 /// Removes the green aura when an a new scene object group is deleted.
166 /// </summary>
167 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
168 {
169 // Deal with new parts not revisioned that have been deleted.
170 SceneObjectPart[] parts = group.Parts;
171 for (int i = 0; i < parts.Length; i++)
172 {
173 if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID))
174 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID);
175 }
176 }
177
178 /// <summary>
179 /// Retrieves the latest revision of a region in xml form,
180 /// converts it to scene object groups and scene presences,
181 /// swaps the current scene's entity list with the revision's list.
182 /// Note: Since deleted objects while
183 /// </summary>
184 public void RollbackRegion(Scene scene)
185 {
186 System.Collections.ArrayList xmllist = null;
187 SceneObjectGroup temp = null;
188 System.Collections.Hashtable deleteListUUIDs = new Hashtable();
189// Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>();
190 Dictionary<UUID, EntityBase> ReplacementList = new Dictionary<UUID,EntityBase>();
191 int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
192// EntityBase[] searchArray;
193
194 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
195 if (xmllist == null)
196 {
197 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
198 return;
199 }
200
201 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
202 m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
203 m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
204
205 m_log.ErrorFormat("[CMMODEL]: 1");
206
207 foreach (string xml in xmllist)
208 {
209 try
210 {
211 temp = SceneObjectSerializer.FromXml2Format(xml);
212 temp.SetScene(scene);
213
214 SceneObjectPart[] parts = temp.Parts;
215 for (int i = 0; i < parts.Length; i++)
216 parts[i].RegionHandle = scene.RegionInfo.RegionHandle;
217
218 ReplacementList.Add(temp.UUID, (EntityBase)temp);
219 }
220 catch (Exception e)
221 {
222 m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e);
223 }
224 }
225
226 //If in scene but not in revision and not a client, remove them
227 while (true)
228 {
229 try
230 {
231 foreach (EntityBase entity in scene.GetEntities())
232 {
233 if (entity == null)
234 continue;
235
236 if (entity is ScenePresence)
237 {
238 ReplacementList.Add(entity.UUID, entity);
239 continue;
240 }
241 else //if (!ReplacementList.ContainsKey(entity.UUID))
242 deleteListUUIDs.Add(entity.UUID, 0);
243 }
244 }
245 catch(Exception e)
246 {
247 m_log.ErrorFormat("[CMMODEL]: " + e);
248 deleteListUUIDs.Clear();
249 ReplacementList.Clear();
250 continue;
251 }
252 break;
253 }
254
255 foreach (UUID uuid in deleteListUUIDs.Keys)
256 {
257 try
258 {
259 // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
260 ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup();
261 scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
262 scene.SendKillObject(new List<uint>() { scene.Entities[uuid].LocalId });
263 scene.SceneGraph.DeleteSceneObject(uuid, false);
264 ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false);
265 scene.SendKillObject(new List<uint>() { ((SceneObjectGroup)scene.Entities[uuid]).LocalId });
266 }
267 catch(Exception e)
268 {
269 m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
270 }
271 }
272
273 lock (scene)
274 {
275 scene.Entities.Clear();
276
277 foreach (KeyValuePair<UUID,EntityBase> kvp in ReplacementList)
278 {
279 scene.Entities.Add(kvp.Value);
280 }
281 }
282
283 foreach (EntityBase ent in ReplacementList.Values)
284 {
285 try
286 {
287 if (!(ent is SceneObjectGroup))
288 continue;
289
290 if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) == 0)
291 ((SceneObjectGroup)ent).ApplyPhysics(true);
292 ((SceneObjectGroup)ent).AttachToBackup();
293 ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
294 ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
295 }
296 catch(Exception e)
297 {
298 m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e);
299 }
300 }
301 m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
302 scene.Backup(true);
303 }
304
305 /// <summary>
306 /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
307 /// and display the differences to clients.
308 /// </summary>
309 public void UpdateCMEntities(Scene scene)
310 {
311 Stopwatch x = new Stopwatch();
312 x.Start();
313
314 System.Collections.ArrayList xmllist = null;
315 m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID);
316 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID);
317 m_log.Info("[FSDB]: got list");
318 if (xmllist == null)
319 return;
320
321 Stopwatch y = new Stopwatch();
322 y.Start();
323 foreach (string xml in xmllist)
324 m_MetaEntityCollection.CreateNewEntity(xml, scene);
325 y.Stop();
326 TimeToConvertXml += y.ElapsedMilliseconds;
327 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
328 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
329
330 m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
331 CheckForNewEntitiesMissingAuras(scene);
332
333 x.Stop();
334 TimeToUpdate += x.ElapsedMilliseconds;
335 m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
336 m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
337 }
338
339 /// <summary>
340 /// Detects if a scene object group from the scene list has moved or changed scale. The green aura
341 /// that surrounds the object is then moved or scaled with the group.
342 /// </summary>
343 public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
344 {
345 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
346 if (group == null)
347 return null;
348
349 SceneObjectPart[] parts = group.Parts;
350 for (int i = 0; i < parts.Length; i++)
351 {
352 SceneObjectPart part = parts[i];
353 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
354 {
355 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale);
356 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
357 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
358 }
359 }
360
361 return auraList;
362 }
363
364 #endregion Public Methods
365 }
366}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
deleted file mode 100644
index 3807ccd..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
+++ /dev/null
@@ -1,206 +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#region Header
29
30// CMView.cs created with MonoDevelop
31// User: bongiojp at 11:57 AM 7/3/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 public class CMView
55 {
56 #region Static Fields
57
58 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
59
60 #endregion Static Fields
61
62 #region Fields
63
64 CMModel m_model = null;
65
66 #endregion Fields
67
68 #region Constructors
69
70 public CMView()
71 {
72 }
73
74 #endregion Constructors
75
76 #region Public Methods
77
78 // Auras To
79 public void DisplayAuras(CMEntityCollection auraCollection)
80 {
81 foreach (Object ent in auraCollection.Auras.Values)
82 ((AuraMetaEntity)ent).SendFullUpdateToAll();
83 }
84
85 // Auras To Client
86 public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client)
87 {
88 foreach (Object ent in auraCollection.Auras.Values)
89 ((AuraMetaEntity)ent).SendFullUpdate(client);
90 }
91
92 // Auras from List To ALL
93 public void DisplayAuras(ArrayList list)
94 {
95 foreach (Object ent in list)
96 {
97 m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW");
98 ((AuraMetaEntity)ent).SendFullUpdateToAll();
99 }
100 }
101
102 // Entities to ALL
103 public void DisplayEntities(CMEntityCollection entityCollection)
104 {
105 foreach (Object ent in entityCollection.Entities.Values)
106 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
107 }
108
109 // Entities to Client
110 public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client)
111 {
112 foreach (Object ent in entityCollection.Entities.Values)
113 ((ContentManagementEntity)ent).SendFullDiffUpdate(client);
114 }
115
116 // Entities from List to ALL
117 public void DisplayEntities(ArrayList list)
118 {
119 foreach (Object ent in list)
120 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
121 }
122
123 // Entity to ALL
124 public void DisplayEntity(ContentManagementEntity ent)
125 {
126 ent.SendFullDiffUpdateToAll();
127 }
128
129 public void DisplayHelpMenu(Scene scene)
130 {
131 string menu = "Menu:\n";
132 menu += "commit (ci) - saves current state of the region to a database on the server\n";
133 menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n";
134 SendSimChatMessage(scene, menu);
135 }
136
137 public void DisplayMetaEntity(UUID uuid)
138 {
139 ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid);
140 if (group != null)
141 group.SendFullDiffUpdateToAll();
142 }
143
144 /// <summary>
145 /// update all clients of red/green/blue auras and meta entities that the model knows about.
146 /// </summary>
147 public void DisplayRecentChanges()
148 {
149 m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects.");
150 DisplayEntities(m_model.MetaEntityCollection);
151 DisplayAuras(m_model.MetaEntityCollection);
152 }
153
154 public void Hide(ContentManagementEntity ent)
155 {
156 ent.HideFromAll();
157 }
158
159 public void HideAllAuras()
160 {
161 foreach (Object obj in m_model.MetaEntityCollection.Auras.Values)
162 ((MetaEntity)obj).HideFromAll();
163 }
164
165 public void HideAllMetaEntities()
166 {
167 foreach (Object obj in m_model.MetaEntityCollection.Entities.Values)
168 ((ContentManagementEntity)obj).HideFromAll();
169 }
170
171 public void Initialise(CMModel model)
172 {
173 m_model = model;
174 }
175
176 /// <summary>
177 /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted.
178 /// If it's a new scene object, any green aura attached to it is deleted.
179 /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will
180 /// figure out that there should be a red aura and not a blue aura/beam.
181 /// </summary>
182 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
183 {
184 // Deal with revisioned parts that have been deleted.
185 if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID))
186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
187
188 // Deal with new parts not revisioned that have been deleted.
189 foreach (SceneObjectPart part in group.Parts)
190 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
191 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
192 }
193
194 public void SendMetaEntitiesToNewClient(IClientAPI client)
195 {
196 }
197
198 public void SendSimChatMessage(Scene scene, string message)
199 {
200 scene.SimChat(Utils.StringToBytes(message),
201 ChatTypeEnum.Broadcast, 0, new Vector3(0,0,0), "Content Manager", UUID.Zero, false);
202 }
203
204 #endregion Public Methods
205 }
206}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
deleted file mode 100644
index 0248f36..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
+++ /dev/null
@@ -1,375 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Drawing;
31
32using OpenMetaverse;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Region.Physics.Manager;
41
42using log4net;
43
44namespace OpenSim.Region.OptionalModules.ContentManagement
45{
46 public class ContentManagementEntity : MetaEntity
47 {
48 #region Static Fields
49
50// static float TimeToDiff = 0;
51// static float TimeToCreateEntities = 0;
52
53 #endregion Static Fields
54
55 #region Fields
56
57 protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
58 protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
59
60 // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
61 // This can come in handy.
62 protected SceneObjectGroup m_UnchangedEntity = null;
63
64 /// <value>
65 /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
66 /// </value>
67 bool DiffersFromSceneGroup = false;
68
69 #endregion Fields
70
71 #region Constructors
72
73 public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
74 : base(Unchanged, false)
75 {
76 m_UnchangedEntity = Unchanged.Copy(false);
77 }
78
79 public ContentManagementEntity(string objectXML, Scene scene, bool physics)
80 : base(objectXML, scene, false)
81 {
82 m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML);
83 }
84
85 #endregion Constructors
86
87 #region Public Properties
88
89 public SceneObjectGroup UnchangedEntity
90 {
91 get { return m_UnchangedEntity; }
92 }
93
94 #endregion Public Properties
95
96 #region Private Methods
97
98 /// <summary>
99 /// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
100 /// </summary>
101 private bool ContainsKey(List<EntityBase> list, UUID uuid)
102 {
103 foreach (EntityBase part in list)
104 if (part.UUID == uuid)
105 return true;
106 return false;
107 }
108
109 private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
110 {
111 foreach (EntityBase ent in list)
112 {
113 if (ent is SceneObjectGroup)
114 if (ent.UUID == uuid)
115 return (SceneObjectGroup)ent;
116 }
117 return null;
118 }
119
120 #endregion Private Methods
121
122 #region Public Methods
123
124 /// <summary>
125 /// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
126 /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
127 /// </summary>
128 public void FindDifferences()
129 {
130 List<EntityBase> sceneEntityList = new List<EntityBase>(m_Entity.Scene.GetEntities());
131 DiffersFromSceneGroup = false;
132 // if group is not contained in scene's list
133 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
134 {
135 foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
136 {
137 // if scene list no longer contains this part, display translucent part and mark with red aura
138 if (!ContainsKey(sceneEntityList, part.UUID))
139 {
140 // if already displaying a red aura over part, make sure its red
141 if (m_AuraEntities.ContainsKey(part.UUID))
142 {
143 m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale);
144 }
145 else
146 {
147 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
148 part.GetWorldPosition(),
149 MetaEntity.TRANSLUCENT,
150 new Vector3(254, 0, 0),
151 part.Scale
152 );
153 m_AuraEntities.Add(part.UUID, auraGroup);
154 }
155 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
156 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
157 }
158 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
159 }
160
161 // a deleted part has no where to point a beam particle system,
162 // if a metapart had a particle system (maybe it represented a moved part) remove it
163 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
164 {
165 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
166 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
167 }
168
169 DiffersFromSceneGroup = true;
170 }
171 // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
172 else
173 {
174 MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
175 }
176 }
177
178 /// <summary>
179 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
180 /// </summary>
181 public bool HasChildPrim(UUID uuid)
182 {
183 return m_UnchangedEntity.ContainsPart(uuid);
184 }
185
186 /// <summary>
187 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
188 /// </summary>
189 public bool HasChildPrim(uint localID)
190 {
191 foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
192 if (part.LocalId == localID)
193 return true;
194
195 return false;
196 }
197
198 public override void Hide(IClientAPI client)
199 {
200 base.Hide(client);
201 foreach (MetaEntity group in m_AuraEntities.Values)
202 group.Hide(client);
203 foreach (MetaEntity group in m_BeamEntities.Values)
204 group.Hide(client);
205 }
206
207 public override void HideFromAll()
208 {
209 base.HideFromAll();
210 foreach (MetaEntity group in m_AuraEntities.Values)
211 group.HideFromAll();
212 foreach (MetaEntity group in m_BeamEntities.Values)
213 group.HideFromAll();
214 }
215
216 /// <summary>
217 /// Returns true if there was a change between meta entity and the entity group, false otherwise.
218 /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
219 /// </summary>
220 public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
221 {
222 SceneObjectPart sceneEntityPart;
223 SceneObjectPart metaEntityPart;
224 Diff differences;
225 bool changed = false;
226
227 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
228 // had originally saved.
229 // m_Entity will NOT necessarily be the same entity as the user had saved.
230 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts)
231 {
232 //This is the part that we use to show changes.
233 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
234 if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID))
235 {
236 sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID);
237 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
238 if (differences != Diff.NONE)
239 metaEntityPart.Text = "CHANGE: " + differences.ToString();
240 if (differences != 0)
241 {
242 // Root Part that has been modified
243 if ((differences & Diff.POSITION) > 0)
244 {
245 // If the position of any part has changed, make sure the RootPart of the
246 // meta entity is pointing with a beam particle system
247 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
248 {
249 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
250 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
251 }
252 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
253 m_UnchangedEntity.RootPart.GetWorldPosition(),
254 MetaEntity.TRANSLUCENT,
255 sceneEntityPart,
256 new Vector3(0, 0, 254)
257 );
258 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
259 }
260
261 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
262 {
263 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
264 m_AuraEntities.Remove(UnchangedPart.UUID);
265 }
266 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
267 UnchangedPart.GetWorldPosition(),
268 MetaEntity.TRANSLUCENT,
269 new Vector3(0, 0, 254),
270 UnchangedPart.Scale
271 );
272 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
273 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
274
275 DiffersFromSceneGroup = true;
276 }
277 else // no differences between scene part and meta part
278 {
279 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
280 {
281 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
282 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
283 }
284 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
285 {
286 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
287 m_AuraEntities.Remove(UnchangedPart.UUID);
288 }
289 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
290 }
291 }
292 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
293 {
294 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
295 {
296 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
297 m_AuraEntities.Remove(UnchangedPart.UUID);
298 }
299 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
300 UnchangedPart.GetWorldPosition(),
301 MetaEntity.TRANSLUCENT,
302 new Vector3(254, 0, 0),
303 UnchangedPart.Scale
304 );
305 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
306 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
307
308 DiffersFromSceneGroup = true;
309 }
310 }
311
312 return changed;
313 }
314
315 public void SendFullAuraUpdate(IClientAPI client)
316 {
317 if (DiffersFromSceneGroup)
318 {
319 foreach (AuraMetaEntity group in m_AuraEntities.Values)
320 group.SendFullUpdate(client);
321 }
322 }
323
324 public void SendFullAuraUpdateToAll()
325 {
326 if (DiffersFromSceneGroup)
327 {
328 foreach (AuraMetaEntity group in m_AuraEntities.Values)
329 group.SendFullUpdateToAll();
330 }
331 }
332
333 public void SendFullBeamUpdate(IClientAPI client)
334 {
335 if (DiffersFromSceneGroup)
336 {
337 foreach (BeamMetaEntity group in m_BeamEntities.Values)
338 group.SendFullUpdate(client);
339 }
340 }
341
342 public void SendFullBeamUpdateToAll()
343 {
344 if (DiffersFromSceneGroup)
345 {
346 foreach (BeamMetaEntity group in m_BeamEntities.Values)
347 group.SendFullUpdateToAll();
348 }
349 }
350
351 public void SendFullDiffUpdate(IClientAPI client)
352 {
353 FindDifferences();
354 if (DiffersFromSceneGroup)
355 {
356 SendFullUpdate(client);
357 SendFullAuraUpdate(client);
358 SendFullBeamUpdate(client);
359 }
360 }
361
362 public void SendFullDiffUpdateToAll()
363 {
364 FindDifferences();
365 if (DiffersFromSceneGroup)
366 {
367 SendFullUpdateToAll();
368 SendFullAuraUpdateToAll();
369 SendFullBeamUpdateToAll();
370 }
371 }
372
373 #endregion Public Methods
374 }
375}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs
deleted file mode 100644
index 3d1c346..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs
+++ /dev/null
@@ -1,163 +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#region Header
29
30// ContentManagementModule.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Threading;
38
39using OpenMetaverse;
40
41using Nini.Config;
42
43using OpenSim;
44using OpenSim.Framework;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager;
48
49using log4net;
50
51namespace OpenSim.Region.OptionalModules.ContentManagement
52{
53 public class ContentManagementModule : IRegionModule
54 {
55 #region Static Fields
56
57 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
58
59 #endregion Static Fields
60
61 #region Fields
62
63 bool initialised = false;
64 CMController m_control = null;
65 bool m_enabled = false;
66 CMModel m_model = null;
67 bool m_posted = false;
68 CMView m_view = null;
69
70 #endregion Fields
71
72 #region Public Properties
73
74 public bool IsSharedModule
75 {
76 get { return true; }
77 }
78
79 public string Name
80 {
81 get { return "ContentManagementModule"; }
82 }
83
84 #endregion Public Properties
85
86 #region Public Methods
87
88 public void Close()
89 {
90 }
91
92 public void Initialise(Scene scene, IConfigSource source)
93 {
94 string databaseDir = "./";
95 string database = "FileSystemDatabase";
96 int channel = 345;
97 try
98 {
99 if (source.Configs["CMS"] == null)
100 return;
101
102 m_enabled = source.Configs["CMS"].GetBoolean("enabled", false);
103 databaseDir = source.Configs["CMS"].GetString("directory", databaseDir);
104 database = source.Configs["CMS"].GetString("database", database);
105 channel = source.Configs["CMS"].GetInt("channel", channel);
106
107 if (database != "FileSystemDatabase" && database != "GitDatabase")
108 {
109 m_log.ErrorFormat("[Content Management]: The Database attribute must be defined as either FileSystemDatabase or GitDatabase");
110 m_enabled = false;
111 }
112 }
113 catch (Exception e)
114 {
115 m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e);
116 m_enabled = false;
117 }
118
119 if (!m_enabled)
120 {
121 m_log.Info("[Content Management]: Content Management System is not Enabled.");
122 return;
123 }
124
125 lock (this)
126 {
127 if (!initialised) //only init once
128 {
129 m_view = new CMView();
130 m_model = new CMModel();
131 m_control = new CMController(m_model, m_view, scene, channel);
132 m_model.Initialise(database);
133 m_view.Initialise(m_model);
134
135 initialised = true;
136 m_model.InitialiseDatabase(scene, databaseDir);
137 }
138 else
139 {
140 m_model.InitialiseDatabase(scene, databaseDir);
141 m_control.RegisterNewRegion(scene);
142 }
143 }
144 }
145
146 public void PostInitialise()
147 {
148 if (! m_enabled)
149 return;
150
151 lock (this)
152 {
153 if (!m_posted) //only post once
154 {
155 m_model.PostInitialise();
156 m_posted = true;
157 }
158 }
159 }
160
161 #endregion Public Methods
162 }
163}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs
deleted file mode 100644
index a3d7977..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs
+++ /dev/null
@@ -1,317 +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#region Header
29
30// FileSystemDatabase.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Diagnostics;
38using System.IO;
39using Slash = System.IO.Path;
40using System.Reflection;
41using System.Xml;
42
43using OpenMetaverse;
44
45using Nini.Config;
46
47using OpenSim.Framework;
48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Region.Framework.Scenes;
50using OpenSim.Region.CoreModules.World.Serialiser;
51using OpenSim.Region.CoreModules.World.Terrain;
52using OpenSim.Region.Physics.Manager;
53
54using log4net;
55
56namespace OpenSim.Region.OptionalModules.ContentManagement
57{
58 public class FileSystemDatabase : IContentDatabase
59 {
60 #region Static Fields
61
62 public static float TimeToDownload = 0;
63 public static float TimeToSave = 0;
64 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
65
66 #endregion Static Fields
67
68 #region Fields
69
70 private string m_repodir = null;
71 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
72 private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>();
73
74 #endregion Fields
75
76 #region Constructors
77
78 public FileSystemDatabase()
79 {
80 }
81
82 #endregion Constructors
83
84 #region Private Methods
85
86 // called by postinitialise
87 private void CreateDirectory()
88 {
89 string scenedir;
90 if (!Directory.Exists(m_repodir))
91 Directory.CreateDirectory(m_repodir);
92
93 foreach (UUID region in m_scenes.Keys)
94 {
95 scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
96 if (!Directory.Exists(scenedir))
97 Directory.CreateDirectory(scenedir);
98 }
99 }
100
101 // called by postinitialise
102 private void SetupSerialiser()
103 {
104 if (m_serialiser.Count == 0)
105 {
106 foreach (UUID region in m_scenes.Keys)
107 {
108 m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>());
109 }
110 }
111 }
112
113 #endregion Private Methods
114
115 #region Public Methods
116
117 public int GetMostRecentRevision(UUID regionid)
118 {
119 return NumOfRegionRev(regionid);
120 }
121
122 public string GetRegionObjectHeightMap(UUID regionid)
123 {
124 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
125 Slash.DirectorySeparatorChar + "heightmap.r32";
126 FileStream fs = new FileStream(filename, FileMode.Open);
127 StreamReader sr = new StreamReader(fs);
128 String result = sr.ReadToEnd();
129 sr.Close();
130 fs.Close();
131 return result;
132 }
133
134 public string GetRegionObjectHeightMap(UUID regionid, int revision)
135 {
136 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
137 Slash.DirectorySeparatorChar + "heightmap.r32";
138 FileStream fs = new FileStream(filename, FileMode.Open);
139 StreamReader sr = new StreamReader(fs);
140 String result = sr.ReadToEnd();
141 sr.Close();
142 fs.Close();
143 return result;
144 }
145
146 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
147 {
148 System.Collections.ArrayList objectList = new System.Collections.ArrayList();
149 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
150 + revision + Slash.DirectorySeparatorChar + "objects.xml";
151 XmlDocument doc = new XmlDocument();
152 XmlNode rootNode;
153 //int primCount = 0;
154 //SceneObjectGroup obj = null;
155
156 if (File.Exists(filename))
157 {
158 XmlTextReader reader = new XmlTextReader(filename);
159 reader.WhitespaceHandling = WhitespaceHandling.None;
160 doc.Load(reader);
161 reader.Close();
162 rootNode = doc.FirstChild;
163 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
164 {
165 objectList.Add(aPrimNode.OuterXml);
166 }
167 return objectList;
168 }
169 return null;
170 }
171
172 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
173 {
174 int revision = NumOfRegionRev(regionid);
175 m_log.Info("[FSDB]: found revisions:" + revision);
176 System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
177 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
178 + revision + Slash.DirectorySeparatorChar + "objects.xml";
179 XmlDocument doc = new XmlDocument();
180 XmlNode rootNode;
181
182 m_log.Info("[FSDB]: Checking if " + filename + " exists.");
183 if (File.Exists(filename))
184 {
185 Stopwatch x = new Stopwatch();
186 x.Start();
187
188 XmlTextReader reader = new XmlTextReader(filename);
189 reader.WhitespaceHandling = WhitespaceHandling.None;
190 doc.Load(reader);
191 reader.Close();
192 rootNode = doc.FirstChild;
193
194 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
195 {
196 xmlList.Add(aPrimNode.OuterXml);
197 }
198
199 x.Stop();
200 TimeToDownload += x.ElapsedMilliseconds;
201 m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
202
203 return xmlList;
204 }
205 return null;
206 }
207
208 public void Initialise(Scene scene, string dir)
209 {
210 lock (this)
211 {
212 if (m_repodir == null)
213 m_repodir = dir;
214 }
215 lock (m_scenes)
216 m_scenes.Add(scene.RegionInfo.RegionID, scene);
217 }
218
219 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid)
220 {
221 SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
222
223 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
224 string[] directories = Directory.GetDirectories(scenedir);
225
226 FileStream fs = null;
227 StreamReader sr = null;
228 String logMessage = "";
229 String logLocation = "";
230 foreach (string revisionDir in directories)
231 {
232 try
233 {
234 logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
235 fs = new FileStream(logLocation, FileMode.Open);
236 sr = new StreamReader(fs);
237 logMessage = sr.ReadToEnd();
238 sr.Close();
239 fs.Close();
240 revisionDict.Add(revisionDir, logMessage);
241 }
242 catch (Exception)
243 {
244 }
245 }
246
247 return revisionDict;
248 }
249
250 public int NumOfRegionRev(UUID regionid)
251 {
252 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
253 m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
254 string[] directories = Directory.GetDirectories(scenedir);
255 return directories.Length;
256 }
257
258 // Run once and only once.
259 public void PostInitialise()
260 {
261 SetupSerialiser();
262
263 m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
264 CreateDirectory();
265 }
266
267 public void SaveRegion(UUID regionid, string regionName, string logMessage)
268 {
269 m_log.Info("[FSDB]: ...............................");
270 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
271
272 m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
273 if (!Directory.Exists(scenedir))
274 Directory.CreateDirectory(scenedir);
275
276 int newRevisionNum = GetMostRecentRevision(regionid)+1;
277 string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
278
279 m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
280 if (!Directory.Exists(revisiondir))
281 Directory.CreateDirectory(revisiondir);
282
283 try {
284 Stopwatch x = new Stopwatch();
285 x.Start();
286 if (m_scenes.ContainsKey(regionid))
287 {
288 m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
289 }
290 x.Stop();
291 TimeToSave += x.ElapsedMilliseconds;
292 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
293 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
294 }
295 catch (Exception e)
296 {
297 m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
298 return;
299 }
300
301 try {
302 // Finish by writing log message.
303 FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
304 StreamWriter sw = new StreamWriter(file);
305 sw.Write(logMessage);
306 sw.Close();
307 }
308 catch (Exception e)
309 {
310 m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
311 return;
312 }
313 }
314
315 #endregion Public Methods
316 }
317}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs
deleted file mode 100644
index 80a0a93..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs
+++ /dev/null
@@ -1,167 +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#region Header
29
30// GitDatabase.cs
31//
32//
33//
34
35#endregion Header
36
37using System;
38using System.Collections.Generic;
39using System.IO;
40using Slash = System.IO.Path;
41using System.Reflection;
42using System.Xml;
43
44using OpenMetaverse;
45
46using Nini.Config;
47
48using OpenSim.Framework;
49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.Framework.Scenes;
51using OpenSim.Region.CoreModules.World.Serialiser;
52using OpenSim.Region.CoreModules.World.Terrain;
53using OpenSim.Region.Physics.Manager;
54
55using log4net;
56
57namespace OpenSim.Region.OptionalModules.ContentManagement
58{
59 /// <summary>
60 /// Just a stub :-(
61 /// </summary>
62 public class GitDatabase : IContentDatabase
63 {
64 #region Constructors
65
66 public GitDatabase()
67 {
68 }
69
70 #endregion Constructors
71
72 #region Public Methods
73
74 public SceneObjectGroup GetMostRecentObjectRevision(UUID id)
75 {
76 return null;
77 }
78
79 public int GetMostRecentRevision(UUID regionid)
80 {
81 return 0;
82 }
83
84 public SceneObjectGroup GetObjectRevision(UUID id, int revision)
85 {
86 return null;
87 }
88
89 public System.Collections.ArrayList GetObjectsFromRegion(UUID regionid, int revision)
90 {
91 return null;
92 }
93
94 public string GetRegionObjectHeightMap(UUID regionid)
95 {
96 return null;
97 }
98
99 public string GetRegionObjectHeightMap(UUID regionid, int revision)
100 {
101 return null;
102 }
103
104 public string GetRegionObjectXML(UUID regionid)
105 {
106 return null;
107 }
108
109 public string GetRegionObjectXML(UUID regionid, int revision)
110 {
111 return null;
112 }
113
114 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
115 {
116 return null;
117 }
118
119 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
120 {
121 return null;
122 }
123
124 public bool InRepository(UUID id)
125 {
126 return false;
127 }
128
129 public void Initialise(Scene scene, String dir)
130 {
131 }
132
133 public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(UUID id)
134 {
135 return null;
136 }
137
138 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id)
139 {
140 return null;
141 }
142
143 public int NumOfObjectRev(UUID id)
144 {
145 return 0;
146 }
147
148 public int NumOfRegionRev(UUID regionid)
149 {
150 return 0;
151 }
152
153 public void PostInitialise()
154 {
155 }
156
157 public void SaveObject(SceneObjectGroup entity)
158 {
159 }
160
161 public void SaveRegion(UUID regionid, string regionName, string logMessage)
162 {
163 }
164
165 #endregion Public Methods
166 }
167}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs
deleted file mode 100644
index fc1f115..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs
+++ /dev/null
@@ -1,94 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the 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#region Header
29
30// IContentDatabase.cs
31// User: bongiojp
32//
33//
34//
35
36#endregion Header
37
38using System;
39using OpenMetaverse;
40using OpenSim.Region.Framework.Scenes;
41using Nini.Config;
42
43namespace OpenSim.Region.OptionalModules.ContentManagement
44{
45 public interface IContentDatabase
46 {
47 #region Methods
48
49 /// <summary>
50 /// Returns the most recent revision number of a region.
51 /// </summary>
52 int GetMostRecentRevision(UUID regionid);
53
54 string GetRegionObjectHeightMap(UUID regionid);
55
56 string GetRegionObjectHeightMap(UUID regionid, int revision);
57
58 /// <summary>
59 /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region.
60 /// </summary>
61 System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid);
62
63 System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision);
64
65 /// <summary>
66 /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database.
67 /// Initialise should be called one for each region to be contained in the database. The directory should be the full path
68 /// to the repository and will only be defined once, regardless of how many times the method is called.
69 /// </summary>
70 void Initialise(Scene scene, String dir);
71
72 /// <summary>
73 /// Returns a list of the revision numbers and corresponding log messages for a given region.
74 /// </summary>
75 System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id);
76
77 /// <summary>
78 /// Returns the total number of revisions saved for a specific region.
79 /// </summary>
80 int NumOfRegionRev(UUID regionid);
81
82 /// <summary>
83 /// Should be called once after Initialise has been called.
84 /// </summary>
85 void PostInitialise();
86
87 /// <summary>
88 /// Saves the Region terrain map and objects within the region as xml to the database.
89 /// </summary>
90 void SaveRegion(UUID regionid, string regionName, string logMessage);
91
92 #endregion Methods
93 }
94}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
deleted file mode 100644
index cd60f4b..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
+++ /dev/null
@@ -1,270 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Drawing;
31
32using OpenMetaverse;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Region.Physics.Manager;
41
42using log4net;
43
44namespace OpenSim.Region.OptionalModules.ContentManagement
45{
46 public class MetaEntity
47 {
48 #region Constants
49
50 public const float INVISIBLE = .95f;
51
52 // Settings for transparency of metaentity
53 public const float NONE = 0f;
54 public const float TRANSLUCENT = .5f;
55
56 #endregion Constants
57
58 #region Static Fields
59
60 //private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
61
62 #endregion Static Fields
63
64 #region Fields
65
66 protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity.
67 protected uint m_metaLocalid;
68
69 #endregion Fields
70
71 #region Constructors
72
73 public MetaEntity()
74 {
75 }
76
77 /// <summary>
78 /// Makes a new meta entity by copying the given scene object group.
79 /// The physics boolean is just a stub right now.
80 /// </summary>
81 public MetaEntity(SceneObjectGroup orig, bool physics)
82 {
83 m_Entity = orig.Copy(false);
84 Initialize(physics);
85 }
86
87 /// <summary>
88 /// Takes an XML description of a scene object group and converts it to a meta entity.
89 /// </summary>
90 public MetaEntity(string objectXML, Scene scene, bool physics)
91 {
92 m_Entity = SceneObjectSerializer.FromXml2Format(objectXML);
93 m_Entity.SetScene(scene);
94 Initialize(physics);
95 }
96
97 #endregion Constructors
98
99 #region Public Properties
100
101 public SceneObjectPart[] Parts
102 {
103 get { return m_Entity.Parts; }
104 }
105
106 public uint LocalId
107 {
108 get { return m_Entity.LocalId; }
109 set { m_Entity.LocalId = value; }
110 }
111
112 public SceneObjectGroup ObjectGroup
113 {
114 get { return m_Entity; }
115 }
116
117 public int PrimCount
118 {
119 get { return m_Entity.PrimCount; }
120 }
121
122 public SceneObjectPart RootPart
123 {
124 get { return m_Entity.RootPart; }
125 }
126
127 public Scene Scene
128 {
129 get { return m_Entity.Scene; }
130 }
131
132 public UUID UUID
133 {
134 get { return m_Entity.UUID; }
135 set { m_Entity.UUID = value; }
136 }
137
138 #endregion Public Properties
139
140 #region Protected Methods
141
142 // The metaentity objectgroup must have unique localids as well as unique uuids.
143 // localids are used by the client to refer to parts.
144 // uuids are sent to the client and back to the server to identify parts on the server side.
145 /// <summary>
146 /// Changes localids and uuids of m_Entity.
147 /// </summary>
148 protected void Initialize(bool physics)
149 {
150 //make new uuids
151 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
152
153 foreach (SceneObjectPart part in m_Entity.Parts)
154 {
155 part.ResetIDs(part.LinkNum);
156 parts.Add(part.UUID, part);
157 }
158
159 //finalize
160 m_Entity.RootPart.PhysActor = null;
161 foreach (SceneObjectPart part in parts.Values)
162 m_Entity.AddPart(part);
163 }
164
165 #endregion Protected Methods
166
167 #region Public Methods
168
169 /// <summary>
170 /// Hides the metaentity from a single client.
171 /// </summary>
172 public virtual void Hide(IClientAPI client)
173 {
174 //This deletes the group without removing from any databases.
175 //This is important because we are not IN any database.
176 //m_Entity.FakeDeleteGroup();
177 foreach (SceneObjectPart part in m_Entity.Parts)
178 client.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId });
179 }
180
181 /// <summary>
182 /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
183 /// </summary>
184 public virtual void HideFromAll()
185 {
186 foreach (SceneObjectPart part in m_Entity.Parts)
187 {
188 m_Entity.Scene.ForEachClient(
189 delegate(IClientAPI controller)
190 { controller.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId }); }
191 );
192 }
193 }
194
195 public void SendFullUpdate(IClientAPI client)
196 {
197 // Not sure what clientFlags should be but 0 seems to work
198 SendFullUpdate(client, 0);
199 }
200
201 public void SendFullUpdate(IClientAPI client, uint clientFlags)
202 {
203 m_Entity.SendFullUpdateToClient(client);
204 }
205
206 public void SendFullUpdateToAll()
207 {
208 m_Entity.Scene.ForEachClient(
209 delegate(IClientAPI controller)
210 { m_Entity.SendFullUpdateToClient(controller); }
211 );
212 }
213
214 /// <summary>
215 /// Makes a single SceneObjectPart see through.
216 /// </summary>
217 /// <param name="part">
218 /// A <see cref="SceneObjectPart"/>
219 /// The part to make see through
220 /// </param>
221 /// <param name="transparencyAmount">
222 /// A <see cref="System.Single"/>
223 /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible.
224 /// </param>
225 public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount)
226 {
227 Primitive.TextureEntry tex = null;
228 Color4 texcolor;
229 try
230 {
231 tex = part.Shape.Textures;
232 texcolor = new Color4();
233 }
234 catch(Exception)
235 {
236 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e);
237 return;
238 }
239
240 for (uint i = 0; i < tex.FaceTextures.Length; i++)
241 {
242 try {
243 if (tex.FaceTextures[i] != null)
244 {
245 texcolor = tex.FaceTextures[i].RGBA;
246 texcolor.A = transparencyAmount;
247 tex.FaceTextures[i].RGBA = texcolor;
248 }
249 }
250 catch (Exception)
251 {
252 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e);
253 continue;
254 }
255 }
256 try {
257 texcolor = tex.DefaultTexture.RGBA;
258 texcolor.A = transparencyAmount;
259 tex.DefaultTexture.RGBA = texcolor;
260 part.Shape.TextureEntry = tex.GetBytes();
261 }
262 catch (Exception)
263 {
264 //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e);
265 }
266 }
267
268 #endregion Public Methods
269 }
270}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
deleted file mode 100644
index 2c5093f..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
+++ /dev/null
@@ -1,104 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Drawing;
31
32using OpenMetaverse;
33
34using Nini.Config;
35
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Physics.Manager;
40
41using log4net;
42
43namespace OpenSim.Region.OptionalModules.ContentManagement
44{
45 public class PointMetaEntity : MetaEntity
46 {
47 #region Constructors
48
49 public PointMetaEntity(Scene scene, Vector3 groupPos, float transparency)
50 : base()
51 {
52 CreatePointEntity(scene, UUID.Random(), groupPos);
53 SetPartTransparency(m_Entity.RootPart, transparency);
54 }
55
56 public PointMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency)
57 : base()
58 {
59 CreatePointEntity(scene, uuid, groupPos);
60 SetPartTransparency(m_Entity.RootPart, transparency);
61 }
62
63 #endregion Constructors
64
65 #region Private Methods
66
67 private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
68 {
69 SceneObjectPart y = new SceneObjectPart();
70
71 //Initialize part
72 y.Name = "Very Small Point";
73 y.RegionHandle = scene.RegionInfo.RegionHandle;
74 y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
75 y.OwnerID = UUID.Zero;
76 y.CreatorID = UUID.Zero;
77 y.LastOwnerID = UUID.Zero;
78 y.UUID = uuid;
79
80 y.Shape = PrimitiveBaseShape.CreateBox();
81 y.Scale = new Vector3(0.01f,0.01f,0.01f);
82 y.LastOwnerID = UUID.Zero;
83 y.GroupPosition = groupPos;
84 y.OffsetPosition = Vector3.Zero;
85 y.RotationOffset = Quaternion.Identity;
86 y.Velocity = Vector3.Zero;
87 y.AngularVelocity = Vector3.Zero;
88 y.Acceleration = Vector3.Zero;
89
90 y.Flags = 0;
91 y.TrimPermissions();
92
93 //Initialize group and add part as root part
94 SceneObjectGroup x = new SceneObjectGroup(y);
95 x.SetScene(scene);
96 x.RegionHandle = scene.RegionInfo.RegionHandle;
97 x.SetScene(scene);
98
99 m_Entity = x;
100 }
101
102 #endregion Private Methods
103 }
104}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/README b/OpenSim/Region/OptionalModules/ContentManagementSystem/README
deleted file mode 100644
index 1a69fef..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/README
+++ /dev/null
@@ -1,52 +0,0 @@
1This module is meant to be built alone and not added to the Opensim code base. References are made to required dlls through a
2reference file, ContentManagement.mdp. Originally, for development, this project was contained in the Opensim/Region/Modules/
3directory.
4
5To compile: nant
6To use: Copy ContentManagement.dll into the bin directory of your Opensim build. You should find many other dlls in the same directory.
7
8
9--------------------------------------------------------------------------------------------------------------------
10To build the libgit.so file:
11
12#Download GIT git repository
13$ git clone git://git2.kernel.org/pub/OpenSim/Region/Environment/Modules/ContentManagementSystem/scm/git/git.git
14$ cd git
15
16#Compile GIT
17#Note that we are adding two extra flags to pass to gcc while compiling (-c and -fPIC)
18$ autoconf
19$ ./configure
20$ CFLAGS="-g -O2 -Wall -c -fPIC" make
21
22#Copy necessary object files (and some not so necessary) to their own directory for shared object file creation
23$ mkdir ../libgit-objects
24$ cp builtin*.o ../libgit-objects
25$ cp xdiff/*.o ../libgit-objects
26$ cp libgit.a ../libgit-objects
27
28#Remove the main symbol from any object files (like git.o)
29$ cd ../libgit-objects
30$ strip -N main *.o
31
32#Uncompress the plumbing objects from archive created by git
33$ ar x libgit.a
34
35#Create shared object file from all objects (including the zlib library)
36$ ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
37
38
39#You can also just copy the following commands into a file and run as a script inside the git directory
40
41make clean
42autoconf
43./configure
44CFLAGS="-g -O2 -Wall -c -fPIC" make
45mkdir libgit-objects
46cp builtin*.o libgit-objects
47cp xdiff/*.o libgit-objects
48cp libgit.a libgit-objects
49cd libgit-objects
50strip -N main *.o
51ar x libgit.a
52ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
deleted file mode 100644
index a6afa5a..0000000
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
+++ /dev/null
@@ -1,216 +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#region Header
29
30// SceneObjectGroupDiff.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Diagnostics;
38using System.Drawing;
39
40using OpenMetaverse;
41
42using Nini.Config;
43
44using OpenSim.Framework;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager;
48
49using log4net;
50
51namespace OpenSim.Region.OptionalModules.ContentManagement
52{
53 #region Enumerations
54
55 [Flags]
56 public enum Diff
57 {
58 NONE = 0,
59 FACECOLOR = 1,
60 SHAPE = 1<<1,
61 MATERIAL = 1<<2,
62 TEXTURE = 1<<3,
63 SCALE = 1<<4,
64 POSITION = 1<<5,
65 OFFSETPOSITION = 1<<6,
66 ROTATIONOFFSET = 1<<7,
67 ROTATIONALVELOCITY = 1<<8,
68 ACCELERATION = 1<<9,
69 ANGULARVELOCITY = 1<<10,
70 VELOCITY = 1<<11,
71 OBJECTOWNER = 1<<12,
72 PERMISSIONS = 1<<13,
73 DESCRIPTION = 1<<14,
74 NAME = 1<<15,
75 SCRIPT = 1<<16,
76 CLICKACTION = 1<<17,
77 PARTICLESYSTEM = 1<<18,
78 GLOW = 1<<19,
79 SALEPRICE = 1<<20,
80 SITNAME = 1<<21,
81 SITTARGETORIENTATION = 1<<22,
82 SITTARGETPOSITION = 1<<23,
83 TEXT = 1<<24,
84 TOUCHNAME = 1<<25
85 }
86
87 #endregion Enumerations
88
89 public static class Difference
90 {
91 #region Static Fields
92
93 static float TimeToDiff = 0;
94// private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
95
96 #endregion Static Fields
97
98 #region Private Methods
99
100 private static bool AreQuaternionsEquivalent(Quaternion first, Quaternion second)
101 {
102 Vector3 firstVector = llRot2Euler(first);
103 Vector3 secondVector = llRot2Euler(second);
104 return AreVectorsEquivalent(firstVector, secondVector);
105 }
106
107 private static bool AreVectorsEquivalent(Vector3 first, Vector3 second)
108 {
109 if (TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2)
110 && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2)
111 && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2)
112 )
113 return true;
114 else
115 return false;
116 }
117
118 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
119 private static double NormalizeAngle(double angle)
120 {
121 angle = angle % (Math.PI * 2);
122 if (angle < 0) angle = angle + Math.PI * 2;
123 return angle;
124 }
125
126 private static int TruncateSignificant(float num, int digits)
127 {
128 return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits));
129 // return (int) ((num * (10*digits))/10*digits);
130 }
131
132 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
133 // Also changed the original function from LSL_Types to LL types
134 private static Vector3 llRot2Euler(Quaternion r)
135 {
136 Quaternion t = new Quaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W);
137 double m = (t.X + t.Y + t.Z + t.W);
138 if (m == 0) return new Vector3();
139 double n = 2 * (r.Y * r.W + r.X * r.Z);
140 double p = m * m - n * n;
141 if (p > 0)
142 return new Vector3((float)NormalizeAngle(Math.Atan2(2.0 * (r.X * r.W - r.Y * r.Z), (-t.X - t.Y + t.Z + t.W))),
143 (float)NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))),
144 (float)NormalizeAngle(Math.Atan2(2.0 * (r.Z * r.W - r.X * r.Y), (t.X - t.Y - t.Z + t.W))));
145 else if (n > 0)
146 return new Vector3(0.0f, (float)(Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
147 else
148 return new Vector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
149 }
150
151 #endregion Private Methods
152
153 #region Public Methods
154
155 /// <summary>
156 /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts
157 /// and returns a Diff bitmask which details what the differences are.
158 /// </summary>
159 public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
160 {
161 Stopwatch x = new Stopwatch();
162 x.Start();
163
164 Diff result = 0;
165
166 // VECTOR COMPARISONS
167 if (!AreVectorsEquivalent(first.Acceleration, second.Acceleration))
168 result |= Diff.ACCELERATION;
169 if (!AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
170 result |= Diff.POSITION;
171 if (!AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
172 result |= Diff.ANGULARVELOCITY;
173 if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
174 result |= Diff.OFFSETPOSITION;
175 if (!AreVectorsEquivalent(first.Scale, second.Scale))
176 result |= Diff.SCALE;
177 if (!AreVectorsEquivalent(first.Velocity, second.Velocity))
178 result |= Diff.VELOCITY;
179
180
181 // QUATERNION COMPARISONS
182 if (!AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
183 result |= Diff.ROTATIONOFFSET;
184
185
186 // MISC COMPARISONS (UUID, Byte)
187 if (first.ClickAction != second.ClickAction)
188 result |= Diff.CLICKACTION;
189 if (first.OwnerID != second.OwnerID)
190 result |= Diff.OBJECTOWNER;
191
192
193 // STRING COMPARISONS
194 if (first.Description != second.Description)
195 result |= Diff.DESCRIPTION;
196 if (first.Material != second.Material)
197 result |= Diff.MATERIAL;
198 if (first.Name != second.Name)
199 result |= Diff.NAME;
200 if (first.SitName != second.SitName)
201 result |= Diff.SITNAME;
202 if (first.Text != second.Text)
203 result |= Diff.TEXT;
204 if (first.TouchName != second.TouchName)
205 result |= Diff.TOUCHNAME;
206
207 x.Stop();
208 TimeToDiff += x.ElapsedMilliseconds;
209 //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
210
211 return result;
212 }
213
214 #endregion Public Methods
215 }
216}
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index 122ad40..eed6450 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -28,10 +28,14 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Net;
32using System.IO;
33using System.Text;
31 34
32using log4net; 35using log4net;
33using Nini.Config; 36using Nini.Config;
34using OpenMetaverse; 37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
35 39
36using OpenSim.Framework; 40using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
@@ -50,6 +54,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
50 private bool m_lastOarLoadedOk; 54 private bool m_lastOarLoadedOk;
51 private int m_channelNotify = -1000; 55 private int m_channelNotify = -1000;
52 private bool m_enabled = false; 56 private bool m_enabled = false;
57 private bool m_disable_logins = false;
58 private string m_uri = string.Empty;
53 59
54 Scene m_scene = null; 60 Scene m_scene = null;
55 61
@@ -68,10 +74,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
68 if (m_config != null) 74 if (m_config != null)
69 { 75 {
70 m_enabled = m_config.GetBoolean("enabled", false); 76 m_enabled = m_config.GetBoolean("enabled", false);
77
71 if (m_enabled) 78 if (m_enabled)
72 { 79 {
73 m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify); 80 m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify);
74 } 81 m_disable_logins = m_config.GetBoolean("login_disable", false);
82 m_uri = m_config.GetString("alert_uri",string.Empty);
83 }
75 } 84 }
76 85
77// if (!m_enabled) 86// if (!m_enabled)
@@ -91,8 +100,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
91 100
92 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; 101 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
93 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; 102 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
103 m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
94 104
95 m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); 105 m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName);
106
107 if(m_disable_logins == true)
108 {
109 scene.LoginLock = true;
110 scene.LoginsDisabled = true;
111 m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName);
112
113 if(m_uri != string.Empty)
114 {
115 RRAlert("disabled");
116 }
117 }
96 } 118 }
97 119
98 public void RemoveRegion(Scene scene) 120 public void RemoveRegion(Scene scene)
@@ -150,7 +172,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
150 172
151 m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", 173 m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
152 m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); 174 m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
153 m_scene.EventManager.TriggerOnChatBroadcast(this, c); 175
176 m_scene.EventManager.TriggerOnChatBroadcast(this, c);
177 m_scene.EventManager.TriggerLoginsEnabled(m_scene.RegionInfo.RegionName);
154 } 178 }
155 } 179 }
156 180
@@ -165,5 +189,69 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
165 m_lastOarLoadedOk = false; 189 m_lastOarLoadedOk = false;
166 } 190 }
167 } 191 }
192
193 void OnLoginsEnabled(string regionName)
194 {
195 if (m_disable_logins == true)
196 {
197 if (m_scene.StartDisabled == false)
198 {
199 m_scene.LoginsDisabled = false;
200 m_scene.LoginLock = false;
201 m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName);
202 if ( m_uri != string.Empty )
203 {
204 RRAlert("enabled");
205 }
206 }
207 }
208 }
209
210 public void RRAlert(string status)
211 {
212 string request_method = "POST";
213 string content_type = "application/json";
214 OSDMap RRAlert = new OSDMap();
215
216 RRAlert["alert"] = "region_ready";
217 RRAlert["login"] = status;
218 RRAlert["region_name"] = m_scene.RegionInfo.RegionName;
219 RRAlert["region_id"] = m_scene.RegionInfo.RegionID;
220
221 string strBuffer = "";
222 byte[] buffer = new byte[1];
223 try
224 {
225 strBuffer = OSDParser.SerializeJsonString(RRAlert);
226 Encoding str = Util.UTF8;
227 buffer = str.GetBytes(strBuffer);
228
229 }
230 catch (Exception e)
231 {
232 m_log.WarnFormat("[RegionReady]: Exception thrown on alert: {0}", e.Message);
233 }
234
235 WebRequest request = WebRequest.Create(m_uri);
236 request.Method = request_method;
237 request.ContentType = content_type;
238
239 Stream os = null;
240 try
241 {
242 request.ContentLength = buffer.Length;
243 os = request.GetRequestStream();
244 os.Write(buffer, 0, strBuffer.Length);
245 }
246 catch(Exception e)
247 {
248 m_log.WarnFormat("[RegionReady]: Exception thrown sending alert: {0}", e.Message);
249 }
250 finally
251 {
252 if (os != null)
253 os.Close();
254 }
255 }
168 } 256 }
169} 257}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d895438..f07ad67 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -631,7 +631,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
631 { 631 {
632 } 632 }
633 633
634 public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 634 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
635 { 635 {
636 } 636 }
637 637
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3afedc7..d695a0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -309,7 +309,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
310 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
311 // in mouselook. 311 // in mouselook.
312
313 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
314 fromRegionPos = avatar.AbsolutePosition; 313 fromRegionPos = avatar.AbsolutePosition;
315 q = avatar.Rotation; 314 q = avatar.Rotation;
@@ -424,6 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
424 423
425 SceneObjectPart SensePoint = ts.host; 424 SceneObjectPart SensePoint = ts.host;
426 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
426
427 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.RootPart.IsAttachment) 428 if (SensePoint.ParentGroup.RootPart.IsAttachment)
429 { 429 {
@@ -435,6 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
435 fromRegionPos = avatar.AbsolutePosition; 435 fromRegionPos = avatar.AbsolutePosition;
436 q = avatar.Rotation; 436 q = avatar.Rotation;
437 } 437 }
438
438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 439 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 440 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 441 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index f4472c7..8effdd2 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -65,6 +65,10 @@ namespace OpenSim.Server.Base
65 /// <returns></returns> 65 /// <returns></returns>
66 public static T LoadPlugin<T>(string dllName, Object[] args) where T:class 66 public static T LoadPlugin<T>(string dllName, Object[] args) where T:class
67 { 67 {
68 // This is good to debug configuration problems
69 //if (dllName == string.Empty)
70 // Util.PrintCallStack();
71
68 string[] parts = dllName.Split(new char[] {':'}); 72 string[] parts = dllName.Split(new char[] {':'});
69 73
70 dllName = parts[0]; 74 dllName = parts[0];
@@ -124,6 +128,13 @@ namespace OpenSim.Server.Base
124 128
125 return null; 129 return null;
126 } 130 }
131 catch (ReflectionTypeLoadException rtle)
132 {
133 m_log.Error(string.Format("Error loading plugin from {0}:\n{1}", dllName,
134 String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))),
135 rtle);
136 return null;
137 }
127 catch (Exception e) 138 catch (Exception e)
128 { 139 {
129 m_log.Error(string.Format("Error loading plugin from {0}", dllName), e); 140 m_log.Error(string.Format("Error loading plugin from {0}", dllName), e);
diff --git a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
index 074f869..5784bdf 100644
--- a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
@@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
46 if (serverConfig == null) 46 if (serverConfig == null)
47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); 47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
48 48
49 string gridService = serverConfig.GetString("LocalServiceModule", 49 string theService = serverConfig.GetString("LocalServiceModule",
50 String.Empty); 50 String.Empty);
51 51
52 if (gridService == String.Empty) 52 if (theService == String.Empty)
53 throw new Exception("No LocalServiceModule in config file"); 53 throw new Exception("No LocalServiceModule in config file");
54 54
55 Object[] args = new Object[] { config }; 55 Object[] args = new Object[] { config };
56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(gridService, args); 56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
57 57
58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService)); 58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
59 } 59 }
diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
index b168bb3..fc97d8c 100644
--- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
@@ -82,12 +82,18 @@ namespace OpenSim.Server.Handlers.Friends
82 case "getfriends": 82 case "getfriends":
83 return GetFriends(request); 83 return GetFriends(request);
84 84
85 case "getfriends_string":
86 return GetFriendsString(request);
87
85 case "storefriend": 88 case "storefriend":
86 return StoreFriend(request); 89 return StoreFriend(request);
87 90
88 case "deletefriend": 91 case "deletefriend":
89 return DeleteFriend(request); 92 return DeleteFriend(request);
90 93
94 case "deletefriend_string":
95 return DeleteFriendString(request);
96
91 } 97 }
92 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); 98 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
93 } 99 }
@@ -111,7 +117,25 @@ namespace OpenSim.Server.Handlers.Friends
111 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); 117 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
112 118
113 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); 119 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
114 //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); 120
121 return PackageFriends(finfos);
122 }
123
124 byte[] GetFriendsString(Dictionary<string, object> request)
125 {
126 string principalID = string.Empty;
127 if (request.ContainsKey("PRINCIPALID"))
128 principalID = request["PRINCIPALID"].ToString();
129 else
130 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
131
132 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
133
134 return PackageFriends(finfos);
135 }
136
137 private byte[] PackageFriends(FriendInfo[] finfos)
138 {
115 139
116 Dictionary<string, object> result = new Dictionary<string, object>(); 140 Dictionary<string, object> result = new Dictionary<string, object>();
117 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) 141 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
@@ -136,9 +160,9 @@ namespace OpenSim.Server.Handlers.Friends
136 160
137 byte[] StoreFriend(Dictionary<string, object> request) 161 byte[] StoreFriend(Dictionary<string, object> request)
138 { 162 {
139 FriendInfo friend = new FriendInfo(request); 163 string principalID = string.Empty, friend = string.Empty; int flags = 0;
140 164 FromKeyValuePairs(request, out principalID, out friend, out flags);
141 bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags); 165 bool success = m_FriendsService.StoreFriend(principalID, friend, flags);
142 166
143 if (success) 167 if (success)
144 return SuccessResult(); 168 return SuccessResult();
@@ -163,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends
163 else 187 else
164 return FailureResult(); 188 return FailureResult();
165 } 189 }
166 190
191 byte[] DeleteFriendString(Dictionary<string, object> request)
192 {
193 string principalID = string.Empty;
194 if (request.ContainsKey("PRINCIPALID"))
195 principalID = request["PRINCIPALID"].ToString();
196 else
197 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend");
198 string friend = string.Empty;
199 if (request.ContainsKey("FRIEND"))
200 friend = request["FRIEND"].ToString();
201
202 bool success = m_FriendsService.Delete(principalID, friend);
203 if (success)
204 return SuccessResult();
205 else
206 return FailureResult();
207 }
208
167 #endregion 209 #endregion
168 210
169 #region Misc 211 #region Misc
@@ -233,6 +275,19 @@ namespace OpenSim.Server.Handlers.Friends
233 return ms.ToArray(); 275 return ms.ToArray();
234 } 276 }
235 277
278 void FromKeyValuePairs(Dictionary<string, object> kvp, out string principalID, out string friend, out int flags)
279 {
280 principalID = string.Empty;
281 if (kvp.ContainsKey("PrincipalID") && kvp["PrincipalID"] != null)
282 principalID = kvp["PrincipalID"].ToString();
283 friend = string.Empty;
284 if (kvp.ContainsKey("Friend") && kvp["Friend"] != null)
285 friend = kvp["Friend"].ToString();
286 flags = 0;
287 if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null)
288 Int32.TryParse(kvp["MyFlags"].ToString(), out flags);
289 }
290
236 #endregion 291 #endregion
237 } 292 }
238} 293}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
new file mode 100644
index 0000000..82a7220
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34
35namespace OpenSim.Server.Handlers.Hypergrid
36{
37 public class HGFriendsServerConnector : ServiceConnector
38 {
39 private IFriendsService m_FriendsService;
40 private IUserAgentService m_UserAgentService;
41 private string m_ConfigName = "HGFriendsService";
42
43 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != string.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
52
53 string theService = serverConfig.GetString("LocalServiceModule",
54 String.Empty);
55
56 if (theService == String.Empty)
57 throw new Exception("No LocalServiceModule in config file");
58
59 Object[] args = new Object[] { config };
60 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
61
62 theService = serverConfig.GetString("UserAgentService", string.Empty);
63 if (theService == String.Empty)
64 throw new Exception("No UserAgentService in " + m_ConfigName);
65
66 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args);
67
68 server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
69 }
70 }
71}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
new file mode 100644
index 0000000..5c89d0f
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -0,0 +1,320 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using Nini.Config;
29using log4net;
30using System;
31using System.Reflection;
32using System.IO;
33using System.Net;
34using System.Text;
35using System.Text.RegularExpressions;
36using System.Xml;
37using System.Xml.Serialization;
38using System.Collections.Generic;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class HGFriendsServerPostHandler : BaseStreamHandler
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private IFriendsService m_FriendsService;
53 private IUserAgentService m_UserAgentService;
54
55 public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
56 base("POST", "/hgfriends")
57 {
58 m_FriendsService = service;
59 m_UserAgentService = uservice;
60 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
61 }
62
63 public override byte[] Handle(string path, Stream requestData,
64 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
65 {
66 StreamReader sr = new StreamReader(requestData);
67 string body = sr.ReadToEnd();
68 sr.Close();
69 body = body.Trim();
70
71 //m_log.DebugFormat("[XXX]: query String: {0}", body);
72
73 try
74 {
75 Dictionary<string, object> request =
76 ServerUtils.ParseQueryString(body);
77
78 if (!request.ContainsKey("METHOD"))
79 return FailureResult();
80
81 string method = request["METHOD"].ToString();
82
83 switch (method)
84 {
85 case "getfriendperms":
86 return GetFriendPerms(request);
87
88 case "newfriendship":
89 return NewFriendship(request);
90
91 case "deletefriendship":
92 return DeleteFriendship(request);
93 }
94 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
95 }
96 catch (Exception e)
97 {
98 m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
99 }
100
101 return FailureResult();
102
103 }
104
105 #region Method-specific handlers
106
107 byte[] GetFriendPerms(Dictionary<string, object> request)
108 {
109 if (!VerifyServiceKey(request))
110 return FailureResult();
111
112 UUID principalID = UUID.Zero;
113 if (request.ContainsKey("PRINCIPALID"))
114 UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
115 else
116 {
117 m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
118 return FailureResult();
119 }
120
121 UUID friendID = UUID.Zero;
122 if (request.ContainsKey("FRIENDID"))
123 UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
124 else
125 {
126 m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
127 return FailureResult();
128 }
129
130 string perms = "0";
131 FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
132 foreach (FriendInfo finfo in friendsInfo)
133 {
134 if (finfo.Friend.StartsWith(friendID.ToString()))
135 return SuccessResult(finfo.TheirFlags.ToString());
136 }
137
138 return FailureResult("Friend not found");
139 }
140
141 byte[] NewFriendship(Dictionary<string, object> request)
142 {
143 if (!VerifyServiceKey(request))
144 return FailureResult();
145
146 // OK, can proceed
147 FriendInfo friend = new FriendInfo(request);
148 UUID friendID;
149 string tmp = string.Empty;
150 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
151 return FailureResult();
152
153
154 m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
155
156 // If the friendship already exists, return fail
157 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
158 foreach (FriendInfo finfo in finfos)
159 if (finfo.Friend.StartsWith(friendID.ToString()))
160 return FailureResult();
161
162 // the user needs to confirm when he gets home
163 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
164
165 if (success)
166 return SuccessResult();
167 else
168 return FailureResult();
169 }
170
171 byte[] DeleteFriendship(Dictionary<string, object> request)
172 {
173 FriendInfo friend = new FriendInfo(request);
174 string secret = string.Empty;
175 if (request.ContainsKey("SECRET"))
176 secret = request["SECRET"].ToString();
177
178 if (secret == string.Empty)
179 return FailureResult();
180
181 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
182 foreach (FriendInfo finfo in finfos)
183 {
184 // We check the secret here
185 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
186 {
187 m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
188 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
189 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
190
191 return SuccessResult();
192 }
193 }
194
195 return FailureResult();
196 }
197
198 #endregion
199
200 #region Misc
201
202 private bool VerifyServiceKey(Dictionary<string, object> request)
203 {
204 if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
205 {
206 m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
207 return false;
208 }
209
210 string serviceKey = request["KEY"].ToString();
211 string sessionStr = request["SESSIONID"].ToString();
212 UUID sessionID;
213 UUID.TryParse(sessionStr, out sessionID);
214
215 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
216 {
217 m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
218 return false;
219 }
220
221 m_log.DebugFormat("[HGFRIENDS HANDLER]: Verification ok");
222 return true;
223 }
224
225 private byte[] SuccessResult()
226 {
227 XmlDocument doc = new XmlDocument();
228
229 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
230 "", "");
231
232 doc.AppendChild(xmlnode);
233
234 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
235 "");
236
237 doc.AppendChild(rootElement);
238
239 XmlElement result = doc.CreateElement("", "Result", "");
240 result.AppendChild(doc.CreateTextNode("Success"));
241
242 rootElement.AppendChild(result);
243
244 return DocToBytes(doc);
245 }
246
247 private byte[] SuccessResult(string value)
248 {
249 XmlDocument doc = new XmlDocument();
250
251 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
252 "", "");
253
254 doc.AppendChild(xmlnode);
255
256 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
257 "");
258
259 doc.AppendChild(rootElement);
260
261 XmlElement result = doc.CreateElement("", "Result", "");
262 result.AppendChild(doc.CreateTextNode("Success"));
263
264 rootElement.AppendChild(result);
265
266 XmlElement message = doc.CreateElement("", "Value", "");
267 message.AppendChild(doc.CreateTextNode(value));
268
269 rootElement.AppendChild(message);
270
271 return DocToBytes(doc);
272 }
273
274
275 private byte[] FailureResult()
276 {
277 return FailureResult(String.Empty);
278 }
279
280 private byte[] FailureResult(string msg)
281 {
282 XmlDocument doc = new XmlDocument();
283
284 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
285 "", "");
286
287 doc.AppendChild(xmlnode);
288
289 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
290 "");
291
292 doc.AppendChild(rootElement);
293
294 XmlElement result = doc.CreateElement("", "Result", "");
295 result.AppendChild(doc.CreateTextNode("Failure"));
296
297 rootElement.AppendChild(result);
298
299 XmlElement message = doc.CreateElement("", "Message", "");
300 message.AppendChild(doc.CreateTextNode(msg));
301
302 rootElement.AppendChild(message);
303
304 return DocToBytes(doc);
305 }
306
307 private byte[] DocToBytes(XmlDocument doc)
308 {
309 MemoryStream ms = new MemoryStream();
310 XmlTextWriter xw = new XmlTextWriter(ms, null);
311 xw.Formatting = Formatting.Indented;
312 doc.WriteTo(xw);
313 xw.Flush();
314
315 return ms.ToArray();
316 }
317
318 #endregion
319 }
320}
diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs
new file mode 100644
index 0000000..80eb5d2
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs
@@ -0,0 +1,243 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Server.Handlers.Base;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41
42using log4net;
43using Nwc.XmlRpc;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class InstantMessageServerConnector : ServiceConnector
49 {
50 private static readonly ILog m_log =
51 LogManager.GetLogger(
52 MethodBase.GetCurrentMethod().DeclaringType);
53
54 private IInstantMessage m_IMService;
55
56 public InstantMessageServerConnector(IConfigSource config, IHttpServer server) :
57 this(config, server, null)
58 {
59 }
60
61 public InstantMessageServerConnector(IConfigSource config, IHttpServer server, IInstantMessageSimConnector simConnector) :
62 base(config, server, String.Empty)
63 {
64 IConfig gridConfig = config.Configs["HGInstantMessageService"];
65 if (gridConfig != null)
66 {
67 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
68
69 Object[] args = new Object[] { config, simConnector };
70 m_IMService = ServerUtils.LoadPlugin<IInstantMessage>(serviceDll, args);
71 }
72 if (m_IMService == null)
73 throw new Exception("InstantMessage server connector cannot proceed because of missing service");
74
75 server.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false);
76
77 }
78
79 public IInstantMessage GetService()
80 {
81 return m_IMService;
82 }
83
84 protected virtual XmlRpcResponse ProcessInstantMessage(XmlRpcRequest request, IPEndPoint remoteClient)
85 {
86 bool successful = false;
87
88 try
89 {
90 // various rational defaults
91 UUID fromAgentID = UUID.Zero;
92 UUID toAgentID = UUID.Zero;
93 UUID imSessionID = UUID.Zero;
94 uint timestamp = 0;
95 string fromAgentName = "";
96 string message = "";
97 byte dialog = (byte)0;
98 bool fromGroup = false;
99 byte offline = (byte)0;
100 uint ParentEstateID = 0;
101 Vector3 Position = Vector3.Zero;
102 UUID RegionID = UUID.Zero;
103 byte[] binaryBucket = new byte[0];
104
105 float pos_x = 0;
106 float pos_y = 0;
107 float pos_z = 0;
108 //m_log.Info("Processing IM");
109
110
111 Hashtable requestData = (Hashtable)request.Params[0];
112 // Check if it's got all the data
113 if (requestData.ContainsKey("from_agent_id")
114 && requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id")
115 && requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name")
116 && requestData.ContainsKey("message") && requestData.ContainsKey("dialog")
117 && requestData.ContainsKey("from_group")
118 && requestData.ContainsKey("offline") && requestData.ContainsKey("parent_estate_id")
119 && requestData.ContainsKey("position_x") && requestData.ContainsKey("position_y")
120 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
121 && requestData.ContainsKey("binary_bucket"))
122 {
123 // Do the easy way of validating the UUIDs
124 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
125 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
126 UUID.TryParse((string)requestData["im_session_id"], out imSessionID);
127 UUID.TryParse((string)requestData["region_id"], out RegionID);
128 try
129 {
130 timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]);
131 }
132 catch (ArgumentException)
133 {
134 }
135 catch (FormatException)
136 {
137 }
138 catch (OverflowException)
139 {
140 }
141
142 fromAgentName = (string)requestData["from_agent_name"];
143 message = (string)requestData["message"];
144 if (message == null)
145 message = string.Empty;
146
147 // Bytes don't transfer well over XMLRPC, so, we Base64 Encode them.
148 string requestData1 = (string)requestData["dialog"];
149 if (string.IsNullOrEmpty(requestData1))
150 {
151 dialog = 0;
152 }
153 else
154 {
155 byte[] dialogdata = Convert.FromBase64String(requestData1);
156 dialog = dialogdata[0];
157 }
158
159 if ((string)requestData["from_group"] == "TRUE")
160 fromGroup = true;
161
162 string requestData2 = (string)requestData["offline"];
163 if (String.IsNullOrEmpty(requestData2))
164 {
165 offline = 0;
166 }
167 else
168 {
169 byte[] offlinedata = Convert.FromBase64String(requestData2);
170 offline = offlinedata[0];
171 }
172
173 try
174 {
175 ParentEstateID = (uint)Convert.ToInt32((string)requestData["parent_estate_id"]);
176 }
177 catch (ArgumentException)
178 {
179 }
180 catch (FormatException)
181 {
182 }
183 catch (OverflowException)
184 {
185 }
186
187 float.TryParse((string)requestData["position_x"], out pos_x);
188 float.TryParse((string)requestData["position_y"], out pos_y);
189 float.TryParse((string)requestData["position_z"], out pos_z);
190
191 Position = new Vector3(pos_x, pos_y, pos_z);
192
193 string requestData3 = (string)requestData["binary_bucket"];
194 if (string.IsNullOrEmpty(requestData3))
195 {
196 binaryBucket = new byte[0];
197 }
198 else
199 {
200 binaryBucket = Convert.FromBase64String(requestData3);
201 }
202
203 // Create a New GridInstantMessageObject the the data
204 GridInstantMessage gim = new GridInstantMessage();
205 gim.fromAgentID = fromAgentID.Guid;
206 gim.fromAgentName = fromAgentName;
207 gim.fromGroup = fromGroup;
208 gim.imSessionID = imSessionID.Guid;
209 gim.RegionID = RegionID.Guid;
210 gim.timestamp = timestamp;
211 gim.toAgentID = toAgentID.Guid;
212 gim.message = message;
213 gim.dialog = dialog;
214 gim.offline = offline;
215 gim.ParentEstateID = ParentEstateID;
216 gim.Position = Position;
217 gim.binaryBucket = binaryBucket;
218
219 successful = m_IMService.IncomingInstantMessage(gim);
220
221 }
222 }
223 catch (Exception e)
224 {
225 m_log.Error("[INSTANT MESSAGE]: Caught unexpected exception:", e);
226 successful = false;
227 }
228
229 //Send response back to region calling if it was successful
230 // calling region uses this to know when to look up a user's location again.
231 XmlRpcResponse resp = new XmlRpcResponse();
232 Hashtable respdata = new Hashtable();
233 if (successful)
234 respdata["success"] = "TRUE";
235 else
236 respdata["success"] = "FALSE";
237 resp.Value = respdata;
238
239 return resp;
240 }
241
242 }
243}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index 0e8ce80..72a4aea 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -52,15 +52,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
52// MethodBase.GetCurrentMethod().DeclaringType); 52// MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private IUserAgentService m_HomeUsersService; 54 private IUserAgentService m_HomeUsersService;
55 private string[] m_AuthorizedCallers;
56
57 private bool m_VerifyCallers = false;
55 58
56 public UserAgentServerConnector(IConfigSource config, IHttpServer server) : 59 public UserAgentServerConnector(IConfigSource config, IHttpServer server) :
60 this(config, server, null)
61 {
62 }
63
64 public UserAgentServerConnector(IConfigSource config, IHttpServer server, IFriendsSimConnector friendsConnector) :
57 base(config, server, String.Empty) 65 base(config, server, String.Empty)
58 { 66 {
59 IConfig gridConfig = config.Configs["UserAgentService"]; 67 IConfig gridConfig = config.Configs["UserAgentService"];
60 if (gridConfig != null) 68 if (gridConfig != null)
61 { 69 {
62 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); 70 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
63 Object[] args = new Object[] { config }; 71
72 Object[] args = new Object[] { config, friendsConnector };
64 m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args); 73 m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args);
65 } 74 }
66 if (m_HomeUsersService == null) 75 if (m_HomeUsersService == null)
@@ -69,12 +78,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
69 string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1"); 78 string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1");
70 bool proxy = gridConfig.GetBoolean("HasProxy", false); 79 bool proxy = gridConfig.GetBoolean("HasProxy", false);
71 80
81 m_VerifyCallers = gridConfig.GetBoolean("VerifyCallers", false);
82 string csv = gridConfig.GetString("AuthorizedCallers", "127.0.0.1");
83 csv = csv.Replace(" ", "");
84 m_AuthorizedCallers = csv.Split(',');
85
72 server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false); 86 server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false);
73 server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false); 87 server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false);
74 server.AddXmlRPCHandler("verify_agent", VerifyAgent, false); 88 server.AddXmlRPCHandler("verify_agent", VerifyAgent, false);
75 server.AddXmlRPCHandler("verify_client", VerifyClient, false); 89 server.AddXmlRPCHandler("verify_client", VerifyClient, false);
76 server.AddXmlRPCHandler("logout_agent", LogoutAgent, false); 90 server.AddXmlRPCHandler("logout_agent", LogoutAgent, false);
77 91
92 server.AddXmlRPCHandler("status_notification", StatusNotification, false);
93 server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false);
94 server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false);
95
96 server.AddXmlRPCHandler("locate_user", LocateUser, false);
97 server.AddXmlRPCHandler("get_uui", GetUUI, false);
98
78 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); 99 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
79 } 100 }
80 101
@@ -194,5 +215,201 @@ namespace OpenSim.Server.Handlers.Hypergrid
194 215
195 } 216 }
196 217
218 public XmlRpcResponse StatusNotification(XmlRpcRequest request, IPEndPoint remoteClient)
219 {
220 Hashtable hash = new Hashtable();
221 hash["result"] = "false";
222
223 Hashtable requestData = (Hashtable)request.Params[0];
224 //string host = (string)requestData["host"];
225 //string portstr = (string)requestData["port"];
226 if (requestData.ContainsKey("userID") && requestData.ContainsKey("online"))
227 {
228 string userID_str = (string)requestData["userID"];
229 UUID userID = UUID.Zero;
230 UUID.TryParse(userID_str, out userID);
231 List<string> ids = new List<string>();
232 foreach (object key in requestData.Keys)
233 {
234 if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
235 ids.Add(requestData[key].ToString());
236 }
237 bool online = false;
238 bool.TryParse(requestData["online"].ToString(), out online);
239
240 // let's spawn a thread for this, because it may take a long time...
241 List<UUID> friendsOnline = m_HomeUsersService.StatusNotification(ids, userID, online);
242 if (friendsOnline.Count > 0)
243 {
244 int i = 0;
245 foreach (UUID id in friendsOnline)
246 {
247 hash["friend_" + i.ToString()] = id.ToString();
248 i++;
249 }
250 }
251 else
252 hash["result"] = "No Friends Online";
253
254 }
255
256 XmlRpcResponse response = new XmlRpcResponse();
257 response.Value = hash;
258 return response;
259
260 }
261
262 public XmlRpcResponse GetOnlineFriends(XmlRpcRequest request, IPEndPoint remoteClient)
263 {
264 Hashtable hash = new Hashtable();
265
266 Hashtable requestData = (Hashtable)request.Params[0];
267 //string host = (string)requestData["host"];
268 //string portstr = (string)requestData["port"];
269 if (requestData.ContainsKey("userID"))
270 {
271 string userID_str = (string)requestData["userID"];
272 UUID userID = UUID.Zero;
273 UUID.TryParse(userID_str, out userID);
274 List<string> ids = new List<string>();
275 foreach (object key in requestData.Keys)
276 {
277 if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
278 ids.Add(requestData[key].ToString());
279 }
280
281 //List<UUID> online = m_HomeUsersService.GetOnlineFriends(userID, ids);
282 //if (online.Count > 0)
283 //{
284 // int i = 0;
285 // foreach (UUID id in online)
286 // {
287 // hash["friend_" + i.ToString()] = id.ToString();
288 // i++;
289 // }
290 //}
291 //else
292 // hash["result"] = "No Friends Online";
293 }
294
295 XmlRpcResponse response = new XmlRpcResponse();
296 response.Value = hash;
297 return response;
298
299 }
300
301 public XmlRpcResponse GetServerURLs(XmlRpcRequest request, IPEndPoint remoteClient)
302 {
303 Hashtable hash = new Hashtable();
304
305 Hashtable requestData = (Hashtable)request.Params[0];
306 //string host = (string)requestData["host"];
307 //string portstr = (string)requestData["port"];
308 if (requestData.ContainsKey("userID"))
309 {
310 string userID_str = (string)requestData["userID"];
311 UUID userID = UUID.Zero;
312 UUID.TryParse(userID_str, out userID);
313
314 Dictionary<string, object> serverURLs = m_HomeUsersService.GetServerURLs(userID);
315 if (serverURLs.Count > 0)
316 {
317 foreach (KeyValuePair<string, object> kvp in serverURLs)
318 hash["SRV_" + kvp.Key] = kvp.Value.ToString();
319 }
320 else
321 hash["result"] = "No Service URLs";
322 }
323
324 XmlRpcResponse response = new XmlRpcResponse();
325 response.Value = hash;
326 return response;
327
328 }
329
330 /// <summary>
331 /// Locates the user.
332 /// This is a sensitive operation, only authorized IP addresses can perform it.
333 /// </summary>
334 /// <param name="request"></param>
335 /// <param name="remoteClient"></param>
336 /// <returns></returns>
337 public XmlRpcResponse LocateUser(XmlRpcRequest request, IPEndPoint remoteClient)
338 {
339 Hashtable hash = new Hashtable();
340
341 bool authorized = true;
342 if (m_VerifyCallers)
343 {
344 authorized = false;
345 foreach (string s in m_AuthorizedCallers)
346 if (s == remoteClient.Address.ToString())
347 {
348 authorized = true;
349 break;
350 }
351 }
352
353 if (authorized)
354 {
355 Hashtable requestData = (Hashtable)request.Params[0];
356 //string host = (string)requestData["host"];
357 //string portstr = (string)requestData["port"];
358 if (requestData.ContainsKey("userID"))
359 {
360 string userID_str = (string)requestData["userID"];
361 UUID userID = UUID.Zero;
362 UUID.TryParse(userID_str, out userID);
363
364 string url = m_HomeUsersService.LocateUser(userID);
365 if (url != string.Empty)
366 hash["URL"] = url;
367 else
368 hash["result"] = "Unable to locate user";
369 }
370 }
371
372 XmlRpcResponse response = new XmlRpcResponse();
373 response.Value = hash;
374 return response;
375
376 }
377
378 /// <summary>
379 /// Locates the user.
380 /// This is a sensitive operation, only authorized IP addresses can perform it.
381 /// </summary>
382 /// <param name="request"></param>
383 /// <param name="remoteClient"></param>
384 /// <returns></returns>
385 public XmlRpcResponse GetUUI(XmlRpcRequest request, IPEndPoint remoteClient)
386 {
387 Hashtable hash = new Hashtable();
388
389 Hashtable requestData = (Hashtable)request.Params[0];
390 //string host = (string)requestData["host"];
391 //string portstr = (string)requestData["port"];
392 if (requestData.ContainsKey("userID") && requestData.ContainsKey("targetUserID"))
393 {
394 string userID_str = (string)requestData["userID"];
395 UUID userID = UUID.Zero;
396 UUID.TryParse(userID_str, out userID);
397
398 string tuserID_str = (string)requestData["targetUserID"];
399 UUID targetUserID = UUID.Zero;
400 UUID.TryParse(tuserID_str, out targetUserID);
401 string uui = m_HomeUsersService.GetUUI(userID, targetUserID);
402 if (uui != string.Empty)
403 hash["UUI"] = uui;
404 else
405 hash["result"] = "User unknown";
406 }
407
408 XmlRpcResponse response = new XmlRpcResponse();
409 response.Value = hash;
410 return response;
411
412 }
413
197 } 414 }
198} 415}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
index 861c475..c5ae0c0 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
@@ -38,7 +38,7 @@ using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base; 38using OpenSim.Server.Base;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41namespace OpenSim.Services.Connectors 41namespace OpenSim.Services.Connectors.Friends
42{ 42{
43 public class FriendsServicesConnector : IFriendsService 43 public class FriendsServicesConnector : IFriendsService
44 { 44 {
@@ -84,7 +84,7 @@ namespace OpenSim.Services.Connectors
84 84
85 85
86 #region IFriendsService 86 #region IFriendsService
87 87
88 public FriendInfo[] GetFriends(UUID PrincipalID) 88 public FriendInfo[] GetFriends(UUID PrincipalID)
89 { 89 {
90 Dictionary<string, object> sendData = new Dictionary<string, object>(); 90 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -92,6 +92,21 @@ namespace OpenSim.Services.Connectors
92 sendData["PRINCIPALID"] = PrincipalID.ToString(); 92 sendData["PRINCIPALID"] = PrincipalID.ToString();
93 sendData["METHOD"] = "getfriends"; 93 sendData["METHOD"] = "getfriends";
94 94
95 return GetFriends(sendData, PrincipalID.ToString());
96 }
97
98 public FriendInfo[] GetFriends(string PrincipalID)
99 {
100 Dictionary<string, object> sendData = new Dictionary<string, object>();
101
102 sendData["PRINCIPALID"] = PrincipalID;
103 sendData["METHOD"] = "getfriends_string";
104
105 return GetFriends(sendData, PrincipalID);
106 }
107
108 protected FriendInfo[] GetFriends(Dictionary<string, object> sendData, string PrincipalID)
109 {
95 string reqString = ServerUtils.BuildQueryString(sendData); 110 string reqString = ServerUtils.BuildQueryString(sendData);
96 111
97 try 112 try
@@ -144,14 +159,10 @@ namespace OpenSim.Services.Connectors
144 159
145 } 160 }
146 161
147 public bool StoreFriend(UUID PrincipalID, string Friend, int flags) 162 public bool StoreFriend(string PrincipalID, string Friend, int flags)
148 { 163 {
149 FriendInfo finfo = new FriendInfo();
150 finfo.PrincipalID = PrincipalID;
151 finfo.Friend = Friend;
152 finfo.MyFlags = flags;
153 164
154 Dictionary<string, object> sendData = finfo.ToKeyValuePairs(); 165 Dictionary<string, object> sendData = ToKeyValuePairs(PrincipalID, Friend, flags);
155 166
156 sendData["METHOD"] = "storefriend"; 167 sendData["METHOD"] = "storefriend";
157 168
@@ -189,6 +200,16 @@ namespace OpenSim.Services.Connectors
189 200
190 } 201 }
191 202
203 public bool Delete(string PrincipalID, string Friend)
204 {
205 Dictionary<string, object> sendData = new Dictionary<string, object>();
206 sendData["PRINCIPALID"] = PrincipalID.ToString();
207 sendData["FRIEND"] = Friend;
208 sendData["METHOD"] = "deletefriend_string";
209
210 return Delete(sendData, PrincipalID, Friend);
211 }
212
192 public bool Delete(UUID PrincipalID, string Friend) 213 public bool Delete(UUID PrincipalID, string Friend)
193 { 214 {
194 Dictionary<string, object> sendData = new Dictionary<string, object>(); 215 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -196,6 +217,11 @@ namespace OpenSim.Services.Connectors
196 sendData["FRIEND"] = Friend; 217 sendData["FRIEND"] = Friend;
197 sendData["METHOD"] = "deletefriend"; 218 sendData["METHOD"] = "deletefriend";
198 219
220 return Delete(sendData, PrincipalID.ToString(), Friend);
221 }
222
223 public bool Delete(Dictionary<string, object> sendData, string PrincipalID, string Friend)
224 {
199 string reply = string.Empty; 225 string reply = string.Empty;
200 try 226 try
201 { 227 {
@@ -230,5 +256,16 @@ namespace OpenSim.Services.Connectors
230 } 256 }
231 257
232 #endregion 258 #endregion
259
260 public Dictionary<string, object> ToKeyValuePairs(string principalID, string friend, int flags)
261 {
262 Dictionary<string, object> result = new Dictionary<string, object>();
263 result["PrincipalID"] = principalID;
264 result["Friend"] = friend;
265 result["MyFlags"] = flags;
266
267 return result;
268 }
269
233 } 270 }
234} \ No newline at end of file 271} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
new file mode 100644
index 0000000..d699f59
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
@@ -0,0 +1,206 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Services.Interfaces;
36using OpenSim.Services.Connectors.Friends;
37using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base;
39using OpenMetaverse;
40
41namespace OpenSim.Services.Connectors.Hypergrid
42{
43 public class HGFriendsServicesConnector
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType);
48
49 private string m_ServerURI = String.Empty;
50 private string m_ServiceKey = String.Empty;
51 private UUID m_SessionID;
52
53 public HGFriendsServicesConnector()
54 {
55 }
56
57 public HGFriendsServicesConnector(string serverURI)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 }
61
62 public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey)
63 {
64 m_ServerURI = serverURI.TrimEnd('/');
65 m_ServiceKey = serviceKey;
66 m_SessionID = sessionID;
67 }
68
69 #region IFriendsService
70
71 public uint GetFriendPerms(UUID PrincipalID, UUID friendID)
72 {
73 Dictionary<string, object> sendData = new Dictionary<string, object>();
74
75 sendData["PRINCIPALID"] = PrincipalID.ToString();
76 sendData["FRIENDID"] = friendID.ToString();
77 sendData["METHOD"] = "getfriendperms";
78 sendData["KEY"] = m_ServiceKey;
79 sendData["SESSIONID"] = m_SessionID.ToString();
80
81 string reqString = ServerUtils.BuildQueryString(sendData);
82
83 try
84 {
85 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
86 m_ServerURI + "/hgfriends",
87 reqString);
88 if (reply != string.Empty)
89 {
90 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
91
92 if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null))
93 {
94 uint perms = 0;
95 uint.TryParse(replyData["Value"].ToString(), out perms);
96 return perms;
97 }
98 else
99 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response",
100 PrincipalID);
101
102 }
103 }
104 catch (Exception e)
105 {
106 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
107 }
108
109 return 0;
110
111 }
112
113 public bool NewFriendship(UUID PrincipalID, string Friend)
114 {
115 FriendInfo finfo = new FriendInfo();
116 finfo.PrincipalID = PrincipalID;
117 finfo.Friend = Friend;
118
119 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
120
121 sendData["METHOD"] = "newfriendship";
122 sendData["KEY"] = m_ServiceKey;
123 sendData["SESSIONID"] = m_SessionID.ToString();
124
125 string reply = string.Empty;
126 try
127 {
128 reply = SynchronousRestFormsRequester.MakeRequest("POST",
129 m_ServerURI + "/hgfriends",
130 ServerUtils.BuildQueryString(sendData));
131 }
132 catch (Exception e)
133 {
134 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
135 return false;
136 }
137
138 if (reply != string.Empty)
139 {
140 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
141
142 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
143 {
144 bool success = false;
145 Boolean.TryParse(replyData["Result"].ToString(), out success);
146 return success;
147 }
148 else
149 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
150 PrincipalID, Friend);
151 }
152 else
153 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply");
154
155 return false;
156
157 }
158
159 public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret)
160 {
161 FriendInfo finfo = new FriendInfo();
162 finfo.PrincipalID = PrincipalID;
163 finfo.Friend = Friend.ToString();
164
165 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
166
167 sendData["METHOD"] = "deletefriendship";
168 sendData["SECRET"] = secret;
169
170 string reply = string.Empty;
171 try
172 {
173 reply = SynchronousRestFormsRequester.MakeRequest("POST",
174 m_ServerURI + "/hgfriends",
175 ServerUtils.BuildQueryString(sendData));
176 }
177 catch (Exception e)
178 {
179 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
180 return false;
181 }
182
183 if (reply != string.Empty)
184 {
185 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
186
187 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
188 {
189 bool success = false;
190 Boolean.TryParse(replyData["Result"].ToString(), out success);
191 return success;
192 }
193 else
194 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response",
195 PrincipalID, Friend);
196 }
197 else
198 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply");
199
200 return false;
201
202 }
203
204 #endregion
205 }
206} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 7ddcfa6..5028206 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -400,6 +400,329 @@ namespace OpenSim.Services.Connectors.Hypergrid
400 GetBoolResponse(request, out reason); 400 GetBoolResponse(request, out reason);
401 } 401 }
402 402
403 public List<UUID> StatusNotification(List<string> friends, UUID userID, bool online)
404 {
405 Hashtable hash = new Hashtable();
406 hash["userID"] = userID.ToString();
407 hash["online"] = online.ToString();
408 int i = 0;
409 foreach (string s in friends)
410 {
411 hash["friend_" + i.ToString()] = s;
412 i++;
413 }
414
415 IList paramList = new ArrayList();
416 paramList.Add(hash);
417
418 XmlRpcRequest request = new XmlRpcRequest("status_notification", paramList);
419 string reason = string.Empty;
420
421 // Send and get reply
422 List<UUID> friendsOnline = new List<UUID>();
423 XmlRpcResponse response = null;
424 try
425 {
426 response = request.Send(m_ServerURL, 10000);
427 }
428 catch (Exception e)
429 {
430 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
431 reason = "Exception: " + e.Message;
432 return friendsOnline;
433 }
434
435 if (response.IsFault)
436 {
437 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
438 reason = "XMLRPC Fault";
439 return friendsOnline;
440 }
441
442 hash = (Hashtable)response.Value;
443 //foreach (Object o in hash)
444 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
445 try
446 {
447 if (hash == null)
448 {
449 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
450 reason = "Internal error 1";
451 return friendsOnline;
452 }
453
454 // Here is the actual response
455 foreach (object key in hash.Keys)
456 {
457 if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null)
458 {
459 UUID uuid;
460 if (UUID.TryParse(hash[key].ToString(), out uuid))
461 friendsOnline.Add(uuid);
462 }
463 }
464
465 }
466 catch (Exception e)
467 {
468 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
469 reason = "Exception: " + e.Message;
470 }
471
472 return friendsOnline;
473 }
474
475 public List<UUID> GetOnlineFriends(UUID userID, List<string> friends)
476 {
477 Hashtable hash = new Hashtable();
478 hash["userID"] = userID.ToString();
479 int i = 0;
480 foreach (string s in friends)
481 {
482 hash["friend_" + i.ToString()] = s;
483 i++;
484 }
485
486 IList paramList = new ArrayList();
487 paramList.Add(hash);
488
489 XmlRpcRequest request = new XmlRpcRequest("get_online_friends", paramList);
490 string reason = string.Empty;
491
492 // Send and get reply
493 List<UUID> online = new List<UUID>();
494 XmlRpcResponse response = null;
495 try
496 {
497 response = request.Send(m_ServerURL, 10000);
498 }
499 catch (Exception e)
500 {
501 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
502 reason = "Exception: " + e.Message;
503 return online;
504 }
505
506 if (response.IsFault)
507 {
508 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
509 reason = "XMLRPC Fault";
510 return online;
511 }
512
513 hash = (Hashtable)response.Value;
514 //foreach (Object o in hash)
515 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
516 try
517 {
518 if (hash == null)
519 {
520 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
521 reason = "Internal error 1";
522 return online;
523 }
524
525 // Here is the actual response
526 foreach (object key in hash.Keys)
527 {
528 if (key is string && ((string)key).StartsWith("friend_") && hash[key] != null)
529 {
530 UUID uuid;
531 if (UUID.TryParse(hash[key].ToString(), out uuid))
532 online.Add(uuid);
533 }
534 }
535
536 }
537 catch (Exception e)
538 {
539 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
540 reason = "Exception: " + e.Message;
541 }
542
543 return online;
544 }
545
546 public Dictionary<string, object> GetServerURLs(UUID userID)
547 {
548 Hashtable hash = new Hashtable();
549 hash["userID"] = userID.ToString();
550
551 IList paramList = new ArrayList();
552 paramList.Add(hash);
553
554 XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList);
555 string reason = string.Empty;
556
557 // Send and get reply
558 Dictionary<string, object> serverURLs = new Dictionary<string,object>();
559 XmlRpcResponse response = null;
560 try
561 {
562 response = request.Send(m_ServerURL, 10000);
563 }
564 catch (Exception e)
565 {
566 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
567 reason = "Exception: " + e.Message;
568 return serverURLs;
569 }
570
571 if (response.IsFault)
572 {
573 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
574 reason = "XMLRPC Fault";
575 return serverURLs;
576 }
577
578 hash = (Hashtable)response.Value;
579 //foreach (Object o in hash)
580 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
581 try
582 {
583 if (hash == null)
584 {
585 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
586 reason = "Internal error 1";
587 return serverURLs;
588 }
589
590 // Here is the actual response
591 foreach (object key in hash.Keys)
592 {
593 if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
594 {
595 string serverType = key.ToString().Substring(4); // remove "SRV_"
596 serverURLs.Add(serverType, hash[key].ToString());
597 }
598 }
599
600 }
601 catch (Exception e)
602 {
603 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
604 reason = "Exception: " + e.Message;
605 }
606
607 return serverURLs;
608 }
609
610 public string LocateUser(UUID userID)
611 {
612 Hashtable hash = new Hashtable();
613 hash["userID"] = userID.ToString();
614
615 IList paramList = new ArrayList();
616 paramList.Add(hash);
617
618 XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList);
619 string reason = string.Empty;
620
621 // Send and get reply
622 string url = string.Empty;
623 XmlRpcResponse response = null;
624 try
625 {
626 response = request.Send(m_ServerURL, 10000);
627 }
628 catch (Exception e)
629 {
630 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
631 reason = "Exception: " + e.Message;
632 return url;
633 }
634
635 if (response.IsFault)
636 {
637 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
638 reason = "XMLRPC Fault";
639 return url;
640 }
641
642 hash = (Hashtable)response.Value;
643 //foreach (Object o in hash)
644 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
645 try
646 {
647 if (hash == null)
648 {
649 m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
650 reason = "Internal error 1";
651 return url;
652 }
653
654 // Here's the actual response
655 if (hash.ContainsKey("URL"))
656 url = hash["URL"].ToString();
657
658 }
659 catch (Exception e)
660 {
661 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
662 reason = "Exception: " + e.Message;
663 }
664
665 return url;
666 }
667
668 public string GetUUI(UUID userID, UUID targetUserID)
669 {
670 Hashtable hash = new Hashtable();
671 hash["userID"] = userID.ToString();
672 hash["targetUserID"] = targetUserID.ToString();
673
674 IList paramList = new ArrayList();
675 paramList.Add(hash);
676
677 XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList);
678 string reason = string.Empty;
679
680 // Send and get reply
681 string uui = string.Empty;
682 XmlRpcResponse response = null;
683 try
684 {
685 response = request.Send(m_ServerURL, 10000);
686 }
687 catch (Exception e)
688 {
689 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0}", m_ServerURL);
690 reason = "Exception: " + e.Message;
691 return uui;
692 }
693
694 if (response.IsFault)
695 {
696 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} returned an error: {1}", m_ServerURL, response.FaultString);
697 reason = "XMLRPC Fault";
698 return uui;
699 }
700
701 hash = (Hashtable)response.Value;
702 //foreach (Object o in hash)
703 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
704 try
705 {
706 if (hash == null)
707 {
708 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
709 reason = "Internal error 1";
710 return uui;
711 }
712
713 // Here's the actual response
714 if (hash.ContainsKey("UUI"))
715 uui = hash["UUI"].ToString();
716
717 }
718 catch (Exception e)
719 {
720 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
721 reason = "Exception: " + e.Message;
722 }
723
724 return uui;
725 }
403 726
404 private bool GetBoolResponse(XmlRpcRequest request, out string reason) 727 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
405 { 728 {
diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
new file mode 100644
index 0000000..dbce9f6
--- /dev/null
+++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
@@ -0,0 +1,131 @@
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 */
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenMetaverse;
34using Nwc.XmlRpc;
35using log4net;
36
37using OpenSim.Framework;
38
39namespace OpenSim.Services.Connectors.InstantMessage
40{
41 public class InstantMessageServiceConnector
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
46
47 /// <summary>
48 /// This actually does the XMLRPC Request
49 /// </summary>
50 /// <param name="url">URL we pull the data out of to send the request to</param>
51 /// <param name="im">The Instant Message </param>
52 /// <returns>Bool if the message was successfully delivered at the other side.</returns>
53 public static bool SendInstantMessage(string url, GridInstantMessage im)
54 {
55 Hashtable xmlrpcdata = ConvertGridInstantMessageToXMLRPC(im);
56 xmlrpcdata["region_handle"] = 0;
57
58 ArrayList SendParams = new ArrayList();
59 SendParams.Add(xmlrpcdata);
60 XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);
61 try
62 {
63
64 XmlRpcResponse GridResp = GridReq.Send(url, 10000);
65
66 Hashtable responseData = (Hashtable)GridResp.Value;
67
68 if (responseData.ContainsKey("success"))
69 {
70 if ((string)responseData["success"] == "TRUE")
71 {
72 //m_log.DebugFormat("[XXX] Success");
73 return true;
74 }
75 else
76 {
77 //m_log.DebugFormat("[XXX] Fail");
78 return false;
79 }
80 }
81 else
82 {
83 m_log.DebugFormat("[GRID INSTANT MESSAGE]: No response from {0}", url);
84 return false;
85 }
86 }
87 catch (WebException e)
88 {
89 m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond " + e.ToString(), url);
90 }
91
92 return false;
93 }
94
95 /// <summary>
96 /// Takes a GridInstantMessage and converts it into a Hashtable for XMLRPC
97 /// </summary>
98 /// <param name="msg">The GridInstantMessage object</param>
99 /// <returns>Hashtable containing the XMLRPC request</returns>
100 protected static Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg)
101 {
102 Hashtable gim = new Hashtable();
103 gim["from_agent_id"] = msg.fromAgentID.ToString();
104 // Kept for compatibility
105 gim["from_agent_session"] = UUID.Zero.ToString();
106 gim["to_agent_id"] = msg.toAgentID.ToString();
107 gim["im_session_id"] = msg.imSessionID.ToString();
108 gim["timestamp"] = msg.timestamp.ToString();
109 gim["from_agent_name"] = msg.fromAgentName;
110 gim["message"] = msg.message;
111 byte[] dialogdata = new byte[1]; dialogdata[0] = msg.dialog;
112 gim["dialog"] = Convert.ToBase64String(dialogdata, Base64FormattingOptions.None);
113
114 if (msg.fromGroup)
115 gim["from_group"] = "TRUE";
116 else
117 gim["from_group"] = "FALSE";
118 byte[] offlinedata = new byte[1]; offlinedata[0] = msg.offline;
119 gim["offline"] = Convert.ToBase64String(offlinedata, Base64FormattingOptions.None);
120 gim["parent_estate_id"] = msg.ParentEstateID.ToString();
121 gim["position_x"] = msg.Position.X.ToString();
122 gim["position_y"] = msg.Position.Y.ToString();
123 gim["position_z"] = msg.Position.Z.ToString();
124 gim["region_id"] = msg.RegionID.ToString();
125 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None);
126
127 return gim;
128 }
129
130 }
131}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
index 6f2d735..7422d94 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -78,6 +78,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
78 78
79 public FriendInfo[] GetFriends(UUID principalID) 79 public FriendInfo[] GetFriends(UUID principalID)
80 { 80 {
81 return GetFriends(principalID.ToString());
82 }
83
84 public FriendInfo[] GetFriends(string principalID)
85 {
81 if (String.IsNullOrEmpty(m_serverUrl)) 86 if (String.IsNullOrEmpty(m_serverUrl))
82 return new FriendInfo[0]; 87 return new FriendInfo[0];
83 88
@@ -95,7 +100,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
95 UUID friendID = friendEntry["Key"].AsUUID(); 100 UUID friendID = friendEntry["Key"].AsUUID();
96 101
97 FriendInfo friend = new FriendInfo(); 102 FriendInfo friend = new FriendInfo();
98 friend.PrincipalID = principalID; 103 if (!UUID.TryParse(principalID, out friend.PrincipalID))
104 {
105 string tmp = string.Empty;
106 if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp, out tmp))
107 // bad record. ignore this entry
108 continue;
109 }
110
99 friend.Friend = friendID.ToString(); 111 friend.Friend = friendID.ToString();
100 friend.MyFlags = friendEntry["Value"].AsInteger(); 112 friend.MyFlags = friendEntry["Value"].AsInteger();
101 friend.TheirFlags = -1; 113 friend.TheirFlags = -1;
@@ -127,7 +139,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
127 return array; 139 return array;
128 } 140 }
129 141
130 public bool StoreFriend(UUID principalID, string friend, int flags) 142 public bool StoreFriend(string principalID, string friend, int flags)
131 { 143 {
132 if (String.IsNullOrEmpty(m_serverUrl)) 144 if (String.IsNullOrEmpty(m_serverUrl))
133 return true; 145 return true;
@@ -152,6 +164,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
152 164
153 public bool Delete(UUID principalID, string friend) 165 public bool Delete(UUID principalID, string friend)
154 { 166 {
167 return Delete(principalID.ToString(), friend);
168 }
169
170 public bool Delete(string principalID, string friend)
171 {
155 if (String.IsNullOrEmpty(m_serverUrl)) 172 if (String.IsNullOrEmpty(m_serverUrl))
156 return true; 173 return true;
157 174
@@ -174,7 +191,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
174 191
175 #endregion IFriendsService 192 #endregion IFriendsService
176 193
177 private OSDArray GetFriended(UUID ownerID) 194 private OSDArray GetFriended(string ownerID)
178 { 195 {
179 NameValueCollection requestArgs = new NameValueCollection 196 NameValueCollection requestArgs = new NameValueCollection
180 { 197 {
@@ -195,7 +212,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
195 } 212 }
196 } 213 }
197 214
198 private OSDArray GetFriendedBy(UUID ownerID) 215 private OSDArray GetFriendedBy(string ownerID)
199 { 216 {
200 NameValueCollection requestArgs = new NameValueCollection 217 NameValueCollection requestArgs = new NameValueCollection
201 { 218 {
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 725c6df..6fb583c 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -103,16 +103,31 @@ namespace OpenSim.Services.Connectors.Simulation
103 args["teleport_flags"] = OSD.FromString(flags.ToString()); 103 args["teleport_flags"] = OSD.FromString(flags.ToString());
104 104
105 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); 105 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000);
106 if (result["Success"].AsBoolean()) 106 bool success = result["success"].AsBoolean();
107 return true; 107 if (success && result.ContainsKey("_Result"))
108 108 {
109 OSDMap data = (OSDMap)result["_Result"];
110
111 reason = data["reason"].AsString();
112 success = data["success"].AsBoolean();
113 return success;
114 }
115
116 // Try the old version, uncompressed
109 result = WebUtil.PostToService(uri, args, 30000); 117 result = WebUtil.PostToService(uri, args, 30000);
110 118
111 if (result["Success"].AsBoolean()) 119 if (result["Success"].AsBoolean())
112 { 120 {
113 m_log.WarnFormat( 121 if (result.ContainsKey("_Result"))
114 "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); 122 {
115 return true; 123 OSDMap data = (OSDMap)result["_Result"];
124
125 reason = data["reason"].AsString();
126 success = data["success"].AsBoolean();
127 m_log.WarnFormat(
128 "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
129 return success;
130 }
116 } 131 }
117 132
118 m_log.WarnFormat( 133 m_log.WarnFormat(
diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs
index c3f1056..201e72f 100644
--- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs
+++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs
@@ -54,10 +54,10 @@ namespace OpenSim.Services.FreeswitchService
54 54
55 Hashtable response = new Hashtable(); 55 Hashtable response = new Hashtable();
56 56
57 foreach (DictionaryEntry item in request) 57// foreach (DictionaryEntry item in request)
58 { 58// {
59// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value); 59//// m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value);
60 } 60// }
61 61
62 string requestcontext = (string) request["Hunt-Context"]; 62 string requestcontext = (string) request["Hunt-Context"];
63 response["content_type"] = "text/xml"; 63 response["content_type"] = "text/xml";
diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs
index 3c64ecc..e2033ac 100644
--- a/OpenSim/Services/Friends/FriendsService.cs
+++ b/OpenSim/Services/Friends/FriendsService.cs
@@ -43,17 +43,42 @@ namespace OpenSim.Services.Friends
43 { 43 {
44 } 44 }
45 45
46 public FriendInfo[] GetFriends(UUID PrincipalID) 46 public virtual FriendInfo[] GetFriends(UUID PrincipalID)
47 { 47 {
48 FriendsData[] data = m_Database.GetFriends(PrincipalID); 48 FriendsData[] data = m_Database.GetFriends(PrincipalID);
49 List<FriendInfo> info = new List<FriendInfo>();
50
51 foreach (FriendsData d in data)
52 {
53 FriendInfo i = new FriendInfo();
54
55 i.PrincipalID = new UUID(d.PrincipalID);
56 i.Friend = d.Friend;
57 i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
58 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
59
60 info.Add(i);
61 }
62
63 return info.ToArray();
64 }
49 65
66 public virtual FriendInfo[] GetFriends(string PrincipalID)
67 {
68 FriendsData[] data = m_Database.GetFriends(PrincipalID);
50 List<FriendInfo> info = new List<FriendInfo>(); 69 List<FriendInfo> info = new List<FriendInfo>();
51 70
52 foreach (FriendsData d in data) 71 foreach (FriendsData d in data)
53 { 72 {
54 FriendInfo i = new FriendInfo(); 73 FriendInfo i = new FriendInfo();
55 74
56 i.PrincipalID = d.PrincipalID; 75 if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID))
76 {
77 string tmp = string.Empty;
78 if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp, out tmp))
79 // bad record. ignore this entry
80 continue;
81 }
57 i.Friend = d.Friend; 82 i.Friend = d.Friend;
58 i.MyFlags = Convert.ToInt32(d.Data["Flags"]); 83 i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
59 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]); 84 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
@@ -64,7 +89,7 @@ namespace OpenSim.Services.Friends
64 return info.ToArray(); 89 return info.ToArray();
65 } 90 }
66 91
67 public bool StoreFriend(UUID PrincipalID, string Friend, int flags) 92 public virtual bool StoreFriend(string PrincipalID, string Friend, int flags)
68 { 93 {
69 FriendsData d = new FriendsData(); 94 FriendsData d = new FriendsData();
70 95
@@ -76,7 +101,12 @@ namespace OpenSim.Services.Friends
76 return m_Database.Store(d); 101 return m_Database.Store(d);
77 } 102 }
78 103
79 public bool Delete(UUID PrincipalID, string Friend) 104 public bool Delete(string principalID, string friend)
105 {
106 return m_Database.Delete(principalID, friend);
107 }
108
109 public virtual bool Delete(UUID PrincipalID, string Friend)
80 { 110 {
81 return m_Database.Delete(PrincipalID, Friend); 111 return m_Database.Delete(PrincipalID, Friend);
82 } 112 }
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
index b226971..6d63748 100644
--- a/OpenSim/Services/GridService/HypergridLinker.cs
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -327,10 +327,13 @@ namespace OpenSim.Services.GridService
327 else 327 else
328 regInfo.RegionName = externalName; 328 regInfo.RegionName = externalName;
329 329
330 m_log.Debug("[HYPERGRID LINKER]: naming linked region " + regInfo.RegionName); 330 m_log.DebugFormat("[HYPERGRID LINKER]: naming linked region {0}, handle {1}", regInfo.RegionName, handle.ToString());
331 331
332 // Get the map image 332 // Get the map image
333 regInfo.TerrainImage = m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory); 333 regInfo.TerrainImage = GetMapImage(regionID, imageURL);
334
335 // Store the origin's coordinates somewhere
336 regInfo.RegionSecret = handle.ToString();
334 337
335 AddHyperlinkRegion(regInfo, handle); 338 AddHyperlinkRegion(regInfo, handle);
336 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID); 339 m_log.Info("[HYPERGRID LINKER]: Successfully linked to region_uuid " + regInfo.RegionID);
@@ -427,6 +430,10 @@ namespace OpenSim.Services.GridService
427 m_Database.Delete(regionID); 430 m_Database.Delete(regionID);
428 } 431 }
429 432
433 public UUID GetMapImage(UUID regionID, string imageURL)
434 {
435 return m_GatekeeperConnector.GetMapImage(regionID, imageURL, m_MapTileDirectory);
436 }
430 #endregion 437 #endregion
431 438
432 439
diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
new file mode 100644
index 0000000..ded589d
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
@@ -0,0 +1,349 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends;
35using OpenSim.Services.Connectors.Hypergrid;
36using OpenSim.Services.Interfaces;
37using OpenSim.Services.Connectors.InstantMessage;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenSim.Server.Base;
40using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
41
42using OpenMetaverse;
43using log4net;
44using Nini.Config;
45
46namespace OpenSim.Services.HypergridService
47{
48 /// <summary>
49 /// Inter-grid IM
50 /// </summary>
51 public class HGInstantMessageService : IInstantMessage
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56
57 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours
58
59 static bool m_Initialized = false;
60
61 protected static IGridService m_GridService;
62 protected static IPresenceService m_PresenceService;
63 protected static IUserAgentService m_UserAgentService;
64
65 protected static IInstantMessageSimConnector m_IMSimConnector;
66
67 protected static Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
68 private static ExpiringCache<UUID, GridRegion> m_RegionCache;
69
70 private static string m_RestURL;
71 private static bool m_ForwardOfflineGroupMessages;
72 private static bool m_InGatekeeper;
73
74 public HGInstantMessageService(IConfigSource config)
75 : this(config, null)
76 {
77 }
78
79 public HGInstantMessageService(IConfigSource config, IInstantMessageSimConnector imConnector)
80 {
81 if (imConnector != null)
82 m_IMSimConnector = imConnector;
83
84 if (!m_Initialized)
85 {
86 m_Initialized = true;
87
88 IConfig serverConfig = config.Configs["HGInstantMessageService"];
89 if (serverConfig == null)
90 throw new Exception(String.Format("No section HGInstantMessageService in config file"));
91
92 string gridService = serverConfig.GetString("GridService", String.Empty);
93 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
94 string userAgentService = serverConfig.GetString("UserAgentService", String.Empty);
95 m_InGatekeeper = serverConfig.GetBoolean("InGatekeeper", false);
96 m_log.DebugFormat("[HG IM SERVICE]: Starting... InRobust? {0}", m_InGatekeeper);
97
98
99 if (gridService == string.Empty || presenceService == string.Empty)
100 throw new Exception(String.Format("Incomplete specifications, InstantMessage Service cannot function."));
101
102 Object[] args = new Object[] { config };
103 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
104 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
105 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args);
106
107 m_RegionCache = new ExpiringCache<UUID, GridRegion>();
108
109 IConfig cnf = config.Configs["Messaging"];
110 if (cnf == null)
111 {
112 return;
113 }
114
115 m_RestURL = cnf.GetString("OfflineMessageURL", string.Empty);
116 m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", false);
117
118 }
119 }
120
121 public bool IncomingInstantMessage(GridInstantMessage im)
122 {
123 m_log.DebugFormat("[HG IM SERVICE]: Received message from {0} to {1}", im.fromAgentID, im.toAgentID);
124 UUID toAgentID = new UUID(im.toAgentID);
125
126 bool success = false;
127 if (m_IMSimConnector != null)
128 {
129 //m_log.DebugFormat("[XXX] SendIMToRegion local im connector");
130 success = m_IMSimConnector.SendInstantMessage(im);
131 }
132 else
133 {
134 success = TrySendInstantMessage(im, "", true, false);
135 }
136
137 if (!success && m_InGatekeeper) // we do this only in the Gatekeeper IM service
138 UndeliveredMessage(im);
139
140 return success;
141 }
142
143 public bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner)
144 {
145 m_log.DebugFormat("[HG IM SERVICE]: Sending message from {0} to {1}@{2}", im.fromAgentID, im.toAgentID, url);
146 if (url != string.Empty)
147 return TrySendInstantMessage(im, url, true, foreigner);
148 else
149 {
150 PresenceInfo upd = new PresenceInfo();
151 upd.RegionID = UUID.Zero;
152 return TrySendInstantMessage(im, upd, true, foreigner);
153 }
154
155 }
156
157 protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime, bool foreigner)
158 {
159 UUID toAgentID = new UUID(im.toAgentID);
160
161 PresenceInfo upd = null;
162 string url = string.Empty;
163
164 bool lookupAgent = false;
165
166 lock (m_UserLocationMap)
167 {
168 if (m_UserLocationMap.ContainsKey(toAgentID))
169 {
170 object o = m_UserLocationMap[toAgentID];
171 if (o is PresenceInfo)
172 upd = (PresenceInfo)o;
173 else if (o is string)
174 url = (string)o;
175
176 // We need to compare the current location with the previous
177 // or the recursive loop will never end because it will never try to lookup the agent again
178 if (!firstTime)
179 {
180 lookupAgent = true;
181 upd = null;
182 }
183 }
184 else
185 {
186 lookupAgent = true;
187 }
188 }
189
190 //m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no"));
191
192 // Are we needing to look-up an agent?
193 if (lookupAgent)
194 {
195 // Non-cached user agent lookup.
196 PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { toAgentID.ToString() });
197 if (presences != null && presences.Length > 0)
198 {
199 foreach (PresenceInfo p in presences)
200 {
201 if (p.RegionID != UUID.Zero)
202 {
203 //m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID);
204 upd = p;
205 break;
206 }
207 }
208 }
209
210 if (upd == null && !foreigner)
211 {
212 // Let's check with the UAS if the user is elsewhere
213 m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service");
214 url = m_UserAgentService.LocateUser(toAgentID);
215 }
216
217 // check if we've tried this before..
218 // This is one way to end the recursive loop
219 //
220 if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) ||
221 (previousLocation is string && upd == null && previousLocation.Equals(url))))
222 {
223 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
224 m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url);
225
226 return false;
227 }
228 }
229
230 if (upd != null)
231 {
232 // ok, the user is around somewhere. Let's send back the reply with "success"
233 // even though the IM may still fail. Just don't keep the caller waiting for
234 // the entire time we're trying to deliver the IM
235 return SendIMToRegion(upd, im, toAgentID, foreigner);
236 }
237 else if (url != string.Empty)
238 {
239 // ok, the user is around somewhere. Let's send back the reply with "success"
240 // even though the IM may still fail. Just don't keep the caller waiting for
241 // the entire time we're trying to deliver the IM
242 return ForwardIMToGrid(url, im, toAgentID, foreigner);
243 }
244 else if (firstTime && previousLocation is string && (string)previousLocation != string.Empty)
245 {
246 return ForwardIMToGrid((string)previousLocation, im, toAgentID, foreigner);
247 }
248 else
249 m_log.DebugFormat("[HG IM SERVICE]: Unable to locate user {0}", toAgentID);
250 return false;
251 }
252
253 bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID, bool foreigner)
254 {
255 bool imresult = false;
256 GridRegion reginfo = null;
257 if (!m_RegionCache.TryGetValue(upd.RegionID, out reginfo))
258 {
259 reginfo = m_GridService.GetRegionByUUID(UUID.Zero /*!!!*/, upd.RegionID);
260 if (reginfo != null)
261 m_RegionCache.AddOrUpdate(upd.RegionID, reginfo, CACHE_EXPIRATION_SECONDS);
262 }
263
264 if (reginfo != null)
265 {
266 imresult = InstantMessageServiceConnector.SendInstantMessage(reginfo.ServerURI, im);
267 }
268 else
269 {
270 m_log.DebugFormat("[HG IM SERVICE]: Failed to deliver message to {0}", reginfo.ServerURI);
271 return false;
272 }
273
274 if (imresult)
275 {
276 // IM delivery successful, so store the Agent's location in our local cache.
277 lock (m_UserLocationMap)
278 {
279 if (m_UserLocationMap.ContainsKey(toAgentID))
280 {
281 m_UserLocationMap[toAgentID] = upd;
282 }
283 else
284 {
285 m_UserLocationMap.Add(toAgentID, upd);
286 }
287 }
288 return true;
289 }
290 else
291 {
292 // try again, but lookup user this time.
293 // Warning, this must call the Async version
294 // of this method or we'll be making thousands of threads
295 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
296 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
297
298 // This is recursive!!!!!
299 return TrySendInstantMessage(im, upd, false, foreigner);
300 }
301 }
302
303 bool ForwardIMToGrid(string url, GridInstantMessage im, UUID toAgentID, bool foreigner)
304 {
305 if (InstantMessageServiceConnector.SendInstantMessage(url, im))
306 {
307 // IM delivery successful, so store the Agent's location in our local cache.
308 lock (m_UserLocationMap)
309 {
310 if (m_UserLocationMap.ContainsKey(toAgentID))
311 {
312 m_UserLocationMap[toAgentID] = url;
313 }
314 else
315 {
316 m_UserLocationMap.Add(toAgentID, url);
317 }
318 }
319
320 return true;
321 }
322 else
323 {
324 // try again, but lookup user this time.
325
326 // This is recursive!!!!!
327 return TrySendInstantMessage(im, url, false, foreigner);
328 }
329
330 }
331
332 private bool UndeliveredMessage(GridInstantMessage im)
333 {
334 if (m_RestURL != string.Empty && (im.offline != 0)
335 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
336 {
337 m_log.DebugFormat("[HG IM SERVICE]: Message saved");
338 return SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
339 "POST", m_RestURL + "/SaveMessage/", im);
340
341 }
342
343 else
344 {
345 return false;
346 }
347 }
348 }
349}
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
index 9ee1ae4..4eb61ba 100644
--- a/OpenSim/Services/HypergridService/HGInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -134,6 +134,7 @@ namespace OpenSim.Services.HypergridService
134 134
135 public override InventoryFolderBase GetRootFolder(UUID principalID) 135 public override InventoryFolderBase GetRootFolder(UUID principalID)
136 { 136 {
137 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
137 // Warp! Root folder for travelers 138 // Warp! Root folder for travelers
138 XInventoryFolder[] folders = m_Database.GetFolders( 139 XInventoryFolder[] folders = m_Database.GetFolders(
139 new string[] { "agentID", "folderName"}, 140 new string[] { "agentID", "folderName"},
@@ -171,6 +172,7 @@ namespace OpenSim.Services.HypergridService
171 172
172 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 173 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
173 { 174 {
175 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
174 return GetRootFolder(principalID); 176 return GetRootFolder(principalID);
175 } 177 }
176 178
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 09e785f..41d5a88 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -31,10 +31,12 @@ using System.Net;
31using System.Reflection; 31using System.Reflection;
32 32
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends;
34using OpenSim.Services.Connectors.Hypergrid; 35using OpenSim.Services.Connectors.Hypergrid;
35using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
36using GridRegion = OpenSim.Services.Interfaces.GridRegion; 37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37using OpenSim.Server.Base; 38using OpenSim.Server.Base;
39using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38 40
39using OpenMetaverse; 41using OpenMetaverse;
40using log4net; 42using log4net;
@@ -63,19 +65,35 @@ namespace OpenSim.Services.HypergridService
63 protected static IGridService m_GridService; 65 protected static IGridService m_GridService;
64 protected static GatekeeperServiceConnector m_GatekeeperConnector; 66 protected static GatekeeperServiceConnector m_GatekeeperConnector;
65 protected static IGatekeeperService m_GatekeeperService; 67 protected static IGatekeeperService m_GatekeeperService;
68 protected static IFriendsService m_FriendsService;
69 protected static IPresenceService m_PresenceService;
70 protected static IUserAccountService m_UserAccountService;
71 protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule
72 protected static FriendsSimConnector m_FriendsSimConnector; // grid
66 73
67 protected static string m_GridName; 74 protected static string m_GridName;
68 75
69 protected static bool m_BypassClientVerification; 76 protected static bool m_BypassClientVerification;
70 77
71 public UserAgentService(IConfigSource config) 78 public UserAgentService(IConfigSource config) : this(config, null)
72 { 79 {
80 }
81
82 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
83 {
84 // Let's set this always, because we don't know the sequence
85 // of instantiations
86 if (friendsConnector != null)
87 m_FriendsLocalSimConnector = friendsConnector;
88
73 if (!m_Initialized) 89 if (!m_Initialized)
74 { 90 {
75 m_Initialized = true; 91 m_Initialized = true;
76 92
77 m_log.DebugFormat("[HOME USERS SECURITY]: Starting..."); 93 m_log.DebugFormat("[HOME USERS SECURITY]: Starting...");
78 94
95 m_FriendsSimConnector = new FriendsSimConnector();
96
79 IConfig serverConfig = config.Configs["UserAgentService"]; 97 IConfig serverConfig = config.Configs["UserAgentService"];
80 if (serverConfig == null) 98 if (serverConfig == null)
81 throw new Exception(String.Format("No section UserAgentService in config file")); 99 throw new Exception(String.Format("No section UserAgentService in config file"));
@@ -83,6 +101,9 @@ namespace OpenSim.Services.HypergridService
83 string gridService = serverConfig.GetString("GridService", String.Empty); 101 string gridService = serverConfig.GetString("GridService", String.Empty);
84 string gridUserService = serverConfig.GetString("GridUserService", String.Empty); 102 string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
85 string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty); 103 string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty);
104 string friendsService = serverConfig.GetString("FriendsService", String.Empty);
105 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
106 string userAccountService = serverConfig.GetString("UserAccountService", String.Empty);
86 107
87 m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false); 108 m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false);
88 109
@@ -94,6 +115,9 @@ namespace OpenSim.Services.HypergridService
94 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args); 115 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
95 m_GatekeeperConnector = new GatekeeperServiceConnector(); 116 m_GatekeeperConnector = new GatekeeperServiceConnector();
96 m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args); 117 m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args);
118 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(friendsService, args);
119 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
120 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args);
97 121
98 m_GridName = serverConfig.GetString("ExternalName", string.Empty); 122 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
99 if (m_GridName == string.Empty) 123 if (m_GridName == string.Empty)
@@ -155,12 +179,17 @@ namespace OpenSim.Services.HypergridService
155 string myExternalIP = string.Empty; 179 string myExternalIP = string.Empty;
156 string gridName = gatekeeper.ServerURI; 180 string gridName = gatekeeper.ServerURI;
157 181
158 m_log.DebugFormat("[USER AGENT SERVICE]: m_grid - {0}, gn - {1}", m_GridName, gridName); 182 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName);
159 183
160 if (m_GridName == gridName) 184 if (m_GridName == gridName)
161 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); 185 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
162 else 186 else
187 {
163 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason); 188 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
189 if (success)
190 // Report them as nowhere
191 m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero);
192 }
164 193
165 if (!success) 194 if (!success)
166 { 195 {
@@ -168,8 +197,11 @@ namespace OpenSim.Services.HypergridService
168 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); 197 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
169 198
170 // restore the old travel info 199 // restore the old travel info
171 lock (m_TravelingAgents) 200 if(reason != "Logins Disabled")
172 m_TravelingAgents[agentCircuit.SessionID] = old; 201 {
202 lock (m_TravelingAgents)
203 m_TravelingAgents[agentCircuit.SessionID] = old;
204 }
173 205
174 return false; 206 return false;
175 } 207 }
@@ -179,6 +211,7 @@ namespace OpenSim.Services.HypergridService
179 if (clientIP != null) 211 if (clientIP != null)
180 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString(); 212 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString();
181 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; 213 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
214
182 return true; 215 return true;
183 } 216 }
184 217
@@ -289,6 +322,213 @@ namespace OpenSim.Services.HypergridService
289 return false; 322 return false;
290 } 323 }
291 324
325 public List<UUID> StatusNotification(List<string> friends, UUID foreignUserID, bool online)
326 {
327 if (m_FriendsService == null || m_PresenceService == null)
328 {
329 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
330 return new List<UUID>();
331 }
332
333 List<UUID> localFriendsOnline = new List<UUID>();
334
335 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);
336
337 // First, let's double check that the reported friends are, indeed, friends of that user
338 // And let's check that the secret matches
339 List<string> usersToBeNotified = new List<string>();
340 foreach (string uui in friends)
341 {
342 UUID localUserID;
343 string secret = string.Empty, tmp = string.Empty;
344 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
345 {
346 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
347 foreach (FriendInfo finfo in friendInfos)
348 {
349 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret))
350 {
351 // great!
352 usersToBeNotified.Add(localUserID.ToString());
353 }
354 }
355 }
356 }
357
358 // Now, let's send the notifications
359 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);
360
361 // First, let's send notifications to local users who are online in the home grid
362 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
363 if (friendSessions != null && friendSessions.Length > 0)
364 {
365 PresenceInfo friendSession = null;
366 foreach (PresenceInfo pinfo in friendSessions)
367 if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents
368 {
369 friendSession = pinfo;
370 break;
371 }
372
373 if (friendSession != null)
374 {
375 ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
376 usersToBeNotified.Remove(friendSession.UserID.ToString());
377 UUID id;
378 if (UUID.TryParse(friendSession.UserID, out id))
379 localFriendsOnline.Add(id);
380
381 }
382 }
383
384 // Lastly, let's notify the rest who may be online somewhere else
385 foreach (string user in usersToBeNotified)
386 {
387 UUID id = new UUID(user);
388 if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName)
389 {
390 string url = m_TravelingAgents[id].GridExternalName;
391 // forward
392 m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
393 }
394 }
395
396 // and finally, let's send the online friends
397 if (online)
398 {
399 return localFriendsOnline;
400 }
401 else
402 return new List<UUID>();
403 }
404
405 protected void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online)
406 {
407 UUID userID;
408 if (UUID.TryParse(user, out userID))
409 {
410 if (m_FriendsLocalSimConnector != null)
411 {
412 m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline"));
413 m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online);
414 }
415 else
416 {
417 GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID);
418 if (region != null)
419 {
420 m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline"));
421 m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID, online);
422 }
423 }
424 }
425 }
426
427 public List<UUID> GetOnlineFriends(UUID foreignUserID, List<string> friends)
428 {
429 List<UUID> online = new List<UUID>();
430
431 if (m_FriendsService == null || m_PresenceService == null)
432 {
433 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
434 return online;
435 }
436
437 m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);
438
439 // First, let's double check that the reported friends are, indeed, friends of that user
440 // And let's check that the secret matches and the rights
441 List<string> usersToBeNotified = new List<string>();
442 foreach (string uui in friends)
443 {
444 UUID localUserID;
445 string secret = string.Empty, tmp = string.Empty;
446 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
447 {
448 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
449 foreach (FriendInfo finfo in friendInfos)
450 {
451 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) &&
452 (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
453 {
454 // great!
455 usersToBeNotified.Add(localUserID.ToString());
456 }
457 }
458 }
459 }
460
461 // Now, let's find out their status
462 m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);
463
464 // First, let's send notifications to local users who are online in the home grid
465 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
466 if (friendSessions != null && friendSessions.Length > 0)
467 {
468 foreach (PresenceInfo pi in friendSessions)
469 {
470 UUID presenceID;
471 if (UUID.TryParse(pi.UserID, out presenceID))
472 online.Add(presenceID);
473 }
474 }
475
476 return online;
477 }
478
479 public Dictionary<string, object> GetServerURLs(UUID userID)
480 {
481 if (m_UserAccountService == null)
482 {
483 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing");
484 return new Dictionary<string, object>();
485 }
486 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
487 if (account != null)
488 return account.ServiceURLs;
489
490 return new Dictionary<string, object>();
491 }
492
493 public string LocateUser(UUID userID)
494 {
495 foreach (TravelingAgentInfo t in m_TravelingAgents.Values)
496 {
497 if (t == null)
498 {
499 m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis");
500 continue;
501 }
502 if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName))
503 return t.GridExternalName;
504 }
505
506 return string.Empty;
507 }
508
509 public string GetUUI(UUID userID, UUID targetUserID)
510 {
511 // Let's see if it's a local user
512 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID);
513 if (account != null)
514 return targetUserID.ToString() + ";" + m_GridName + ";" + account.FirstName + " " + account.LastName ;
515
516 // Let's try the list of friends
517 FriendInfo[] friends = m_FriendsService.GetFriends(userID);
518 if (friends != null && friends.Length > 0)
519 {
520 foreach (FriendInfo f in friends)
521 if (f.Friend.StartsWith(targetUserID.ToString()))
522 {
523 // Let's remove the secret
524 UUID id; string tmp = string.Empty, secret = string.Empty;
525 if (Util.ParseUniversalUserIdentifier(f.Friend, out id, out tmp, out tmp, out tmp, out secret))
526 return f.Friend.Replace(secret, "0");
527 }
528 }
529
530 return string.Empty;
531 }
292 } 532 }
293 533
294 class TravelingAgentInfo 534 class TravelingAgentInfo
diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs
index 0ddd5e5..1664f3b 100644
--- a/OpenSim/Services/Interfaces/IFriendsService.cs
+++ b/OpenSim/Services/Interfaces/IFriendsService.cs
@@ -74,7 +74,9 @@ namespace OpenSim.Services.Interfaces
74 public interface IFriendsService 74 public interface IFriendsService
75 { 75 {
76 FriendInfo[] GetFriends(UUID PrincipalID); 76 FriendInfo[] GetFriends(UUID PrincipalID);
77 bool StoreFriend(UUID PrincipalID, string Friend, int flags); 77 FriendInfo[] GetFriends(string PrincipalID);
78 bool StoreFriend(string PrincipalID, string Friend, int flags);
78 bool Delete(UUID PrincipalID, string Friend); 79 bool Delete(UUID PrincipalID, string Friend);
80 bool Delete(string PrincipalID, string Friend);
79 } 81 }
80} 82}
diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index aac8293..220caef 100644
--- a/OpenSim/Services/Interfaces/IGatekeeperService.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -54,9 +54,34 @@ namespace OpenSim.Services.Interfaces
54 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); 54 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
55 void LogoutAgent(UUID userID, UUID sessionID); 55 void LogoutAgent(UUID userID, UUID sessionID);
56 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); 56 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
57 Dictionary<string, object> GetServerURLs(UUID userID);
58
59 string LocateUser(UUID userID);
60 // Tries to get the universal user identifier for the targetUserId
61 // on behalf of the userID
62 string GetUUI(UUID userID, UUID targetUserID);
63
64 // Returns the local friends online
65 List<UUID> StatusNotification(List<string> friends, UUID userID, bool online);
66 //List<UUID> GetOnlineFriends(UUID userID, List<string> friends);
57 67
58 bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); 68 bool AgentIsComingHome(UUID sessionID, string thisGridExternalName);
59 bool VerifyAgent(UUID sessionID, string token); 69 bool VerifyAgent(UUID sessionID, string token);
60 bool VerifyClient(UUID sessionID, string reportedIP); 70 bool VerifyClient(UUID sessionID, string reportedIP);
61 } 71 }
72
73 public interface IInstantMessage
74 {
75 bool IncomingInstantMessage(GridInstantMessage im);
76 bool OutgoingInstantMessage(GridInstantMessage im, string url, bool foreigner);
77 }
78 public interface IFriendsSimConnector
79 {
80 bool StatusNotify(UUID userID, UUID friendID, bool online);
81 }
82
83 public interface IInstantMessageSimConnector
84 {
85 bool SendInstantMessage(GridInstantMessage im);
86 }
62} 87}
diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs
index e543337..73dd06a 100644
--- a/OpenSim/Services/InventoryService/InventoryService.cs
+++ b/OpenSim/Services/InventoryService/InventoryService.cs
@@ -340,6 +340,9 @@ namespace OpenSim.Services.InventoryService
340 List<InventoryItemBase> itemsList = new List<InventoryItemBase>(); 340 List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
341 341
342 itemsList.AddRange(m_Database.getInventoryInFolder(folderID)); 342 itemsList.AddRange(m_Database.getInventoryInFolder(folderID));
343
344// m_log.DebugFormat(
345// "[INVENTORY SERVICE]: Found {0} items in folder {1} for {2}", itemsList.Count, folderID, userID);
343 346
344 return itemsList; 347 return itemsList;
345 } 348 }
@@ -385,8 +388,9 @@ namespace OpenSim.Services.InventoryService
385 // See IInventoryServices 388 // See IInventoryServices
386 public virtual bool AddItem(InventoryItemBase item) 389 public virtual bool AddItem(InventoryItemBase item)
387 { 390 {
388 m_log.DebugFormat( 391// m_log.DebugFormat(
389 "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); 392// "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}",
393// item.Name, item.ID, item.Folder, item.Owner);
390 394
391 m_Database.addInventoryItem(item); 395 m_Database.addInventoryItem(item);
392 396
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 58c59eb..eeab67a 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
40{ 40{
41 public class XInventoryService : ServiceBase, IInventoryService 41 public class XInventoryService : ServiceBase, IInventoryService
42 { 42 {
43// private static readonly ILog m_log = 43 //private static readonly ILog m_log =
44// LogManager.GetLogger( 44 // LogManager.GetLogger(
45// MethodBase.GetCurrentMethod().DeclaringType); 45 // MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 protected IXInventoryData m_Database; 47 protected IXInventoryData m_Database;
48 protected bool m_AllowDelete = true; 48 protected bool m_AllowDelete = true;
@@ -385,8 +385,8 @@ namespace OpenSim.Services.InventoryService
385 385
386 public virtual bool AddItem(InventoryItemBase item) 386 public virtual bool AddItem(InventoryItemBase item)
387 { 387 {
388// m_log.DebugFormat( 388 //m_log.DebugFormat(
389// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); 389 // "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner);
390 390
391 return m_Database.StoreItem(ConvertFromOpenSim(item)); 391 return m_Database.StoreItem(ConvertFromOpenSim(item));
392 } 392 }
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index f8868f5..82acfbc 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -627,7 +627,19 @@ namespace OpenSim.Services.LLLoginService
627 if (finfo.TheirFlags == -1) 627 if (finfo.TheirFlags == -1)
628 continue; 628 continue;
629 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend); 629 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
630 buddyitem.BuddyID = finfo.Friend; 630 // finfo.Friend may not be a simple uuid
631 UUID friendID = UUID.Zero;
632 if (UUID.TryParse(finfo.Friend, out friendID))
633 buddyitem.BuddyID = finfo.Friend;
634 else
635 {
636 string tmp;
637 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
638 buddyitem.BuddyID = friendID.ToString();
639 else
640 // junk entry
641 continue;
642 }
631 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags; 643 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
632 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags; 644 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
633 buddylistreturn.AddNewBuddy(buddyitem); 645 buddylistreturn.AddNewBuddy(buddyitem);
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index ffed15e..6683caf 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -523,6 +523,7 @@ namespace OpenSim.Services.LLLoginService
523 // free uri form 523 // free uri form
524 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34 524 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
525 where = "url"; 525 where = "url";
526 GridRegion region = null;
526 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$"); 527 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
527 Match uriMatch = reURI.Match(startLocation); 528 Match uriMatch = reURI.Match(startLocation);
528 if (uriMatch == null) 529 if (uriMatch == null)
@@ -553,8 +554,18 @@ namespace OpenSim.Services.LLLoginService
553 } 554 }
554 else 555 else
555 { 556 {
556 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation); 557 m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
557 return null; 558 region = FindAlternativeRegion(scopeID);
559 if (region != null)
560 {
561 where = "safe";
562 return region;
563 }
564 else
565 {
566 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions and no alternative found.", startLocation);
567 return null;
568 }
558 } 569 }
559 } 570 }
560 return regions[0]; 571 return regions[0];
@@ -582,7 +593,8 @@ namespace OpenSim.Services.LLLoginService
582 if (parts.Length > 1) 593 if (parts.Length > 1)
583 UInt32.TryParse(parts[1], out port); 594 UInt32.TryParse(parts[1], out port);
584 595
585 GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper); 596// GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
597 region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
586 return region; 598 return region;
587 } 599 }
588 } 600 }
@@ -811,16 +823,13 @@ namespace OpenSim.Services.LLLoginService
811 // Old style: get the service keys from the DB 823 // Old style: get the service keys from the DB
812 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) 824 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs)
813 { 825 {
814 if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty)) 826 if (kvp.Value != null)
815 {
816 aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty);
817 }
818 else
819 { 827 {
820 aCircuit.ServiceURLs[kvp.Key] = kvp.Value; 828 aCircuit.ServiceURLs[kvp.Key] = kvp.Value;
829
830 if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/"))
831 aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/";
821 } 832 }
822 if (!aCircuit.ServiceURLs[kvp.Key].ToString().EndsWith("/"))
823 aCircuit.ServiceURLs[kvp.Key] = aCircuit.ServiceURLs[kvp.Key] + "/";
824 } 833 }
825 834
826 // New style: service keys start with SRV_; override the previous 835 // New style: service keys start with SRV_; override the previous
@@ -828,16 +837,29 @@ namespace OpenSim.Services.LLLoginService
828 837
829 if (keys.Length > 0) 838 if (keys.Length > 0)
830 { 839 {
840 bool newUrls = false;
831 IEnumerable<string> serviceKeys = keys.Where(value => value.StartsWith("SRV_")); 841 IEnumerable<string> serviceKeys = keys.Where(value => value.StartsWith("SRV_"));
832 foreach (string serviceKey in serviceKeys) 842 foreach (string serviceKey in serviceKeys)
833 { 843 {
834 string keyName = serviceKey.Replace("SRV_", ""); 844 string keyName = serviceKey.Replace("SRV_", "");
835 aCircuit.ServiceURLs[keyName] = m_LoginServerConfig.GetString(serviceKey, string.Empty); 845 string keyValue = m_LoginServerConfig.GetString(serviceKey, string.Empty);
836 if (!aCircuit.ServiceURLs[keyName].ToString().EndsWith("/")) 846 if (!keyValue.EndsWith("/"))
837 aCircuit.ServiceURLs[keyName] = aCircuit.ServiceURLs[keyName] + "/"; 847 keyValue = keyValue + "/";
848
849 if (!account.ServiceURLs.ContainsKey(keyName) || (account.ServiceURLs.ContainsKey(keyName) && account.ServiceURLs[keyName] != keyValue))
850 {
851 account.ServiceURLs[keyName] = keyValue;
852 newUrls = true;
853 }
854 aCircuit.ServiceURLs[keyName] = keyValue;
838 855
839 m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]); 856 m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]);
840 } 857 }
858
859 // The grid operator decided to override the defaults in the
860 // [LoginService] configuration. Let's store the correct ones.
861 if (newUrls)
862 m_UserAccountService.StoreUserAccount(account);
841 } 863 }
842 864
843 } 865 }
diff --git a/OpenSim/Tests/Clients/InstantMessage/IMClient.cs b/OpenSim/Tests/Clients/InstantMessage/IMClient.cs
new file mode 100644
index 0000000..e7304a2
--- /dev/null
+++ b/OpenSim/Tests/Clients/InstantMessage/IMClient.cs
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using System.Reflection;
32
33using OpenMetaverse;
34using log4net;
35using log4net.Appender;
36using log4net.Layout;
37
38using OpenSim.Framework;
39using OpenSim.Services.Interfaces;
40using OpenSim.Services.Connectors.InstantMessage;
41
42namespace OpenSim.Tests.Clients.InstantMessage
43{
44 public class IMClient
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType);
49
50 public static void Main(string[] args)
51 {
52 ConsoleAppender consoleAppender = new ConsoleAppender();
53 consoleAppender.Layout =
54 new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline");
55 log4net.Config.BasicConfigurator.Configure(consoleAppender);
56
57 string serverURI = "http://127.0.0.1:8002";
58 GridInstantMessage im = new GridInstantMessage();
59 im.fromAgentID = new Guid();
60 im.toAgentID = new Guid();
61 im.message = "Hello";
62 im.imSessionID = new Guid();
63
64 bool success = InstantMessageServiceConnector.SendInstantMessage(serverURI, im);
65
66 if (success)
67 m_log.InfoFormat("[IM CLIENT]: Successfully IMed {0}", serverURI);
68 else
69 m_log.InfoFormat("[IM CLIENT]: failed to IM {0}", serverURI);
70
71 System.Console.WriteLine("\n");
72 }
73
74 }
75}
diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs
index 8cfad79..d924ecd 100644
--- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs
@@ -118,16 +118,19 @@ namespace OpenSim.Tests.Common
118 118
119 public static UserAccount CreateUserWithInventory(Scene scene) 119 public static UserAccount CreateUserWithInventory(Scene scene)
120 { 120 {
121 return CreateUserWithInventory(scene, 99);
122 }
123
124 public static UserAccount CreateUserWithInventory(Scene scene, int uuidTail)
125 {
121 return CreateUserWithInventory( 126 return CreateUserWithInventory(
122 scene, "Bill", "Bailey", UUID.Parse("00000000-0000-0000-0000-000000000099"), "troll"); 127 scene, "Bill", "Bailey", new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail)), "troll");
123 } 128 }
124 129
125 public static UserAccount CreateUserWithInventory( 130 public static UserAccount CreateUserWithInventory(
126 Scene scene, string firstName, string lastName, UUID userId, string pw) 131 Scene scene, string firstName, string lastName, UUID userId, string pw)
127 { 132 {
128 UserAccount ua 133 UserAccount ua = new UserAccount(userId) { FirstName = firstName, LastName = lastName };
129 = new UserAccount(userId)
130 { FirstName = firstName, LastName = lastName };
131 CreateUserWithInventory(scene, ua, pw); 134 CreateUserWithInventory(scene, ua, pw);
132 return ua; 135 return ua;
133 } 136 }
diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
index 0419134..1703597 100644
--- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
@@ -26,8 +26,10 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using OpenMetaverse; 30using OpenMetaverse;
30using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
31using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
32using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
33 35
@@ -40,18 +42,41 @@ namespace OpenSim.Tests.Common
40 { 42 {
41 public static readonly string PATH_DELIMITER = "/"; 43 public static readonly string PATH_DELIMITER = "/";
42 44
43 public static InventoryItemBase CreateInventoryItem( 45 /// <summary>
44 Scene scene, string itemName, UUID itemId, string folderPath, UUID userId) 46 /// Creates a notecard in the objects folder and specify an item id.
47 /// </summary>
48 /// <param name="scene"></param>
49 /// <param name="itemName"></param>
50 /// <param name="itemId"></param>
51 /// <param name="userId"></param>
52 /// <returns></returns>
53 public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID userId)
45 { 54 {
55 return CreateInventoryItem(scene, itemName, UUID.Random(), userId);
56 }
57
58 /// <summary>
59 /// Creates a notecard in the objects folder and specify an item id.
60 /// </summary>
61 /// <param name="scene"></param>
62 /// <param name="itemName"></param>
63 /// <param name="itemId"></param>
64 /// <param name="userId"></param>
65 /// <returns></returns>
66 public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID itemId, UUID userId)
67 {
68 AssetBase asset = AssetHelpers.CreateAsset(scene, userId);
46 InventoryItemBase item = new InventoryItemBase(); 69 InventoryItemBase item = new InventoryItemBase();
47 item.Name = itemName; 70 item.Name = itemName;
48 item.AssetID = AssetHelpers.CreateAsset(scene, userId).FullID; 71 item.AssetID = asset.FullID;
49 item.ID = itemId; 72 item.ID = itemId;
73 item.Owner = userId;
74 item.AssetType = asset.Type;
75 item.InvType = (int)InventoryType.Notecard;
76
77 InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, AssetType.Notecard);
50 78
51 // Really quite bad since the objs folder could be moved in the future and confuse the tests 79 item.Folder = folder.ID;
52 InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object);
53
54 item.Folder = objsFolder.ID;
55 scene.AddInventoryItem(item); 80 scene.AddInventoryItem(item);
56 81
57 return item; 82 return item;
@@ -111,5 +136,60 @@ namespace OpenSim.Tests.Common
111 else 136 else
112 return newFolder; 137 return newFolder;
113 } 138 }
139
140 /// <summary>
141 /// Get the inventory folder that matches the path name. If there are multiple folders then only the first
142 /// is returned.
143 /// </summary>
144 /// <param name="inventoryService"></param>
145 /// <param name="userId"></param>
146 /// <param name="path"></param>
147 /// <returns>null if no folder matching the path was found</returns>
148 public static InventoryFolderBase GetInventoryFolder(IInventoryService inventoryService, UUID userId, string path)
149 {
150 List<InventoryFolderBase> folders = GetInventoryFolders(inventoryService, userId, path);
151
152 if (folders.Count != 0)
153 return folders[0];
154 else
155 return null;
156 }
157
158 /// <summary>
159 /// Get the inventory folders that match the path name.
160 /// </summary>
161 /// <param name="inventoryService"></param>
162 /// <param name="userId"></param>
163 /// <param name="path"></param>
164 /// <returns>An empty list if no matching folders were found</returns>
165 public static List<InventoryFolderBase> GetInventoryFolders(IInventoryService inventoryService, UUID userId, string path)
166 {
167 return InventoryArchiveUtils.FindFolderByPath(inventoryService, userId, path);
168 }
169
170 /// <summary>
171 /// Get the inventory item that matches the path name. If there are multiple items then only the first
172 /// is returned.
173 /// </summary>
174 /// <param name="inventoryService"></param>
175 /// <param name="userId"></param>
176 /// <param name="path"></param>
177 /// <returns>null if no item matching the path was found</returns>
178 public static InventoryItemBase GetInventoryItem(IInventoryService inventoryService, UUID userId, string path)
179 {
180 return InventoryArchiveUtils.FindItemByPath(inventoryService, userId, path);
181 }
182
183 /// <summary>
184 /// Get the inventory items that match the path name.
185 /// </summary>
186 /// <param name="inventoryService"></param>
187 /// <param name="userId"></param>
188 /// <param name="path"></param>
189 /// <returns>An empty list if no matching items were found.</returns>
190 public static List<InventoryItemBase> GetInventoryItems(IInventoryService inventoryService, UUID userId, string path)
191 {
192 return InventoryArchiveUtils.FindItemsByPath(inventoryService, userId, path);
193 }
114 } 194 }
115} \ No newline at end of file 195} \ No newline at end of file
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 7f0eaa7..bacd773 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -637,7 +637,7 @@ namespace OpenSim.Tests.Common.Mock
637 { 637 {
638 } 638 }
639 639
640 public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) 640 public virtual void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
641 { 641 {
642 } 642 }
643 643