aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2013-03-15 23:45:32 +0000
committerMelanie2013-03-15 23:45:32 +0000
commitb9146a79220c7e15ff0241fb6216028ddf15bee8 (patch)
tree18e3342a99e448b19a1a5bb29d9579ef9d9bb817 /OpenSim
parentMerge branch 'master' into careminster (diff)
parentChange the table and field names of XAssetService mysql db tables to be capit... (diff)
downloadopensim-SC-b9146a79220c7e15ff0241fb6216028ddf15bee8.zip
opensim-SC-b9146a79220c7e15ff0241fb6216028ddf15bee8.tar.gz
opensim-SC-b9146a79220c7e15ff0241fb6216028ddf15bee8.tar.bz2
opensim-SC-b9146a79220c7e15ff0241fb6216028ddf15bee8.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Framework/Servers/BaseOpenSimServer.cs OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/MySQL/MySQLXAssetData.cs169
-rw-r--r--OpenSim/Data/MySQL/Resources/XAssetStore.migrations30
-rw-r--r--OpenSim/Framework/ILandChannel.cs7
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs2
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs20
-rw-r--r--OpenSim/Region/Application/OpenSim.cs1
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs51
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs41
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs2
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs220
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs44
-rw-r--r--OpenSim/Server/Base/ServerUtils.cs20
-rw-r--r--OpenSim/Server/Base/ServicesServerBase.cs5
-rw-r--r--OpenSim/Server/ServerMain.cs2
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs32
-rw-r--r--OpenSim/Services/AssetService/XAssetService.cs63
-rw-r--r--OpenSim/Services/AssetService/XAssetServiceBase.cs47
-rw-r--r--OpenSim/Tests/Common/Mock/TestLandChannel.cs5
23 files changed, 472 insertions, 339 deletions
diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs
index d561c89..15ac921 100644
--- a/OpenSim/Data/MySQL/MySQLXAssetData.cs
+++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs
@@ -50,6 +50,11 @@ namespace OpenSim.Data.MySQL
50 get { return GetType().Assembly; } 50 get { return GetType().Assembly; }
51 } 51 }
52 52
53 /// <summary>
54 /// Number of days that must pass before we update the access time on an asset when it has been fetched.
55 /// </summary>
56 private const int DaysBetweenAccessTimeUpdates = 30;
57
53 private bool m_enableCompression = false; 58 private bool m_enableCompression = false;
54 private string m_connectionString; 59 private string m_connectionString;
55 private object m_dbLock = new object(); 60 private object m_dbLock = new object();
@@ -133,10 +138,10 @@ namespace OpenSim.Data.MySQL
133 dbcon.Open(); 138 dbcon.Open();
134 139
135 using (MySqlCommand cmd = new MySqlCommand( 140 using (MySqlCommand cmd = new MySqlCommand(
136 "SELECT name, description, asset_type, local, temporary, asset_flags, creator_id, data FROM xassetsmeta JOIN xassetsdata ON xassetsmeta.hash = xassetsdata.hash WHERE id=?id", 141 "SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID",
137 dbcon)) 142 dbcon))
138 { 143 {
139 cmd.Parameters.AddWithValue("?id", assetID.ToString()); 144 cmd.Parameters.AddWithValue("?ID", assetID.ToString());
140 145
141 try 146 try
142 { 147 {
@@ -144,18 +149,18 @@ namespace OpenSim.Data.MySQL
144 { 149 {
145 if (dbReader.Read()) 150 if (dbReader.Read())
146 { 151 {
147 asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["asset_type"], dbReader["creator_id"].ToString()); 152 asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
148 asset.Data = (byte[])dbReader["data"]; 153 asset.Data = (byte[])dbReader["Data"];
149 asset.Description = (string)dbReader["description"]; 154 asset.Description = (string)dbReader["Description"];
150 155
151 string local = dbReader["local"].ToString(); 156 string local = dbReader["Local"].ToString();
152 if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) 157 if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
153 asset.Local = true; 158 asset.Local = true;
154 else 159 else
155 asset.Local = false; 160 asset.Local = false;
156 161
157 asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); 162 asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
158 asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); 163 asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
159 164
160 if (m_enableCompression) 165 if (m_enableCompression)
161 { 166 {
@@ -171,12 +176,14 @@ namespace OpenSim.Data.MySQL
171 // asset.ID, asset.Name, asset.Data.Length, compressedLength); 176 // asset.ID, asset.Name, asset.Data.Length, compressedLength);
172 } 177 }
173 } 178 }
179
180 UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
174 } 181 }
175 } 182 }
176 } 183 }
177 catch (Exception e) 184 catch (Exception e)
178 { 185 {
179 m_log.Error("[MYSQL XASSET DATA]: MySql failure fetching asset " + assetID + ": " + e.Message); 186 m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
180 } 187 }
181 } 188 }
182 } 189 }
@@ -242,23 +249,23 @@ namespace OpenSim.Data.MySQL
242 { 249 {
243 using (MySqlCommand cmd = 250 using (MySqlCommand cmd =
244 new MySqlCommand( 251 new MySqlCommand(
245 "replace INTO xassetsmeta(id, hash, name, description, asset_type, local, temporary, create_time, access_time, asset_flags, creator_id)" + 252 "replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" +
246 "VALUES(?id, ?hash, ?name, ?description, ?asset_type, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?creator_id)", 253 "VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)",
247 dbcon)) 254 dbcon))
248 { 255 {
249 // create unix epoch time 256 // create unix epoch time
250 int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); 257 int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
251 cmd.Parameters.AddWithValue("?id", asset.ID); 258 cmd.Parameters.AddWithValue("?ID", asset.ID);
252 cmd.Parameters.AddWithValue("?hash", hash); 259 cmd.Parameters.AddWithValue("?Hash", hash);
253 cmd.Parameters.AddWithValue("?name", assetName); 260 cmd.Parameters.AddWithValue("?Name", assetName);
254 cmd.Parameters.AddWithValue("?description", assetDescription); 261 cmd.Parameters.AddWithValue("?Description", assetDescription);
255 cmd.Parameters.AddWithValue("?asset_type", asset.Type); 262 cmd.Parameters.AddWithValue("?AssetType", asset.Type);
256 cmd.Parameters.AddWithValue("?local", asset.Local); 263 cmd.Parameters.AddWithValue("?Local", asset.Local);
257 cmd.Parameters.AddWithValue("?temporary", asset.Temporary); 264 cmd.Parameters.AddWithValue("?Temporary", asset.Temporary);
258 cmd.Parameters.AddWithValue("?create_time", now); 265 cmd.Parameters.AddWithValue("?CreateTime", now);
259 cmd.Parameters.AddWithValue("?access_time", now); 266 cmd.Parameters.AddWithValue("?AccessTime", now);
260 cmd.Parameters.AddWithValue("?creator_id", asset.Metadata.CreatorID); 267 cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
261 cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); 268 cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags);
262 cmd.ExecuteNonQuery(); 269 cmd.ExecuteNonQuery();
263 } 270 }
264 } 271 }
@@ -278,11 +285,11 @@ namespace OpenSim.Data.MySQL
278 { 285 {
279 using (MySqlCommand cmd = 286 using (MySqlCommand cmd =
280 new MySqlCommand( 287 new MySqlCommand(
281 "INSERT INTO xassetsdata(hash, data) VALUES(?hash, ?data)", 288 "INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)",
282 dbcon)) 289 dbcon))
283 { 290 {
284 cmd.Parameters.AddWithValue("?hash", hash); 291 cmd.Parameters.AddWithValue("?Hash", hash);
285 cmd.Parameters.AddWithValue("?data", asset.Data); 292 cmd.Parameters.AddWithValue("?Data", asset.Data);
286 cmd.ExecuteNonQuery(); 293 cmd.ExecuteNonQuery();
287 } 294 }
288 } 295 }
@@ -303,41 +310,49 @@ namespace OpenSim.Data.MySQL
303 } 310 }
304 } 311 }
305 312
306// private void UpdateAccessTime(AssetBase asset) 313 /// <summary>
307// { 314 /// Updates the access time of the asset if it was accessed above a given threshhold amount of time.
308// lock (m_dbLock) 315 /// </summary>
309// { 316 /// <remarks>
310// using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 317 /// This gives us some insight into assets which haven't ben accessed for a long period. This is only done
311// { 318 /// over the threshold time to avoid excessive database writes as assets are fetched.
312// dbcon.Open(); 319 /// </remarks>
313// MySqlCommand cmd = 320 /// <param name='asset'></param>
314// new MySqlCommand("update assets set access_time=?access_time where id=?id", 321 /// <param name='accessTime'></param>
315// dbcon); 322 private void UpdateAccessTime(AssetMetadata assetMetadata, int accessTime)
316// 323 {
317// // need to ensure we dispose 324 DateTime now = DateTime.UtcNow;
318// try 325
319// { 326 if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
320// using (cmd) 327 return;
321// { 328
322// // create unix epoch time 329 lock (m_dbLock)
323// int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); 330 {
324// cmd.Parameters.AddWithValue("?id", asset.ID); 331 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
325// cmd.Parameters.AddWithValue("?access_time", now); 332 {
326// cmd.ExecuteNonQuery(); 333 dbcon.Open();
327// cmd.Dispose(); 334 MySqlCommand cmd =
328// } 335 new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon);
329// } 336
330// catch (Exception e) 337 try
331// { 338 {
332// m_log.ErrorFormat( 339 using (cmd)
333// "[ASSETS DB]: " + 340 {
334// "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString() 341 // create unix epoch time
335// + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); 342 cmd.Parameters.AddWithValue("?ID", assetMetadata.ID);
336// } 343 cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now));
337// } 344 cmd.ExecuteNonQuery();
338// } 345 }
339// 346 }
340// } 347 catch (Exception e)
348 {
349 m_log.ErrorFormat(
350 "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
351 assetMetadata.ID, assetMetadata.Name);
352 }
353 }
354 }
355 }
341 356
342 /// <summary> 357 /// <summary>
343 /// We assume we already have the m_dbLock. 358 /// We assume we already have the m_dbLock.
@@ -353,9 +368,9 @@ namespace OpenSim.Data.MySQL
353 368
354 bool exists = false; 369 bool exists = false;
355 370
356 using (MySqlCommand cmd = new MySqlCommand("SELECT hash FROM xassetsdata WHERE hash=?hash", dbcon)) 371 using (MySqlCommand cmd = new MySqlCommand("SELECT Hash FROM XAssetsData WHERE Hash=?Hash", dbcon))
357 { 372 {
358 cmd.Parameters.AddWithValue("?hash", hash); 373 cmd.Parameters.AddWithValue("?Hash", hash);
359 374
360 try 375 try
361 { 376 {
@@ -395,9 +410,9 @@ namespace OpenSim.Data.MySQL
395 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 410 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
396 { 411 {
397 dbcon.Open(); 412 dbcon.Open();
398 using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM xassetsmeta WHERE id=?id", dbcon)) 413 using (MySqlCommand cmd = new MySqlCommand("SELECT ID FROM XAssetsMeta WHERE ID=?ID", dbcon))
399 { 414 {
400 cmd.Parameters.AddWithValue("?id", uuid.ToString()); 415 cmd.Parameters.AddWithValue("?ID", uuid.ToString());
401 416
402 try 417 try
403 { 418 {
@@ -412,8 +427,7 @@ namespace OpenSim.Data.MySQL
412 } 427 }
413 catch (Exception e) 428 catch (Exception e)
414 { 429 {
415 m_log.ErrorFormat( 430 m_log.Error(string.Format("[XASSETS DB]: MySql failure fetching asset {0}", uuid), e);
416 "[XASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
417 } 431 }
418 } 432 }
419 } 433 }
@@ -422,6 +436,7 @@ namespace OpenSim.Data.MySQL
422 return assetExists; 436 return assetExists;
423 } 437 }
424 438
439
425 /// <summary> 440 /// <summary>
426 /// Returns a list of AssetMetadata objects. The list is a subset of 441 /// Returns a list of AssetMetadata objects. The list is a subset of
427 /// the entire data set offset by <paramref name="start" /> containing 442 /// the entire data set offset by <paramref name="start" /> containing
@@ -439,7 +454,7 @@ namespace OpenSim.Data.MySQL
439 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 454 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
440 { 455 {
441 dbcon.Open(); 456 dbcon.Open();
442 MySqlCommand cmd = new MySqlCommand("SELECT name,description,asset_type,temporary,id,asset_flags,creator_id FROM xassetsmeta LIMIT ?start, ?count", dbcon); 457 MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon);
443 cmd.Parameters.AddWithValue("?start", start); 458 cmd.Parameters.AddWithValue("?start", start);
444 cmd.Parameters.AddWithValue("?count", count); 459 cmd.Parameters.AddWithValue("?count", count);
445 460
@@ -450,17 +465,19 @@ namespace OpenSim.Data.MySQL
450 while (dbReader.Read()) 465 while (dbReader.Read())
451 { 466 {
452 AssetMetadata metadata = new AssetMetadata(); 467 AssetMetadata metadata = new AssetMetadata();
453 metadata.Name = (string)dbReader["name"]; 468 metadata.Name = (string)dbReader["Name"];
454 metadata.Description = (string)dbReader["description"]; 469 metadata.Description = (string)dbReader["Description"];
455 metadata.Type = (sbyte)dbReader["asset_type"]; 470 metadata.Type = (sbyte)dbReader["AssetType"];
456 metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. 471 metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
457 metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); 472 metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
458 metadata.FullID = DBGuid.FromDB(dbReader["id"]); 473 metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
459 metadata.CreatorID = dbReader["creator_id"].ToString(); 474 metadata.CreatorID = dbReader["CreatorID"].ToString();
460 475
461 // We'll ignore this for now - it appears unused! 476 // We'll ignore this for now - it appears unused!
462// metadata.SHA1 = dbReader["hash"]); 477// metadata.SHA1 = dbReader["hash"]);
463 478
479 UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
480
464 retList.Add(metadata); 481 retList.Add(metadata);
465 } 482 }
466 } 483 }
@@ -485,9 +502,9 @@ namespace OpenSim.Data.MySQL
485 { 502 {
486 dbcon.Open(); 503 dbcon.Open();
487 504
488 using (MySqlCommand cmd = new MySqlCommand("delete from xassetsmeta where id=?id", dbcon)) 505 using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon))
489 { 506 {
490 cmd.Parameters.AddWithValue("?id", id); 507 cmd.Parameters.AddWithValue("?ID", id);
491 cmd.ExecuteNonQuery(); 508 cmd.ExecuteNonQuery();
492 } 509 }
493 510
diff --git a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations
index d3cca5e..0c49d0d 100644
--- a/OpenSim/Data/MySQL/Resources/XAssetStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/XAssetStore.migrations
@@ -3,24 +3,24 @@
3 3
4BEGIN; 4BEGIN;
5 5
6CREATE TABLE `xassetsmeta` ( 6CREATE TABLE `XAssetsMeta` (
7 `id` char(36) NOT NULL, 7 `ID` char(36) NOT NULL,
8 `hash` binary(32) NOT NULL, 8 `Hash` binary(32) NOT NULL,
9 `name` varchar(64) NOT NULL, 9 `Name` varchar(64) NOT NULL,
10 `description` varchar(64) NOT NULL, 10 `Description` varchar(64) NOT NULL,
11 `asset_type` tinyint(4) NOT NULL, 11 `AssetType` tinyint(4) NOT NULL,
12 `local` tinyint(1) NOT NULL, 12 `Local` tinyint(1) NOT NULL,
13 `temporary` tinyint(1) NOT NULL, 13 `Temporary` tinyint(1) NOT NULL,
14 `create_time` int(11) NOT NULL, 14 `CreateTime` int(11) NOT NULL,
15 `access_time` int(11) NOT NULL, 15 `AccessTime` int(11) NOT NULL,
16 `asset_flags` int(11) NOT NULL, 16 `AssetFlags` int(11) NOT NULL,
17 `creator_id` varchar(128) NOT NULL, 17 `CreatorID` varchar(128) NOT NULL,
18 PRIMARY KEY (`id`) 18 PRIMARY KEY (`id`)
19) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1'; 19) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
20 20
21CREATE TABLE `xassetsdata` ( 21CREATE TABLE `XAssetsData` (
22 `hash` binary(32) NOT NULL, 22 `Hash` binary(32) NOT NULL,
23 `data` longblob NOT NULL, 23 `Data` longblob NOT NULL,
24 PRIMARY KEY (`hash`) 24 PRIMARY KEY (`hash`)
25) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1'; 25) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
26 26
diff --git a/OpenSim/Framework/ILandChannel.cs b/OpenSim/Framework/ILandChannel.cs
index 869d4c8..c46c03c 100644
--- a/OpenSim/Framework/ILandChannel.cs
+++ b/OpenSim/Framework/ILandChannel.cs
@@ -56,6 +56,13 @@ namespace OpenSim.Region.Framework.Interfaces
56 ILandObject GetLandObject(float x, float y); 56 ILandObject GetLandObject(float x, float y);
57 57
58 /// <summary> 58 /// <summary>
59 /// Get the parcel at the specified point
60 /// </summary>
61 /// <param name="position">Vector where x and y components are between 0 and 256. z component is ignored.</param>
62 /// <returns>Land object at the point supplied</returns>
63 ILandObject GetLandObject(Vector3 position);
64
65 /// <summary>
59 /// Get the parcels near the specified point 66 /// Get the parcels near the specified point
60 /// </summary> 67 /// </summary>
61 /// <param name="position"></param> 68 /// <param name="position"></param>
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index cb47cbf..6c04c69 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -189,4 +189,4 @@ namespace OpenSim.Framework.Servers
189 } 189 }
190 } 190 }
191 } 191 }
192} \ No newline at end of file 192}
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index 65ccd10..1ff8aca 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -113,6 +113,26 @@ namespace OpenSim.Framework.Servers
113 } 113 }
114 } 114 }
115 115
116 /// <summary>
117 /// Log information about the circumstances in which we're running (OpenSimulator version number, CLR details,
118 /// etc.).
119 /// </summary>
120 public void LogEnvironmentInformation()
121 {
122 // FIXME: This should be done down in ServerBase but we need to sort out and refactor the log4net
123 // XmlConfigurator calls first accross servers.
124 m_log.InfoFormat("[SERVER BASE]: Starting in {0}", m_startupDirectory);
125
126 m_log.InfoFormat("[SERVER BASE]: OpenSimulator version: {0}", m_version);
127
128 // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
129 // the clr version number doesn't match the project version number under Mono.
130 //m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
131 m_log.InfoFormat(
132 "[SERVER BASE]: Operating system version: {0}, .NET platform {1}, {2}-bit",
133 Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
134 }
135
116 public void RegisterCommonAppenders(IConfig startupConfig) 136 public void RegisterCommonAppenders(IConfig startupConfig)
117 { 137 {
118 ILoggerRepository repository = LogManager.GetRepository(); 138 ILoggerRepository repository = LogManager.GetRepository();
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index a5b9443..a7e7d03 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -159,6 +159,7 @@ namespace OpenSim
159 159
160 MainConsole.Instance = m_console; 160 MainConsole.Instance = m_console;
161 161
162 LogEnvironmentInformation();
162 RegisterCommonAppenders(Config.Configs["Startup"]); 163 RegisterCommonAppenders(Config.Configs["Startup"]);
163 RegisterConsoleCommands(); 164 RegisterConsoleCommands();
164 165
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 7497d88..7361f50 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -138,10 +138,6 @@ namespace OpenSim
138 /// <param name="configSource"></param> 138 /// <param name="configSource"></param>
139 public OpenSimBase(IConfigSource configSource) : base() 139 public OpenSimBase(IConfigSource configSource) : base()
140 { 140 {
141 // FIXME: This should be done down in ServerBase but we need to sort out and refactor the log4net
142 // XmlConfigurator calls first accross servers.
143 m_log.InfoFormat("[SERVER BASE]: Starting in {0}", m_startupDirectory);
144
145 LoadConfigSettings(configSource); 141 LoadConfigSettings(configSource);
146 } 142 }
147 143
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d49f1f7..e07ce4c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -281,25 +281,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
281 m_shouldCollectStats = false; 281 m_shouldCollectStats = false;
282 if (config != null) 282 if (config != null)
283 { 283 {
284 if (config.Contains("enabled") && config.GetBoolean("enabled")) 284 m_shouldCollectStats = config.GetBoolean("Enabled", false);
285 { 285 binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("packet_headers_period_seconds", 300));
286 if (config.Contains("collect_packet_headers")) 286 binStatsDir = config.GetString("stats_dir", ".");
287 m_shouldCollectStats = config.GetBoolean("collect_packet_headers"); 287 m_aggregatedBWStats = config.GetBoolean("aggregatedBWStats", false);
288 if (config.Contains("packet_headers_period_seconds")) 288 }
289 { 289 #endregion BinaryStats
290 binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds"));
291 }
292 if (config.Contains("stats_dir"))
293 {
294 binStatsDir = config.GetString("stats_dir");
295 }
296 }
297 else
298 {
299 m_shouldCollectStats = false;
300 }
301 }
302 #endregion BinaryStats
303 290
304 m_throttle = new TokenBucket(null, sceneThrottleBps); 291 m_throttle = new TokenBucket(null, sceneThrottleBps);
305 ThrottleRates = new ThrottleRates(configSource); 292 ThrottleRates = new ThrottleRates(configSource);
@@ -1309,8 +1296,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1309 static object binStatsLogLock = new object(); 1296 static object binStatsLogLock = new object();
1310 static string binStatsDir = ""; 1297 static string binStatsDir = "";
1311 1298
1299 //for Aggregated In/Out BW logging
1300 static bool m_aggregatedBWStats = false;
1301 static long m_aggregatedBytesIn = 0;
1302 static long m_aggregatedByestOut = 0;
1303 static object aggBWStatsLock = new object();
1304
1305 public static long AggregatedLLUDPBytesIn
1306 {
1307 get { return m_aggregatedBytesIn; }
1308 }
1309 public static long AggregatedLLUDPBytesOut
1310 {
1311 get {return m_aggregatedByestOut;}
1312 }
1313
1312 public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) 1314 public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size)
1313 { 1315 {
1316 if (m_aggregatedBWStats)
1317 {
1318 lock (aggBWStatsLock)
1319 {
1320 if (incoming)
1321 m_aggregatedBytesIn += size;
1322 else
1323 m_aggregatedByestOut += size;
1324 }
1325 }
1326
1314 if (!m_shouldCollectStats) return; 1327 if (!m_shouldCollectStats) return;
1315 1328
1316 // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size 1329 // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
index f874495..1f1568f 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -39,7 +39,7 @@ using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41 41
42namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule 42namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
43{ 43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
45 public class DAExampleModule : INonSharedRegionModule 45 public class DAExampleModule : INonSharedRegionModule
@@ -48,6 +48,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
48 48
49 private static readonly bool ENABLED = false; // enable for testing 49 private static readonly bool ENABLED = false; // enable for testing
50 50
51 public const string DANamespace = "DAExample Module";
52
51 protected Scene m_scene; 53 protected Scene m_scene;
52 protected IDialogModule m_dialogMod; 54 protected IDialogModule m_dialogMod;
53 55
@@ -89,7 +91,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
89 if (sop == null) 91 if (sop == null)
90 return true; 92 return true;
91 93
92 if (!sop.DynAttrs.TryGetValue(Name, out attrs)) 94 if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs))
93 attrs = new OSDMap(); 95 attrs = new OSDMap();
94 96
95 OSDInteger newValue; 97 OSDInteger newValue;
@@ -104,8 +106,10 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
104 106
105 attrs["moves"] = newValue; 107 attrs["moves"] = newValue;
106 108
107 sop.DynAttrs[Name] = attrs; 109 sop.DynAttrs[DANamespace] = attrs;
108 } 110 }
111
112 sop.ParentGroup.HasGroupChanged = true;
109 113
110 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); 114 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue));
111 115
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
index 71bb3f0..650aa35 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -36,6 +36,7 @@ using OpenMetaverse.Packets;
36using OpenMetaverse.StructuredData; 36using OpenMetaverse.StructuredData;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Region.Framework; 38using OpenSim.Region.Framework;
39using OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule;
39using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
41 42
@@ -50,9 +51,14 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
50 public class MyObject 51 public class MyObject
51 { 52 {
52 public int Moves { get; set; } 53 public int Moves { get; set; }
54
55 public MyObject(int moves)
56 {
57 Moves = moves;
58 }
53 } 59 }
54 60
55 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 62
57 private static readonly bool ENABLED = false; // enable for testing 63 private static readonly bool ENABLED = false; // enable for testing
58 64
@@ -92,7 +98,23 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
92 98
93 private void OnObjectAddedToScene(SceneObjectGroup so) 99 private void OnObjectAddedToScene(SceneObjectGroup so)
94 { 100 {
95 so.RootPart.DynObjs.Add(Name, new MyObject()); 101 SceneObjectPart rootPart = so.RootPart;
102
103 OSDMap attrs;
104
105 int movesSoFar = 0;
106
107// Console.WriteLine("Here for {0}", so.Name);
108
109 if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs))
110 {
111 movesSoFar = attrs["moves"].AsInteger();
112
113 m_log.DebugFormat(
114 "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name);
115 }
116
117 rootPart.DynObjs.Add(Name, new MyObject(movesSoFar));
96 } 118 }
97 119
98 private bool OnSceneGroupMove(UUID groupId, Vector3 delta) 120 private bool OnSceneGroupMove(UUID groupId, Vector3 delta)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 7fc358d..73c592d 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -95,6 +95,11 @@ namespace OpenSim.Region.CoreModules.World.Land
95 return null; 95 return null;
96 } 96 }
97 97
98 public ILandObject GetLandObject(Vector3 position)
99 {
100 return GetLandObject(position.X, position.Y);
101 }
102
98 public ILandObject GetLandObject(int x, int y) 103 public ILandObject GetLandObject(int x, int y)
99 { 104 {
100 if (m_landManagementModule != null) 105 if (m_landManagementModule != null)
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
index a3d2436..6e74ce0 100644
--- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
+++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
@@ -140,9 +140,12 @@ public class ServerStats : ISharedRegionModule
140 } 140 }
141 #endregion ISharedRegionModule 141 #endregion ISharedRegionModule
142 142
143 private void MakeStat(string pName, string pUnit, string pContainer, Action<Stat> act) 143 private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act)
144 { 144 {
145 Stat stat = new Stat(pName, pName, "", pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info); 145 string desc = pDesc;
146 if (desc == null)
147 desc = pName;
148 Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info);
146 StatsManager.RegisterStat(stat); 149 StatsManager.RegisterStat(stat);
147 RegisteredStats.Add(pName, stat); 150 RegisteredStats.Add(pName, stat);
148 } 151 }
@@ -166,16 +169,16 @@ public class ServerStats : ISharedRegionModule
166 StatsManager.RegisterStat(tempStat); 169 StatsManager.RegisterStat(tempStat);
167 RegisteredStats.Add(tempName, tempStat); 170 RegisteredStats.Add(tempName, tempStat);
168 171
169 MakeStat("TotalProcessorTime", "sec", ContainerProcessor, 172 MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
170 (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); 173 (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
171 174
172 MakeStat("UserProcessorTime", "sec", ContainerProcessor, 175 MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
173 (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); 176 (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
174 177
175 MakeStat("PrivilegedProcessorTime", "sec", ContainerProcessor, 178 MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
176 (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); 179 (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
177 180
178 MakeStat("Threads", "threads", ContainerProcessor, 181 MakeStat("Threads", null, "threads", ContainerProcessor,
179 (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); 182 (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
180 } 183 }
181 catch (Exception e) 184 catch (Exception e)
@@ -196,8 +199,10 @@ public class ServerStats : ISharedRegionModule
196 string nicInterfaceType = nic.NetworkInterfaceType.ToString(); 199 string nicInterfaceType = nic.NetworkInterfaceType.ToString();
197 if (!okInterfaceTypes.Contains(nicInterfaceType)) 200 if (!okInterfaceTypes.Contains(nicInterfaceType))
198 { 201 {
199 m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'. To include, add to [Monitoring]NetworkInterfaceTypes='Ethernet,Loopback'", 202 m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.",
200 LogHeader, nic.Name, nicInterfaceType); 203 LogHeader, nic.Name, nicInterfaceType);
204 m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}",
205 LogHeader, NetworkInterfaceTypes);
201 continue; 206 continue;
202 } 207 }
203 208
@@ -206,14 +211,15 @@ public class ServerStats : ISharedRegionModule
206 IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); 211 IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
207 if (nicStats != null) 212 if (nicStats != null)
208 { 213 {
209 MakeStat("BytesRcvd/" + nic.Name, "KB", ContainerNetwork, 214 MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork,
210 (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }); 215 (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
211 MakeStat("BytesSent/" + nic.Name, "KB", ContainerNetwork, 216 MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork,
212 (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }); 217 (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
213 MakeStat("TotalBytes/" + nic.Name, "KB", ContainerNetwork, 218 MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork,
214 (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }); 219 (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
215 } 220 }
216 } 221 }
222 // TODO: add IPv6 (it may actually happen someday)
217 } 223 }
218 } 224 }
219 catch (Exception e) 225 catch (Exception e)
@@ -221,13 +227,13 @@ public class ServerStats : ISharedRegionModule
221 m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); 227 m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
222 } 228 }
223 229
224 MakeStat("ProcessMemory", "MB", ContainerMemory, 230 MakeStat("ProcessMemory", null, "MB", ContainerMemory,
225 (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }); 231 (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; });
226 MakeStat("ObjectMemory", "MB", ContainerMemory, 232 MakeStat("ObjectMemory", null, "MB", ContainerMemory,
227 (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }); 233 (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; });
228 MakeStat("LastMemoryChurn", "MB/sec", ContainerMemory, 234 MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory,
229 (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }); 235 (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); });
230 MakeStat("AverageMemoryChurn", "MB/sec", ContainerMemory, 236 MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory,
231 (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }); 237 (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); });
232 } 238 }
233 239
@@ -263,6 +269,8 @@ public class ServerStats : ISharedRegionModule
263 } 269 }
264 } 270 }
265 271
272 // Lookup the nic that goes with this stat and set the value by using a fetch action.
273 // Not sure about closure with delegates inside delegates.
266 private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat); 274 private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat);
267 private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor) 275 private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor)
268 { 276 {
@@ -275,7 +283,10 @@ public class ServerStats : ISharedRegionModule
275 { 283 {
276 IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics(); 284 IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics();
277 if (intrStats != null) 285 if (intrStats != null)
278 stat.Value = Math.Round(getter(intrStats) / factor, 3); 286 {
287 double newVal = Math.Round(getter(intrStats) / factor, 3);
288 stat.Value = newVal;
289 }
279 break; 290 break;
280 } 291 }
281 } 292 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 235cefc..d347159 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -1335,7 +1335,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1335 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG 1335 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
1336 vertContributionV /= m_verticalAttractionTimescale; 1336 vertContributionV /= m_verticalAttractionTimescale;
1337 1337
1338 VehicleRotationalVelocity += vertContributionV * VehicleOrientation; 1338 VehicleRotationalVelocity += vertContributionV;
1339 1339
1340 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", 1340 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
1341 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, 1341 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
index a133e51..b4abc1d 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
@@ -68,6 +68,11 @@ public class RegionCombinerLargeLandChannel : ILandChannel
68 RootRegionLandChannel.Clear(setupDefaultParcel); 68 RootRegionLandChannel.Clear(setupDefaultParcel);
69 } 69 }
70 70
71 public ILandObject GetLandObject(Vector3 position)
72 {
73 return GetLandObject(position.X, position.Y);
74 }
75
71 public ILandObject GetLandObject(int x, int y) 76 public ILandObject GetLandObject(int x, int y)
72 { 77 {
73 //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y); 78 //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d634805..1fbfc52 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -371,6 +371,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
371 } 371 }
372 } 372 }
373 373
374 /// <summary>
375 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
376 /// </summary>
377 /// <remarks>
378 /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then
379 /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset.
380 /// The ScenePresences receive linknums in the order in which they sat.
381 /// </remarks>
382 /// <returns>
383 /// The link entity. null if not found.
384 /// </returns>
385 /// <param name='linknum'>
386 /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4).
387 /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned.
388 /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any
389 /// positive integer is given in this case then null is returned.
390 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
391 /// of entities, then the entity which corresponds to that linknum is returned.
392 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
393 /// null is returned.
394 /// </param>
395 public ISceneEntity GetLinkEntity(int linknum)
396 {
397 if (linknum < 0)
398 {
399 if (linknum == ScriptBaseClass.LINK_THIS)
400 return m_host;
401 else
402 return null;
403 }
404
405 int actualPrimCount = m_host.ParentGroup.PrimCount;
406 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
407 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
408
409 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
410 // prim that has any avatars sat upon it (in which case the root prim is link 1).
411 if (linknum == 0)
412 {
413 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
414 return m_host;
415
416 return null;
417 }
418 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
419 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
420 else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
421 {
422 if (sittingAvatarIds.Count > 0)
423 return m_host.ParentGroup.RootPart;
424 else
425 return null;
426 }
427 else if (linknum <= adjustedPrimCount)
428 {
429 if (linknum <= actualPrimCount)
430 {
431 return m_host.ParentGroup.GetLinkNumPart(linknum);
432 }
433 else
434 {
435 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
436 if (sp != null)
437 return sp;
438 else
439 return null;
440 }
441 }
442 else
443 {
444 return null;
445 }
446 }
447
374 public List<SceneObjectPart> GetLinkParts(int linkType) 448 public List<SceneObjectPart> GetLinkParts(int linkType)
375 { 449 {
376 return GetLinkParts(m_host, linkType); 450 return GetLinkParts(m_host, linkType);
@@ -4149,55 +4223,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4149 { 4223 {
4150 m_host.AddScriptLPS(1); 4224 m_host.AddScriptLPS(1);
4151 4225
4152 if (linknum < 0) 4226 ISceneEntity entity = GetLinkEntity(linknum);
4153 {
4154 if (linknum == ScriptBaseClass.LINK_THIS)
4155 return m_host.Name;
4156 else
4157 return ScriptBaseClass.NULL_KEY;
4158 }
4159
4160 int actualPrimCount = m_host.ParentGroup.PrimCount;
4161 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
4162 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
4163
4164 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
4165 // prim that has any avatars sat upon it (in which case the root prim is link 1).
4166 if (linknum == 0)
4167 {
4168 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
4169 return m_host.Name;
4170 4227
4171 return ScriptBaseClass.NULL_KEY; 4228 if (entity != null)
4172 } 4229 return entity.Name;
4173 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
4174 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
4175 else if (linknum == 1 && actualPrimCount == 1)
4176 {
4177 if (sittingAvatarIds.Count > 0)
4178 return m_host.ParentGroup.RootPart.Name;
4179 else
4180 return ScriptBaseClass.NULL_KEY;
4181 }
4182 else if (linknum <= adjustedPrimCount)
4183 {
4184 if (linknum <= actualPrimCount)
4185 {
4186 return m_host.ParentGroup.GetLinkNumPart(linknum).Name;
4187 }
4188 else
4189 {
4190 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
4191 if (sp != null)
4192 return sp.Name;
4193 else
4194 return ScriptBaseClass.NULL_KEY;
4195 }
4196 }
4197 else 4230 else
4198 {
4199 return ScriptBaseClass.NULL_KEY; 4231 return ScriptBaseClass.NULL_KEY;
4200 }
4201 } 4232 }
4202 4233
4203 public LSL_Integer llGetInventoryNumber(int type) 4234 public LSL_Integer llGetInventoryNumber(int type)
@@ -4562,8 +4593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4562 if (presence.UserLevel >= 200) return; 4593 if (presence.UserLevel >= 200) return;
4563 4594
4564 // agent must be over the owners land 4595 // agent must be over the owners land
4565 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4596 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4566 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4567 { 4597 {
4568 if (!World.TeleportClientHome(agentId, presence.ControllingClient)) 4598 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4569 { 4599 {
@@ -4579,6 +4609,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4579 } 4609 }
4580 } 4610 }
4581 } 4611 }
4612
4582 ScriptSleep(5000); 4613 ScriptSleep(5000);
4583 } 4614 }
4584 4615
@@ -4598,10 +4629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4598 if (destination == String.Empty) 4629 if (destination == String.Empty)
4599 destination = World.RegionInfo.RegionName; 4630 destination = World.RegionInfo.RegionName;
4600 4631
4601 Vector3 pos = presence.AbsolutePosition;
4602
4603 // agent must be over the owners land 4632 // agent must be over the owners land
4604 if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) 4633 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4605 { 4634 {
4606 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4635 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4607 } 4636 }
@@ -4631,10 +4660,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4631 // agent must not be a god 4660 // agent must not be a god
4632 if (presence.GodLevel >= 200) return; 4661 if (presence.GodLevel >= 200) return;
4633 4662
4634 Vector3 pos = presence.AbsolutePosition;
4635
4636 // agent must be over the owners land 4663 // agent must be over the owners land
4637 if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID) 4664 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4638 { 4665 {
4639 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4666 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4640 } 4667 }
@@ -4849,7 +4876,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4849 { 4876 {
4850 if (pushrestricted) 4877 if (pushrestricted)
4851 { 4878 {
4852 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4879 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4853 4880
4854 // We didn't find the parcel but region is push restricted so assume it is NOT ok 4881 // We didn't find the parcel but region is push restricted so assume it is NOT ok
4855 if (targetlandObj == null) 4882 if (targetlandObj == null)
@@ -4864,7 +4891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4864 } 4891 }
4865 else 4892 else
4866 { 4893 {
4867 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4894 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4868 if (targetlandObj == null) 4895 if (targetlandObj == null)
4869 { 4896 {
4870 // We didn't find the parcel but region isn't push restricted so assume it's ok 4897 // We didn't find the parcel but region isn't push restricted so assume it's ok
@@ -6146,12 +6173,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6146 } 6173 }
6147 6174
6148 ILandObject land; 6175 ILandObject land;
6149 Vector3 pos;
6150 UUID id = UUID.Zero; 6176 UUID id = UUID.Zero;
6177
6151 if (parcel || parcelOwned) 6178 if (parcel || parcelOwned)
6152 { 6179 {
6153 pos = m_host.ParentGroup.RootPart.GetWorldPosition(); 6180 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
6154 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6155 if (land == null) 6181 if (land == null)
6156 { 6182 {
6157 id = UUID.Zero; 6183 id = UUID.Zero;
@@ -6177,8 +6203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6177 { 6203 {
6178 if (!regionWide) 6204 if (!regionWide)
6179 { 6205 {
6180 pos = ssp.AbsolutePosition; 6206 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
6181 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6182 if (land != null) 6207 if (land != null)
6183 { 6208 {
6184 if (parcelOwned && land.LandData.OwnerID == id || 6209 if (parcelOwned && land.LandData.OwnerID == id ||
@@ -6308,10 +6333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6308 ScenePresence presence = World.GetScenePresence(agentID); 6333 ScenePresence presence = World.GetScenePresence(agentID);
6309 if (presence != null) 6334 if (presence != null)
6310 { 6335 {
6311 Vector3 pos = presence.AbsolutePosition;
6312
6313 // agent must be over the owners land 6336 // agent must be over the owners land
6314 ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y); 6337 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
6315 if (land == null) 6338 if (land == null)
6316 return; 6339 return;
6317 6340
@@ -6340,9 +6363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6340 ScenePresence presence = World.GetScenePresence(key); 6363 ScenePresence presence = World.GetScenePresence(key);
6341 if (presence != null) // object is an avatar 6364 if (presence != null) // object is an avatar
6342 { 6365 {
6343 Vector3 pos = presence.AbsolutePosition; 6366 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
6344
6345 if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID)
6346 return 1; 6367 return 1;
6347 } 6368 }
6348 else // object is not an avatar 6369 else // object is not an avatar
@@ -6351,9 +6372,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6351 6372
6352 if (obj != null) 6373 if (obj != null)
6353 { 6374 {
6354 Vector3 pos = obj.AbsolutePosition; 6375 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
6355
6356 if (m_host.OwnerID == World.LandChannel.GetLandObject(pos.X, pos.Y).LandData.OwnerID)
6357 return 1; 6376 return 1;
6358 } 6377 }
6359 } 6378 }
@@ -6463,10 +6482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6463 // if the land is group owned and the object is group owned by the same group 6482 // if the land is group owned and the object is group owned by the same group
6464 // or 6483 // or
6465 // if the object is owned by a person with estate access. 6484 // if the object is owned by a person with estate access.
6466 6485 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
6467 Vector3 pos = av.AbsolutePosition;
6468
6469 ILandObject parcel = World.LandChannel.GetLandObject(pos.X, pos.Y);
6470 if (parcel != null) 6486 if (parcel != null)
6471 { 6487 {
6472 if (m_host.OwnerID == parcel.LandData.OwnerID || 6488 if (m_host.OwnerID == parcel.LandData.OwnerID ||
@@ -7053,9 +7069,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7053 { 7069 {
7054 m_host.AddScriptLPS(1); 7070 m_host.AddScriptLPS(1);
7055 UUID key; 7071 UUID key;
7056 Vector3 pos = m_host.AbsolutePosition; 7072 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7057 7073
7058 ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y);
7059 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7074 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
7060 { 7075 {
7061 int expires = 0; 7076 int expires = 0;
@@ -8492,8 +8507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8492 { 8507 {
8493 m_host.AddScriptLPS(1); 8508 m_host.AddScriptLPS(1);
8494 8509
8495 Vector3 pos = m_host.AbsolutePosition; 8510 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8496 ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y);
8497 8511
8498 if (land.LandData.OwnerID != m_host.OwnerID) 8512 if (land.LandData.OwnerID != m_host.OwnerID)
8499 return; 8513 return;
@@ -8507,8 +8521,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8507 { 8521 {
8508 m_host.AddScriptLPS(1); 8522 m_host.AddScriptLPS(1);
8509 8523
8510 Vector3 pos = m_host.AbsolutePosition; 8524 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8511 ILandObject land = World.LandChannel.GetLandObject(pos.X, pos.Y);
8512 8525
8513 if (land.LandData.OwnerID != m_host.OwnerID) 8526 if (land.LandData.OwnerID != m_host.OwnerID)
8514 return String.Empty; 8527 return String.Empty;
@@ -8717,8 +8730,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8717 8730
8718 public LSL_Vector llGetGeometricCenter() 8731 public LSL_Vector llGetGeometricCenter()
8719 { 8732 {
8720 Vector3 tmp = m_host.GetGeometricCenter(); 8733 return new LSL_Vector(m_host.GetGeometricCenter());
8721 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
8722 } 8734 }
8723 8735
8724 public LSL_List llGetPrimitiveParams(LSL_List rules) 8736 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8825,9 +8837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8825 break; 8837 break;
8826 8838
8827 case (int)ScriptBaseClass.PRIM_SIZE: 8839 case (int)ScriptBaseClass.PRIM_SIZE:
8828 res.Add(new LSL_Vector(part.Scale.X, 8840 res.Add(new LSL_Vector(part.Scale));
8829 part.Scale.Y,
8830 part.Scale.Z));
8831 break; 8841 break;
8832 8842
8833 case (int)ScriptBaseClass.PRIM_ROTATION: 8843 case (int)ScriptBaseClass.PRIM_ROTATION:
@@ -9188,9 +9198,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9188 case (int)ScriptBaseClass.PRIM_DESC: 9198 case (int)ScriptBaseClass.PRIM_DESC:
9189 res.Add(new LSL_String(part.Description)); 9199 res.Add(new LSL_String(part.Description));
9190 break; 9200 break;
9191 9201 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9192 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9202 res.Add(new LSL_Rotation(part.RotationOffset));
9193 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
9194 break; 9203 break;
9195 9204
9196 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9205 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
@@ -10374,7 +10383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10374 10383
10375 // according to the docs, this command only works if script owner and land owner are the same 10384 // according to the docs, this command only works if script owner and land owner are the same
10376 // lets add estate owners and gods, too, and use the generic permission check. 10385 // lets add estate owners and gods, too, and use the generic permission check.
10377 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10386 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10378 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 10387 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
10379 10388
10380 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 10389 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
@@ -10697,22 +10706,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10697 m_host.AddScriptLPS(1); 10706 m_host.AddScriptLPS(1);
10698 10707
10699 if (m_item.PermsGranter == UUID.Zero) 10708 if (m_item.PermsGranter == UUID.Zero)
10700 return new LSL_Vector(); 10709 return Vector3.Zero;
10701 10710
10702 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10711 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10703 { 10712 {
10704 ShoutError("No permissions to track the camera"); 10713 ShoutError("No permissions to track the camera");
10705 return new LSL_Vector(); 10714 return Vector3.Zero;
10706 } 10715 }
10707 10716
10708// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10717// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10709 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10718 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10710 if (presence != null) 10719 if (presence != null)
10711 { 10720 {
10712 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10721 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
10713 return pos; 10722 return pos;
10714 } 10723 }
10715 return new LSL_Vector(); 10724
10725 return Vector3.Zero;
10716 } 10726 }
10717 10727
10718 public LSL_Rotation llGetCameraRot() 10728 public LSL_Rotation llGetCameraRot()
@@ -10720,22 +10730,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10720 m_host.AddScriptLPS(1); 10730 m_host.AddScriptLPS(1);
10721 10731
10722 if (m_item.PermsGranter == UUID.Zero) 10732 if (m_item.PermsGranter == UUID.Zero)
10723 return new LSL_Rotation(); 10733 return Quaternion.Identity;
10724 10734
10725 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10735 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10726 { 10736 {
10727 ShoutError("No permissions to track the camera"); 10737 ShoutError("No permissions to track the camera");
10728 return new LSL_Rotation(); 10738 return Quaternion.Identity;
10729 } 10739 }
10730 10740
10731// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10741// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10732 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10742 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10733 if (presence != null) 10743 if (presence != null)
10734 { 10744 {
10735 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10745 return new LSL_Rotation(presence.CameraRotation);
10736 } 10746 }
10737 10747
10738 return new LSL_Rotation(); 10748 return Quaternion.Identity;
10739 } 10749 }
10740 10750
10741 /// <summary> 10751 /// <summary>
@@ -10816,7 +10826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10816 { 10826 {
10817 m_host.AddScriptLPS(1); 10827 m_host.AddScriptLPS(1);
10818 UUID key; 10828 UUID key;
10819 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10829 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10820 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10830 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10821 { 10831 {
10822 int expires = 0; 10832 int expires = 0;
@@ -10857,7 +10867,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10857 { 10867 {
10858 m_host.AddScriptLPS(1); 10868 m_host.AddScriptLPS(1);
10859 UUID key; 10869 UUID key;
10860 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10870 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10861 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10871 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10862 { 10872 {
10863 if (UUID.TryParse(avatar, out key)) 10873 if (UUID.TryParse(avatar, out key))
@@ -10884,7 +10894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10884 { 10894 {
10885 m_host.AddScriptLPS(1); 10895 m_host.AddScriptLPS(1);
10886 UUID key; 10896 UUID key;
10887 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10897 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10888 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10898 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10889 { 10899 {
10890 if (UUID.TryParse(avatar, out key)) 10900 if (UUID.TryParse(avatar, out key))
@@ -11250,7 +11260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11250 public void llResetLandBanList() 11260 public void llResetLandBanList()
11251 { 11261 {
11252 m_host.AddScriptLPS(1); 11262 m_host.AddScriptLPS(1);
11253 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11263 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11254 if (land.OwnerID == m_host.OwnerID) 11264 if (land.OwnerID == m_host.OwnerID)
11255 { 11265 {
11256 foreach (LandAccessEntry entry in land.ParcelAccessList) 11266 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11267,7 +11277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11267 public void llResetLandPassList() 11277 public void llResetLandPassList()
11268 { 11278 {
11269 m_host.AddScriptLPS(1); 11279 m_host.AddScriptLPS(1);
11270 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11280 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11271 if (land.OwnerID == m_host.OwnerID) 11281 if (land.OwnerID == m_host.OwnerID)
11272 { 11282 {
11273 foreach (LandAccessEntry entry in land.ParcelAccessList) 11283 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11967,7 +11977,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11967 World.ForEachScenePresence(delegate(ScenePresence sp) 11977 World.ForEachScenePresence(delegate(ScenePresence sp)
11968 { 11978 {
11969 Vector3 ac = sp.AbsolutePosition - rayStart; 11979 Vector3 ac = sp.AbsolutePosition - rayStart;
11970 Vector3 bc = sp.AbsolutePosition - rayEnd; 11980// Vector3 bc = sp.AbsolutePosition - rayEnd;
11971 11981
11972 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11982 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11973 11983
@@ -12057,7 +12067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12057 radius = Math.Abs(maxZ); 12067 radius = Math.Abs(maxZ);
12058 radius = radius*1.413f; 12068 radius = radius*1.413f;
12059 Vector3 ac = group.AbsolutePosition - rayStart; 12069 Vector3 ac = group.AbsolutePosition - rayStart;
12060 Vector3 bc = group.AbsolutePosition - rayEnd; 12070// Vector3 bc = group.AbsolutePosition - rayEnd;
12061 12071
12062 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 12072 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
12063 12073
@@ -12435,7 +12445,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12435 list.Add(new LSL_Integer(linkNum)); 12445 list.Add(new LSL_Integer(linkNum));
12436 12446
12437 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 12447 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
12438 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); 12448 list.Add(new LSL_Vector(result.Normal));
12439 12449
12440 values++; 12450 values++;
12441 if (values >= count) 12451 if (values >= count)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index a214935..234ba34 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -372,7 +372,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
372 //OSSL only may be used if object is in the same group as the parcel 372 //OSSL only may be used if object is in the same group as the parcel
373 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER")) 373 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER"))
374 { 374 {
375 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 375 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
376 376
377 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) 377 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
378 { 378 {
@@ -383,7 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
383 //Only Parcelowners may use the function 383 //Only Parcelowners may use the function
384 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER")) 384 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER"))
385 { 385 {
386 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 386 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
387 387
388 if (land.LandData.OwnerID == ownerID) 388 if (land.LandData.OwnerID == ownerID)
389 { 389 {
@@ -1511,8 +1511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1511 1511
1512 m_host.AddScriptLPS(1); 1512 m_host.AddScriptLPS(1);
1513 1513
1514 ILandObject land 1514 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1515 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1516 1515
1517 if (land.LandData.OwnerID != m_host.OwnerID) 1516 if (land.LandData.OwnerID != m_host.OwnerID)
1518 return; 1517 return;
@@ -1528,8 +1527,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1528 1527
1529 m_host.AddScriptLPS(1); 1528 m_host.AddScriptLPS(1);
1530 1529
1531 ILandObject land 1530 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1532 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1533 1531
1534 if (land.LandData.OwnerID != m_host.OwnerID) 1532 if (land.LandData.OwnerID != m_host.OwnerID)
1535 { 1533 {
@@ -2578,13 +2576,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2578 ScenePresence sp = World.GetScenePresence(npcId); 2576 ScenePresence sp = World.GetScenePresence(npcId);
2579 2577
2580 if (sp != null) 2578 if (sp != null)
2581 { 2579 return new LSL_Vector(sp.AbsolutePosition);
2582 Vector3 pos = sp.AbsolutePosition;
2583 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2584 }
2585 } 2580 }
2586 2581
2587 return new LSL_Vector(0, 0, 0); 2582 return Vector3.Zero;
2588 } 2583 }
2589 2584
2590 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) 2585 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
@@ -2652,7 +2647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2652 return new LSL_Rotation(sp.GetWorldRotation()); 2647 return new LSL_Rotation(sp.GetWorldRotation());
2653 } 2648 }
2654 2649
2655 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2650 return Quaternion.Identity;
2656 } 2651 }
2657 2652
2658 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 2653 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
@@ -3098,20 +3093,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3098 3093
3099 UUID avatarId = new UUID(avatar); 3094 UUID avatarId = new UUID(avatar);
3100 ScenePresence presence = World.GetScenePresence(avatarId); 3095 ScenePresence presence = World.GetScenePresence(avatarId);
3101 Vector3 pos = m_host.GetWorldPosition(); 3096
3102 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.X, (float)pos.Y, (float)pos.Z)); 3097 if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition()))
3103 if (result)
3104 { 3098 {
3105 if (presence != null) 3099 float health = presence.Health;
3106 { 3100 health += (float)healing;
3107 float health = presence.Health; 3101
3108 health += (float)healing; 3102 if (health >= 100)
3109 if (health >= 100) 3103 health = 100;
3110 { 3104
3111 health = 100; 3105 presence.setHealthWithUpdate(health);
3112 }
3113 presence.setHealthWithUpdate(health);
3114 }
3115 } 3106 }
3116 } 3107 }
3117 3108
@@ -3188,8 +3179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3188 if (avatar != null && avatar.UUID != m_host.OwnerID) 3179 if (avatar != null && avatar.UUID != m_host.OwnerID)
3189 { 3180 {
3190 result.Add(new LSL_String(avatar.UUID.ToString())); 3181 result.Add(new LSL_String(avatar.UUID.ToString()));
3191 OpenMetaverse.Vector3 ap = avatar.AbsolutePosition; 3182 result.Add(new LSL_Vector(avatar.AbsolutePosition));
3192 result.Add(new LSL_Vector(ap.X, ap.Y, ap.Z));
3193 result.Add(new LSL_String(avatar.Name)); 3183 result.Add(new LSL_String(avatar.Name));
3194 } 3184 }
3195 }); 3185 });
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index 2e6d279..210a314 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -138,17 +138,17 @@ namespace OpenSim.Server.Base
138 case ExtensionChange.Add: 138 case ExtensionChange.Add:
139 if (a.AddinFile.Contains(Registry.DefaultAddinsFolder)) 139 if (a.AddinFile.Contains(Registry.DefaultAddinsFolder))
140 { 140 {
141 m_log.InfoFormat("[SERVER]: Adding {0} from registry", a.Name); 141 m_log.InfoFormat("[SERVER UTILS]: Adding {0} from registry", a.Name);
142 connector.PluginPath = System.IO.Path.Combine(Registry.DefaultAddinsFolder,a.Name.Replace(',', '.')); } 142 connector.PluginPath = System.IO.Path.Combine(Registry.DefaultAddinsFolder,a.Name.Replace(',', '.')); }
143 else 143 else
144 { 144 {
145 m_log.InfoFormat("[SERVER]: Adding {0} from ./bin", a.Name); 145 m_log.InfoFormat("[SERVER UTILS]: Adding {0} from ./bin", a.Name);
146 connector.PluginPath = a.AddinFile; 146 connector.PluginPath = a.AddinFile;
147 } 147 }
148 LoadPlugin(connector); 148 LoadPlugin(connector);
149 break; 149 break;
150 case ExtensionChange.Remove: 150 case ExtensionChange.Remove:
151 m_log.InfoFormat("[SERVER]: Removing {0}", a.Name); 151 m_log.InfoFormat("[SERVER UTILS]: Removing {0}", a.Name);
152 UnloadPlugin(connector); 152 UnloadPlugin(connector);
153 break; 153 break;
154 } 154 }
@@ -166,13 +166,13 @@ namespace OpenSim.Server.Base
166 } 166 }
167 else 167 else
168 { 168 {
169 m_log.InfoFormat("[SERVER]: {0} Disabled.", connector.ConfigName); 169 m_log.InfoFormat("[SERVER UTILS]: {0} Disabled.", connector.ConfigName);
170 } 170 }
171 } 171 }
172 172
173 private void UnloadPlugin(IRobustConnector connector) 173 private void UnloadPlugin(IRobustConnector connector)
174 { 174 {
175 m_log.InfoFormat("[Server]: Unloading {0}", connector.ConfigName); 175 m_log.InfoFormat("[SERVER UTILS]: Unloading {0}", connector.ConfigName);
176 176
177 connector.Unload(); 177 connector.Unload();
178 } 178 }
@@ -280,7 +280,7 @@ namespace OpenSim.Server.Base
280 { 280 {
281 if (!(e is System.MissingMethodException)) 281 if (!(e is System.MissingMethodException))
282 { 282 {
283 m_log.ErrorFormat("Error loading plugin {0} from {1}. Exception: {2}, {3}", 283 m_log.ErrorFormat("[SERVER UTILS]: Error loading plugin {0} from {1}. Exception: {2}, {3}",
284 interfaceName, 284 interfaceName,
285 dllName, 285 dllName,
286 e.InnerException == null ? e.Message : e.InnerException.Message, 286 e.InnerException == null ? e.Message : e.InnerException.Message,
@@ -298,14 +298,14 @@ namespace OpenSim.Server.Base
298 } 298 }
299 catch (ReflectionTypeLoadException rtle) 299 catch (ReflectionTypeLoadException rtle)
300 { 300 {
301 m_log.Error(string.Format("Error loading plugin from {0}:\n{1}", dllName, 301 m_log.Error(string.Format("[SERVER UTILS]: Error loading plugin from {0}:\n{1}", dllName,
302 String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))), 302 String.Join("\n", Array.ConvertAll(rtle.LoaderExceptions, e => e.ToString()))),
303 rtle); 303 rtle);
304 return null; 304 return null;
305 } 305 }
306 catch (Exception e) 306 catch (Exception e)
307 { 307 {
308 m_log.Error(string.Format("Error loading plugin from {0}", dllName), e); 308 m_log.Error(string.Format("[SERVER UTILS]: Error loading plugin from {0}", dllName), e);
309 return null; 309 return null;
310 } 310 }
311 } 311 }
@@ -517,7 +517,7 @@ namespace OpenSim.Server.Base
517 public static IConfigSource LoadInitialConfig(string url) 517 public static IConfigSource LoadInitialConfig(string url)
518 { 518 {
519 IConfigSource source = new XmlConfigSource(); 519 IConfigSource source = new XmlConfigSource();
520 m_log.InfoFormat("[CONFIG]: {0} is a http:// URI, fetching ...", url); 520 m_log.InfoFormat("[SERVER UTILS]: {0} is a http:// URI, fetching ...", url);
521 521
522 // The ini file path is a http URI 522 // The ini file path is a http URI
523 // Try to read it 523 // Try to read it
@@ -529,7 +529,7 @@ namespace OpenSim.Server.Base
529 } 529 }
530 catch (Exception e) 530 catch (Exception e)
531 { 531 {
532 m_log.FatalFormat("[CONFIG]: Exception reading config from URI {0}\n" + e.ToString(), url); 532 m_log.FatalFormat("[SERVER UTILS]: Exception reading config from URI {0}\n" + e.ToString(), url);
533 Environment.Exit(1); 533 Environment.Exit(1);
534 } 534 }
535 535
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs
index 5aff72a..7c8e6b7 100644
--- a/OpenSim/Server/Base/ServicesServerBase.cs
+++ b/OpenSim/Server/Base/ServicesServerBase.cs
@@ -186,10 +186,7 @@ namespace OpenSim.Server.Base
186 XmlConfigurator.Configure(); 186 XmlConfigurator.Configure();
187 } 187 }
188 188
189 // FIXME: This should be done down in ServerBase but we need to sort out and refactor the log4net 189 LogEnvironmentInformation();
190 // XmlConfigurator calls first accross servers.
191 m_log.InfoFormat("[SERVER BASE]: Starting in {0}", m_startupDirectory);
192
193 RegisterCommonAppenders(startupConfig); 190 RegisterCommonAppenders(startupConfig);
194 191
195 if (startupConfig.GetString("PIDFile", String.Empty) != String.Empty) 192 if (startupConfig.GetString("PIDFile", String.Empty) != String.Empty)
diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs
index 8be69a9..65e9287 100644
--- a/OpenSim/Server/ServerMain.cs
+++ b/OpenSim/Server/ServerMain.cs
@@ -145,7 +145,7 @@ namespace OpenSim.Server
145 } 145 }
146 else 146 else
147 { 147 {
148 m_log.InfoFormat("[SERVER]: Failed to load {0}", conn); 148 m_log.ErrorFormat("[SERVER]: Failed to load {0}", conn);
149 } 149 }
150 } 150 }
151 151
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index f1bffa4..90c30c8 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -123,46 +123,32 @@ namespace OpenSim.Services.AssetService
123 public virtual AssetMetadata GetMetadata(string id) 123 public virtual AssetMetadata GetMetadata(string id)
124 { 124 {
125// m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id); 125// m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id);
126
127 UUID assetID;
128 126
129 if (!UUID.TryParse(id, out assetID)) 127 AssetBase asset = Get(id);
130 return null;
131 128
132 AssetBase asset = m_Database.GetAsset(assetID);
133 if (asset != null) 129 if (asset != null)
134 return asset.Metadata; 130 return asset.Metadata;
135 131 else
136 return null; 132 return null;
137 } 133 }
138 134
139 public virtual byte[] GetData(string id) 135 public virtual byte[] GetData(string id)
140 { 136 {
141// m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id); 137// m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id);
142
143 UUID assetID;
144 138
145 if (!UUID.TryParse(id, out assetID)) 139 AssetBase asset = Get(id);
146 return null;
147 140
148 AssetBase asset = m_Database.GetAsset(assetID); 141 if (asset != null)
149 return asset.Data; 142 return asset.Data;
143 else
144 return null;
150 } 145 }
151 146
152 public virtual bool Get(string id, Object sender, AssetRetrieved handler) 147 public virtual bool Get(string id, Object sender, AssetRetrieved handler)
153 { 148 {
154 //m_log.DebugFormat("[AssetService]: Get asset async {0}", id); 149 //m_log.DebugFormat("[AssetService]: Get asset async {0}", id);
155
156 UUID assetID;
157 150
158 if (!UUID.TryParse(id, out assetID)) 151 handler(id, sender, Get(id));
159 return false;
160
161 AssetBase asset = m_Database.GetAsset(assetID);
162
163 //m_log.DebugFormat("[AssetService]: Got asset {0}", asset);
164
165 handler(id, sender, asset);
166 152
167 return true; 153 return true;
168 } 154 }
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs
index a1d10ed..8a2ca7c 100644
--- a/OpenSim/Services/AssetService/XAssetService.cs
+++ b/OpenSim/Services/AssetService/XAssetService.cs
@@ -39,8 +39,7 @@ using OpenMetaverse;
39namespace OpenSim.Services.AssetService 39namespace OpenSim.Services.AssetService
40{ 40{
41 /// <summary> 41 /// <summary>
42 /// This will be developed into a de-duplicating asset service. 42 /// A de-duplicating asset service.
43 /// XXX: Currently it's a just a copy of the existing AssetService. so please don't attempt to use it.
44 /// </summary> 43 /// </summary>
45 public class XAssetService : XAssetServiceBase, IAssetService 44 public class XAssetService : XAssetServiceBase, IAssetService
46 { 45 {
@@ -48,7 +47,9 @@ namespace OpenSim.Services.AssetService
48 47
49 protected static XAssetService m_RootInstance; 48 protected static XAssetService m_RootInstance;
50 49
51 public XAssetService(IConfigSource config) : base(config) 50 public XAssetService(IConfigSource config) : this(config, "AssetService") {}
51
52 public XAssetService(IConfigSource config, string configName) : base(config, configName)
52 { 53 {
53 if (m_RootInstance == null) 54 if (m_RootInstance == null)
54 { 55 {
@@ -56,22 +57,21 @@ namespace OpenSim.Services.AssetService
56 57
57 if (m_AssetLoader != null) 58 if (m_AssetLoader != null)
58 { 59 {
59 IConfig assetConfig = config.Configs["AssetService"]; 60 IConfig assetConfig = config.Configs[configName];
60 if (assetConfig == null) 61 if (assetConfig == null)
61 throw new Exception("No AssetService configuration"); 62 throw new Exception("No AssetService configuration");
62 63
63 string loaderArgs = assetConfig.GetString("AssetLoaderArgs", 64 string loaderArgs = assetConfig.GetString("AssetLoaderArgs", String.Empty);
64 String.Empty);
65 65
66 bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true); 66 bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true);
67 67
68 if (assetLoaderEnabled) 68 if (assetLoaderEnabled && !HasChainedAssetService)
69 { 69 {
70 m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs); 70 m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs);
71 71
72 m_AssetLoader.ForEachDefaultXmlAsset( 72 m_AssetLoader.ForEachDefaultXmlAsset(
73 loaderArgs, 73 loaderArgs,
74 delegate(AssetBase a) 74 a =>
75 { 75 {
76 AssetBase existingAsset = Get(a.ID); 76 AssetBase existingAsset = Get(a.ID);
77// AssetMetadata existingMetadata = GetMetadata(a.ID); 77// AssetMetadata existingMetadata = GetMetadata(a.ID);
@@ -103,7 +103,23 @@ namespace OpenSim.Services.AssetService
103 103
104 try 104 try
105 { 105 {
106 return m_Database.GetAsset(assetID); 106 AssetBase asset = m_Database.GetAsset(assetID);
107
108 if (asset != null)
109 {
110 return asset;
111 }
112 else if (HasChainedAssetService)
113 {
114 asset = m_ChainedAssetService.Get(id);
115
116 if (asset != null)
117 MigrateFromChainedService(asset);
118
119 return asset;
120 }
121
122 return null;
107 } 123 }
108 catch (Exception e) 124 catch (Exception e)
109 { 125 {
@@ -120,30 +136,25 @@ namespace OpenSim.Services.AssetService
120 public virtual AssetMetadata GetMetadata(string id) 136 public virtual AssetMetadata GetMetadata(string id)
121 { 137 {
122// m_log.DebugFormat("[XASSET SERVICE]: Get asset metadata for {0}", id); 138// m_log.DebugFormat("[XASSET SERVICE]: Get asset metadata for {0}", id);
123
124 UUID assetID;
125 139
126 if (!UUID.TryParse(id, out assetID)) 140 AssetBase asset = Get(id);
127 return null;
128 141
129 AssetBase asset = m_Database.GetAsset(assetID);
130 if (asset != null) 142 if (asset != null)
131 return asset.Metadata; 143 return asset.Metadata;
132 144 else
133 return null; 145 return null;
134 } 146 }
135 147
136 public virtual byte[] GetData(string id) 148 public virtual byte[] GetData(string id)
137 { 149 {
138// m_log.DebugFormat("[XASSET SERVICE]: Get asset data for {0}", id); 150// m_log.DebugFormat("[XASSET SERVICE]: Get asset data for {0}", id);
139 151
140 UUID assetID; 152 AssetBase asset = Get(id);
141 153
142 if (!UUID.TryParse(id, out assetID)) 154 if (asset != null)
155 return asset.Data;
156 else
143 return null; 157 return null;
144
145 AssetBase asset = m_Database.GetAsset(assetID);
146 return asset.Data;
147 } 158 }
148 159
149 public virtual bool Get(string id, Object sender, AssetRetrieved handler) 160 public virtual bool Get(string id, Object sender, AssetRetrieved handler)
@@ -155,7 +166,7 @@ namespace OpenSim.Services.AssetService
155 if (!UUID.TryParse(id, out assetID)) 166 if (!UUID.TryParse(id, out assetID))
156 return false; 167 return false;
157 168
158 AssetBase asset = m_Database.GetAsset(assetID); 169 AssetBase asset = Get(id);
159 170
160 //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset); 171 //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset);
161 172
@@ -194,7 +205,15 @@ namespace OpenSim.Services.AssetService
194 if (!UUID.TryParse(id, out assetID)) 205 if (!UUID.TryParse(id, out assetID))
195 return false; 206 return false;
196 207
208 // Don't bother deleting from a chained asset service. This isn't a big deal since deleting happens
209 // very rarely.
210
197 return m_Database.Delete(id); 211 return m_Database.Delete(id);
198 } 212 }
213
214 private void MigrateFromChainedService(AssetBase asset)
215 {
216 Util.FireAndForget(o => { Store(asset); m_ChainedAssetService.Delete(asset.ID); });
217 }
199 } 218 }
200} \ No newline at end of file 219} \ No newline at end of file
diff --git a/OpenSim/Services/AssetService/XAssetServiceBase.cs b/OpenSim/Services/AssetService/XAssetServiceBase.cs
index 0c5c2c3..c118c9d 100644
--- a/OpenSim/Services/AssetService/XAssetServiceBase.cs
+++ b/OpenSim/Services/AssetService/XAssetServiceBase.cs
@@ -27,9 +27,11 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net;
30using Nini.Config; 31using Nini.Config;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Data; 33using OpenSim.Data;
34using OpenSim.Server.Base;
33using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base; 36using OpenSim.Services.Base;
35 37
@@ -37,10 +39,15 @@ namespace OpenSim.Services.AssetService
37{ 39{
38 public class XAssetServiceBase : ServiceBase 40 public class XAssetServiceBase : ServiceBase
39 { 41 {
40 protected IXAssetDataPlugin m_Database = null; 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 protected IAssetLoader m_AssetLoader = null;
42 43
43 public XAssetServiceBase(IConfigSource config) : base(config) 44 protected IXAssetDataPlugin m_Database;
45 protected IAssetLoader m_AssetLoader;
46 protected IAssetService m_ChainedAssetService;
47
48 protected bool HasChainedAssetService { get { return m_ChainedAssetService != null; } }
49
50 public XAssetServiceBase(IConfigSource config, string configName) : base(config)
44 { 51 {
45 string dllName = String.Empty; 52 string dllName = String.Empty;
46 string connString = String.Empty; 53 string connString = String.Empty;
@@ -48,7 +55,7 @@ namespace OpenSim.Services.AssetService
48 // 55 //
49 // Try reading the [AssetService] section first, if it exists 56 // Try reading the [AssetService] section first, if it exists
50 // 57 //
51 IConfig assetConfig = config.Configs["AssetService"]; 58 IConfig assetConfig = config.Configs[configName];
52 if (assetConfig != null) 59 if (assetConfig != null)
53 { 60 {
54 dllName = assetConfig.GetString("StorageProvider", dllName); 61 dllName = assetConfig.GetString("StorageProvider", dllName);
@@ -77,17 +84,35 @@ namespace OpenSim.Services.AssetService
77 if (m_Database == null) 84 if (m_Database == null)
78 throw new Exception("Could not find a storage interface in the given module"); 85 throw new Exception("Could not find a storage interface in the given module");
79 86
80 m_Database.Initialise(connString); 87 string chainedAssetServiceDesignator = assetConfig.GetString("ChainedServiceModule", null);
88
89 if (chainedAssetServiceDesignator != null)
90 {
91 m_log.InfoFormat(
92 "[XASSET SERVICE BASE]: Loading chained asset service from {0}", chainedAssetServiceDesignator);
81 93
82 string loaderName = assetConfig.GetString("DefaultAssetLoader", 94 Object[] args = new Object[] { config, configName };
83 String.Empty); 95 m_ChainedAssetService = ServerUtils.LoadPlugin<IAssetService>(chainedAssetServiceDesignator, args);
84 96
85 if (loaderName != String.Empty) 97 if (!HasChainedAssetService)
98 throw new Exception(
99 String.Format("Failed to load ChainedAssetService from {0}", chainedAssetServiceDesignator));
100 }
101
102 m_Database.Initialise(connString);
103
104 if (HasChainedAssetService)
86 { 105 {
87 m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName); 106 string loaderName = assetConfig.GetString("DefaultAssetLoader",
107 String.Empty);
108
109 if (loaderName != String.Empty)
110 {
111 m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName);
88 112
89 if (m_AssetLoader == null) 113 if (m_AssetLoader == null)
90 throw new Exception("Asset loader could not be loaded"); 114 throw new Exception("Asset loader could not be loaded");
115 }
91 } 116 }
92 } 117 }
93 } 118 }
diff --git a/OpenSim/Tests/Common/Mock/TestLandChannel.cs b/OpenSim/Tests/Common/Mock/TestLandChannel.cs
index 4b4d52d..3115035 100644
--- a/OpenSim/Tests/Common/Mock/TestLandChannel.cs
+++ b/OpenSim/Tests/Common/Mock/TestLandChannel.cs
@@ -81,6 +81,11 @@ namespace OpenSim.Tests.Common.Mock
81 return obj; 81 return obj;
82 } 82 }
83 83
84 public ILandObject GetLandObject(Vector3 position)
85 {
86 return GetLandObject(position.X, position.Y);
87 }
88
84 public ILandObject GetLandObject(int x, int y) 89 public ILandObject GetLandObject(int x, int y)
85 { 90 {
86 return GetNoLand(); 91 return GetNoLand();