Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

0.7.4.1
Dan Lake 2012-03-27 12:51:58 -07:00
commit 971d32fda3
198 changed files with 6761 additions and 2342 deletions

View File

@ -86,8 +86,10 @@ what it is today.
* Grumly57 * Grumly57
* GuduleLapointe * GuduleLapointe
* Ewe Loon * Ewe Loon
* Fernando Oliveira
* Fly-Man * Fly-Man
* Flyte Xevious * Flyte Xevious
* Garmin Kawaguichi
* Imaze Rhiano * Imaze Rhiano
* Intimidated * Intimidated
* Jeremy Bongio (IBM) * Jeremy Bongio (IBM)
@ -106,6 +108,7 @@ what it is today.
* M.Igarashi * M.Igarashi
* maimedleech * maimedleech
* Mana Janus * Mana Janus
* MarcelEdward
* Mic Bowman * Mic Bowman
* Michelle Argus * Michelle Argus
* Michael Cortez (The Flotsam Project, http://osflotsam.org/) * Michael Cortez (The Flotsam Project, http://osflotsam.org/)
@ -135,6 +138,7 @@ what it is today.
* Ruud Lathorp * Ruud Lathorp
* SachaMagne * SachaMagne
* Salahzar Stenvaag * Salahzar Stenvaag
* satguru p srivastava
* sempuki * sempuki
* SignpostMarv * SignpostMarv
* SpotOn3D * SpotOn3D

View File

@ -26,38 +26,22 @@
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Region.Framework.Scenes.Animation namespace OpenSim.Data
{ {
public class AvatarAnimations /// <summary>
/// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService
/// for now.
/// </summary>
public interface IXAssetDataPlugin : IPlugin
{ {
public Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>(); AssetBase GetAsset(UUID uuid);
public Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>(); void StoreAsset(AssetBase asset);
public Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>(); bool ExistsAsset(UUID uuid);
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
public AvatarAnimations() void Initialise(string connect);
{ bool Delete(string id);
using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
{
XmlDocument doc = new XmlDocument();
doc.Load(reader);
foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
{
if (nod.Attributes["name"] != null)
{
string name = (string)nod.Attributes["name"].Value;
UUID id = (UUID)nod.InnerText;
string animState = (string)nod.Attributes["state"].Value;
AnimsUUID.Add(name, id);
AnimsNames.Add(id, name);
if (animState != "")
AnimStateNames.Add(id, animState);
}
}
}
}
} }
} }

View File

@ -89,5 +89,11 @@ namespace OpenSim.Data.MSSQL
return DoQuery(cmd); return DoQuery(cmd);
} }
} }
public FriendsData[] GetFriends(Guid principalID)
{
return GetFriends(principalID.ToString());
}
} }
} }

View File

@ -813,7 +813,7 @@ namespace OpenSim.Data.MSSQL
{ {
try try
{ {
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection)) using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
{ {
command.Parameters.Add(database.CreateParameter("folderID", folderID)); command.Parameters.Add(database.CreateParameter("folderID", folderID));

View File

@ -675,7 +675,7 @@ VALUES
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags],[Expires]) VALUES (@LandUUID,@AccessUUID,@Flags,@Expires)";
using (SqlConnection conn = new SqlConnection(m_connectionString)) using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn)) using (SqlCommand cmd = new SqlCommand(sql, conn))
@ -1215,6 +1215,8 @@ VALUES
//Store new values //Store new values
StoreNewRegionSettings(regionSettings); StoreNewRegionSettings(regionSettings);
LoadSpawnPoints(regionSettings);
return regionSettings; return regionSettings;
} }
@ -1252,7 +1254,7 @@ VALUES
,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se ,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se
,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit ,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit
,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position ,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id ,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id, [map_tile_id] = @TerrainImageID, [telehubobject] = @telehubobject, [parcel_tile_id] = @ParcelImageID
WHERE [regionUUID] = @regionUUID"; WHERE [regionUUID] = @regionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString)) using (SqlConnection conn = new SqlConnection(m_connectionString))
@ -1263,6 +1265,7 @@ VALUES
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
SaveSpawnPoints(regionSettings);
} }
public void Shutdown() public void Shutdown()
@ -1383,6 +1386,11 @@ VALUES
newSettings.LoadedCreationID = ""; newSettings.LoadedCreationID = "";
else else
newSettings.LoadedCreationID = (String)row["loaded_creation_id"]; newSettings.LoadedCreationID = (String)row["loaded_creation_id"];
newSettings.TerrainImageID = new UUID((string)row["map_tile_ID"]);
newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]);
newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]);
return newSettings; return newSettings;
} }
@ -1454,6 +1462,13 @@ VALUES
} }
newData.ParcelAccessList = new List<LandAccessEntry>(); newData.ParcelAccessList = new List<LandAccessEntry>();
newData.MediaDescription = (string)row["MediaDescription"];
newData.MediaType = (string)row["MediaType"];
newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
return newData; return newData;
} }
@ -1468,7 +1483,7 @@ VALUES
LandAccessEntry entry = new LandAccessEntry(); LandAccessEntry entry = new LandAccessEntry();
entry.AgentID = new UUID((Guid)row["AccessUUID"]); entry.AgentID = new UUID((Guid)row["AccessUUID"]);
entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]); entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]);
entry.Expires = 0; entry.Expires = Convert.ToInt32(row["Expires"]);
return entry; return entry;
} }
@ -1497,7 +1512,8 @@ VALUES
prim.TouchName = (string)primRow["TouchName"]; prim.TouchName = (string)primRow["TouchName"];
// permissions // permissions
prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]); prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]);
prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); //prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
prim.CreatorIdentification = (string)primRow["CreatorID"];
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
prim.GroupID = new UUID((Guid)primRow["GroupID"]); prim.GroupID = new UUID((Guid)primRow["GroupID"]);
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
@ -1691,7 +1707,8 @@ VALUES
taskItem.Name = (string)inventoryRow["name"]; taskItem.Name = (string)inventoryRow["name"];
taskItem.Description = (string)inventoryRow["description"]; taskItem.Description = (string)inventoryRow["description"];
taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]); taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]);
taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); //taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
taskItem.CreatorIdentification = (string)inventoryRow["creatorID"];
taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]); taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]);
taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]); taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]);
taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]); taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]);
@ -1792,6 +1809,9 @@ VALUES
parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime)); parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime));
parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime)); parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime));
parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID)); parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID));
parameters.Add(_Database.CreateParameter("TerrainImageID", settings.TerrainImageID));
parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID));
parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject));
return parameters.ToArray(); return parameters.ToArray();
} }
@ -1859,6 +1879,7 @@ VALUES
parameters.Add(_Database.CreateParameter("LandUUID", parcelID)); parameters.Add(_Database.CreateParameter("LandUUID", parcelID));
parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID)); parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID));
parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags)); parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags));
parameters.Add(_Database.CreateParameter("Expires", parcelAccessEntry.Expires));
return parameters.ToArray(); return parameters.ToArray();
} }
@ -2063,5 +2084,57 @@ VALUES
#endregion #endregion
#endregion #endregion
private void LoadSpawnPoints(RegionSettings rs)
{
rs.ClearSpawnPoints();
string sql = "SELECT Yaw, Pitch, Distance FROM spawn_points WHERE RegionUUID = @RegionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID.ToString()));
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
SpawnPoint sp = new SpawnPoint();
sp.Yaw = (float)reader["Yaw"];
sp.Pitch = (float)reader["Pitch"];
sp.Distance = (float)reader["Distance"];
rs.AddSpawnPoint(sp);
}
}
}
}
private void SaveSpawnPoints(RegionSettings rs)
{
string sql = "DELETE FROM spawn_points WHERE RegionUUID = @RegionUUID";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
conn.Open();
cmd.ExecuteNonQuery();
}
foreach (SpawnPoint p in rs.SpawnPoints())
{
sql = "INSERT INTO spawn_points (RegionUUID, Yaw, Pitch, Distance) VALUES (@RegionUUID, @Yaw, @Pitch, @Distance)";
using (SqlConnection conn = new SqlConnection(m_connectionString))
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
cmd.Parameters.Add(_Database.CreateParameter("@Yaw", p.Yaw));
cmd.Parameters.Add(_Database.CreateParameter("@Pitch", p.Pitch));
cmd.Parameters.Add(_Database.CreateParameter("@Distance", p.Distance));
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
} }
} }

View File

@ -1044,10 +1044,93 @@ ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
COMMIT COMMIT
:VERSION 29 #--------------------- :VERSION 29 #----------------- Region Covenant changed time
BEGIN TRANSACTION BEGIN TRANSACTION
ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0 ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0
COMMIT COMMIT
:VERSION 30 #------------------Migrate creatorID storage to varchars instead of UUIDs for HG support
BEGIN TRANSACTION
EXECUTE sp_rename N'dbo.prims.creatorid', N'creatoridold', 'COLUMN'
EXECUTE sp_rename N'dbo.primitems.creatorid', N'creatoridold', 'COLUMN'
COMMIT
:VERSION 31 #---------------------
BEGIN TRANSACTION
ALTER TABLE prims ADD CreatorID varchar(255)
ALTER TABLE primitems ADD CreatorID varchar(255)
COMMIT
:VERSION 32 #---------------------
BEGIN TRANSACTION
UPDATE prims SET prims.CreatorID = CONVERT(varchar(255), creatoridold)
UPDATE primitems SET primitems.CreatorID = CONVERT(varchar(255), creatoridold)
COMMIT
:VERSION 33 #---------------------
BEGIN TRANSACTION
ALTER TABLE prims
ADD CONSTRAINT DF_prims_CreatorIDNew
DEFAULT '00000000-0000-0000-0000-000000000000'
FOR CreatorID
ALTER TABLE prims ALTER COLUMN CreatorID varchar(255) NOT NULL
ALTER TABLE primitems
ADD CONSTRAINT DF_primitems_CreatorIDNew
DEFAULT '00000000-0000-0000-0000-000000000000'
FOR CreatorID
ALTER TABLE primitems ALTER COLUMN CreatorID varchar(255) NOT NULL
COMMIT
:VERSION 34 #--------------- Telehub support
BEGIN TRANSACTION
CREATE TABLE [dbo].[Spawn_Points](
[RegionUUID] [uniqueidentifier] NOT NULL,
[Yaw] [float] NOT NULL,
[Pitch] [float] NOT NULL,
[Distance] [float] NOT NULL,
PRIMARY KEY CLUSTERED
(
[RegionUUID] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE regionsettings ADD TelehubObject uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT
:VERSION 35 #---------------- Parcels for sale
BEGIN TRANSACTION
ALTER TABLE regionsettings ADD parcel_tile_ID uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT
:VERSION 36 #---------------- Timed bans/access
BEGIN TRANSACTION
ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
COMMIT

View File

@ -0,0 +1,500 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
namespace OpenSim.Data.MySQL
{
public class MySQLXAssetData : IXAssetDataPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected virtual Assembly Assembly
{
get { return GetType().Assembly; }
}
private bool m_enableCompression = false;
private string m_connectionString;
private object m_dbLock = new object();
/// <summary>
/// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
/// </summary>
private HashAlgorithm hasher = new SHA256CryptoServiceProvider();
#region IPlugin Members
public string Version { get { return "1.0.0.0"; } }
/// <summary>
/// <para>Initialises Asset interface</para>
/// <para>
/// <list type="bullet">
/// <item>Loads and initialises the MySQL storage plugin.</item>
/// <item>Warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
/// <item>Check for migration</item>
/// </list>
/// </para>
/// </summary>
/// <param name="connect">connect string</param>
public void Initialise(string connect)
{
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: THIS PLUGIN IS STRICTLY EXPERIMENTAL.");
m_log.ErrorFormat("[MYSQL XASSETDATA]: DO NOT USE FOR ANY DATA THAT YOU DO NOT MIND LOSING.");
m_log.ErrorFormat("[MYSQL XASSETDATA]: DATABASE TABLES CAN CHANGE AT ANY TIME, CAUSING EXISTING DATA TO BE LOST.");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
m_connectionString = connect;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
Migration m = new Migration(dbcon, Assembly, "XAssetStore");
m.Update();
}
}
public void Initialise()
{
throw new NotImplementedException();
}
public void Dispose() { }
/// <summary>
/// The name of this DB provider
/// </summary>
public string Name
{
get { return "MySQL XAsset storage engine"; }
}
#endregion
#region IAssetDataPlugin Members
/// <summary>
/// Fetch Asset <paramref name="assetID"/> from database
/// </summary>
/// <param name="assetID">Asset UUID to fetch</param>
/// <returns>Return the asset</returns>
/// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks>
public AssetBase GetAsset(UUID assetID)
{
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
AssetBase asset = null;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand(
"SELECT name, description, asset_type, local, temporary, asset_flags, creator_id, data FROM xassetsmeta JOIN xassetsdata ON xassetsmeta.hash = xassetsdata.hash WHERE id=?id",
dbcon))
{
cmd.Parameters.AddWithValue("?id", assetID.ToString());
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["asset_type"], dbReader["creator_id"].ToString());
asset.Data = (byte[])dbReader["data"];
asset.Description = (string)dbReader["description"];
string local = dbReader["local"].ToString();
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
asset.Local = true;
else
asset.Local = false;
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
if (m_enableCompression)
{
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
{
MemoryStream outputStream = new MemoryStream();
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
// int compressedLength = asset.Data.Length;
asset.Data = outputStream.ToArray();
// m_log.DebugFormat(
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
}
}
}
}
}
catch (Exception e)
{
m_log.Error("[MYSQL XASSET DATA]: MySql failure fetching asset " + assetID + ": " + e.Message);
}
}
}
}
return asset;
}
/// <summary>
/// Create an asset in database, or update it if existing.
/// </summary>
/// <param name="asset">Asset UUID to create</param>
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
public void StoreAsset(AssetBase asset)
{
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlTransaction transaction = dbcon.BeginTransaction())
{
string assetName = asset.Name;
if (asset.Name.Length > 64)
{
assetName = asset.Name.Substring(0, 64);
m_log.Warn("[XASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
}
string assetDescription = asset.Description;
if (asset.Description.Length > 64)
{
assetDescription = asset.Description.Substring(0, 64);
m_log.Warn("[XASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
}
if (m_enableCompression)
{
MemoryStream outputStream = new MemoryStream();
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
{
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
compressionStream.Close();
byte[] compressedData = outputStream.ToArray();
asset.Data = compressedData;
}
}
byte[] hash = hasher.ComputeHash(asset.Data);
// m_log.DebugFormat(
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
// asset.ID, asset.Name, hash, compressedData.Length);
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"replace INTO xassetsmeta(id, hash, name, description, asset_type, local, temporary, create_time, access_time, asset_flags, creator_id)" +
"VALUES(?id, ?hash, ?name, ?description, ?asset_type, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?creator_id)",
dbcon))
{
// create unix epoch time
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
cmd.Parameters.AddWithValue("?id", asset.ID);
cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?name", assetName);
cmd.Parameters.AddWithValue("?description", assetDescription);
cmd.Parameters.AddWithValue("?asset_type", asset.Type);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?create_time", now);
cmd.Parameters.AddWithValue("?access_time", now);
cmd.Parameters.AddWithValue("?creator_id", asset.Metadata.CreatorID);
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
if (!ExistsData(dbcon, transaction, hash))
{
try
{
using (MySqlCommand cmd =
new MySqlCommand(
"INSERT INTO xassetsdata(hash, data) VALUES(?hash, ?data)",
dbcon))
{
cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
asset.FullID, asset.Name, e.Message);
transaction.Rollback();
return;
}
}
transaction.Commit();
}
}
}
}
// private void UpdateAccessTime(AssetBase asset)
// {
// lock (m_dbLock)
// {
// using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
// {
// dbcon.Open();
// MySqlCommand cmd =
// new MySqlCommand("update assets set access_time=?access_time where id=?id",
// dbcon);
//
// // need to ensure we dispose
// try
// {
// using (cmd)
// {
// // create unix epoch time
// int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
// cmd.Parameters.AddWithValue("?id", asset.ID);
// cmd.Parameters.AddWithValue("?access_time", now);
// cmd.ExecuteNonQuery();
// cmd.Dispose();
// }
// }
// catch (Exception e)
// {
// m_log.ErrorFormat(
// "[ASSETS DB]: " +
// "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
// + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
// }
// }
// }
//
// }
/// <summary>
/// We assume we already have the m_dbLock.
/// </summary>
/// TODO: need to actually use the transaction.
/// <param name="dbcon"></param>
/// <param name="transaction"></param>
/// <param name="hash"></param>
/// <returns></returns>
private bool ExistsData(MySqlConnection dbcon, MySqlTransaction transaction, byte[] hash)
{
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
bool exists = false;
using (MySqlCommand cmd = new MySqlCommand("SELECT hash FROM xassetsdata WHERE hash=?hash", dbcon))
{
cmd.Parameters.AddWithValue("?hash", hash);
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
exists = true;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[XASSETS DB]: MySql failure in ExistsData fetching hash {0}. Exception {1}{2}",
hash, e.Message, e.StackTrace);
}
}
return exists;
}
/// <summary>
/// Check if the asset exists in the database
/// </summary>
/// <param name="uuid">The asset UUID</param>
/// <returns>true if it exists, false otherwise.</returns>
public bool ExistsAsset(UUID uuid)
{
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
bool assetExists = false;
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM xassetsmeta WHERE id=?id", dbcon))
{
cmd.Parameters.AddWithValue("?id", uuid.ToString());
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
assetExists = true;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[XASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
}
}
}
}
return assetExists;
}
/// <summary>
/// Returns a list of AssetMetadata objects. The list is a subset of
/// the entire data set offset by <paramref name="start" /> containing
/// <paramref name="count" /> elements.
/// </summary>
/// <param name="start">The number of results to discard from the total data set.</param>
/// <param name="count">The number of rows the returned list should contain.</param>
/// <returns>A list of AssetMetadata objects.</returns>
public List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
{
List<AssetMetadata> retList = new List<AssetMetadata>(count);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
MySqlCommand cmd = new MySqlCommand("SELECT name,description,asset_type,temporary,id,asset_flags,creator_id FROM xassetsmeta LIMIT ?start, ?count", dbcon);
cmd.Parameters.AddWithValue("?start", start);
cmd.Parameters.AddWithValue("?count", count);
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader())
{
while (dbReader.Read())
{
AssetMetadata metadata = new AssetMetadata();
metadata.Name = (string)dbReader["name"];
metadata.Description = (string)dbReader["description"];
metadata.Type = (sbyte)dbReader["asset_type"];
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
metadata.CreatorID = dbReader["creator_id"].ToString();
// We'll ignore this for now - it appears unused!
// metadata.SHA1 = dbReader["hash"]);
retList.Add(metadata);
}
}
}
catch (Exception e)
{
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
}
}
}
return retList;
}
public bool Delete(string id)
{
// m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id);
lock (m_dbLock)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = new MySqlCommand("delete from xassetsmeta where id=?id", dbcon))
{
cmd.Parameters.AddWithValue("?id", id);
cmd.ExecuteNonQuery();
}
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
// keep a reference count (?)
}
}
return true;
}
#endregion
}
}

View File

@ -0,0 +1,27 @@
# -----------------
:VERSION 1
BEGIN;
CREATE TABLE `xassetsmeta` (
`id` char(36) NOT NULL,
`hash` binary(32) NOT NULL,
`name` varchar(64) NOT NULL,
`description` varchar(64) NOT NULL,
`asset_type` tinyint(4) NOT NULL,
`local` tinyint(1) NOT NULL,
`temporary` tinyint(1) NOT NULL,
`create_time` int(11) NOT NULL,
`access_time` int(11) NOT NULL,
`asset_flags` int(11) NOT NULL,
`creator_id` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
CREATE TABLE `xassetsdata` (
`hash` binary(32) NOT NULL,
`data` longblob NOT NULL,
PRIMARY KEY (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
COMMIT;

View File

@ -29,6 +29,7 @@ using System;
using System.Xml; using System.Xml;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console
{ {
public class Commands : ICommands public class Commands : ICommands
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// Encapsulates a command that can be invoked from the console /// Encapsulates a command that can be invoked from the console
/// </summary> /// </summary>
@ -76,12 +79,19 @@ namespace OpenSim.Framework.Console
public List<CommandDelegate> fn; public List<CommandDelegate> fn;
} }
public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:";
/// <value> /// <value>
/// Commands organized by keyword in a tree /// Commands organized by keyword in a tree
/// </value> /// </value>
private Dictionary<string, object> tree = private Dictionary<string, object> tree =
new Dictionary<string, object>(); new Dictionary<string, object>();
/// <summary>
/// Commands organized by module
/// </summary>
private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>();
/// <summary> /// <summary>
/// Get help for the given help string /// Get help for the given help string
/// </summary> /// </summary>
@ -98,8 +108,8 @@ namespace OpenSim.Framework.Console
// General help // General help
if (helpParts.Count == 0) if (helpParts.Count == 0)
{ {
help.AddRange(CollectHelp(tree)); help.Add(GeneralHelpText);
help.Sort(); help.AddRange(CollectModulesHelp(tree));
} }
else else
{ {
@ -119,6 +129,13 @@ namespace OpenSim.Framework.Console
string originalHelpRequest = string.Join(" ", helpParts.ToArray()); string originalHelpRequest = string.Join(" ", helpParts.ToArray());
List<string> help = new List<string>(); List<string> help = new List<string>();
// Check modules first to see if we just need to display a list of those commands
if (TryCollectModuleHelp(originalHelpRequest, help))
{
help.Insert(0, GeneralHelpText);
return help;
}
Dictionary<string, object> dict = tree; Dictionary<string, object> dict = tree;
while (helpParts.Count > 0) while (helpParts.Count > 0)
{ {
@ -161,26 +178,64 @@ namespace OpenSim.Framework.Console
return help; return help;
} }
private List<string> CollectHelp(Dictionary<string, object> dict) /// <summary>
/// Try to collect help for the given module if that module exists.
/// </summary>
/// <param name="moduleName"></param>
/// <param name="helpText">/param>
/// <returns>true if there was the module existed, false otherwise.</returns>
private bool TryCollectModuleHelp(string moduleName, List<string> helpText)
{ {
List<string> result = new List<string>(); lock (m_modulesCommands)
foreach (KeyValuePair<string, object> kvp in dict)
{ {
if (kvp.Value is Dictionary<string, Object>) foreach (string key in m_modulesCommands.Keys)
{ {
result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); // Allow topic help requests to succeed whether they are upper or lowercase.
} if (moduleName.ToLower() == key.ToLower())
else {
{ List<CommandInfo> commands = m_modulesCommands[key];
if (((CommandInfo)kvp.Value).long_help != String.Empty) var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
result.Add(((CommandInfo)kvp.Value).help_text+" - "+ ourHelpText.Sort();
((CommandInfo)kvp.Value).long_help); helpText.AddRange(ourHelpText);
return true;
}
} }
return false;
} }
return result;
} }
private List<string> CollectModulesHelp(Dictionary<string, object> dict)
{
lock (m_modulesCommands)
{
List<string> helpText = new List<string>(m_modulesCommands.Keys);
helpText.Sort();
return helpText;
}
}
// private List<string> CollectHelp(Dictionary<string, object> dict)
// {
// List<string> result = new List<string>();
//
// foreach (KeyValuePair<string, object> kvp in dict)
// {
// if (kvp.Value is Dictionary<string, Object>)
// {
// result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
// }
// else
// {
// if (((CommandInfo)kvp.Value).long_help != String.Empty)
// result.Add(((CommandInfo)kvp.Value).help_text+" - "+
// ((CommandInfo)kvp.Value).long_help);
// }
// }
// return result;
// }
/// <summary> /// <summary>
/// Add a command to those which can be invoked from the console. /// Add a command to those which can be invoked from the console.
/// </summary> /// </summary>
@ -212,21 +267,19 @@ namespace OpenSim.Framework.Console
Dictionary<string, Object> current = tree; Dictionary<string, Object> current = tree;
foreach (string s in parts) foreach (string part in parts)
{ {
if (current.ContainsKey(s)) if (current.ContainsKey(part))
{ {
if (current[s] is Dictionary<string, Object>) if (current[part] is Dictionary<string, Object>)
{ current = (Dictionary<string, Object>)current[part];
current = (Dictionary<string, Object>)current[s];
}
else else
return; return;
} }
else else
{ {
current[s] = new Dictionary<string, Object>(); current[part] = new Dictionary<string, Object>();
current = (Dictionary<string, Object>)current[s]; current = (Dictionary<string, Object>)current[part];
} }
} }
@ -250,6 +303,24 @@ namespace OpenSim.Framework.Console
info.fn = new List<CommandDelegate>(); info.fn = new List<CommandDelegate>();
info.fn.Add(fn); info.fn.Add(fn);
current[String.Empty] = info; current[String.Empty] = info;
// Now add command to modules dictionary
lock (m_modulesCommands)
{
List<CommandInfo> commands;
if (m_modulesCommands.ContainsKey(module))
{
commands = m_modulesCommands[module];
}
else
{
commands = new List<CommandInfo>();
m_modulesCommands[module] = commands;
}
// m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command);
commands.Add(info);
}
} }
public string[] FindNextOption(string[] cmd, bool term) public string[] FindNextOption(string[] cmd, bool term)
@ -607,8 +678,9 @@ namespace OpenSim.Framework.Console
{ {
Commands = new Commands(); Commands = new Commands();
Commands.AddCommand("console", false, "help", "help [<command>]", Commands.AddCommand(
"Get general command list or more detailed help on a specific command", Help); "Help", false, "help", "help [<item>]",
"Display help on a particular command or on a list of commands in a category", Help);
} }
private void Help(string module, string[] cmd) private void Help(string module, string[] cmd)

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using log4net;
public class GcNotify
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static bool Enabled
{
get { return s_initialized; }
set
{
if (!s_initialized && value)
new GcNotify();
s_initialized = value;
}
}
private static bool s_initialized = false;
private GcNotify() {}
~GcNotify()
{
if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
{
m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered.");
if (Enabled)
new GcNotify();
}
}
}

View File

@ -1218,7 +1218,6 @@ namespace OpenSim.Framework
void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks); void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks);
void SendViewerTime(int phase); void SendViewerTime(int phase);
UUID GetDefaultAnimation(string name);
void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout, void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout,
uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID); uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID);

View File

@ -40,7 +40,7 @@ namespace OpenSim.Framework
/// <summary> /// <summary>
/// Get help for the given help string /// Get help for the given help string
/// </summary> /// </summary>
/// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param> /// <param name="cmd">Parsed parts of the help string. If empty then general help is returned.</param>
/// <returns></returns> /// <returns></returns>
List<string> GetHelp(string[] cmd); List<string> GetHelp(string[] cmd);

View File

@ -71,6 +71,7 @@ namespace OpenSim.Framework
bool IsEitherBannedOrRestricted(UUID avatar); bool IsEitherBannedOrRestricted(UUID avatar);
bool IsBannedFromLand(UUID avatar); bool IsBannedFromLand(UUID avatar);
bool IsRestrictedFromLand(UUID avatar); bool IsRestrictedFromLand(UUID avatar);
bool IsInLandAccessList(UUID avatar);
void SendLandUpdateToClient(IClientAPI remote_client); void SendLandUpdateToClient(IClientAPI remote_client);
void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag); List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag);

View File

@ -119,7 +119,7 @@ namespace OpenSim.Framework
// Copy the temporary stream to the network stream // Copy the temporary stream to the network stream
formDataStream.Seek(0, SeekOrigin.Begin); formDataStream.Seek(0, SeekOrigin.Begin);
using (Stream requestStream = request.GetRequestStream()) using (Stream requestStream = request.GetRequestStream())
formDataStream.CopyTo(requestStream, (int)formDataStream.Length); formDataStream.CopyStream(requestStream, (int)formDataStream.Length);
} }
#endregion Stream Writing #endregion Stream Writing

View File

@ -421,12 +421,18 @@ namespace OpenSim.Framework
set { m_internalEndPoint = value; } set { m_internalEndPoint = value; }
} }
/// <summary>
/// The x co-ordinate of this region in map tiles (e.g. 1000).
/// </summary>
public uint RegionLocX public uint RegionLocX
{ {
get { return m_regionLocX.Value; } get { return m_regionLocX.Value; }
set { m_regionLocX = value; } set { m_regionLocX = value; }
} }
/// <summary>
/// The y co-ordinate of this region in map tiles (e.g. 1000).
/// </summary>
public uint RegionLocY public uint RegionLocY
{ {
get { return m_regionLocY.Value; } get { return m_regionLocY.Value; }

View File

@ -27,7 +27,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Reflection; using System.Reflection;
using System.Xml;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;

View File

@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
} }
m_console.Commands.AddCommand("base", false, "quit", m_console.Commands.AddCommand("General", false, "quit",
"quit", "quit",
"Quit the application", HandleQuit); "Quit the application", HandleQuit);
m_console.Commands.AddCommand("base", false, "shutdown", m_console.Commands.AddCommand("General", false, "shutdown",
"shutdown", "shutdown",
"Quit the application", HandleQuit); "Quit the application", HandleQuit);
m_console.Commands.AddCommand("base", false, "set log level", m_console.Commands.AddCommand("General", false, "set log level",
"set log level <level>", "set log level <level>",
"Set the console logging level", HandleLogLevel); "Set the console logging level", HandleLogLevel);
m_console.Commands.AddCommand("base", false, "show info", m_console.Commands.AddCommand("General", false, "show info",
"show info", "show info",
"Show general information about the server", HandleShow); "Show general information about the server", HandleShow);
m_console.Commands.AddCommand("base", false, "show stats", m_console.Commands.AddCommand("General", false, "show stats",
"show stats", "show stats",
"Show statistics", HandleShow); "Show statistics", HandleShow);
m_console.Commands.AddCommand("base", false, "show threads", m_console.Commands.AddCommand("General", false, "show threads",
"show threads", "show threads",
"Show thread status", HandleShow); "Show thread status", HandleShow);
m_console.Commands.AddCommand("base", false, "show uptime", m_console.Commands.AddCommand("General", false, "show uptime",
"show uptime", "show uptime",
"Show server uptime", HandleShow); "Show server uptime", HandleShow);
m_console.Commands.AddCommand("base", false, "show version", m_console.Commands.AddCommand("General", false, "show version",
"show version", "show version",
"Show server version", HandleShow); "Show server version", HandleShow);
m_console.Commands.AddCommand("base", false, "threads abort", m_console.Commands.AddCommand("General", false, "threads abort",
"threads abort <thread-id>", "threads abort <thread-id>",
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
m_console.Commands.AddCommand("base", false, "threads show", m_console.Commands.AddCommand("General", false, "threads show",
"threads show", "threads show",
"Show thread status. Synonym for \"show threads\"", "Show thread status. Synonym for \"show threads\"",
(string module, string[] args) => Notice(GetThreadsReport())); (string module, string[] args) => Notice(GetThreadsReport()));
@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers
t.Priority, t.Priority,
t.ThreadState); t.ThreadState);
sb.Append(Environment.NewLine); sb.Append("\n");
} }
int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; sb.Append("\n");
ThreadPool.GetAvailableThreads(out workers, out ports);
ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts);
sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine); // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); // zero active threads.
int totalThreads = Process.GetCurrentProcess().Threads.Count;
if (totalThreads > 0)
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
sb.Append("Main threadpool (excluding script engine pools)\n");
sb.Append(Util.GetThreadPoolReport());
return sb.ToString(); return sb.ToString();
} }

View File

@ -26,8 +26,8 @@
*/ */
using System; using System;
using System.Diagnostics;
using System.Text; using System.Text;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
sb.Append( sb.Append(
string.Format( string.Format(
"Allocated to OpenSim : {0} MB" + Environment.NewLine, "Allocated to OpenSim objects: {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
sb.Append(
string.Format(
"Process memory : {0} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
return sb.ToString(); return sb.ToString();
} }

View File

@ -81,12 +81,15 @@ namespace OpenSim.Framework
private static uint nextXferID = 5000; private static uint nextXferID = 5000;
private static Random randomClass = new Random(); private static Random randomClass = new Random();
// Get a list of invalid file characters (OS dependent) // Get a list of invalid file characters (OS dependent)
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
private static object XferLock = new object(); private static object XferLock = new object();
/// <summary>Thread pool used for Util.FireAndForget if
/// FireAndForgetMethod.SmartThreadPool is used</summary> /// <summary>
/// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
/// </summary>
private static SmartThreadPool m_ThreadPool; private static SmartThreadPool m_ThreadPool;
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
@ -144,7 +147,6 @@ namespace OpenSim.Framework
return lerp(y, lerp(x, a, b), lerp(x, c, d)); return lerp(y, lerp(x, a, b), lerp(x, c, d));
} }
public static Encoding UTF8 = Encoding.UTF8; public static Encoding UTF8 = Encoding.UTF8;
/// <value> /// <value>
@ -1671,6 +1673,61 @@ namespace OpenSim.Framework
} }
} }
/// <summary>
/// Get a thread pool report.
/// </summary>
/// <returns></returns>
public static string GetThreadPoolReport()
{
string threadPoolUsed = null;
int maxThreads = 0;
int minThreads = 0;
int allocatedThreads = 0;
int inUseThreads = 0;
int waitingCallbacks = 0;
int completionPortThreads = 0;
StringBuilder sb = new StringBuilder();
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
{
threadPoolUsed = "SmartThreadPool";
maxThreads = m_ThreadPool.MaxThreads;
minThreads = m_ThreadPool.MinThreads;
inUseThreads = m_ThreadPool.InUseThreads;
allocatedThreads = m_ThreadPool.ActiveThreads;
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
}
else if (
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
{
threadPoolUsed = "BuiltInThreadPool";
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
int availableThreads;
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
inUseThreads = maxThreads - availableThreads;
allocatedThreads = -1;
waitingCallbacks = -1;
}
if (threadPoolUsed != null)
{
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
sb.AppendFormat("Max threads : {0}\n", maxThreads);
sb.AppendFormat("Min threads : {0}\n", minThreads);
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
}
else
{
sb.AppendFormat("Thread pool not used\n");
}
return sb.ToString();
}
private static object SmartThreadPoolCallback(object o) private static object SmartThreadPoolCallback(object o)
{ {
object[] array = (object[])o; object[] array = (object[])o;
@ -1696,6 +1753,20 @@ namespace OpenSim.Framework
} }
const Int32 EnvironmentTickCountMask = 0x3fffffff; const Int32 EnvironmentTickCountMask = 0x3fffffff;
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
/// 'EnvironmentTickCount()') and accounts for any wrapping.
/// </summary>
/// <param name="newValue"></param>
/// <param name="prevValue"></param>
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
{
Int32 diff = newValue - prevValue;
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
}
/// <summary> /// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by /// and negative every 24.9 days. Subtracts the passed value (previously fetched by
@ -1704,8 +1775,7 @@ namespace OpenSim.Framework
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
{ {
Int32 diff = EnvironmentTickCount() - prevValue; return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
} }
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
@ -1870,11 +1940,12 @@ namespace OpenSim.Framework
#region Universal User Identifiers #region Universal User Identifiers
/// <summary> /// <summary>
/// </summary> /// </summary>
/// <param name="value">uuid[;endpoint[;name]]</param> /// <param name="value">uuid[;endpoint[;first last[;secret]]]</param>
/// <param name="uuid"></param> /// <param name="uuid">the uuid part</param>
/// <param name="url"></param> /// <param name="url">the endpoint part (e.g. http://foo.com)</param>
/// <param name="firstname"></param> /// <param name="firstname">the first name part (e.g. Test)</param>
/// <param name="lastname"></param> /// <param name="lastname">the last name part (e.g User)</param>
/// <param name="secret">the secret part</param>
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
{ {
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
@ -1903,31 +1974,64 @@ namespace OpenSim.Framework
} }
/// <summary> /// <summary>
/// /// Produces a universal (HG) system-facing identifier given the information
/// </summary> /// </summary>
/// <param name="acircuit"></param> /// <param name="acircuit"></param>
/// <returns>uuid[;endpoint[;name]]</returns> /// <returns>uuid[;homeURI[;first last]]</returns>
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
{ {
if (acircuit.ServiceURLs.ContainsKey("HomeURI")) if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
{ return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString());
string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
if (!agentsURI.EndsWith("/"))
agentsURI += "/";
// This is ugly, but there's no other way, given that the name is changed
// in the agent circuit data for foreigners
if (acircuit.lastname.Contains("@"))
{
string[] parts = acircuit.firstname.Split(new char[] { '.' });
if (parts.Length == 2)
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
}
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
}
else else
return acircuit.AgentID.ToString(); return acircuit.AgentID.ToString();
} }
/// <summary>
/// Produces a universal (HG) system-facing identifier given the information
/// </summary>
/// <param name="id">UUID of the user</param>
/// <param name="firstName">first name (e.g Test)</param>
/// <param name="lastName">last name (e.g. User)</param>
/// <param name="homeURI">homeURI (e.g. http://foo.com)</param>
/// <returns>a string of the form uuid[;homeURI[;first last]]</returns>
public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI)
{
string agentsURI = homeURI;
if (!agentsURI.EndsWith("/"))
agentsURI += "/";
// This is ugly, but there's no other way, given that the name is changed
// in the agent circuit data for foreigners
if (lastName.Contains("@"))
{
string[] parts = firstName.Split(new char[] { '.' });
if (parts.Length == 2)
return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
}
return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
}
/// <summary>
/// Produces a universal (HG) user-facing name given the information
/// </summary>
/// <param name="firstName"></param>
/// <param name="lastName"></param>
/// <param name="homeURI"></param>
/// <returns>string of the form first.last @foo.com or first last</returns>
public static string UniversalName(String firstName, String lastName, String homeURI)
{
Uri uri = null;
try
{
uri = new Uri(homeURI);
}
catch (UriFormatException)
{
return firstName + " " + lastName;
}
return firstName + "." + lastName + " " + "@" + uri.Authority;
}
#endregion #endregion
} }
} }

View File

@ -63,6 +63,31 @@ namespace OpenSim.Framework
// a "long" call for warning & debugging purposes // a "long" call for warning & debugging purposes
public const int LongCallTime = 500; public const int LongCallTime = 500;
// dictionary of end points
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
private static object EndPointLock(string url)
{
System.Uri uri = new System.Uri(url);
string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port);
lock (m_endpointSerializer)
{
object eplock = null;
if (! m_endpointSerializer.TryGetValue(endpoint,out eplock))
{
eplock = new object();
m_endpointSerializer.Add(endpoint,eplock);
// m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint);
}
return eplock;
}
}
#region JSONRequest #region JSONRequest
/// <summary> /// <summary>
@ -95,6 +120,14 @@ namespace OpenSim.Framework
} }
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed) public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
{
lock (EndPointLock(url))
{
return ServiceOSDRequestWorker(url,data,method,timeout,compressed);
}
}
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
{ {
int reqnum = m_requestNumber++; int reqnum = m_requestNumber++;
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
@ -247,6 +280,14 @@ namespace OpenSim.Framework
} }
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
{
lock (EndPointLock(url))
{
return ServiceFormRequestWorker(url,data,timeout);
}
}
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
{ {
int reqnum = m_requestNumber++; int reqnum = m_requestNumber++;
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
@ -469,8 +510,13 @@ namespace OpenSim.Framework
/// <remarks> /// <remarks>
/// Copying begins at the streams' current positions. The positions are /// Copying begins at the streams' current positions. The positions are
/// NOT reset after copying is complete. /// NOT reset after copying is complete.
/// NOTE!! .NET 4.0 adds the method 'Stream.CopyTo(stream, bufferSize)'.
/// This function could be replaced with that method once we move
/// totally to .NET 4.0. For versions before, this routine exists.
/// This routine used to be named 'CopyTo' but the int parameter has
/// a different meaning so this method was renamed to avoid any confusion.
/// </remarks> /// </remarks>
public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) public static int CopyStream(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy)
{ {
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
int readBytes; int readBytes;

View File

@ -225,12 +225,12 @@ namespace OpenSim
/// </summary> /// </summary>
private void RegisterConsoleCommands() private void RegisterConsoleCommands()
{ {
m_console.Commands.AddCommand("region", false, "force update", m_console.Commands.AddCommand("Regions", false, "force update",
"force update", "force update",
"Force the update of all objects on clients", "Force the update of all objects on clients",
HandleForceUpdate); HandleForceUpdate);
m_console.Commands.AddCommand("region", false, "debug packet", m_console.Commands.AddCommand("Comms", false, "debug packet",
"debug packet <level> [<avatar-first-name> <avatar-last-name>]", "debug packet <level> [<avatar-first-name> <avatar-last-name>]",
"Turn on packet debugging", "Turn on packet debugging",
"If level > 255 then all incoming and outgoing packets are logged.\n" "If level > 255 then all incoming and outgoing packets are logged.\n"
@ -242,7 +242,7 @@ namespace OpenSim
+ "If an avatar name is given then only packets from that avatar are logged", + "If an avatar name is given then only packets from that avatar are logged",
Debug); Debug);
m_console.Commands.AddCommand("region", false, "debug http", m_console.Commands.AddCommand("Comms", false, "debug http",
"debug http <level>", "debug http <level>",
"Turn on inbound http request debugging for everything except the event queue (see debug eq).", "Turn on inbound http request debugging for everything except the event queue (see debug eq).",
"If level >= 2 then the handler used to service the request is logged.\n" "If level >= 2 then the handler used to service the request is logged.\n"
@ -250,37 +250,37 @@ namespace OpenSim
+ "If level <= 0 then no extra http logging is done.\n", + "If level <= 0 then no extra http logging is done.\n",
Debug); Debug);
m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
m_console.Commands.AddCommand("region", false, "debug scene", m_console.Commands.AddCommand("Regions", false, "debug scene",
"debug scene <scripting> <collisions> <physics>", "debug scene <scripting> <collisions> <physics>",
"Turn on scene debugging", Debug); "Turn on scene debugging", Debug);
m_console.Commands.AddCommand("region", false, "change region", m_console.Commands.AddCommand("General", false, "change region",
"change region <region name>", "change region <region name>",
"Change current console region", ChangeSelectedRegion); "Change current console region", ChangeSelectedRegion);
m_console.Commands.AddCommand("region", false, "save xml", m_console.Commands.AddCommand("Archiving", false, "save xml",
"save xml", "save xml",
"Save a region's data in XML format", SaveXml); "Save a region's data in XML format", SaveXml);
m_console.Commands.AddCommand("region", false, "save xml2", m_console.Commands.AddCommand("Archiving", false, "save xml2",
"save xml2", "save xml2",
"Save a region's data in XML2 format", SaveXml2); "Save a region's data in XML2 format", SaveXml2);
m_console.Commands.AddCommand("region", false, "load xml", m_console.Commands.AddCommand("Archiving", false, "load xml",
"load xml [-newIDs [<x> <y> <z>]]", "load xml [-newIDs [<x> <y> <z>]]",
"Load a region's data from XML format", LoadXml); "Load a region's data from XML format", LoadXml);
m_console.Commands.AddCommand("region", false, "load xml2", m_console.Commands.AddCommand("Archiving", false, "load xml2",
"load xml2", "load xml2",
"Load a region's data from XML2 format", LoadXml2); "Load a region's data from XML2 format", LoadXml2);
m_console.Commands.AddCommand("region", false, "save prims xml2", m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
"save prims xml2 [<prim name> <file name>]", "save prims xml2 [<prim name> <file name>]",
"Save named prim to XML2", SavePrimsXml2); "Save named prim to XML2", SavePrimsXml2);
m_console.Commands.AddCommand("region", false, "load oar", m_console.Commands.AddCommand("Archiving", false, "load oar",
"load oar [--merge] [--skip-assets] [<OAR path>]", "load oar [--merge] [--skip-assets] [<OAR path>]",
"Load a region's data from an OAR archive.", "Load a region's data from an OAR archive.",
"--merge will merge the OAR with the existing scene." + Environment.NewLine "--merge will merge the OAR with the existing scene." + Environment.NewLine
@ -289,7 +289,7 @@ namespace OpenSim
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.", + " If this is not given then the command looks for an OAR named region.oar in the current directory.",
LoadOar); LoadOar);
m_console.Commands.AddCommand("region", false, "save oar", m_console.Commands.AddCommand("Archiving", false, "save oar",
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]", "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
"Save a region's data to an OAR archive.", "Save a region's data to an OAR archive.",
@ -306,54 +306,54 @@ namespace OpenSim
+ " If this is not given then the oar is saved to region.oar in the current directory.", + " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar); SaveOar);
m_console.Commands.AddCommand("region", false, "edit scale", m_console.Commands.AddCommand("Regions", false, "edit scale",
"edit scale <name> <x> <y> <z>", "edit scale <name> <x> <y> <z>",
"Change the scale of a named prim", HandleEditScale); "Change the scale of a named prim", HandleEditScale);
m_console.Commands.AddCommand("region", false, "kick user", m_console.Commands.AddCommand("Users", false, "kick user",
"kick user <first> <last> [message]", "kick user <first> <last> [message]",
"Kick a user off the simulator", KickUserCommand); "Kick a user off the simulator", KickUserCommand);
m_console.Commands.AddCommand("region", false, "show users", m_console.Commands.AddCommand("Users", false, "show users",
"show users [full]", "show users [full]",
"Show user data for users currently on the region", "Show user data for users currently on the region",
"Without the 'full' option, only users actually on the region are shown." "Without the 'full' option, only users actually on the region are shown."
+ " With the 'full' option child agents of users in neighbouring regions are also shown.", + " With the 'full' option child agents of users in neighbouring regions are also shown.",
HandleShow); HandleShow);
m_console.Commands.AddCommand("region", false, "show connections", m_console.Commands.AddCommand("Comms", false, "show connections",
"show connections", "show connections",
"Show connection data", HandleShow); "Show connection data", HandleShow);
m_console.Commands.AddCommand("region", false, "show circuits", m_console.Commands.AddCommand("Comms", false, "show circuits",
"show circuits", "show circuits",
"Show agent circuit data", HandleShow); "Show agent circuit data", HandleShow);
m_console.Commands.AddCommand("region", false, "show http-handlers", m_console.Commands.AddCommand("Comms", false, "show http-handlers",
"show http-handlers", "show http-handlers",
"Show all registered http handlers", HandleShow); "Show all registered http handlers", HandleShow);
m_console.Commands.AddCommand("region", false, "show pending-objects", m_console.Commands.AddCommand("Comms", false, "show pending-objects",
"show pending-objects", "show pending-objects",
"Show # of objects on the pending queues of all scene viewers", HandleShow); "Show # of objects on the pending queues of all scene viewers", HandleShow);
m_console.Commands.AddCommand("region", false, "show modules", m_console.Commands.AddCommand("General", false, "show modules",
"show modules", "show modules",
"Show module data", HandleShow); "Show module data", HandleShow);
m_console.Commands.AddCommand("region", false, "show regions", m_console.Commands.AddCommand("Regions", false, "show regions",
"show regions", "show regions",
"Show region data", HandleShow); "Show region data", HandleShow);
m_console.Commands.AddCommand("region", false, "show ratings", m_console.Commands.AddCommand("Regions", false, "show ratings",
"show ratings", "show ratings",
"Show rating data", HandleShow); "Show rating data", HandleShow);
m_console.Commands.AddCommand("region", false, "backup", m_console.Commands.AddCommand("Regions", false, "backup",
"backup", "backup",
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
m_console.Commands.AddCommand("region", false, "create region", m_console.Commands.AddCommand("Regions", false, "create region",
"create region [\"region name\"] <region_file.ini>", "create region [\"region name\"] <region_file.ini>",
"Create a new region.", "Create a new region.",
"The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given." "The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
@ -362,62 +362,57 @@ namespace OpenSim
+ "If <region_file.ini> does not exist, it will be created.", + "If <region_file.ini> does not exist, it will be created.",
HandleCreateRegion); HandleCreateRegion);
m_console.Commands.AddCommand("region", false, "restart", m_console.Commands.AddCommand("Regions", false, "restart",
"restart", "restart",
"Restart all sims in this instance", RunCommand); "Restart all sims in this instance", RunCommand);
m_console.Commands.AddCommand("region", false, "config set", m_console.Commands.AddCommand("General", false, "config set",
"config set <section> <key> <value>", "config set <section> <key> <value>",
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig); "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
m_console.Commands.AddCommand("region", false, "config get", m_console.Commands.AddCommand("General", false, "config get",
"config get [<section>] [<key>]", "config get [<section>] [<key>]",
"Synonym for config show", "Synonym for config show",
HandleConfig); HandleConfig);
m_console.Commands.AddCommand("region", false, "config show", m_console.Commands.AddCommand("General", false, "config show",
"config show [<section>] [<key>]", "config show [<section>] [<key>]",
"Show config information", "Show config information",
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
+ "If a section is given but not a field, then all fields in that section are printed.", + "If a section is given but not a field, then all fields in that section are printed.",
HandleConfig); HandleConfig);
m_console.Commands.AddCommand("region", false, "config save", m_console.Commands.AddCommand("General", false, "config save",
"config save <path>", "config save <path>",
"Save current configuration to a file at the given path", HandleConfig); "Save current configuration to a file at the given path", HandleConfig);
m_console.Commands.AddCommand("region", false, "command-script", m_console.Commands.AddCommand("General", false, "command-script",
"command-script <script>", "command-script <script>",
"Run a command script from file", RunCommand); "Run a command script from file", RunCommand);
m_console.Commands.AddCommand("region", false, "remove-region", m_console.Commands.AddCommand("Regions", false, "remove-region",
"remove-region <name>", "remove-region <name>",
"Remove a region from this simulator", RunCommand); "Remove a region from this simulator", RunCommand);
m_console.Commands.AddCommand("region", false, "delete-region", m_console.Commands.AddCommand("Regions", false, "delete-region",
"delete-region <name>", "delete-region <name>",
"Delete a region from disk", RunCommand); "Delete a region from disk", RunCommand);
m_console.Commands.AddCommand("region", false, "modules list", m_console.Commands.AddCommand("General", false, "modules list",
"modules list", "modules list",
"List modules", HandleModules); "List modules", HandleModules);
m_console.Commands.AddCommand("region", false, "modules load", m_console.Commands.AddCommand("General", false, "modules load",
"modules load <name>", "modules load <name>",
"Load a module", HandleModules); "Load a module", HandleModules);
m_console.Commands.AddCommand("region", false, "modules unload", m_console.Commands.AddCommand("General", false, "modules unload",
"modules unload <name>", "modules unload <name>",
"Unload a module", HandleModules); "Unload a module", HandleModules);
m_console.Commands.AddCommand("region", false, "Add-InventoryHost", m_console.Commands.AddCommand("Regions", false, "kill uuid",
"Add-InventoryHost <host>",
String.Empty, RunCommand);
m_console.Commands.AddCommand("region", false, "kill uuid",
"kill uuid <UUID>", "kill uuid <UUID>",
"Kill an object by UUID", KillUUID); "Kill an object by UUID", KillUUID);
} }
public override void ShutdownSpecific() public override void ShutdownSpecific()
@ -508,7 +503,11 @@ namespace OpenSim
string currentCommand; string currentCommand;
while ((currentCommand = readFile.ReadLine()) != null) while ((currentCommand = readFile.ReadLine()) != null)
{ {
if (currentCommand != String.Empty) currentCommand = currentCommand.Trim();
if (!(currentCommand == ""
|| currentCommand.StartsWith(";")
|| currentCommand.StartsWith("//")
|| currentCommand.StartsWith("#")))
{ {
m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'"); m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
m_console.RunCommand(currentCommand); m_console.RunCommand(currentCommand);
@ -829,14 +828,6 @@ namespace OpenSim
case "restart": case "restart":
m_sceneManager.RestartCurrentScene(); m_sceneManager.RestartCurrentScene();
break; break;
case "Add-InventoryHost":
if (cmdparams.Length > 0)
{
MainConsole.Instance.Output("Not implemented.");
}
break;
} }
} }
@ -928,7 +919,7 @@ namespace OpenSim
break; break;
case "scene": case "scene":
if (args.Length == 5) if (args.Length == 4)
{ {
if (m_sceneManager.CurrentScene == null) if (m_sceneManager.CurrentScene == null)
{ {
@ -936,39 +927,21 @@ namespace OpenSim
} }
else else
{ {
bool scriptingOn = !Convert.ToBoolean(args[2]); string key = args[2];
bool collisionsOn = !Convert.ToBoolean(args[3]); string value = args[3];
bool physicsOn = !Convert.ToBoolean(args[4]); m_sceneManager.CurrentScene.SetSceneCoreDebug(
m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn); new Dictionary<string, string>() { { key, value } });
MainConsole.Instance.Output( MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
String.Format(
"Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
!scriptingOn, !collisionsOn, !physicsOn));
} }
} }
else else
{ {
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)"); MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
} }
break; break;
case "teleport":
foreach(Scene s in m_sceneManager.Scenes)
{
if (s.DEBUG)
{
s.DEBUG = false;
MainConsole.Instance.Output("Teleport debugging is disabled!");
}
else{
s.DEBUG = true;
MainConsole.Instance.Output("Teleport debugging is enabled!");
}
}
break;
default: default:
MainConsole.Instance.Output("Unknown debug command"); MainConsole.Instance.Output("Unknown debug command");
break; break;

View File

@ -28,6 +28,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
@ -67,6 +68,9 @@ namespace OpenSim
private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache"; private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache";
private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient"; private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient";
// OpenSim.ini Section name for ESTATES Settings
public const string ESTATE_SECTION_NAME = "Estates";
protected string proxyUrl; protected string proxyUrl;
protected int proxyOffset = 0; protected int proxyOffset = 0;
@ -242,15 +246,18 @@ namespace OpenSim
foreach (string topic in topics) foreach (string topic in topics)
{ {
m_console.Commands.AddCommand("plugin", false, "help " + topic, string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
"help " + topic,
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
// away at some point.
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'", "Get help on plugin command '" + topic + "'",
HandleCommanderHelp); HandleCommanderHelp);
m_console.Commands.AddCommand("plugin", false, topic,
topic,
"Execute subcommand for plugin '" + topic + "'",
null);
ICommander commander = null; ICommander commander = null;
@ -267,7 +274,7 @@ namespace OpenSim
foreach (string command in commander.Commands.Keys) foreach (string command in commander.Commands.Keys)
{ {
m_console.Commands.AddCommand(topic, false, m_console.Commands.AddCommand(capitalizedTopic, false,
topic + " " + command, topic + " " + command,
topic + " " + commander.Commands[command].ShortHelp(), topic + " " + commander.Commands[command].ShortHelp(),
String.Empty, HandleCommanderCommand); String.Empty, HandleCommanderCommand);
@ -286,7 +293,7 @@ namespace OpenSim
// Only safe for the interactive console, since it won't // Only safe for the interactive console, since it won't
// let us come here unless both scene and commander exist // let us come here unless both scene and commander exist
// //
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]); ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
if (moduleCommander != null) if (moduleCommander != null)
m_console.Output(moduleCommander.Help); m_console.Output(moduleCommander.Help);
} }
@ -424,7 +431,7 @@ namespace OpenSim
mscene = scene; mscene = scene;
scene.StartTimer(); scene.Start();
scene.StartScripts(); scene.StartScripts();
@ -443,12 +450,42 @@ namespace OpenSim
{ {
RegionInfo regionInfo = scene.RegionInfo; RegionInfo regionInfo = scene.RegionInfo;
string estateOwnerFirstName = null;
string estateOwnerLastName = null;
string estateOwnerEMail = null;
string estateOwnerPassword = null;
string rawEstateOwnerUuid = null;
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
{
string defaultEstateOwnerName
= m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim();
string[] ownerNames = defaultEstateOwnerName.Split(' ');
if (ownerNames.Length >= 2)
{
estateOwnerFirstName = ownerNames[0];
estateOwnerLastName = ownerNames[1];
}
// Info to be used only on Standalone Mode
rawEstateOwnerUuid = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null);
estateOwnerEMail = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null);
estateOwnerPassword = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null);
}
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName); MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
List<char> excluded = new List<char>(new char[1]{' '}); List<char> excluded = new List<char>(new char[1]{' '});
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last);
if (estateOwnerFirstName == null || estateOwnerLastName == null)
{
estateOwnerFirstName = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
estateOwnerLastName = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
}
UserAccount account
= scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, estateOwnerFirstName, estateOwnerLastName);
if (account == null) if (account == null)
{ {
@ -467,23 +504,35 @@ namespace OpenSim
if (scene.UserAccountService is UserAccountService) if (scene.UserAccountService is UserAccountService)
{ {
string password = MainConsole.Instance.PasswdPrompt("Password"); if (estateOwnerPassword == null)
string email = MainConsole.Instance.CmdPrompt("Email", ""); estateOwnerPassword = MainConsole.Instance.PasswdPrompt("Password");
string rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString()); if (estateOwnerEMail == null)
estateOwnerEMail = MainConsole.Instance.CmdPrompt("Email");
UUID principalId = UUID.Zero; if (rawEstateOwnerUuid == null)
if (!UUID.TryParse(rawPrincipalId, out principalId)) rawEstateOwnerUuid = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
UUID estateOwnerUuid = UUID.Zero;
if (!UUID.TryParse(rawEstateOwnerUuid, out estateOwnerUuid))
{ {
m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawPrincipalId); m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawEstateOwnerUuid);
return; return;
} }
// If we've been given a zero uuid then this signals that we should use a random user id
if (estateOwnerUuid == UUID.Zero)
estateOwnerUuid = UUID.Random();
account account
= ((UserAccountService)scene.UserAccountService).CreateUser( = ((UserAccountService)scene.UserAccountService).CreateUser(
regionInfo.ScopeID, principalId, first, last, password, email); regionInfo.ScopeID,
estateOwnerUuid,
estateOwnerFirstName,
estateOwnerLastName,
estateOwnerPassword,
estateOwnerEMail);
} }
// }
} }
if (account == null) if (account == null)
@ -883,15 +932,21 @@ namespace OpenSim
/// This method doesn't allow an estate to be created with the same name as existing estates. /// This method doesn't allow an estate to be created with the same name as existing estates.
/// </remarks> /// </remarks>
/// <param name="regInfo"></param> /// <param name="regInfo"></param>
/// <param name="existingName">A list of estate names that already exist.</param> /// <param name="estatesByName">A list of estate names that already exist.</param>
/// <param name="estateName">Estate name to create if already known</param>
/// <returns>true if the estate was created, false otherwise</returns> /// <returns>true if the estate was created, false otherwise</returns>
public bool CreateEstate(RegionInfo regInfo, List<string> existingNames) public bool CreateEstate(RegionInfo regInfo, Dictionary<string, EstateSettings> estatesByName, string estateName)
{ {
// Create a new estate // Create a new estate
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true); regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true);
string newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
if (existingNames.Contains(newName)) string newName;
if (estateName != null && estateName != "")
newName = estateName;
else
newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
if (estatesByName.ContainsKey(newName))
{ {
MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName); MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName);
return false; return false;
@ -918,66 +973,102 @@ namespace OpenSim
if (EstateDataService != null) if (EstateDataService != null)
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false); regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
if (regInfo.EstateSettings.EstateID == 0) // No record at all if (regInfo.EstateSettings.EstateID != 0)
return;
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
Dictionary<string, EstateSettings> estatesByName = new Dictionary<string, EstateSettings>();
foreach (EstateSettings estate in estates)
estatesByName[estate.EstateName] = estate;
string defaultEstateName = null;
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
{ {
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); defaultEstateName = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll(); if (defaultEstateName != null)
List<string> estateNames = new List<string>();
foreach (EstateSettings estate in estates)
estateNames.Add(estate.EstateName);
while (true)
{ {
if (estates.Count == 0) EstateSettings defaultEstate;
{ bool defaultEstateJoined = false;
m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
if (CreateEstate(regInfo, estateNames)) if (estatesByName.ContainsKey(defaultEstateName))
{
defaultEstate = estatesByName[defaultEstateName];
if (EstateDataService.LinkRegion(regInfo.RegionID, (int)defaultEstate.EstateID))
defaultEstateJoined = true;
}
else
{
if (CreateEstate(regInfo, estatesByName, defaultEstateName))
defaultEstateJoined = true;
}
if (defaultEstateJoined)
return;
else
m_log.ErrorFormat(
"[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
}
}
// If we have no default estate or creation of the default estate failed then ask the user.
while (true)
{
if (estates.Count == 0)
{
m_log.Info("[ESTATE]: No existing estates found. You must create a new one.");
if (CreateEstate(regInfo, estatesByName, null))
break;
else
continue;
}
else
{
string response
= MainConsole.Instance.CmdPrompt(
string.Format(
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
"yes",
new List<string>() { "yes", "no" });
if (response == "no")
{
if (CreateEstate(regInfo, estatesByName, null))
break; break;
else else
continue; continue;
} }
else else
{ {
string response string[] estateNames = estatesByName.Keys.ToArray();
response
= MainConsole.Instance.CmdPrompt( = MainConsole.Instance.CmdPrompt(
string.Format( string.Format(
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName), "Name of estate to join. Existing estate names are ({0})",
"yes", string.Join(", ", estateNames)),
new List<string>() { "yes", "no" }); estateNames[0]);
if (response == "no") List<int> estateIDs = EstateDataService.GetEstates(response);
if (estateIDs.Count < 1)
{ {
if (CreateEstate(regInfo, estateNames)) MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
break; continue;
else
continue;
} }
else
{
response
= MainConsole.Instance.CmdPrompt(
string.Format(
"Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
estateNames[0]);
List<int> estateIDs = EstateDataService.GetEstates(response); int estateID = estateIDs[0];
if (estateIDs.Count < 1)
{
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
continue;
}
int estateID = estateIDs[0]; regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID); if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
break;
if (EstateDataService.LinkRegion(regInfo.RegionID, estateID)) MainConsole.Instance.Output("Joining the estate failed. Please try again.");
break;
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
}
} }
} }
} }

View File

@ -262,7 +262,7 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
try try
{ {
m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); // m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
//m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
@ -761,7 +761,7 @@ namespace OpenSim.Region.ClientStack.Linden
SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID); SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
if (part != null) if (part != null)
{ {
TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID); // TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID)) if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
{ {
return LLSDHelpers.SerialiseLLSDReply(response); return LLSDHelpers.SerialiseLLSDReply(response);

View File

@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden
scene.EventManager.OnRegisterCaps += OnRegisterCaps; scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"event queue", "Comms",
false, false,
"debug eq", "debug eq",
"debug eq [0|1]", "debug eq [0|1]",

View File

@ -317,7 +317,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected readonly UUID m_agentId; protected readonly UUID m_agentId;
private readonly uint m_circuitCode; private readonly uint m_circuitCode;
private readonly byte[] m_channelVersion = Utils.EmptyBytes; private readonly byte[] m_channelVersion = Utils.EmptyBytes;
private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>();
private readonly IGroupsModule m_GroupsModule; private readonly IGroupsModule m_GroupsModule;
private int m_cachedTextureSerial; private int m_cachedTextureSerial;
@ -452,10 +451,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
RegisterInterface<IClientChat>(this); RegisterInterface<IClientChat>(this);
RegisterInterface<IClientIPEndpoint>(this); RegisterInterface<IClientIPEndpoint>(this);
InitDefaultAnimations();
m_scene = scene; m_scene = scene;
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
m_entityProps = new PriorityQueue(m_scene.Entities.Count); m_entityProps = new PriorityQueue(m_scene.Entities.Count);
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
@ -11210,32 +11206,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(scriptQuestion, ThrottleOutPacketType.Task); OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
} }
private void InitDefaultAnimations()
{
using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
{
XmlDocument doc = new XmlDocument();
doc.Load(reader);
if (doc.DocumentElement != null)
foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
{
if (nod.Attributes["name"] != null)
{
string name = nod.Attributes["name"].Value.ToLower();
string id = nod.InnerText;
m_defaultAnimations.Add(name, (UUID)id);
}
}
}
}
public UUID GetDefaultAnimation(string name)
{
if (m_defaultAnimations.ContainsKey(name))
return m_defaultAnimations[name];
return UUID.Zero;
}
/// <summary> /// <summary>
/// Handler called when we receive a logout packet. /// Handler called when we receive a logout packet.
/// </summary> /// </summary>

View File

@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
m_regStatus = RegionStatus.Up; m_regStatus = RegionStatus.Up;
} }
public override void Update() {} public override void Update(int frames) {}
public override void LoadWorldMap() {} public override void LoadWorldMap() {}
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)

View File

@ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTierLen = 4; m_CacheDirectoryTierLen = 4;
} }
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand); MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
} }
} }
} }

View File

@ -51,12 +51,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
m_scene.RegisterModuleInterface<IDialogModule>(this); m_scene.RegisterModuleInterface<IDialogModule>(this);
m_scene.AddCommand( m_scene.AddCommand(
this, "alert", "alert <message>", "Users", this, "alert", "alert <message>",
"Send an alert to everyone", "Send an alert to everyone",
HandleAlertConsoleCommand); HandleAlertConsoleCommand);
m_scene.AddCommand( m_scene.AddCommand(
this, "alert-user", "alert-user <first> <last> <message>", "Users", this, "alert-user", "alert-user <first> <last> <message>",
"Send an alert to a user", "Send an alert to a user",
HandleAlertConsoleCommand); HandleAlertConsoleCommand);
} }

View File

@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
scene.EventManager.OnClientLogin += OnClientLogin; scene.EventManager.OnClientLogin += OnClientLogin;
} }
public void RegionLoaded(Scene scene) public virtual void RegionLoaded(Scene scene)
{ {
} }
@ -550,7 +550,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UUID principalID = new UUID(im.fromAgentID); UUID principalID = new UUID(im.fromAgentID);
UUID friendID = new UUID(im.toAgentID); UUID friendID = new UUID(im.toAgentID);
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID); m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
// Check that the friendship doesn't exist yet
FriendInfo[] finfos = GetFriends(principalID);
if (finfos != null)
{
FriendInfo f = GetFriend(finfos, friendID);
if (f != null)
{
client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
return;
}
}
// This user wants to be friends with the other user. // This user wants to be friends with the other user.
// Let's add the relation backwards, in case the other is not online // Let's add the relation backwards, in case the other is not online
@ -561,7 +573,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
{ {
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
// We stick this agent's ID as imSession, so that it's directly available on the receiving end // We stick this agent's ID as imSession, so that it's directly available on the receiving end
@ -570,7 +582,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Try the local sim // Try the local sim
if (LocalFriendshipOffered(friendID, im)) if (LocalFriendshipOffered(friendID, im))
return; return true;
// The prospective friend is not here [as root]. Let's forward. // The prospective friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@ -581,9 +593,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
return true;
} }
} }
// If the prospective friend is not online, he'll get the message upon login. // If the prospective friend is not online, he'll get the message upon login.
return false;
} }
protected virtual string GetFriendshipRequesterName(UUID agentID) protected virtual string GetFriendshipRequesterName(UUID agentID)
@ -592,7 +606,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
} }
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
{ {
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
@ -603,7 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
StoreFriendships(client.AgentId, friendID); StoreFriendships(client.AgentId, friendID);
// Update the local cache // Update the local cache.
RecacheFriends(client); RecacheFriends(client);
// //
@ -756,7 +770,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#region Local #region Local
public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
{ {
IClientAPI friendClient = LocateClientObject(toID); IClientAPI friendClient = LocateClientObject(toID);
if (friendClient != null) if (friendClient != null)
@ -912,7 +926,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return FriendsService.GetFriends(client.AgentId); return FriendsService.GetFriends(client.AgentId);
} }
private void RecacheFriends(IClientAPI client) protected void RecacheFriends(IClientAPI client)
{ {
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
// is on the critical path for transferring an avatar from one region to another. // is on the critical path for transferring an avatar from one region to another.

View File

@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
IUserManagement m_uMan; IUserManagement m_uMan;
IUserManagement UserManagementModule public IUserManagement UserManagementModule
{ {
get get
{ {
@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector();
protected HGStatusNotifier m_StatusNotifier;
#region ISharedRegionModule #region ISharedRegionModule
public override string Name public override string Name
{ {
@ -76,6 +79,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
scene.RegisterModuleInterface<IFriendsSimConnector>(this); scene.RegisterModuleInterface<IFriendsSimConnector>(this);
} }
public override void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
if (m_StatusNotifier == null)
m_StatusNotifier = new HGStatusNotifier(this);
}
#endregion #endregion
#region IFriendsSimConnector #region IFriendsSimConnector
@ -94,6 +105,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
{
// Update the local cache. Yes, we need to do it right here
// because the HGFriendsService placed something on the DB
// from under the sim
base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders);
}
protected override bool CacheFriends(IClientAPI client) protected override bool CacheFriends(IClientAPI client)
{ {
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name); // m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
@ -183,91 +202,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID); // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
} }
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
//{
// // Let's single out the UUIs
// List<string> localFriends = new List<string>();
// List<string> foreignFriends = new List<string>();
// string tmp = string.Empty;
// foreach (string s in friendList)
// {
// UUID id;
// if (UUID.TryParse(s, out id))
// localFriends.Add(s);
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
// {
// foreignFriends.Add(s);
// // add it here too, who knows maybe the foreign friends happens to be on this grid
// localFriends.Add(id.ToString());
// }
// }
// // OK, see who's present on this grid
// List<string> toBeRemoved = new List<string>();
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
// foreach (PresenceInfo pi in presence)
// {
// UUID presenceID;
// if (UUID.TryParse(pi.UserID, out presenceID))
// {
// online.Add(presenceID);
// foreach (string s in foreignFriends)
// if (s.StartsWith(pi.UserID))
// toBeRemoved.Add(s);
// }
// }
// foreach (string s in toBeRemoved)
// foreignFriends.Remove(s);
// // OK, let's send this up the stack, and leave a closure here
// // collecting online friends in other grids
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
//}
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
//{
// // let's divide the friends on a per-domain basis
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
// foreach (string friend in foreignFriends)
// {
// UUID friendID;
// if (!UUID.TryParse(friend, out friendID))
// {
// // it's a foreign friend
// string url = string.Empty, tmp = string.Empty;
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
// {
// if (!friendsPerDomain.ContainsKey(url))
// friendsPerDomain[url] = new List<string>();
// friendsPerDomain[url].Add(friend);
// }
// }
// }
// // Now, call those worlds
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
// {
// List<string> ids = new List<string>();
// foreach (string f in kvp.Value)
// ids.Add(f);
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
// // Finally send the notifications to the user
// // this whole process may take a while, so let's check at every
// // iteration that the user is still here
// IClientAPI client = LocateClientObject(userID);
// if (client != null)
// client.SendAgentOnline(online.ToArray());
// else
// break;
// }
//}
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{ {
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
@ -305,25 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (friendsPerDomain.ContainsKey("local")) if (friendsPerDomain.ContainsKey("local"))
base.StatusNotify(friendsPerDomain["local"], userID, online); base.StatusNotify(friendsPerDomain["local"], userID, online);
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain) m_StatusNotifier.Notify(userID, friendsPerDomain, online);
{
if (kvp.Key != "local")
{
// For the others, call the user agent service
List<string> ids = new List<string>();
foreach (FriendInfo f in kvp.Value)
ids.Add(f.Friend);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
if (online && friendsOnline.Count > 0)
{
IClientAPI client = LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(friendsOnline.ToArray());
}
}
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID); // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
} }
@ -335,26 +251,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return true; return true;
// fid is not a UUID... // fid is not a UUID...
string url = string.Empty, tmp = string.Empty; string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty;
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp))
{ {
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); if (!agentID.Equals(UUID.Zero))
userMan.AddUser(agentID, first, last, url); {
m_uMan.AddUser(agentID, f, l, url);
return true; string name = m_uMan.GetUserName(agentID);
string[] parts = name.Trim().Split(new char[] { ' ' });
if (parts.Length == 2)
{
first = parts[0];
last = parts[1];
}
else
{
first = f;
last = l;
}
return true;
}
} }
return false; return false;
} }
protected override string GetFriendshipRequesterName(UUID agentID) protected override string GetFriendshipRequesterName(UUID agentID)
{ {
// For the time being we assume that HG friendship requests can only happen return m_uMan.GetUserName(agentID);
// when avies are on the same region.
IClientAPI client = LocateClientObject(agentID);
if (client != null)
return client.FirstName + " " + client.LastName;
else
return base.GetFriendshipRequesterName(agentID);
} }
protected override string FriendshipMessage(string friendID) protected override string FriendshipMessage(string friendID)
@ -392,10 +316,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (agentClientCircuit != null) if (agentClientCircuit != null)
{ {
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
finfos = FriendsService.GetFriends(agentUUI); finfos = FriendsService.GetFriends(client.AgentId.ToString());
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
} }
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
@ -454,16 +378,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
} }
// Are they both local users? // Is the requester a local user?
if (agentIsLocal && friendIsLocal) if (agentIsLocal)
{ {
// local grid users // local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards.");
base.StoreBackwards(friendID, agentID); base.StoreBackwards(friendID, agentID);
return; return;
} }
// no provision for this temporary friendship state // no provision for this temporary friendship state when user is not local
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
} }
@ -501,12 +426,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
RecacheFriends(agentClient);
} }
if (friendClient != null) if (friendClient != null)
{ {
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
RecacheFriends(friendClient);
} }
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
@ -515,14 +442,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Generate a random 8-character hex number that will sign this friendship // Generate a random 8-character hex number that will sign this friendship
string secret = UUID.Random().ToString().Substring(0, 8); string secret = UUID.Random().ToString().Substring(0, 8);
string theFriendUUID = friendUUI + ";" + secret;
string agentUUID = agentUUI + ";" + secret;
if (agentIsLocal) // agent is local, 'friend' is foreigner if (agentIsLocal) // agent is local, 'friend' is foreigner
{ {
// This may happen when the agent returned home, in which case the friend is not there // This may happen when the agent returned home, in which case the friend is not there
// We need to look for its information in the friends list itself // We need to look for its information in the friends list itself
FriendInfo[] finfos = null;
bool confirming = false; bool confirming = false;
if (friendUUI == string.Empty) if (friendUUI == string.Empty)
{ {
FriendInfo[] finfos = GetFriends(agentID); finfos = GetFriends(agentID);
foreach (FriendInfo finfo in finfos) foreach (FriendInfo finfo in finfos)
{ {
if (finfo.TheirFlags == -1) if (finfo.TheirFlags == -1)
@ -530,29 +461,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (finfo.Friend.StartsWith(friendID.ToString())) if (finfo.Friend.StartsWith(friendID.ToString()))
{ {
friendUUI = finfo.Friend; friendUUI = finfo.Friend;
theFriendUUID = friendUUI;
UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty;
// If it's confirming the friendship, we already have the full UUI with the secret
if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
{
agentUUID = agentUUI + ";" + secret;
m_uMan.AddUser(utmp, first, last, url);
}
confirming = true; confirming = true;
break;
} }
} }
} }
if (!confirming)
{
friendUUI = m_uMan.GetUserUUI(friendID);
theFriendUUID = friendUUI + ";" + secret;
}
friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
// m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
// agentUUI, friendUUI, agentFriendService, friendFriendService);
} }
// If it's confirming the friendship, we already have the full friendUUI with the secret // Delete any previous friendship relations
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; DeletePreviousRelations(agentID, friendID);
// store in the local friends service a reference to the foreign friend // store in the local friends service a reference to the foreign friend
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
// and also the converse // and also the converse
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
if (!confirming && friendClientCircuit != null) //if (!confirming)
{ //{
// store in the foreign friends service a reference to the local agent // store in the foreign friends service a reference to the local agent
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); HGFriendsServicesConnector friendsConn = null;
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); if (friendClientCircuit != null) // the friend is here, validate session
} friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
else // the friend is not here, he initiated the request in his home world
friendsConn = new HGFriendsServicesConnector(friendFriendService);
friendsConn.NewFriendship(friendID, agentUUID);
//}
} }
else if (friendIsLocal) // 'friend' is local, agent is foreigner else if (friendIsLocal) // 'friend' is local, agent is foreigner
{ {
// Delete any previous friendship relations
DeletePreviousRelations(agentID, friendID);
// store in the local friends service a reference to the foreign agent // store in the local friends service a reference to the foreign agent
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
// and also the converse // and also the converse
@ -582,6 +541,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// my brain hurts now // my brain hurts now
} }
private void DeletePreviousRelations(UUID a1, UUID a2)
{
// Delete any previous friendship relations
FriendInfo[] finfos = null;
FriendInfo f = null;
finfos = GetFriends(a1);
if (finfos != null)
{
f = GetFriend(finfos, a2);
if (f != null)
{
FriendsService.Delete(a1, f.Friend);
// and also the converse
FriendsService.Delete(f.Friend, a1.ToString());
}
}
finfos = GetFriends(a2);
if (finfos != null)
{
f = GetFriend(finfos, a1);
if (f != null)
{
FriendsService.Delete(a2, f.Friend);
// and also the converse
FriendsService.Delete(f.Friend, a2.ToString());
}
}
}
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
{ {
Boolean agentIsLocal = true; Boolean agentIsLocal = true;
@ -684,5 +673,80 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendConn.DeleteFriendship(foreignUser, localUser, secret); friendConn.DeleteFriendship(foreignUser, localUser, secret);
} }
} }
protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
{
if (base.ForwardFriendshipOffer(agentID, friendID, im))
return true;
// OK, that didn't work, so let's try to find this user somewhere
if (!m_uMan.IsLocalGridUser(friendID))
{
string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
if (friendsURL != string.Empty)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL);
GridRegion region = new GridRegion();
region.ServerURI = friendsURL;
string name = im.fromAgentName;
if (m_uMan.IsLocalGridUser(agentID))
{
IClientAPI agentClient = LocateClientObject(agentID);
AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
string agentHomeService = string.Empty;
try
{
agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString();
string lastname = "@" + new Uri(agentHomeService).Authority;
string firstname = im.fromAgentName.Replace(" ", ".");
name = firstname + lastname;
}
catch (KeyNotFoundException)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID);
return false;
}
catch (NullReferenceException)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID);
return false;
}
catch (UriFormatException)
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID);
return false;
}
}
m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name);
return true;
}
}
return false;
}
public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
{
if (base.LocalFriendshipOffered(toID, im))
{
if (im.fromAgentName.Contains("@"))
{
string[] parts = im.fromAgentName.Split(new char[] { '@' });
if (parts.Length == 2)
{
string[] fl = parts[0].Trim().Split(new char[] { '.' });
if (fl.Length == 2)
m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], fl[1], "http://" + parts[1]);
else
m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], "", "http://" + parts[1]);
}
}
return true;
}
return false;
}
} }
} }

View File

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
using OpenMetaverse;
using log4net;
namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public class HGStatusNotifier
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private HGFriendsModule m_FriendsModule;
public HGStatusNotifier(HGFriendsModule friendsModule)
{
m_FriendsModule = friendsModule;
}
public void Notify(UUID userID, Dictionary<string, List<FriendInfo>> friendsPerDomain, bool online)
{
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
{
if (kvp.Key != "local")
{
// For the others, call the user agent service
List<string> ids = new List<string>();
foreach (FriendInfo f in kvp.Value)
ids.Add(f.Friend);
if (ids.Count == 0)
continue; // no one to notify. caller don't do this
m_log.DebugFormat("[HG STATUS NOTIFIER]: Notifying {0} friends in {1}", ids.Count, kvp.Key);
// ASSUMPTION: we assume that all users for one home domain
// have exactly the same set of service URLs.
// If this is ever not true, we need to change this.
UUID friendID = UUID.Zero; String tmp = String.Empty;
if (Util.ParseUniversalUserIdentifier(ids[0], out friendID, out tmp, out tmp, out tmp, out tmp))
{
string friendsServerURI = m_FriendsModule.UserManagementModule.GetUserServerURL(friendID, "FriendsServerURI");
if (friendsServerURI != string.Empty)
{
HGFriendsServicesConnector fConn = new HGFriendsServicesConnector(friendsServerURI);
List<UUID> friendsOnline = fConn.StatusNotification(ids, userID, online);
if (online && friendsOnline.Count > 0)
{
IClientAPI client = m_FriendsModule.LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(friendsOnline.ToArray());
}
}
}
}
}
}
}
}

View File

@ -270,11 +270,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_archiveWriter = new TarArchiveWriter(m_saveStream); m_archiveWriter = new TarArchiveWriter(m_saveStream);
m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");
// Write out control file. This has to be done first so that subsequent loaders will see this file first // Write out control file. This has to be done first so that subsequent loaders will see this file first
// XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
// not sure how to fix this though, short of going with a completely different file format. // not sure how to fix this though, short of going with a completely different file format.
m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
m_log.InfoFormat("[INVENTORY ARCHIVER]: Added control file to archive.");
if (inventoryFolder != null) if (inventoryFolder != null)
{ {

View File

@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
scene.AddCommand( scene.AddCommand(
this, "load iar", "Archiving", this, "load iar",
"load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
"Load user inventory archive (IAR).", "Load user inventory archive (IAR).",
"-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
@ -121,18 +121,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
HandleLoadInvConsoleCommand); HandleLoadInvConsoleCommand);
scene.AddCommand( scene.AddCommand(
this, "save iar", "Archiving", this, "save iar",
"save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]",
"Save user inventory archive (IAR).", "Save user inventory archive (IAR).",
"<first> is the user's first name." + Environment.NewLine "<first> is the user's first name.\n"
+ "<last> is the user's last name." + Environment.NewLine + "<last> is the user's last name.\n"
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
+ "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
+ "-v|--verbose extra debug messages." + Environment.NewLine
+ "--noassets stops assets being saved to the IAR."
+ "<IAR path> is the filesystem path at which to save the IAR." + "<IAR path> is the filesystem path at which to save the IAR."
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
+ "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
+ "-c|--creators preserves information about foreign creators.\n"
+ "-v|--verbose extra debug messages.\n"
+ "--noassets stops assets being saved to the IAR.",
HandleSaveInvConsoleCommand); HandleSaveInvConsoleCommand);
m_aScene = scene; m_aScene = scene;

View File

@ -69,9 +69,10 @@ namespace OpenSim.Region.CoreModules.Framework
{ {
m_scene = scene; m_scene = scene;
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps",
"show caps", "show caps",
"Shows all registered capabilities", HandleShowCapsCommand); "Shows all registered capabilities for users", HandleShowCapsCommand);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)

View File

@ -304,6 +304,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return; return;
} }
if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this.
return;
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}", "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}",
reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
@ -444,7 +447,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.", "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.",
sp.Name, finalDestination.RegionName); sp.Name, finalDestination.RegionName);
Fail(sp, finalDestination); Fail(sp, finalDestination, logout);
return; return;
} }
@ -476,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.",
sp.Name, finalDestination.RegionName); sp.Name, finalDestination.RegionName);
Fail(sp, finalDestination); Fail(sp, finalDestination, logout);
return; return;
} }
@ -527,7 +530,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
} }
private void Fail(ScenePresence sp, GridRegion finalDestination) protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
{ {
// Client never contacted destination. Let's restore everything back // Client never contacted destination. Let's restore everything back
sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
@ -1861,6 +1864,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
} }
protected bool IsInTransit(UUID id)
{
lock (m_agentsInTransit)
{
if (m_agentsInTransit.Contains(id))
return true;
}
return false;
}
protected bool ResetFromTransit(UUID id) protected bool ResetFromTransit(UUID id)
{ {
lock (m_agentsInTransit) lock (m_agentsInTransit)

View File

@ -50,6 +50,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private bool m_Initialized = false; private bool m_Initialized = false;
private bool m_RestrictInventoryAccessAbroad = false;
private GatekeeperServiceConnector m_GatekeeperConnector; private GatekeeperServiceConnector m_GatekeeperConnector;
#region ISharedRegionModule #region ISharedRegionModule
@ -68,6 +70,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (name == Name) if (name == Name)
{ {
InitialiseCommon(source); InitialiseCommon(source);
IConfig transferConfig = source.Configs["HGEntityTransfer"];
if (transferConfig != null)
m_RestrictInventoryAccessAbroad = transferConfig.GetBoolean("RestrictInventoryAccessAbroad", false);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
} }
} }
@ -170,6 +176,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason);
logout = success; // flag for later logout from this grid; this is an HG TP logout = success; // flag for later logout from this grid; this is an HG TP
if (success && m_RestrictInventoryAccessAbroad)
{
// TODO tell the viewer to remove the root folder
}
return success; return success;
} }
else else
@ -283,6 +294,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
protected override void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
{
base.Fail(sp, finalDestination, logout);
if (logout && m_RestrictInventoryAccessAbroad)
{
// Restore the user's inventory, because we removed it earlier on
InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(sp.UUID);
if (root != null)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring");
sp.ControllingClient.SendBulkUpdateInventory(root);
}
}
}
#endregion #endregion
#region IUserAgentVerificationModule #region IUserAgentVerificationModule

View File

@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
m_scene = scene; m_scene = scene;
m_scene.AddCommand(this, "monitor report", m_scene.AddCommand("General", this, "monitor report",
"monitor report", "monitor report",
"Returns a variety of statistics about the current region and/or simulator", "Returns a variety of statistics about the current region and/or simulator",
DebugMonitors); DebugMonitors);

View File

@ -0,0 +1,161 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
using Nini.Config;
namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region ISharedRegionModule
public new void Initialise(IConfigSource config)
{
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", base.Name);
if (umanmod == Name)
{
m_Enabled = true;
RegisterConsoleCmds();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
}
}
public override string Name
{
get { return "HGUserManagementModule"; }
}
#endregion ISharedRegionModule
protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
{
if (query.Contains("@")) // First.Last@foo.com, maybe?
{
string[] words = query.Split(new char[] { '@' });
if (words.Length != 2)
{
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", query);
return;
}
words[0] = words[0].Trim(); // it has at least 1
words[1] = words[1].Trim();
if (words[0] == String.Empty) // query was @foo.com?
{
foreach (UserData d in m_UserCache.Values)
{
if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
users.Add(d);
}
// We're done
return;
}
// words.Length == 2 and words[0] != string.empty
// first.last@foo.com ?
foreach (UserData d in m_UserCache.Values)
{
if (d.LastName.StartsWith("@") &&
d.FirstName.ToLower().Equals(words[0].ToLower()) &&
d.LastName.ToLower().Equals("@" + words[1].ToLower()))
{
users.Add(d);
// It's cached. We're done
return;
}
}
// This is it! Let's ask the other world
if (words[0].Contains("."))
{
string[] names = words[0].Split(new char[] { '.' });
if (names.Length >= 2)
{
string uriStr = "http://" + words[1];
// Let's check that the last name is a valid address
try
{
new Uri(uriStr);
}
catch (UriFormatException)
{
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
return;
}
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
UUID userID = uasConn.GetUUID(names[0], names[1]);
if (!userID.Equals(UUID.Zero))
{
UserData ud = new UserData();
ud.Id = userID;
ud.FirstName = words[0];
ud.LastName = "@" + words[1];
users.Add(ud);
AddUser(userID, names[0], names[1], uriStr);
m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
}
else
m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
}
}
}
//else
//{
// foreach (UserData d in m_UserCache.Values)
// {
// if (d.LastName.StartsWith("@") &&
// (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
// d.LastName.ToLower().StartsWith(query.ToLower())))
// users.Add(d);
// }
//}
}
}
}

View File

@ -38,12 +38,13 @@ using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid; using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
namespace OpenSim.Region.CoreModules.Framework.UserManagement namespace OpenSim.Region.CoreModules.Framework.UserManagement
{ {
class UserData public class UserData
{ {
public UUID Id { get; set; } public UUID Id { get; set; }
public string FirstName { get; set; } public string FirstName { get; set; }
@ -56,36 +57,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<Scene> m_Scenes = new List<Scene>(); protected bool m_Enabled;
protected List<Scene> m_Scenes = new List<Scene>();
// The cache // The cache
Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
#region ISharedRegionModule #region ISharedRegionModule
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
//m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled); string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
//if (m_Enabled) if (umanmod == Name)
//{ {
// IConfig libConfig = config.Configs["LibraryService"]; m_Enabled = true;
// if (libConfig != null) RegisterConsoleCmds();
// { m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
// string dllName = libConfig.GetString("LocalServiceModule", string.Empty); }
// m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName);
// if (dllName != string.Empty)
// {
// Object[] args = new Object[] { config };
// m_Library = ServerUtils.LoadPlugin<ILibraryService>(dllName, args);
// }
// }
//}
MainConsole.Instance.Commands.AddCommand("grid", true,
"show names",
"show names",
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
} }
public bool IsSharedModule public bool IsSharedModule
@ -93,9 +81,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
get { return true; } get { return true; }
} }
public string Name public virtual string Name
{ {
get { return "UserManagement Module"; } get { return "BasicUserManagementModule"; }
} }
public Type ReplaceableInterface public Type ReplaceableInterface
@ -105,17 +93,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
m_Scenes.Add(scene); if (m_Enabled)
{
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IUserManagement>(this); scene.RegisterModuleInterface<IUserManagement>(this);
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
}
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
scene.UnregisterModuleInterface<IUserManagement>(this); if (m_Enabled)
m_Scenes.Remove(scene); {
scene.UnregisterModuleInterface<IUserManagement>(this);
m_Scenes.Remove(scene);
}
} }
public void RegionLoaded(Scene s) public void RegionLoaded(Scene s)
@ -149,7 +143,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
void EventManager_OnNewClient(IClientAPI client) void EventManager_OnNewClient(IClientAPI client)
{ {
client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest);
}
void HandleConnectionClosed(IClientAPI client)
{
client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest);
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
} }
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
@ -170,6 +172,77 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
} }
} }
public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
{
//EventManager.TriggerAvatarPickerRequest();
m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
List<UserData> users = new List<UserData>();
if (accs != null)
{
foreach (UserAccount acc in accs)
{
UserData ud = new UserData();
ud.FirstName = acc.FirstName;
ud.LastName = acc.LastName;
ud.Id = acc.PrincipalID;
users.Add(ud);
}
}
AddAdditionalUsers(avatarID, query, users);
AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
// TODO: don't create new blocks if recycling an old packet
AvatarPickerReplyPacket.DataBlock[] searchData =
new AvatarPickerReplyPacket.DataBlock[users.Count];
AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
agentData.AgentID = avatarID;
agentData.QueryID = RequestID;
replyPacket.AgentData = agentData;
//byte[] bytes = new byte[AvatarResponses.Count*32];
int i = 0;
foreach (UserData item in users)
{
UUID translatedIDtem = item.Id;
searchData[i] = new AvatarPickerReplyPacket.DataBlock();
searchData[i].AvatarID = translatedIDtem;
searchData[i].FirstName = Utils.StringToBytes((string)item.FirstName);
searchData[i].LastName = Utils.StringToBytes((string)item.LastName);
i++;
}
if (users.Count == 0)
{
searchData = new AvatarPickerReplyPacket.DataBlock[0];
}
replyPacket.Data = searchData;
AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
agent_data.AgentID = replyPacket.AgentData.AgentID;
agent_data.QueryID = replyPacket.AgentData.QueryID;
List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
for (i = 0; i < replyPacket.Data.Length; i++)
{
AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
data_arg.AvatarID = replyPacket.Data[i].AvatarID;
data_arg.FirstName = replyPacket.Data[i].FirstName;
data_arg.LastName = replyPacket.Data[i].LastName;
data_args.Add(data_arg);
}
client.SendAvatarPickerReply(agent_data, data_args);
}
protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
{
}
#endregion Event Handlers #endregion Event Handlers
private void CacheCreators(SceneObjectGroup sog) private void CacheCreators(SceneObjectGroup sog)
@ -226,7 +299,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public string GetUserName(UUID uuid) public string GetUserName(UUID uuid)
{ {
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
string[] names = GetUserNames(uuid); string[] names = GetUserNames(uuid);
if (names.Length == 2) if (names.Length == 2)
{ {
@ -267,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
{ {
m_log.DebugFormat( //m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
serverType, userdata.HomeURL, userID); // serverType, userdata.HomeURL, userID);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
userdata.ServerURLs = uConn.GetServerURLs(userID); userdata.ServerURLs = uConn.GetServerURLs(userID);
@ -328,11 +400,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public void AddUser(UUID uuid, string first, string last, string homeURL) public void AddUser(UUID uuid, string first, string last, string homeURL)
{ {
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
AddUser(uuid, homeURL + ";" + first + " " + last); AddUser(uuid, homeURL + ";" + first + " " + last);
} }
public void AddUser (UUID id, string creatorData) public void AddUser (UUID id, string creatorData)
{ {
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
UserData oldUser; UserData oldUser;
//lock the whole block - prevent concurrent update //lock the whole block - prevent concurrent update
lock (m_UserCache) lock (m_UserCache)
@ -358,9 +434,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return; return;
} }
} }
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id); UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
if (account != null) if (account != null)
{ {
@ -409,9 +484,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache) lock (m_UserCache)
m_UserCache[user.Id] = user; m_UserCache[user.Id] = user;
// m_log.DebugFormat( //m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
// user.Id, user.FirstName, user.LastName, user.HomeURL); // user.Id, user.FirstName, user.LastName, user.HomeURL);
} }
public bool IsLocalGridUser(UUID uuid) public bool IsLocalGridUser(UUID uuid)
@ -425,13 +500,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#endregion IUserManagement #endregion IUserManagement
protected void RegisterConsoleCmds()
{
MainConsole.Instance.Commands.AddCommand("Users", true,
"show names",
"show names",
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
}
private void HandleShowUsers(string module, string[] cmd) private void HandleShowUsers(string module, string[] cmd)
{ {
lock (m_UserCache) lock (m_UserCache)
{ {
if (m_UserCache.Count == 0) if (m_UserCache.Count == 0)
{ {
MainConsole.Instance.Output("No users not found"); MainConsole.Instance.Output("No users found");
return; return;
} }

View File

@ -9,6 +9,7 @@
<Extension path = "/OpenSim/RegionModules"> <Extension path = "/OpenSim/RegionModules">
<RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" /> <RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
<RegionModule id="HGUserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.HGUserManagementModule" />
<RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" /> <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
<RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" /> <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
<RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" /> <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />

View File

@ -151,6 +151,14 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
#region IWorldComm Members #region IWorldComm Members
public int ListenerCount
{
get
{
return m_listenerManager.ListenerCount;
}
}
/// <summary> /// <summary>
/// Create a listen event callback with the specified filters. /// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify /// The parameters localID,itemID are needed to uniquely identify
@ -438,6 +446,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
private int m_maxhandles; private int m_maxhandles;
private int m_curlisteners; private int m_curlisteners;
/// <summary>
/// Total number of listeners
/// </summary>
public int ListenerCount
{
get
{
lock (m_listeners)
return m_listeners.Count;
}
}
public ListenerManager(int maxlisteners, int maxhandles) public ListenerManager(int maxlisteners, int maxhandles)
{ {
m_maxlisteners = maxlisteners; m_maxlisteners = maxlisteners;

View File

@ -48,8 +48,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
private static bool m_Enabled = false; private static bool m_Enabled = false;
private IConfigSource m_Config; private IConfigSource m_Config;
bool m_Registered = false; private bool m_Registered = false;
GatekeeperServiceInConnector m_HypergridHandler; private string m_LocalServiceDll = String.Empty;
private GatekeeperServiceInConnector m_HypergridHandler;
private UserAgentServerConnector m_UASHandler;
#region IRegionModule interface #region IRegionModule interface
@ -63,6 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
if (m_Enabled) if (m_Enabled)
{ {
m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled"); m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled");
IConfig fconfig = config.Configs["FriendsService"];
if (fconfig != null)
{
m_LocalServiceDll = fconfig.GetString("LocalServiceModule", m_LocalServiceDll);
if (m_LocalServiceDll == String.Empty)
m_log.WarnFormat("[HGGRID IN CONNECTOR]: Friends LocalServiceModule config missing");
}
} }
} }
@ -91,7 +100,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
{ {
if (!m_Enabled) if (!m_Enabled)
return; return;
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -112,14 +120,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
m_log.Info("[HypergridService]: Starting..."); m_log.Info("[HypergridService]: Starting...");
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
Object[] args = new Object[] { m_Config };
IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args);
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>(); m_UASHandler = new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService", friendsConn);
} }
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
scene.RegisterModuleInterface<IUserAgentService>(m_UASHandler.HomeUsersService);
} }
#endregion #endregion

View File

@ -73,14 +73,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
return; return;
} }
string serviceDll = assetConfig.GetString("LocalServiceModule", string serviceDll = assetConfig.GetString("LocalServiceModule", String.Empty);
String.Empty);
if (serviceDll == String.Empty) if (serviceDll == String.Empty)
{ {
m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService"); m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService");
return; return;
} }
else
{
m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Loading asset service at {0}", serviceDll);
}
Object[] args = new Object[] { source }; Object[] args = new Object[] { source };
m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args); m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args);

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Nini.Config;
using log4net;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
{
public class AuthorizationService : IAuthorizationService
{
private enum AccessFlags
{
None = 0, /* No restrictions */
DisallowResidents = 1, /* Only gods and managers*/
DisallowForeigners = 2, /* Only local people */
}
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private IUserManagement m_UserManagement;
private IGridService m_GridService;
private Scene m_Scene;
AccessFlags m_accessValue = AccessFlags.None;
public AuthorizationService(IConfig config, Scene scene)
{
m_Scene = scene;
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
m_GridService = scene.GridService;
if (config != null)
{
string accessStr = config.GetString("Region_" + scene.RegionInfo.RegionName.Replace(' ', '_'), String.Empty);
if (accessStr != string.Empty)
{
try
{
m_accessValue = (AccessFlags)Enum.Parse(typeof(AccessFlags), accessStr);
}
catch (ArgumentException)
{
m_log.WarnFormat("[AuthorizationService]: {0} is not a valid access flag", accessStr);
}
}
m_log.DebugFormat("[AuthorizationService]: Region {0} access restrictions: {1}", m_Scene.RegionInfo.RegionName, m_accessValue);
}
}
public bool IsAuthorizedForRegion(
string user, string firstName, string lastName, string regionID, out string message)
{
message = "authorized";
// This should not happen
if (m_Scene.RegionInfo.RegionID.ToString() != regionID)
{
m_log.WarnFormat("[AuthorizationService]: Service for region {0} received request to authorize for region {1}",
m_Scene.RegionInfo.RegionID, regionID);
return true;
}
if (m_accessValue == AccessFlags.None)
return true;
UUID userID = new UUID(user);
bool authorized = true;
if ((m_accessValue & AccessFlags.DisallowForeigners) == AccessFlags.DisallowForeigners)
{
authorized = m_UserManagement.IsLocalGridUser(userID);
if (!authorized)
message = "no foreigner users allowed in this region";
}
if (authorized && (m_accessValue & AccessFlags.DisallowResidents) == AccessFlags.DisallowResidents)
{
authorized = m_Scene.Permissions.IsGod(userID) | m_Scene.Permissions.IsAdministrator(userID);
if (!authorized)
message = "only Admins and Managers allowed in this region";
}
return authorized;
}
}
}

View File

@ -39,13 +39,15 @@ using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
{ {
public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private IAuthorizationService m_AuthorizationService; private IAuthorizationService m_AuthorizationService;
private Scene m_Scene;
private IConfig m_AuthorizationConfig;
private bool m_Enabled = false; private bool m_Enabled = false;
@ -69,33 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
string name = moduleConfig.GetString("AuthorizationServices", string.Empty); string name = moduleConfig.GetString("AuthorizationServices", string.Empty);
if (name == Name) if (name == Name)
{ {
IConfig authorizationConfig = source.Configs["AuthorizationService"];
if (authorizationConfig == null)
{
m_log.Error("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini");
return;
}
string serviceDll = authorizationConfig.GetString("LocalServiceModule",
String.Empty);
if (serviceDll == String.Empty)
{
m_log.Error("[AUTHORIZATION CONNECTOR]: No LocalServiceModule named in section AuthorizationService");
return;
}
Object[] args = new Object[] { source };
m_AuthorizationService =
ServerUtils.LoadPlugin<IAuthorizationService>(serviceDll,
args);
if (m_AuthorizationService == null)
{
m_log.Error("[AUTHORIZATION CONNECTOR]: Can't load authorization service");
return;
}
m_Enabled = true; m_Enabled = true;
m_AuthorizationConfig = source.Configs["AuthorizationService"];
m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled"); m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled");
} }
} }
@ -115,6 +92,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
return; return;
scene.RegisterModuleInterface<IAuthorizationService>(this); scene.RegisterModuleInterface<IAuthorizationService>(this);
m_Scene = scene;
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -126,6 +104,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
if (!m_Enabled) if (!m_Enabled)
return; return;
m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
m_log.InfoFormat( m_log.InfoFormat(
"[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
scene.RegionInfo.RegionName); scene.RegionInfo.RegionName);
@ -134,6 +114,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
public bool IsAuthorizedForRegion( public bool IsAuthorizedForRegion(
string userID, string firstName, string lastName, string regionID, out string message) string userID, string firstName, string lastName, string regionID, out string message)
{ {
message = "";
if (!m_Enabled)
return true;
return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message); return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
} }
} }

View File

@ -48,8 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private static LocalGridServicesConnector m_MainInstance;
private IGridService m_GridService; private IGridService m_GridService;
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>(); private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
@ -62,7 +60,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public LocalGridServicesConnector(IConfigSource source) public LocalGridServicesConnector(IConfigSource source)
{ {
m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated"); m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated");
m_MainInstance = this;
InitialiseService(source); InitialiseService(source);
} }
@ -87,7 +84,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (name == Name) if (name == Name)
{ {
InitialiseService(source); InitialiseService(source);
m_MainInstance = this;
m_Enabled = true; m_Enabled = true;
m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled"); m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled");
} }
@ -126,12 +122,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public void PostInitialise() public void PostInitialise()
{ {
if (m_MainInstance == this) MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours",
{ "show neighbours",
MainConsole.Instance.Commands.AddCommand("LocalGridConnector", false, "show neighbours", "Shows the local regions' neighbours", NeighboursCommand);
"show neighbours",
"Shows the local regions' neighbours", NeighboursCommand);
}
} }
public void Close() public void Close()
@ -143,22 +136,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (m_Enabled) if (m_Enabled)
scene.RegisterModuleInterface<IGridService>(this); scene.RegisterModuleInterface<IGridService>(this);
if (m_MainInstance == this) if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
{ m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) else
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
else
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
}
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (m_MainInstance == this) m_LocalCache[scene.RegionInfo.RegionID].Clear();
{ m_LocalCache.Remove(scene.RegionInfo.RegionID);
m_LocalCache[scene.RegionInfo.RegionID].Clear();
m_LocalCache.Remove(scene.RegionInfo.RegionID);
}
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
@ -259,6 +246,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
MainConsole.Instance.Output(caps.ToString()); MainConsole.Instance.Output(caps.ToString());
} }
} }
} }

View File

@ -58,6 +58,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private List<Scene> m_Scenes = new List<Scene>(); private List<Scene> m_Scenes = new List<Scene>();
private InventoryCache m_Cache = new InventoryCache();
protected IUserManagement m_UserManagement; protected IUserManagement m_UserManagement;
protected IUserManagement UserManagementModule protected IUserManagement UserManagementModule
{ {
@ -312,6 +314,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
public InventoryFolderBase GetRootFolder(UUID userID) public InventoryFolderBase GetRootFolder(UUID userID)
{ {
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID); //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID);
InventoryFolderBase root = m_Cache.GetRootFolder(userID);
if (root != null)
return root;
string invURL = GetInventoryServiceURL(userID); string invURL = GetInventoryServiceURL(userID);
@ -320,12 +325,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
IInventoryService connector = GetConnector(invURL); IInventoryService connector = GetConnector(invURL);
return connector.GetRootFolder(userID); root = connector.GetRootFolder(userID);
m_Cache.Cache(userID, root);
return root;
} }
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
{ {
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type); //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type);
InventoryFolderBase f = m_Cache.GetFolderForType(userID, type);
if (f != null)
return f;
string invURL = GetInventoryServiceURL(userID); string invURL = GetInventoryServiceURL(userID);
@ -334,7 +346,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
IInventoryService connector = GetConnector(invURL); IInventoryService connector = GetConnector(invURL);
return connector.GetFolderForType(userID, type); f = connector.GetFolderForType(userID, type);
m_Cache.Cache(userID, type, f);
return f;
} }
public InventoryCollection GetFolderContent(UUID userID, UUID folderID) public InventoryCollection GetFolderContent(UUID userID, UUID folderID)

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using OpenSim.Framework;
using OpenMetaverse;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
public class InventoryCache
{
private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour
private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>();
private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>();
public void Cache(UUID userID, InventoryFolderBase root)
{
lock (m_RootFolders)
m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS);
}
public InventoryFolderBase GetRootFolder(UUID userID)
{
InventoryFolderBase root = null;
if (m_RootFolders.TryGetValue(userID, out root))
return root;
return null;
}
public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
{
lock (m_FolderTypes)
{
Dictionary<AssetType, InventoryFolderBase> ff = null;
if (!m_FolderTypes.TryGetValue(userID, out ff))
{
ff = new Dictionary<AssetType, InventoryFolderBase>();
m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
}
if (!ff.ContainsKey(type))
ff.Add(type, folder);
}
}
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
{
Dictionary<AssetType, InventoryFolderBase> ff = null;
if (m_FolderTypes.TryGetValue(userID, out ff))
{
InventoryFolderBase f = null;
if (ff.TryGetValue(type, out f))
return f;
}
return null;
}
}
}

View File

@ -47,21 +47,21 @@ namespace OpenSim.Region.CoreModules.World
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
MainConsole.Instance.Commands.AddCommand("access", true, MainConsole.Instance.Commands.AddCommand("Users", true,
"login enable", "login enable",
"login enable", "login enable",
"Enable simulator logins", "Enable simulator logins",
String.Empty, String.Empty,
HandleLoginCommand); HandleLoginCommand);
MainConsole.Instance.Commands.AddCommand("access", true, MainConsole.Instance.Commands.AddCommand("Users", true,
"login disable", "login disable",
"login disable", "login disable",
"Disable simulator logins", "Disable simulator logins",
String.Empty, String.Empty,
HandleLoginCommand); HandleLoginCommand);
MainConsole.Instance.Commands.AddCommand("access", true, MainConsole.Instance.Commands.AddCommand("Users", true,
"login status", "login status",
"login status", "login status",
"Show login status", "Show login status",

View File

@ -108,12 +108,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// "[ARCHIVER]: Received {0} of {1} assets requested", // "[ARCHIVER]: Received {0} of {1} assets requested",
// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
// Write out region settings // Write out region settings
string settingsPath string settingsPath
= String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName); = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings)); m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
m_log.InfoFormat("[ARCHIVER]: Added region settings to archive."); m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
// Write out land data (aka parcel) settings // Write out land data (aka parcel) settings
List<ILandObject>landObjects = m_scene.LandChannel.AllParcels(); List<ILandObject>landObjects = m_scene.LandChannel.AllParcels();
@ -124,7 +126,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
landData.GlobalID.ToString()); landData.GlobalID.ToString());
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData)); m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
} }
m_log.InfoFormat("[ARCHIVER]: Added parcel settings to archive.");
m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
// Write out terrain // Write out terrain
string terrainPath string terrainPath
@ -135,7 +138,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_archiveWriter.WriteFile(terrainPath, ms.ToArray()); m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
ms.Close(); ms.Close();
m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive."); m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
// Write out scene object metadata // Write out scene object metadata
foreach (SceneObjectGroup sceneObject in m_sceneObjects) foreach (SceneObjectGroup sceneObject in m_sceneObjects)
@ -145,10 +148,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options); string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options);
m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject); m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
} }
m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive.");
} }
} }
} }

View File

@ -219,12 +219,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
if (SaveAssets) if (SaveAssets)
new AssetsRequest( {
new AssetsArchiver(archiveWriter), assetUuids, AssetsRequest ar
m_scene.AssetService, m_scene.UserAccountService, = new AssetsRequest(
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); new AssetsArchiver(archiveWriter), assetUuids,
m_scene.AssetService, m_scene.UserAccountService,
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets);
Util.FireAndForget(o => ar.Execute());
}
else else
{
awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>()); awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
}
} }
catch (Exception) catch (Exception)
{ {

View File

@ -142,12 +142,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
return; return;
} }
m_requestCallbackTimer.Enabled = true;
foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids) foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
{ {
m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); // m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
AssetBase asset = m_assetService.Get(kvp.Key.ToString());
PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
} }
m_requestCallbackTimer.Enabled = true;
} }
protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)

View File

@ -62,58 +62,25 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName); m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName);
m_module.Scene.AddCommand(m_module, "set terrain texture", m_module.Scene.AddCommand("Regions", m_module, "set terrain texture",
"set terrain texture <number> <uuid> [<x>] [<y>]", "set terrain texture <number> <uuid> [<x>] [<y>]",
"Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " + "Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate.", " that coordinate.",
consoleSetTerrainTexture); consoleSetTerrainTexture);
m_module.Scene.AddCommand(m_module, "set terrain heights", m_module.Scene.AddCommand("Regions", m_module, "set terrain heights",
"set terrain heights <corner> <min> <max> [<x>] [<y>]", "set terrain heights <corner> <min> <max> [<x>] [<y>]",
"Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " + "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.", " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
consoleSetTerrainHeights); consoleSetTerrainHeights);
Command showCommand m_module.Scene.AddCommand(
= new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowEstatesCommand, "Shows all estates on the simulator."); "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand);
m_commander.RegisterCommand("show", showCommand);
m_module.Scene.RegisterModuleCommander(m_commander);
m_module.Scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole;
} }
public void Close() public void Close() {}
{
m_module.Scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole;
m_module.Scene.UnregisterModuleCommander(m_commander.Name);
}
/// <summary>
/// Processes commandline input. Do not call directly.
/// </summary>
/// <param name="args">Commandline arguments</param>
protected void EventManagerOnPluginConsole(string[] args)
{
if (args[0] == "estate")
{
if (args.Length == 1)
{
m_commander.ProcessConsoleCommand("help", new string[0]);
return;
}
string[] tmpArgs = new string[args.Length - 2];
int i;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
protected void consoleSetTerrainTexture(string module, string[] args) protected void consoleSetTerrainTexture(string module, string[] args)
{ {
@ -201,7 +168,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
} }
} }
protected void ShowEstatesCommand(Object[] args) protected void ShowEstatesCommand(string module, string[] cmd)
{ {
StringBuilder report = new StringBuilder(); StringBuilder report = new StringBuilder();
RegionInfo ri = m_module.Scene.RegionInfo; RegionInfo ri = m_module.Scene.RegionInfo;

View File

@ -26,8 +26,10 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Security; using System.Security;
using log4net; using log4net;
@ -45,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private delegate void LookupUUIDS(List<UUID> uuidLst);
public Scene Scene { get; private set; } public Scene Scene { get; private set; }
public IUserManagement UserManager { get; private set; } public IUserManagement UserManager { get; private set; }
@ -604,7 +604,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
{ {
uint ObjectLocalID;
SceneObjectPart part; SceneObjectPart part;
switch (cmd) switch (cmd)
@ -661,28 +660,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
TriggerEstateMessage(senderID, senderName, message); TriggerEstateMessage(senderID, senderName, message);
} }
private void handleEstateDebugRegionRequest(IClientAPI remote_client, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics) private void handleEstateDebugRegionRequest(
IClientAPI remote_client, UUID invoice, UUID senderID,
bool disableScripts, bool disableCollisions, bool disablePhysics)
{ {
if (physics) Scene.RegionInfo.RegionSettings.DisablePhysics = disablePhysics;
Scene.RegionInfo.RegionSettings.DisablePhysics = true; Scene.RegionInfo.RegionSettings.DisableScripts = disableScripts;
else Scene.RegionInfo.RegionSettings.DisableCollisions = disableCollisions;
Scene.RegionInfo.RegionSettings.DisablePhysics = false;
if (scripted)
Scene.RegionInfo.RegionSettings.DisableScripts = true;
else
Scene.RegionInfo.RegionSettings.DisableScripts = false;
if (collisionEvents)
Scene.RegionInfo.RegionSettings.DisableCollisions = true;
else
Scene.RegionInfo.RegionSettings.DisableCollisions = false;
Scene.RegionInfo.RegionSettings.Save(); Scene.RegionInfo.RegionSettings.Save();
TriggerRegionInfoChange(); TriggerRegionInfoChange();
Scene.SetSceneCoreDebug(scripted, collisionEvents, physics); Scene.SetSceneCoreDebug(
new Dictionary<string, string>() {
{ "scripting", (!disableScripts).ToString() },
{ "collisions", (!disableCollisions).ToString() },
{ "physics", (!disablePhysics).ToString() }
}
);
} }
private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
@ -876,98 +870,76 @@ namespace OpenSim.Region.CoreModules.World.Estate
if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false)) if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false))
return; return;
Dictionary<uint, float> SceneData = new Dictionary<uint,float>(); Dictionary<uint, float> sceneData = null;
List<UUID> uuidNameLookupList = new List<UUID>();
if (reportType == 1) if (reportType == 1)
{ {
SceneData = Scene.PhysicsScene.GetTopColliders(); sceneData = Scene.PhysicsScene.GetTopColliders();
} }
else if (reportType == 0) else if (reportType == 0)
{ {
SceneData = Scene.SceneGraph.GetTopScripts(); IScriptModule scriptModule = Scene.RequestModuleInterface<IScriptModule>();
if (scriptModule != null)
sceneData = scriptModule.GetObjectScriptsExecutionTimes();
} }
List<LandStatReportItem> SceneReport = new List<LandStatReportItem>(); List<LandStatReportItem> SceneReport = new List<LandStatReportItem>();
lock (SceneData) if (sceneData != null)
{ {
foreach (uint obj in SceneData.Keys) var sortedSceneData
= sceneData.Select(
item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) });
sortedSceneData.OrderBy(item => item.Measurement);
int items = 0;
foreach (var entry in sortedSceneData)
{ {
SceneObjectPart prt = Scene.GetSceneObjectPart(obj); // The object may have been deleted since we received the data.
if (prt != null) if (entry.Part == null)
continue;
// Don't show scripts that haven't executed or where execution time is below one microsecond in
// order to produce a more readable report.
if (entry.Measurement < 0.001)
continue;
items++;
SceneObjectGroup so = entry.Part.ParentGroup;
LandStatReportItem lsri = new LandStatReportItem();
lsri.LocationX = so.AbsolutePosition.X;
lsri.LocationY = so.AbsolutePosition.Y;
lsri.LocationZ = so.AbsolutePosition.Z;
lsri.Score = entry.Measurement;
lsri.TaskID = so.UUID;
lsri.TaskLocalID = so.LocalId;
lsri.TaskName = entry.Part.Name;
lsri.OwnerName = UserManager.GetUserName(so.OwnerID);
if (filter.Length != 0)
{ {
SceneObjectGroup sog = prt.ParentGroup; if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
LandStatReportItem lsri = new LandStatReportItem();
lsri.LocationX = sog.AbsolutePosition.X;
lsri.LocationY = sog.AbsolutePosition.Y;
lsri.LocationZ = sog.AbsolutePosition.Z;
lsri.Score = SceneData[obj];
lsri.TaskID = sog.UUID;
lsri.TaskLocalID = sog.LocalId;
lsri.TaskName = sog.GetPartName(obj);
lsri.OwnerName = "waiting";
lock (uuidNameLookupList)
uuidNameLookupList.Add(sog.OwnerID);
if (filter.Length != 0)
{ {
if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
{
}
else
{
continue;
}
} }
else
SceneReport.Add(lsri); {
continue;
}
} }
SceneReport.Add(lsri);
if (items >= 100)
break;
} }
} }
remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
if (uuidNameLookupList.Count > 0)
LookupUUID(uuidNameLookupList);
} }
private static void LookupUUIDSCompleted(IAsyncResult iar)
{
LookupUUIDS icon = (LookupUUIDS)iar.AsyncState;
icon.EndInvoke(iar);
}
private void LookupUUID(List<UUID> uuidLst)
{
LookupUUIDS d = LookupUUIDsAsync;
d.BeginInvoke(uuidLst,
LookupUUIDSCompleted,
d);
}
private void LookupUUIDsAsync(List<UUID> uuidLst)
{
UUID[] uuidarr;
lock (uuidLst)
{
uuidarr = uuidLst.ToArray();
}
for (int i = 0; i < uuidarr.Length; i++)
{
// string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
IUserManagement userManager = Scene.RequestModuleInterface<IUserManagement>();
if (userManager != null)
userManager.GetUserName(uuidarr[i]);
// we drop it. It gets cached though... so we're ready for the next request.
// diva commnent 11/21/2010: uh?!? wft?
// justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume.
}
}
#endregion #endregion
#region Outgoing Packets #region Outgoing Packets

View File

@ -448,8 +448,6 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsRestrictedFromLand(UUID avatar) public bool IsRestrictedFromLand(UUID avatar)
{ {
ExpireAccessList();
if (m_scene.Permissions.IsAdministrator(avatar)) if (m_scene.Permissions.IsAdministrator(avatar))
return false; return false;
@ -459,20 +457,27 @@ namespace OpenSim.Region.CoreModules.World.Land
if (avatar == LandData.OwnerID) if (avatar == LandData.OwnerID)
return false; return false;
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
return false;
return (!IsInLandAccessList(avatar));
}
public bool IsInLandAccessList(UUID avatar)
{
ExpireAccessList();
if (LandData.ParcelAccessList.FindIndex(
delegate(LandAccessEntry e)
{
if (e.AgentID == avatar && e.Flags == AccessList.Access)
return true;
return false;
}) == -1)
{ {
if (LandData.ParcelAccessList.FindIndex( return false;
delegate(LandAccessEntry e)
{
if (e.AgentID == avatar && e.Flags == AccessList.Access)
return true;
return false;
}) == -1)
{
return true;
}
} }
return false; return true;
} }
public void SendLandUpdateToClient(IClientAPI remote_client) public void SendLandUpdateToClient(IClientAPI remote_client)

View File

@ -78,45 +78,45 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_scene = scene; m_scene = scene;
m_console = MainConsole.Instance; m_console = MainConsole.Instance;
m_console.Commands.AddCommand("region", false, "delete object owner", m_console.Commands.AddCommand("Regions", false, "delete object owner",
"delete object owner <UUID>", "delete object owner <UUID>",
"Delete a scene object by owner", HandleDeleteObject); "Delete a scene object by owner", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object creator", m_console.Commands.AddCommand("Regions", false, "delete object creator",
"delete object creator <UUID>", "delete object creator <UUID>",
"Delete a scene object by creator", HandleDeleteObject); "Delete a scene object by creator", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object uuid", m_console.Commands.AddCommand("Regions", false, "delete object uuid",
"delete object uuid <UUID>", "delete object uuid <UUID>",
"Delete a scene object by uuid", HandleDeleteObject); "Delete a scene object by uuid", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object name", m_console.Commands.AddCommand("Regions", false, "delete object name",
"delete object name <name>", "delete object name <name>",
"Delete a scene object by name", HandleDeleteObject); "Delete a scene object by name", HandleDeleteObject);
m_console.Commands.AddCommand("region", false, "delete object outside", m_console.Commands.AddCommand("Regions", false, "delete object outside",
"delete object outside", "delete object outside",
"Delete all scene objects outside region boundaries", HandleDeleteObject); "Delete all scene objects outside region boundaries", HandleDeleteObject);
m_console.Commands.AddCommand( m_console.Commands.AddCommand(
"region", "Regions",
false, false,
"show object uuid", "show object uuid",
"show object uuid <UUID>", "show object uuid <UUID>",
"Show details of a scene object with the given UUID", HandleShowObjectByUuid); "Show details of a scene object with the given UUID", HandleShowObjectByUuid);
m_console.Commands.AddCommand( m_console.Commands.AddCommand(
"region", "Regions",
false, false,
"show object name", "show object name",
"show object name <name>", "show object name <name>",
"Show details of scene objects with the given name", HandleShowObjectByName); "Show details of scene objects with the given name", HandleShowObjectByName);
m_console.Commands.AddCommand( m_console.Commands.AddCommand(
"region", "Regions",
false, false,
"show part uuid", "show part uuid",
"show part uuid <UUID>", "show part uuid <UUID>",
"Show details of a scene object parts with the given UUID", HandleShowPartByUuid); "Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
m_console.Commands.AddCommand( m_console.Commands.AddCommand(
"region", "Regions",
false, false,
"show part name", "show part name",
"show part name <name>", "show part name <name>",

View File

@ -95,6 +95,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
private bool m_RegionManagerIsGod = false; private bool m_RegionManagerIsGod = false;
private bool m_ParcelOwnerIsGod = false; private bool m_ParcelOwnerIsGod = false;
private bool m_SimpleBuildPermissions = false;
/// <value> /// <value>
/// The set of users that are allowed to create scripts. This is only active if permissions are not being /// The set of users that are allowed to create scripts. This is only active if permissions are not being
/// bypassed. This overrides normal permissions. /// bypassed. This overrides normal permissions.
@ -140,6 +142,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false); m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false);
m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true); m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true);
m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false);
m_allowedScriptCreators m_allowedScriptCreators
= ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators); = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators);
m_allowedScriptEditors m_allowedScriptEditors
@ -206,17 +210,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia; m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
m_scene.AddCommand(this, "bypass permissions", m_scene.AddCommand("Users", this, "bypass permissions",
"bypass permissions <true / false>", "bypass permissions <true / false>",
"Bypass permission checks", "Bypass permission checks",
HandleBypassPermissions); HandleBypassPermissions);
m_scene.AddCommand(this, "force permissions", m_scene.AddCommand("Users", this, "force permissions",
"force permissions <true / false>", "force permissions <true / false>",
"Force permissions on or off", "Force permissions on or off",
HandleForcePermissions); HandleForcePermissions);
m_scene.AddCommand(this, "debug permissions", m_scene.AddCommand("Users", this, "debug permissions",
"debug permissions <true / false>", "debug permissions <true / false>",
"Turn on permissions debugging", "Turn on permissions debugging",
HandleDebugPermissions); HandleDebugPermissions);
@ -824,6 +828,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
permission = true; permission = true;
} }
if (m_SimpleBuildPermissions &&
(parcel.LandData.Flags & (uint)ParcelFlags.UseAccessList) == 0 && parcel.IsInLandAccessList(user))
permission = true;
return permission; return permission;
} }

View File

@ -66,21 +66,21 @@ namespace OpenSim.Region.CoreModules.World.Region
m_Scene = scene; m_Scene = scene;
scene.RegisterModuleInterface<IRestartModule>(this); scene.RegisterModuleInterface<IRestartModule>(this);
MainConsole.Instance.Commands.AddCommand("RestartModule", MainConsole.Instance.Commands.AddCommand("Regions",
false, "region restart bluebox", false, "region restart bluebox",
"region restart bluebox <message> <delta seconds>+", "region restart bluebox <message> <delta seconds>+",
"Schedule a region restart", "Schedule a region restart",
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.", "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.",
HandleRegionRestart); HandleRegionRestart);
MainConsole.Instance.Commands.AddCommand("RestartModule", MainConsole.Instance.Commands.AddCommand("Regions",
false, "region restart notice", false, "region restart notice",
"region restart notice <message> <delta seconds>+", "region restart notice <message> <delta seconds>+",
"Schedule a region restart", "Schedule a region restart",
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.", "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.",
HandleRegionRestart); HandleRegionRestart);
MainConsole.Instance.Commands.AddCommand("RestartModule", MainConsole.Instance.Commands.AddCommand("Regions",
false, "region restart abort", false, "region restart abort",
"region restart abort [<message>]", "region restart abort [<message>]",
"Abort a region restart", HandleRegionRestart); "Abort a region restart", HandleRegionRestart);

View File

@ -277,18 +277,19 @@ namespace OpenSim.Region.CoreModules
m_frame = 0; m_frame = 0;
// This one puts an entry in the main help screen // This one puts an entry in the main help screen
m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); // m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
// This one enables the ability to type just "sun" without any parameters // This one enables the ability to type just "sun" without any parameters
m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand); // m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
foreach (KeyValuePair<string, string> kvp in GetParamList()) foreach (KeyValuePair<string, string> kvp in GetParamList())
{ {
m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand); string sunCommand = string.Format("sun {0}", kvp.Key);
m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
} }
TimeZone local = TimeZone.CurrentTimeZone; TimeZone local = TimeZone.CurrentTimeZone;
TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset); m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset);
// Align ticks with Second Life // Align ticks with Second Life

View File

@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{ {
// We need to do this because: // We need to do this because:
// "Saving the image to the same file it was constructed from is not allowed and throws an exception." // "Saving the image to the same file it was constructed from is not allowed and throws an exception."
string tempName = offsetX + "_ " + offsetY + "_" + filename; string tempName = Path.GetTempFileName();
Bitmap entireBitmap = null; Bitmap entireBitmap = null;
Bitmap thisBitmap = null; Bitmap thisBitmap = null;
if (File.Exists(filename)) if (File.Exists(filename))
{ {
File.Copy(filename, tempName); File.Copy(filename, tempName, true);
entireBitmap = new Bitmap(tempName); entireBitmap = new Bitmap(tempName);
if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
{ {
@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
} }
thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
for (int x = 0; x < regionSizeX; x++) for (int x = 0; x < regionSizeX; x++)
for (int y = 0; y < regionSizeY; y++) for (int y = 0; y < regionSizeY; y++)
entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));

View File

@ -38,6 +38,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain
ITerrainChannel LoadStream(Stream stream); ITerrainChannel LoadStream(Stream stream);
void SaveFile(string filename, ITerrainChannel map); void SaveFile(string filename, ITerrainChannel map);
void SaveStream(Stream stream, ITerrainChannel map); void SaveStream(Stream stream, ITerrainChannel map);
/// <summary>
/// Save a number of map tiles to a single big image file.
/// </summary>
/// <remarks>
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
/// will be untouched.
/// </remarks>
/// <param name="filename">The terrain file to save</param>
/// <param name="offsetX">The map x co-ordinate at which to begin the save.</param>
/// <param name="offsetY">The may y co-ordinate at which to begin the save.</param>
/// <param name="fileWidth">The number of tiles to save along the X axis.</param>
/// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
/// <param name="regionSizeX">The width of a map tile.</param>
/// <param name="regionSizeY">The height of a map tile.</param>
void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
} }
} }

View File

@ -86,6 +86,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private volatile bool m_tainted; private volatile bool m_tainted;
private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5);
private String m_InitialTerrain = "pinhead-island";
/// <summary> /// <summary>
/// Human readable list of terrain file extensions that are supported. /// Human readable list of terrain file extensions that are supported.
/// </summary> /// </summary>
@ -109,6 +111,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
/// <param name="config">Config for the region</param> /// <param name="config">Config for the region</param>
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
IConfig terrainConfig = config.Configs["Terrain"];
if (terrainConfig != null)
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
} }
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
@ -120,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
{ {
if (m_scene.Heightmap == null) if (m_scene.Heightmap == null)
{ {
m_channel = new TerrainChannel(); m_channel = new TerrainChannel(m_InitialTerrain);
m_scene.Heightmap = m_channel; m_scene.Heightmap = m_channel;
m_revert = new TerrainChannel(); m_revert = new TerrainChannel();
UpdateRevertMap(); UpdateRevertMap();
@ -556,43 +561,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
} }
/// <summary> /// <summary>
/// Saves the terrain to a larger terrain file. /// Save a number of map tiles to a single big image file.
/// </summary> /// </summary>
/// <remarks>
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
/// will be untouched.
/// </remarks>
/// <param name="filename">The terrain file to save</param> /// <param name="filename">The terrain file to save</param>
/// <param name="fileWidth">The width of the file in units</param> /// <param name="fileWidth">The number of tiles to save along the X axis.</param>
/// <param name="fileHeight">The height of the file in units</param> /// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
/// <param name="fileStartX">Where to begin our slice</param> /// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param>
/// <param name="fileStartY">Where to begin our slice</param> /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
{ {
int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
{ {
// this region is included in the tile request MainConsole.Instance.OutputFormat(
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) "ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
{ m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
fileWidth, fileHeight,
(int)Constants.RegionSize,
(int)Constants.RegionSize);
m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename); return;
}
return;
}
}
m_log.ErrorFormat(
"[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
} }
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{
lock (m_scene)
{
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
fileWidth, fileHeight,
(int)Constants.RegionSize,
(int)Constants.RegionSize);
MainConsole.Instance.OutputFormat(
"Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1,
m_scene.RegionInfo.RegionName, filename);
}
return;
}
}
MainConsole.Instance.OutputFormat(
"ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
} }
/// <summary> /// <summary>
@ -1179,8 +1197,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
"Integer"); "Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
"Integer"); + "= Example =\n"
+ "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
+ " # terrain save-tile ST06.png 2 3 9910 10234\n",
"Integer");
// Terrain adjustments // Terrain adjustments
Command fillRegionCommand = Command fillRegionCommand =
new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");

View File

@ -117,24 +117,31 @@ namespace OpenSim.Region.CoreModules
} }
// This one puts an entry in the main help screen // This one puts an entry in the main help screen
m_scene.AddCommand(this, String.Empty, "wind", "Usage: wind <plugin> <param> [value] - Get or Update Wind paramaters", null); // m_scene.AddCommand("Regions", this, "wind", "wind", "Usage: wind <plugin> <param> [value] - Get or Update Wind paramaters", null);
// This one enables the ability to type just the base command without any parameters // This one enables the ability to type just the base command without any parameters
m_scene.AddCommand(this, "wind", "", "", HandleConsoleCommand); // m_scene.AddCommand("Regions", this, "wind", "", "", HandleConsoleCommand);
// Get a list of the parameters for each plugin // Get a list of the parameters for each plugin
foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values) foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values)
{ {
m_scene.AddCommand(this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand); // m_scene.AddCommand("Regions", this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand);
m_scene.AddCommand(this, String.Format("wind base wind_update_rate"), "Change the wind update rate.", "", HandleConsoleBaseCommand); m_scene.AddCommand(
"Regions",
this,
"wind base wind_update_rate",
"wind base wind_update_rate [<value>]",
"Get or set the wind update rate.",
"",
HandleConsoleBaseCommand);
foreach (KeyValuePair<string, string> kvp in windPlugin.WindParams()) foreach (KeyValuePair<string, string> kvp in windPlugin.WindParams())
{ {
m_scene.AddCommand(this, String.Format("wind {0} {1}", windPlugin.Name, kvp.Key), String.Format("{0} : {1} - {2}", windPlugin.Name, kvp.Key, kvp.Value), "", HandleConsoleParamCommand); string windCommand = String.Format("wind {0} {1}", windPlugin.Name, kvp.Key);
m_scene.AddCommand("Regions", this, windCommand, string.Format("{0} [<value>]", windCommand), kvp.Value, "", HandleConsoleParamCommand);
} }
} }
// Register event handlers for when Avatars enter the region, and frame ticks // Register event handlers for when Avatars enter the region, and frame ticks
m_scene.EventManager.OnFrame += WindUpdate; m_scene.EventManager.OnFrame += WindUpdate;
m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion; m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion;

View File

@ -92,7 +92,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
return; return;
} }
//m_log.DebugFormat("MAP NAME=({0})", mapName); //m_log.DebugFormat("MAP NAME=({0})", mapName);
// Hack to get around the fact that ll V3 now drops the port from the
// map name. See https://jira.secondlife.com/browse/VWR-28570
//
// Caller, use this magic form instead:
// secondlife://http|!!mygrid.com|8002|Region+Name/128/128
// or url encode if possible.
// the hacks we do with this viewer...
//
string mapNameOrig = mapName;
if (mapName.Contains("|"))
mapName = mapName.Replace('|', ':');
if (mapName.Contains("+"))
mapName = mapName.Replace('+', ' ');
if (mapName.Contains("!"))
mapName = mapName.Replace('!', '/');
// try to fetch from GridServer // try to fetch from GridServer
List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
@ -114,7 +130,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
data.MapImageId = UUID.Zero; data.MapImageId = UUID.Zero;
else else
data.MapImageId = info.TerrainImage; data.MapImageId = info.TerrainImage;
data.Name = info.RegionName; // ugh! V2-3 is very sensitive about the result being
// exactly the same as the requested name
if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
data.Name = mapNameOrig;
else
data.Name = info.RegionName;
data.RegionFlags = 0; // TODO not used? data.RegionFlags = 0; // TODO not used?
data.WaterHeight = 0; // not used data.WaterHeight = 0; // not used
data.X = (ushort)(info.RegionLocX / Constants.RegionSize); data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
@ -138,6 +159,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// flags are agent flags sent from the viewer. // flags are agent flags sent from the viewer.
// they have different values depending on different viewers, apparently // they have different values depending on different viewers, apparently
remoteClient.SendMapBlock(blocks, flags); remoteClient.SendMapBlock(blocks, flags);
// send extra user messages for V3
// because the UI is very confusing
// while we don't fix the hard-coded urls
if (flags == 2)
{
if (regionInfos.Count == 0)
remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
else if (regionInfos.Count == 1)
remoteClient.SendAgentAlertMessage("Region found!", false);
}
} }
// private Scene GetClientScene(IClientAPI client) // private Scene GetClientScene(IClientAPI client)

View File

@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
m_scene.RegisterModuleInterface<IWorldMapModule>(this); m_scene.RegisterModuleInterface<IWorldMapModule>(this);
m_scene.AddCommand( m_scene.AddCommand(
this, "export-map", "Regions", this, "export-map",
"export-map [<path>]", "export-map [<path>]",
"Save an image of the world map", HandleExportWorldMapConsoleCommand); "Save an image of the world map", HandleExportWorldMapConsoleCommand);

View File

@ -46,8 +46,6 @@ namespace OpenSim.Region.DataSnapshot
private DataSnapshotManager m_externalData = null; private DataSnapshotManager m_externalData = null;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private readonly string m_discoveryPath = "DS0001/";
public DataRequestHandler(Scene scene, DataSnapshotManager externalData) public DataRequestHandler(Scene scene, DataSnapshotManager externalData)
{ {
m_scene = scene; m_scene = scene;
@ -58,37 +56,9 @@ namespace OpenSim.Region.DataSnapshot
{ {
m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); m_log.Info("[DATASNAPSHOT]: Set up snapshot service");
} }
// Register validation callback handler
MainServer.Instance.AddHTTPHandler("validate", OnValidate);
//Register CAPS handler event
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
//harbl
}
public void OnRegisterCaps(UUID agentID, Caps caps)
{
// m_log.InfoFormat("[DATASNAPSHOT]: Registering service discovery capability for {0}", agentID);
string capsBase = "/CAPS/" + caps.CapsObjectPath;
caps.RegisterHandler("PublicSnapshotDataInfo",
new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt));
}
public string OnDiscoveryAttempt(string request, string path, string param,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
//Very static for now, flexible enough to add new formats
LLSDDiscoveryResponse llsd_response = new LLSDDiscoveryResponse();
llsd_response.snapshot_resources = new OSDArray();
LLSDDiscoveryDataURL llsd_dataurl = new LLSDDiscoveryDataURL();
llsd_dataurl.snapshot_format = "os-datasnapshot-v1";
llsd_dataurl.snapshot_url = "http://" + m_externalData.m_hostname + ":" + m_externalData.m_listener_port + "/?method=collector";
llsd_response.snapshot_resources.Array.Add(llsd_dataurl);
string response = LLSDHelpers.SerialiseLLSDReply(llsd_response);
return response;
} }
public Hashtable OnGetSnapshot(Hashtable keysvals) public Hashtable OnGetSnapshot(Hashtable keysvals)
@ -107,5 +77,23 @@ namespace OpenSim.Region.DataSnapshot
return reply; return reply;
} }
public Hashtable OnValidate(Hashtable keysvals)
{
m_log.Info("[DATASNAPSHOT] Received validation request");
Hashtable reply = new Hashtable();
int statuscode = 200;
string secret = (string)keysvals["secret"];
if (secret == m_externalData.Secret.ToString())
statuscode = 403;
reply["str_response_string"] = string.Empty;
reply["int_response_code"] = statuscode;
reply["content_type"] = "text/plain";
return reply;
}
} }
} }

View File

@ -66,6 +66,7 @@ namespace OpenSim.Region.DataSnapshot
private string m_dataServices = "noservices"; private string m_dataServices = "noservices";
public string m_listener_port = ConfigSettings.DefaultRegionHttpPort.ToString(); public string m_listener_port = ConfigSettings.DefaultRegionHttpPort.ToString();
public string m_hostname = "127.0.0.1"; public string m_hostname = "127.0.0.1";
private UUID m_Secret = UUID.Random();
//Update timers //Update timers
private int m_period = 20; // in seconds private int m_period = 20; // in seconds
@ -85,6 +86,11 @@ namespace OpenSim.Region.DataSnapshot
get { return m_exposure_level; } get { return m_exposure_level; }
} }
public UUID Secret
{
get { return m_Secret; }
}
#endregion #endregion
#region IRegionModule #region IRegionModule
@ -103,10 +109,10 @@ namespace OpenSim.Region.DataSnapshot
m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled);
IConfig conf = config.Configs["GridService"]; IConfig conf = config.Configs["GridService"];
if (conf != null) if (conf != null)
m_gridinfo.Add("gridserverURL", conf.GetString("GridServerURI", "http://127.0.0.1:8003")); m_gridinfo.Add("gatekeeperURL", conf.GetString("Gatekeeper", String.Empty));
m_gridinfo.Add( m_gridinfo.Add(
"Name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo"));
m_exposure_level = config.Configs["DataSnapshot"].GetString("data_exposure", m_exposure_level); m_exposure_level = config.Configs["DataSnapshot"].GetString("data_exposure", m_exposure_level);
m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period);
m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales);
@ -315,6 +321,7 @@ namespace OpenSim.Region.DataSnapshot
cli.AddQueryParameter("service", serviceName); cli.AddQueryParameter("service", serviceName);
cli.AddQueryParameter("host", m_hostname); cli.AddQueryParameter("host", m_hostname);
cli.AddQueryParameter("port", m_listener_port); cli.AddQueryParameter("port", m_listener_port);
cli.AddQueryParameter("secret", m_Secret.ToString());
cli.RequestMethod = "GET"; cli.RequestMethod = "GET";
try try
{ {
@ -341,7 +348,7 @@ namespace OpenSim.Region.DataSnapshot
} }
// This is not quite working, so... // This is not quite working, so...
// string responseStr = Util.UTF8.GetString(response); // string responseStr = Util.UTF8.GetString(response);
m_log.Info("[DATASNAPSHOT]: data service notified: " + url); m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret);
} }
} }

View File

@ -154,6 +154,15 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>null if the item does not exist</returns> /// <returns>null if the item does not exist</returns>
TaskInventoryItem GetInventoryItem(UUID itemId); TaskInventoryItem GetInventoryItem(UUID itemId);
/// <summary>
/// Get all inventory items.
/// </summary>
/// <param name="name"></param>
/// <returns>
/// If there are no inventory items then an empty list is returned.
/// </returns>
List<TaskInventoryItem> GetInventoryItems();
/// <summary> /// <summary>
/// Get inventory items by name. /// Get inventory items by name.
/// </summary> /// </summary>
@ -162,7 +171,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// A list of inventory items with that name. /// A list of inventory items with that name.
/// If no inventory item has that name then an empty list is returned. /// If no inventory item has that name then an empty list is returned.
/// </returns> /// </returns>
IList<TaskInventoryItem> GetInventoryItems(string name); List<TaskInventoryItem> GetInventoryItems(string name);
/// <summary> /// <summary>
/// Get the scene object referenced by an inventory item. /// Get the scene object referenced by an inventory item.

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
@ -74,5 +75,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// Starts the processing threads. /// Starts the processing threads.
/// </summary> /// </summary>
void StartProcessing(); void StartProcessing();
/// <summary>
/// Get the execution times of all scripts in each object.
/// </summary>
/// <returns>
/// A dictionary where the key is the root object ID of a linkset
/// and the value is a representative execution time in milliseconds of all scripts in that linkset.
/// </returns>
Dictionary<uint, float> GetObjectScriptsExecutionTimes();
} }
} }

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Reflection;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
@ -45,6 +46,18 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary> /// </summary>
event ScriptCommand OnScriptCommand; event ScriptCommand OnScriptCommand;
void RegisterScriptInvocation(object target, string method);
void RegisterScriptInvocation(object target, MethodInfo method);
void RegisterScriptInvocation(object target, string[] methods);
Delegate[] GetScriptInvocationList();
Delegate LookupScriptInvocation(string fname);
string LookupModInvocation(string fname);
Type[] LookupTypeSignature(string fname);
Type LookupReturnType(string fname);
object InvokeOperation(UUID hostId, UUID scriptId, string fname, params object[] parms);
/// <summary> /// <summary>
/// Send a link_message event to an in-world script /// Send a link_message event to an in-world script
/// </summary> /// </summary>

View File

@ -49,6 +49,11 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IWorldComm public interface IWorldComm
{ {
/// <summary>
/// Total number of listeners
/// </summary>
int ListenerCount { get; }
/// <summary> /// <summary>
/// Create a listen event callback with the specified filters. /// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify /// The parameters localID,itemID are needed to uniquely identify

View File

@ -27,8 +27,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenSim.Framework; using System.Reflection;
using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework;
using Animation = OpenSim.Framework.Animation; using Animation = OpenSim.Framework.Animation;
@ -37,7 +39,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
[Serializable] [Serializable]
public class AnimationSet public class AnimationSet
{ {
public static AvatarAnimations Animations = new AvatarAnimations(); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation(); private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>(); private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
@ -132,9 +134,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// </summary> /// </summary>
public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID) public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
{ {
if (Animations.AnimsUUID.ContainsKey(anim)) // m_log.DebugFormat(
// "[ANIMATION SET]: Setting default animation {0}, sequence number {1}, object id {2}",
// anim, sequenceNum, objectID);
if (DefaultAvatarAnimations.AnimsUUID.ContainsKey(anim))
{ {
return SetDefaultAnimation(Animations.AnimsUUID[anim], sequenceNum, objectID); return SetDefaultAnimation(DefaultAvatarAnimations.AnimsUUID[anim], sequenceNum, objectID);
} }
return false; return false;
} }

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using log4net;
using OpenMetaverse;
namespace OpenSim.Region.Framework.Scenes.Animation
{
public class DefaultAvatarAnimations
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public static readonly string DefaultAnimationsPath = "data/avataranimations.xml";
public static Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>();
public static Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>();
public static Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>();
static DefaultAvatarAnimations()
{
LoadAnimations(DefaultAnimationsPath);
}
/// <summary>
/// Load the default SL avatar animations.
/// </summary>
/// <returns></returns>
private static void LoadAnimations(string path)
{
// Dictionary<string, UUID> animations = new Dictionary<string, UUID>();
using (XmlTextReader reader = new XmlTextReader(path))
{
XmlDocument doc = new XmlDocument();
doc.Load(reader);
// if (doc.DocumentElement != null)
// {
foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
{
if (nod.Attributes["name"] != null)
{
string name = nod.Attributes["name"].Value;
UUID id = (UUID)nod.InnerText;
string animState = (string)nod.Attributes["state"].Value;
AnimsUUID.Add(name, id);
AnimsNames.Add(id, name);
if (animState != "")
AnimStateNames.Add(id, animState);
// m_log.DebugFormat("[AVATAR ANIMATIONS]: Loaded {0} {1} {2}", id, name, animState);
}
}
// }
}
// return animations;
}
/// <summary>
/// Get the default avatar animation with the given name.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static UUID GetDefaultAnimation(string name)
{
// m_log.DebugFormat(
// "[AVATAR ANIMATIONS]: Looking for default avatar animation with name {0}", name);
if (AnimsUUID.ContainsKey(name))
{
// m_log.DebugFormat(
// "[AVATAR ANIMATIONS]: Found {0} {1} in GetDefaultAvatarAnimation()", AnimsUUID[name], name);
return AnimsUUID[name];
}
return UUID.Zero;
}
}
}

View File

@ -97,7 +97,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if (m_scenePresence.IsChildAgent) if (m_scenePresence.IsChildAgent)
return; return;
UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name); // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
// are referenced with lower case names!
UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
if (animID == UUID.Zero) if (animID == UUID.Zero)
return; return;
@ -121,7 +123,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
if (m_scenePresence.IsChildAgent) if (m_scenePresence.IsChildAgent)
return; return;
UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name); // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
// are referenced with lower case names!
UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
if (animID == UUID.Zero) if (animID == UUID.Zero)
return; return;

View File

@ -138,8 +138,11 @@ namespace OpenSim.Region.Framework.Scenes
public event OnPermissionErrorDelegate OnPermissionError; public event OnPermissionErrorDelegate OnPermissionError;
/// <summary> /// <summary>
/// Fired when a new script is created. /// Fired when a script is run.
/// </summary> /// </summary>
/// <remarks>
/// Occurs after OnNewScript.
/// </remarks>
public event NewRezScript OnRezScript; public event NewRezScript OnRezScript;
public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
@ -187,10 +190,16 @@ namespace OpenSim.Region.Framework.Scenes
public event ClientClosed OnClientClosed; public event ClientClosed OnClientClosed;
// Fired when a script is created
// The indication that a new script exists in this region.
public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID); public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID);
/// <summary>
/// Fired when a script is created.
/// </summary>
/// <remarks>
/// Occurs before OnRezScript
/// </remarks>
public event NewScript OnNewScript; public event NewScript OnNewScript;
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID) public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
{ {
NewScript handlerNewScript = OnNewScript; NewScript handlerNewScript = OnNewScript;
@ -212,10 +221,16 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
//TriggerUpdateScript: triggered after Scene receives client's upload of updated script and stores it as asset
// An indication that the script has changed.
public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
/// <summary>
/// An indication that the script has changed.
/// </summary>
/// <remarks>
/// Triggered after the scene receives a client's upload of an updated script and has stored it in an asset.
/// </remarks>
public event UpdateScript OnUpdateScript; public event UpdateScript OnUpdateScript;
public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
{ {
UpdateScript handlerUpdateScript = OnUpdateScript; UpdateScript handlerUpdateScript = OnUpdateScript;
@ -466,6 +481,13 @@ namespace OpenSim.Region.Framework.Scenes
public event RegionHeartbeatEnd OnRegionHeartbeatEnd; public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
public delegate void LoginsEnabled(string regionName); public delegate void LoginsEnabled(string regionName);
/// <summary>
/// This should only fire in all circumstances if the RegionReady module is active.
/// </summary>
/// <remarks>
/// TODO: Fire this even when the RegionReady module is not active.
/// </remarks>
public event LoginsEnabled OnLoginsEnabled; public event LoginsEnabled OnLoginsEnabled;
public delegate void PrimsLoaded(Scene s); public delegate void PrimsLoaded(Scene s);

View File

@ -633,7 +633,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null) if (invAccess != null)
invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); Util.FireAndForget(delegate { invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); });
} }
if (!Permissions.BypassPermissions()) if (!Permissions.BypassPermissions())
@ -1210,9 +1210,9 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Copy a task (prim) inventory item to another task (prim) /// Copy a task (prim) inventory item to another task (prim)
/// </summary> /// </summary>
/// <param name="destId"></param> /// <param name="destId">ID of destination part</param>
/// <param name="part"></param> /// <param name="part">Source part</param>
/// <param name="itemId"></param> /// <param name="itemId">Source item id to transfer</param>
public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId) public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
{ {
TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId); TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
@ -1238,24 +1238,21 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
} }
// Can't transfer this if (part.OwnerID != destPart.OwnerID)
//
if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
return;
if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
{ {
// object cannot copy items to an object owned by a different owner // Source must have transfer permissions
// unless llAllowInventoryDrop has been called if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
return;
return; // Object cannot copy items to an object owned by a different owner
// unless llAllowInventoryDrop has been called on the destination
if ((destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
return;
} }
// must have both move and modify permission to put an item in an object // must have both move and modify permission to put an item in an object
if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0) if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
{
return; return;
}
TaskInventoryItem destTaskItem = new TaskInventoryItem(); TaskInventoryItem destTaskItem = new TaskInventoryItem();

View File

@ -339,59 +339,6 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg);
} }
public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
{
//EventManager.TriggerAvatarPickerRequest();
List<UserAccount> accounts = UserAccountService.GetUserAccounts(RegionInfo.ScopeID, query);
if (accounts == null)
return;
AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
// TODO: don't create new blocks if recycling an old packet
AvatarPickerReplyPacket.DataBlock[] searchData =
new AvatarPickerReplyPacket.DataBlock[accounts.Count];
AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
agentData.AgentID = avatarID;
agentData.QueryID = RequestID;
replyPacket.AgentData = agentData;
//byte[] bytes = new byte[AvatarResponses.Count*32];
int i = 0;
foreach (UserAccount item in accounts)
{
UUID translatedIDtem = item.PrincipalID;
searchData[i] = new AvatarPickerReplyPacket.DataBlock();
searchData[i].AvatarID = translatedIDtem;
searchData[i].FirstName = Utils.StringToBytes((string) item.FirstName);
searchData[i].LastName = Utils.StringToBytes((string) item.LastName);
i++;
}
if (accounts.Count == 0)
{
searchData = new AvatarPickerReplyPacket.DataBlock[0];
}
replyPacket.Data = searchData;
AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
agent_data.AgentID = replyPacket.AgentData.AgentID;
agent_data.QueryID = replyPacket.AgentData.QueryID;
List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
for (i = 0; i < replyPacket.Data.Length; i++)
{
AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
data_arg.AvatarID = replyPacket.Data[i].AvatarID;
data_arg.FirstName = replyPacket.Data[i].FirstName;
data_arg.LastName = replyPacket.Data[i].LastName;
data_args.Add(data_arg);
}
client.SendAvatarPickerReply(agent_data, data_args);
}
public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
UUID itemID) UUID itemID)
{ {

View File

@ -65,7 +65,16 @@ namespace OpenSim.Region.Framework.Scenes
#region Fields #region Fields
public bool EmergencyMonitoring = false; public bool EmergencyMonitoring = false;
public bool DEBUG = false;
/// <summary>
/// Show debug information about teleports.
/// </summary>
public bool DebugTeleporting { get; private set; }
/// <summary>
/// Show debug information about the scene loop.
/// </summary>
public bool DebugUpdates { get; private set; }
public SynchronizeSceneHandler SynchronizeScene; public SynchronizeSceneHandler SynchronizeScene;
public SimStatsReporter StatsReporter; public SimStatsReporter StatsReporter;
@ -95,6 +104,11 @@ namespace OpenSim.Region.Framework.Scenes
public bool m_allowScriptCrossings; public bool m_allowScriptCrossings;
public bool m_useFlySlow; public bool m_useFlySlow;
/// <summary>
/// Temporarily setting to trigger appearance resends at 60 second intervals.
/// </summary>
public bool SendPeriodicAppearanceUpdates { get; set; }
protected float m_defaultDrawDistance = 255.0f; protected float m_defaultDrawDistance = 255.0f;
public float DefaultDrawDistance public float DefaultDrawDistance
{ {
@ -159,6 +173,11 @@ namespace OpenSim.Region.Framework.Scenes
protected set; protected set;
} }
/// <summary>
/// Current maintenance run number
/// </summary>
public uint MaintenanceRun { get; private set; }
/// <summary> /// <summary>
/// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
/// will sleep for the remaining period. /// will sleep for the remaining period.
@ -169,6 +188,11 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks> /// </remarks>
public float MinFrameTime { get; private set; } public float MinFrameTime { get; private set; }
/// <summary>
/// The minimum length of time in seconds that will be taken for a maintenance run.
/// </summary>
public float MinMaintenanceTime { get; private set; }
private int m_update_physics = 1; private int m_update_physics = 1;
private int m_update_entitymovement = 1; private int m_update_entitymovement = 1;
private int m_update_objects = 1; private int m_update_objects = 1;
@ -190,7 +214,16 @@ namespace OpenSim.Region.Framework.Scenes
private int backupMS; private int backupMS;
private int terrainMS; private int terrainMS;
private int landMS; private int landMS;
private int lastCompletedFrame;
/// <summary>
/// Tick at which the last frame was processed.
/// </summary>
private int m_lastFrameTick;
/// <summary>
/// Tick at which the last maintenance run occurred.
/// </summary>
private int m_lastMaintenanceTick;
/// <summary> /// <summary>
/// Signals whether temporary objects are currently being cleaned up. Needed because this is launched /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
@ -198,14 +231,12 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
private bool m_cleaningTemps = false; private bool m_cleaningTemps = false;
private Object m_heartbeatLock = new Object(); // private Object m_heartbeatLock = new Object();
// TODO: Possibly stop other classes being able to manipulate this directly. // TODO: Possibly stop other classes being able to manipulate this directly.
private SceneGraph m_sceneGraph; private SceneGraph m_sceneGraph;
private volatile int m_bordersLocked; private volatile int m_bordersLocked;
// private int m_RestartTimerCounter;
private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
// private int m_incrementsof15seconds;
private volatile bool m_backingup; private volatile bool m_backingup;
private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
@ -213,14 +244,28 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_physics_enabled = true; private bool m_physics_enabled = true;
private bool m_scripts_enabled = true; private bool m_scripts_enabled = true;
private string m_defaultScriptEngine; private string m_defaultScriptEngine;
/// <summary>
/// Tick at which the last login occurred.
/// </summary>
private int m_LastLogin; private int m_LastLogin;
private Thread HeartbeatThread;
private volatile bool shuttingdown;
private int m_lastUpdate; /// <summary>
private bool m_firstHeartbeat = true; /// Thread that runs the scene loop.
/// </summary>
private Thread m_heartbeatThread;
private object m_deleting_scene_object = new object(); /// <summary>
/// True if these scene is in the process of shutting down or is shutdown.
/// </summary>
public bool ShuttingDown
{
get { return m_shuttingDown; }
}
private volatile bool m_shuttingDown;
// private int m_lastUpdate;
// private bool m_firstHeartbeat = true;
private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
private bool m_reprioritizationEnabled = true; private bool m_reprioritizationEnabled = true;
@ -466,7 +511,7 @@ namespace OpenSim.Region.Framework.Scenes
public int MonitorBackupTime { get { return backupMS; } } public int MonitorBackupTime { get { return backupMS; } }
public int MonitorTerrainTime { get { return terrainMS; } } public int MonitorTerrainTime { get { return terrainMS; } }
public int MonitorLandTime { get { return landMS; } } public int MonitorLandTime { get { return landMS; } }
public int MonitorLastFrameTick { get { return lastCompletedFrame; } } public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
@ -535,6 +580,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_config = config; m_config = config;
MinFrameTime = 0.089f; MinFrameTime = 0.089f;
MinMaintenanceTime = 1;
Random random = new Random(); Random random = new Random();
@ -596,7 +642,7 @@ namespace OpenSim.Region.Framework.Scenes
#endregion Region Settings #endregion Region Settings
MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", MainConsole.Instance.Commands.AddCommand("Estates", false, "reload estate",
"reload estate", "reload estate",
"Reload the estate data", HandleReloadEstate); "Reload the estate data", HandleReloadEstate);
@ -628,10 +674,10 @@ namespace OpenSim.Region.Framework.Scenes
#region Region Config #region Region Config
try // Region config overrides global config
//
if (m_config.Configs["Startup"] != null)
{ {
// Region config overrides global config
//
IConfig startupConfig = m_config.Configs["Startup"]; IConfig startupConfig = m_config.Configs["Startup"];
m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
@ -720,41 +766,36 @@ namespace OpenSim.Region.Framework.Scenes
m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
}
catch SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates);
{
m_log.Warn("[SCENE]: Failed to load StartupConfig");
} }
#endregion Region Config #endregion Region Config
#region Interest Management #region Interest Management
if (m_config != null) IConfig interestConfig = m_config.Configs["InterestManagement"];
if (interestConfig != null)
{ {
IConfig interestConfig = m_config.Configs["InterestManagement"]; string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
if (interestConfig != null)
try
{ {
string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
try
{
m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
}
catch (Exception)
{
m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
m_priorityScheme = UpdatePrioritizationSchemes.Time;
}
m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
} }
catch (Exception)
{
m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
m_priorityScheme = UpdatePrioritizationSchemes.Time;
}
m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
} }
m_log.InfoFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme); m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme);
#endregion Interest Management #endregion Interest Management
@ -797,18 +838,13 @@ namespace OpenSim.Region.Framework.Scenes
m_permissions = new ScenePermissions(this); m_permissions = new ScenePermissions(this);
m_lastUpdate = Util.EnvironmentTickCount(); // m_lastUpdate = Util.EnvironmentTickCount();
} }
#endregion #endregion
#region Startup / Close Methods #region Startup / Close Methods
public bool ShuttingDown
{
get { return shuttingdown; }
}
/// <value> /// <value>
/// The scene graph for this scene /// The scene graph for this scene
/// </value> /// </value>
@ -1025,44 +1061,72 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine) public void SetSceneCoreDebug(Dictionary<string, string> options)
{ {
if (m_scripts_enabled != !ScriptEngine) if (options.ContainsKey("scripting"))
{ {
if (ScriptEngine) bool enableScripts = true;
if (bool.TryParse(options["scripting"], out enableScripts) && m_scripts_enabled != enableScripts)
{ {
m_log.Info("Stopping all Scripts in Scene"); if (!enableScripts)
EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase ent in entities)
{ {
if (ent is SceneObjectGroup) m_log.Info("Stopping all Scripts in Scene");
((SceneObjectGroup)ent).RemoveScriptInstances(false);
}
}
else
{
m_log.Info("Starting all Scripts in Scene");
EntityBase[] entities = Entities.GetEntities(); EntityBase[] entities = Entities.GetEntities();
foreach (EntityBase ent in entities) foreach (EntityBase ent in entities)
{
if (ent is SceneObjectGroup)
{ {
SceneObjectGroup sog = (SceneObjectGroup)ent; if (ent is SceneObjectGroup)
sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0); ((SceneObjectGroup)ent).RemoveScriptInstances(false);
sog.ResumeScripts();
} }
} }
} else
{
m_log.Info("Starting all Scripts in Scene");
m_scripts_enabled = !ScriptEngine; EntityBase[] entities = Entities.GetEntities();
m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine"); foreach (EntityBase ent in entities)
{
if (ent is SceneObjectGroup)
{
SceneObjectGroup sog = (SceneObjectGroup)ent;
sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
sog.ResumeScripts();
}
}
}
m_scripts_enabled = enableScripts;
}
} }
if (m_physics_enabled != !PhysicsEngine) if (options.ContainsKey("physics"))
{ {
m_physics_enabled = !PhysicsEngine; bool enablePhysics;
if (bool.TryParse(options["physics"], out enablePhysics))
m_physics_enabled = enablePhysics;
}
// if (options.ContainsKey("collisions"))
// {
// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow
// // the avatar themselves to collide with the ground.
// }
if (options.ContainsKey("teleport"))
{
bool enableTeleportDebugging;
if (bool.TryParse(options["teleport"], out enableTeleportDebugging))
DebugTeleporting = enableTeleportDebugging;
}
if (options.ContainsKey("updates"))
{
bool enableUpdateDebugging;
if (bool.TryParse(options["updates"], out enableUpdateDebugging))
{
DebugUpdates = enableUpdateDebugging;
GcNotify.Enabled = DebugUpdates;
}
} }
} }
@ -1076,6 +1140,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
StatsReporter.Close();
m_restartTimer.Stop(); m_restartTimer.Stop();
m_restartTimer.Close(); m_restartTimer.Close();
@ -1097,8 +1163,7 @@ namespace OpenSim.Region.Framework.Scenes
ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
// Stop updating the scene objects and agents. // Stop updating the scene objects and agents.
//m_heartbeatTimer.Close(); m_shuttingDown = true;
shuttingdown = true;
m_log.Debug("[SCENE]: Persisting changed objects"); m_log.Debug("[SCENE]: Persisting changed objects");
EventManager.TriggerSceneShuttingDown(this); EventManager.TriggerSceneShuttingDown(this);
@ -1122,23 +1187,23 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Start the timer which triggers regular scene updates /// Start the scene
/// </summary> /// </summary>
public void StartTimer() public void Start()
{ {
// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
//m_heartbeatTimer.Enabled = true; //m_heartbeatTimer.Enabled = true;
//m_heartbeatTimer.Interval = (int)(m_timespan * 1000); //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
//m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
if (HeartbeatThread != null) if (m_heartbeatThread != null)
{ {
HeartbeatThread.Abort(); m_heartbeatThread.Abort();
HeartbeatThread = null; m_heartbeatThread = null;
} }
m_lastUpdate = Util.EnvironmentTickCount(); // m_lastUpdate = Util.EnvironmentTickCount();
HeartbeatThread m_heartbeatThread
= Watchdog.StartThread( = Watchdog.StartThread(
Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
} }
@ -1169,98 +1234,67 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
private void Heartbeat() private void Heartbeat()
{ {
if (!Monitor.TryEnter(m_heartbeatLock)) // if (!Monitor.TryEnter(m_heartbeatLock))
{ // {
Watchdog.RemoveThread(); // Watchdog.RemoveThread();
return; // return;
} // }
try // try
{ // {
m_eventManager.TriggerOnRegionStarted(this);
// The first frame can take a very long time due to physics actors being added on startup. Therefore, m_eventManager.TriggerOnRegionStarted(this);
// don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
// alarms for scenes with many objects.
Update();
Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
while (!shuttingdown) // The first frame can take a very long time due to physics actors being added on startup. Therefore,
Update(); // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
// alarms for scenes with many objects.
Update(1);
m_lastUpdate = Util.EnvironmentTickCount(); Watchdog.StartThread(
m_firstHeartbeat = false; Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
}
catch (ThreadAbortException) Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
{ Update(-1);
}
finally // m_lastUpdate = Util.EnvironmentTickCount();
{ // m_firstHeartbeat = false;
Monitor.Pulse(m_heartbeatLock); // }
Monitor.Exit(m_heartbeatLock); // finally
} // {
// Monitor.Pulse(m_heartbeatLock);
// Monitor.Exit(m_heartbeatLock);
// }
Watchdog.RemoveThread(); Watchdog.RemoveThread();
} }
public override void Update() private void Maintenance()
{ {
float physicsFPS = 0f; DoMaintenance(-1);
int maintc = Util.EnvironmentTickCount(); Watchdog.RemoveThread();
int tmpFrameMS = maintc; }
agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
++Frame; public void DoMaintenance(int runs)
{
long? endRun = null;
int runtc;
int previousMaintenanceTick;
// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); if (runs >= 0)
endRun = MaintenanceRun + runs;
try List<Vector3> coarseLocations;
List<UUID> avatarUUIDs;
while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun))
{ {
int tmpPhysicsMS2 = Util.EnvironmentTickCount(); runtc = Util.EnvironmentTickCount();
if ((Frame % m_update_physics == 0) && m_physics_enabled) ++MaintenanceRun;
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
// Apply any pending avatar force input to the avatar's velocity
int tmpAgentMS = Util.EnvironmentTickCount();
if (Frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateScenePresenceMovement();
agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Perform the main physics update. This will do the actual work of moving objects and avatars according to their
// velocity
int tmpPhysicsMS = Util.EnvironmentTickCount();
if (Frame % m_update_physics == 0)
{
if (m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
if (SynchronizeScene != null)
SynchronizeScene(this);
}
physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
tmpAgentMS = Util.EnvironmentTickCount();
// Check if any objects have reached their targets
CheckAtTargets();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (Frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Run through all ScenePresences looking for updates
// Presence updates and queued object updates for each presence are sent to clients
if (Frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
// Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (Frame % m_update_coarse_locations == 0) if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
{ {
List<Vector3> coarseLocations;
List<UUID> avatarUUIDs;
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
// Send coarse locations to clients // Send coarse locations to clients
ForEachScenePresence(delegate(ScenePresence presence) ForEachScenePresence(delegate(ScenePresence presence)
@ -1269,122 +1303,227 @@ namespace OpenSim.Region.Framework.Scenes
}); });
} }
agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0)
// Delete temp-on-rez stuff
if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
{ {
int tmpTempOnRezMS = Util.EnvironmentTickCount(); // m_log.DebugFormat("[SCENE]: Sending periodic appearance updates");
m_cleaningTemps = true;
Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
}
if (Frame % m_update_events == 0) if (AvatarFactory != null)
{
int evMS = Util.EnvironmentTickCount();
UpdateEvents();
eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
}
if (Frame % m_update_backup == 0)
{
int backMS = Util.EnvironmentTickCount();
UpdateStorageBackup();
backupMS = Util.EnvironmentTickCountSubtract(backMS);
}
if (Frame % m_update_terrain == 0)
{
int terMS = Util.EnvironmentTickCount();
UpdateTerrain();
terrainMS = Util.EnvironmentTickCountSubtract(terMS);
}
//if (Frame % m_update_land == 0)
//{
// int ldMS = Util.EnvironmentTickCount();
// UpdateLand();
// landMS = Util.EnvironmentTickCountSubtract(ldMS);
//}
frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
lastCompletedFrame = Util.EnvironmentTickCount();
// if (Frame%m_update_avatars == 0)
// UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
StatsReporter.addFrameMS(frameMS);
StatsReporter.addAgentMS(agentMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
if (LoginsDisabled && Frame == 20)
{
// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
// In 99.9% of cases it is a bad idea to manually force garbage collection. However,
// this is a rare case where we know we have just went through a long cycle of heap
// allocations, and there is no more work to be done until someone logs in
GC.Collect();
IConfig startupConfig = m_config.Configs["Startup"];
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{ {
// This handles a case of a region having no scripts for the RegionReady module ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID));
if (m_sceneGraph.GetActiveScriptsCount() == 0)
{
// need to be able to tell these have changed in RegionReady
LoginLock = false;
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
}
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
// For RegionReady lockouts
if(LoginLock == false)
{
LoginsDisabled = false;
}
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
}
else
{
StartDisabled = true;
LoginsDisabled = true;
} }
} }
Watchdog.UpdateThread();
previousMaintenanceTick = m_lastMaintenanceTick;
m_lastMaintenanceTick = Util.EnvironmentTickCount();
runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
runtc = (int)(MinMaintenanceTime * 1000) - runtc;
if (runtc > 0)
Thread.Sleep(runtc);
// Optionally warn if a frame takes double the amount of time that it should.
if (DebugUpdates
&& Util.EnvironmentTickCountSubtract(
m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
m_log.WarnFormat(
"[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
MinMaintenanceTime * 1000,
RegionInfo.RegionName);
} }
catch (NotImplementedException) }
public override void Update(int frames)
{
long? endFrame = null;
if (frames >= 0)
endFrame = Frame + frames;
float physicsFPS = 0f;
int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
int previousFrameTick;
int maintc;
while (!m_shuttingDown && (endFrame == null || Frame < endFrame))
{ {
throw; maintc = Util.EnvironmentTickCount();
++Frame;
// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
try
{
tmpPhysicsMS2 = Util.EnvironmentTickCount();
if ((Frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
// Apply any pending avatar force input to the avatar's velocity
tmpAgentMS = Util.EnvironmentTickCount();
if (Frame % m_update_entitymovement == 0)
m_sceneGraph.UpdateScenePresenceMovement();
agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Perform the main physics update. This will do the actual work of moving objects and avatars according to their
// velocity
tmpPhysicsMS = Util.EnvironmentTickCount();
if (Frame % m_update_physics == 0)
{
if (m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
if (SynchronizeScene != null)
SynchronizeScene(this);
}
physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
tmpAgentMS = Util.EnvironmentTickCount();
// Check if any objects have reached their targets
CheckAtTargets();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (Frame % m_update_objects == 0)
m_sceneGraph.UpdateObjectGroups();
// Run through all ScenePresences looking for updates
// Presence updates and queued object updates for each presence are sent to clients
if (Frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Delete temp-on-rez stuff
if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
{
tmpTempOnRezMS = Util.EnvironmentTickCount();
m_cleaningTemps = true;
Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
}
if (Frame % m_update_events == 0)
{
evMS = Util.EnvironmentTickCount();
UpdateEvents();
eventMS = Util.EnvironmentTickCountSubtract(evMS);
}
if (Frame % m_update_backup == 0)
{
backMS = Util.EnvironmentTickCount();
UpdateStorageBackup();
backupMS = Util.EnvironmentTickCountSubtract(backMS);
}
if (Frame % m_update_terrain == 0)
{
terMS = Util.EnvironmentTickCount();
UpdateTerrain();
terrainMS = Util.EnvironmentTickCountSubtract(terMS);
}
//if (Frame % m_update_land == 0)
//{
// int ldMS = Util.EnvironmentTickCount();
// UpdateLand();
// landMS = Util.EnvironmentTickCountSubtract(ldMS);
//}
frameMS = Util.EnvironmentTickCountSubtract(maintc);
otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
// if (Frame%m_update_avatars == 0)
// UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
// frameMS currently records work frame times, not total frame times (work + any required sleep to
// reach min frame time.
StatsReporter.addFrameMS(frameMS);
StatsReporter.addAgentMS(agentMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
if (LoginsDisabled && Frame == 20)
{
// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
// In 99.9% of cases it is a bad idea to manually force garbage collection. However,
// this is a rare case where we know we have just went through a long cycle of heap
// allocations, and there is no more work to be done until someone logs in
GC.Collect();
IConfig startupConfig = m_config.Configs["Startup"];
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
{
// This handles a case of a region having no scripts for the RegionReady module
if (m_sceneGraph.GetActiveScriptsCount() == 0)
{
// need to be able to tell these have changed in RegionReady
LoginLock = false;
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
}
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
// For RegionReady lockouts
if(LoginLock == false)
{
LoginsDisabled = false;
}
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
}
else
{
StartDisabled = true;
LoginsDisabled = true;
}
}
}
catch (Exception e)
{
m_log.ErrorFormat(
"[SCENE]: Failed on region {0} with exception {1}{2}",
RegionInfo.RegionName, e.Message, e.StackTrace);
}
EventManager.TriggerRegionHeartbeatEnd(this);
Watchdog.UpdateThread();
previousFrameTick = m_lastFrameTick;
m_lastFrameTick = Util.EnvironmentTickCount();
maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
maintc = (int)(MinFrameTime * 1000) - maintc;
if (maintc > 0)
Thread.Sleep(maintc);
// Optionally warn if a frame takes double the amount of time that it should.
if (DebugUpdates
&& Util.EnvironmentTickCountSubtract(
m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
m_log.WarnFormat(
"[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
MinFrameTime * 1000,
RegionInfo.RegionName);
} }
catch (Exception e)
{
m_log.ErrorFormat(
"[SCENE]: Failed on region {0} with exception {1}{2}",
RegionInfo.RegionName, e.Message, e.StackTrace);
}
EventManager.TriggerRegionHeartbeatEnd(this);
maintc = Util.EnvironmentTickCountSubtract(maintc);
maintc = (int)(MinFrameTime * 1000) - maintc;
if (maintc > 0)
Thread.Sleep(maintc);
// Tell the watchdog that this thread is still alive
Watchdog.UpdateThread();
} }
public void AddGroupTarget(SceneObjectGroup grp) public void AddGroupTarget(SceneObjectGroup grp)
@ -1583,8 +1722,15 @@ namespace OpenSim.Region.Framework.Scenes
double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID); double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID);
if (map == null) if (map == null)
{ {
m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain."); // This should be in the Terrain module, but it isn't because
Heightmap = new TerrainChannel(); // the heightmap is needed _way_ before the modules are initialized...
IConfig terrainConfig = m_config.Configs["Terrain"];
String m_InitialTerrain = "pinhead-island";
if (terrainConfig != null)
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
Heightmap = new TerrainChannel(m_InitialTerrain);
SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
} }
@ -2000,14 +2146,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
//SceneObjectPart rootPart = group.GetChildPart(group.UUID); group.RemoveScriptInstances(true);
// Serialise calls to RemoveScriptInstances to avoid
// deadlocking on m_parts inside SceneObjectGroup
lock (m_deleting_scene_object)
{
group.RemoveScriptInstances(true);
}
SceneObjectPart[] partList = group.Parts; SceneObjectPart[] partList = group.Parts;
@ -2489,7 +2628,7 @@ namespace OpenSim.Region.Framework.Scenes
= (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
|| (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
CheckHeartbeat(); // CheckHeartbeat();
ScenePresence sp = GetScenePresence(client.AgentId); ScenePresence sp = GetScenePresence(client.AgentId);
@ -2536,6 +2675,14 @@ namespace OpenSim.Region.Framework.Scenes
// Cache the user's name // Cache the user's name
CacheUserName(sp, aCircuit); CacheUserName(sp, aCircuit);
// Let's send the Suitcase folder for incoming HG agents
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
{
m_log.DebugFormat("[SCENE]: Sending root folder to viewer...");
InventoryFolderBase suitcase = InventoryService.GetRootFolder(client.AgentId);
client.SendBulkUpdateInventory(suitcase);
}
EventManager.TriggerOnNewClient(client); EventManager.TriggerOnNewClient(client);
if (vialogin) if (vialogin)
EventManager.TriggerOnClientLogin(client); EventManager.TriggerOnClientLogin(client);
@ -2774,7 +2921,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
//client.OnNameFromUUIDRequest += HandleUUIDNameRequest; //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
client.OnSetStartLocationRequest += SetHomeRezPoint; client.OnSetStartLocationRequest += SetHomeRezPoint;
client.OnRegionHandleRequest += RegionHandleRequest; client.OnRegionHandleRequest += RegionHandleRequest;
} }
@ -2900,7 +3046,6 @@ namespace OpenSim.Region.Framework.Scenes
{ {
//client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
client.OnSetStartLocationRequest -= SetHomeRezPoint; client.OnSetStartLocationRequest -= SetHomeRezPoint;
client.OnRegionHandleRequest -= RegionHandleRequest; client.OnRegionHandleRequest -= RegionHandleRequest;
} }
@ -3067,7 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
public override void RemoveClient(UUID agentID, bool closeChildAgents) public override void RemoveClient(UUID agentID, bool closeChildAgents)
{ {
CheckHeartbeat(); // CheckHeartbeat();
bool isChildAgent = false; bool isChildAgent = false;
ScenePresence avatar = GetScenePresence(agentID); ScenePresence avatar = GetScenePresence(agentID);
if (avatar != null) if (avatar != null)
@ -3540,8 +3685,8 @@ namespace OpenSim.Region.Framework.Scenes
if (!AuthorizationService.IsAuthorizedForRegion( if (!AuthorizationService.IsAuthorizedForRegion(
agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
{ {
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because {4}",
agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason);
return false; return false;
} }
@ -4156,16 +4301,11 @@ namespace OpenSim.Region.Framework.Scenes
public bool PipeEventsForScript(uint localID) public bool PipeEventsForScript(uint localID)
{ {
SceneObjectPart part = GetSceneObjectPart(localID); SceneObjectPart part = GetSceneObjectPart(localID);
if (part != null) if (part != null)
{ {
// Changed so that child prims of attachments return ScriptDanger for their parent, so that
// their scripts will actually run.
// -- Leaf, Tue Aug 12 14:17:05 EDT 2008
SceneObjectPart parent = part.ParentGroup.RootPart; SceneObjectPart parent = part.ParentGroup.RootPart;
if (part.ParentGroup.IsAttachment) return ScriptDanger(parent, parent.GetWorldPosition());
return ScriptDanger(parent, parent.GetWorldPosition());
else
return ScriptDanger(part, part.GetWorldPosition());
} }
else else
{ {
@ -4459,8 +4599,8 @@ namespace OpenSim.Region.Framework.Scenes
// //
int health=1; // Start at 1, means we're up int health=1; // Start at 1, means we're up
if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
health+=1; health += 1;
else else
return health; return health;
@ -4471,7 +4611,7 @@ namespace OpenSim.Region.Framework.Scenes
else else
return health; return health;
CheckHeartbeat(); // CheckHeartbeat();
return health; return health;
} }
@ -4659,14 +4799,14 @@ namespace OpenSim.Region.Framework.Scenes
return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
} }
private void CheckHeartbeat() // private void CheckHeartbeat()
{ // {
if (m_firstHeartbeat) // if (m_firstHeartbeat)
return; // return;
//
if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) // if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000)
StartTimer(); // StartTimer();
} // }
public override ISceneObject DeserializeObject(string representation) public override ISceneObject DeserializeObject(string representation)
{ {

View File

@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes
#region Update Methods #region Update Methods
/// <summary> /// <summary>
/// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) /// Called to update the scene loop by a number of frames and until shutdown.
/// </summary> /// </summary>
public abstract void Update(); /// <param name="frames">
/// Number of frames to update. Exits on shutdown even if there are frames remaining.
/// If -1 then updates until shutdown.
/// </param>
public abstract void Update(int frames);
#endregion #endregion
@ -472,6 +476,63 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Call this from a region module to add a command to the OpenSim console. /// Call this from a region module to add a command to the OpenSim console.
/// </summary> /// </summary>
/// <param name="mod">
/// The use of IRegionModuleBase is a cheap trick to get a different method signature,
/// though all new modules should be using interfaces descended from IRegionModuleBase anyway.
/// </param>
/// <param name="category">
/// Category of the command. This is the section under which it will appear when the user asks for help
/// </param>
/// <param name="command"></param>
/// <param name="shorthelp"></param>
/// <param name="longhelp"></param>
/// <param name="callback"></param>
public void AddCommand(
string category, object mod, string command, string shorthelp, string longhelp, CommandDelegate callback)
{
AddCommand(category, mod, command, shorthelp, longhelp, string.Empty, callback);
}
/// <summary>
/// Call this from a region module to add a command to the OpenSim console.
/// </summary>
/// <param name="mod"></param>
/// <param name="command"></param>
/// <param name="shorthelp"></param>
/// <param name="longhelp"></param>
/// <param name="descriptivehelp"></param>
/// <param name="callback"></param>
public void AddCommand(object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
{
string moduleName = "";
if (mod != null)
{
if (mod is IRegionModule)
{
IRegionModule module = (IRegionModule)mod;
moduleName = module.Name;
}
else if (mod is IRegionModuleBase)
{
IRegionModuleBase module = (IRegionModuleBase)mod;
moduleName = module.Name;
}
else
{
throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
}
}
AddCommand(moduleName, mod, command, shorthelp, longhelp, descriptivehelp, callback);
}
/// <summary>
/// Call this from a region module to add a command to the OpenSim console.
/// </summary>
/// <param name="category">
/// Category of the command. This is the section under which it will appear when the user asks for help
/// </param>
/// <param name="mod"></param> /// <param name="mod"></param>
/// <param name="command"></param> /// <param name="command"></param>
/// <param name="shorthelp"></param> /// <param name="shorthelp"></param>
@ -479,12 +540,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="descriptivehelp"></param> /// <param name="descriptivehelp"></param>
/// <param name="callback"></param> /// <param name="callback"></param>
public void AddCommand( public void AddCommand(
object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) string category, object mod, string command,
string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
{ {
if (MainConsole.Instance == null) if (MainConsole.Instance == null)
return; return;
string modulename = String.Empty;
bool shared = false; bool shared = false;
if (mod != null) if (mod != null)
@ -492,20 +553,20 @@ namespace OpenSim.Region.Framework.Scenes
if (mod is IRegionModule) if (mod is IRegionModule)
{ {
IRegionModule module = (IRegionModule)mod; IRegionModule module = (IRegionModule)mod;
modulename = module.Name;
shared = module.IsSharedModule; shared = module.IsSharedModule;
} }
else if (mod is IRegionModuleBase) else if (mod is IRegionModuleBase)
{ {
IRegionModuleBase module = (IRegionModuleBase)mod;
modulename = module.Name;
shared = mod is ISharedRegionModule; shared = mod is ISharedRegionModule;
} }
else throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase"); else
{
throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
}
} }
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
modulename, shared, command, shorthelp, longhelp, descriptivehelp, callback); category, shared, command, shorthelp, longhelp, descriptivehelp, callback);
} }
public virtual ISceneObject DeserializeObject(string representation) public virtual ISceneObject DeserializeObject(string representation)

View File

@ -215,27 +215,9 @@ namespace OpenSim.Region.Framework.Scenes
if (sp.IsChildAgent) if (sp.IsChildAgent)
continue; continue;
if (sp.ParentID != 0) coarseLocations.Add(sp.AbsolutePosition);
{
// sitting avatar avatarUUIDs.Add(sp.UUID);
SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID);
if (sop != null)
{
coarseLocations.Add(sop.AbsolutePosition + sp.OffsetPosition);
avatarUUIDs.Add(sp.UUID);
}
else
{
// we can't find the parent.. ! arg!
coarseLocations.Add(sp.AbsolutePosition);
avatarUUIDs.Add(sp.UUID);
}
}
else
{
coarseLocations.Add(sp.AbsolutePosition);
avatarUUIDs.Add(sp.UUID);
}
} }
} }
@ -751,6 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
#endregion #endregion
#region Get Methods #region Get Methods
/// <summary> /// <summary>
/// Get the controlling client for the given avatar, if there is one. /// Get the controlling client for the given avatar, if there is one.
/// ///
@ -1092,36 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes
return Entities.GetEntities(); return Entities.GetEntities();
} }
public Dictionary<uint, float> GetTopScripts()
{
Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
EntityBase[] EntityList = GetEntities();
int limit = 0;
foreach (EntityBase ent in EntityList)
{
if (ent is SceneObjectGroup)
{
SceneObjectGroup grp = (SceneObjectGroup)ent;
if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
{
if (grp.scriptScore >= 0.01)
{
topScripts.Add(grp.LocalId, grp.scriptScore);
limit++;
if (limit >= 100)
{
break;
}
}
grp.scriptScore = 0;
}
}
}
return topScripts;
}
#endregion #endregion
#region Other Methods #region Other Methods

View File

@ -229,8 +229,6 @@ namespace OpenSim.Region.Framework.Scenes
get { return RootPart.VolumeDetectActive; } get { return RootPart.VolumeDetectActive; }
} }
public float scriptScore;
private Vector3 lastPhysGroupPos; private Vector3 lastPhysGroupPos;
private Quaternion lastPhysGroupRot; private Quaternion lastPhysGroupRot;
@ -1184,12 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
public void AddScriptLPS(int count) public void AddScriptLPS(int count)
{ {
if (scriptScore + count >= float.MaxValue - count) m_scene.SceneGraph.AddToScriptLPS(count);
scriptScore = 0;
scriptScore += (float)count;
SceneGraph d = m_scene.SceneGraph;
d.AddToScriptLPS(count);
} }
public void AddActiveScriptCount(int count) public void AddActiveScriptCount(int count)

View File

@ -1546,10 +1546,7 @@ namespace OpenSim.Region.Framework.Scenes
if (userExposed) if (userExposed)
dupe.UUID = UUID.Random(); dupe.UUID = UUID.Random();
//memberwiseclone means it also clones the physics actor reference dupe.PhysActor = null;
// This will make physical prim 'bounce' if not set to null.
if (!userExposed)
dupe.PhysActor = null;
dupe.OwnerID = AgentID; dupe.OwnerID = AgentID;
dupe.GroupID = GroupID; dupe.GroupID = GroupID;

View File

@ -590,9 +590,9 @@ namespace OpenSim.Region.Framework.Scenes
/// A list of inventory items with that name. /// A list of inventory items with that name.
/// If no inventory item has that name then an empty list is returned. /// If no inventory item has that name then an empty list is returned.
/// </returns> /// </returns>
public IList<TaskInventoryItem> GetInventoryItems(string name) public List<TaskInventoryItem> GetInventoryItems(string name)
{ {
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); List<TaskInventoryItem> items = new List<TaskInventoryItem>();
lock (m_items) lock (m_items)
{ {
@ -1100,7 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes
public List<TaskInventoryItem> GetInventoryItems() public List<TaskInventoryItem> GetInventoryItems()
{ {
List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
lock (m_items) lock (m_items)
ret = new List<TaskInventoryItem>(m_items.Values); ret = new List<TaskInventoryItem>(m_items.Values);

View File

@ -432,7 +432,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
get get
{ {
if (PhysicsActor != null && m_parentID == 0) if (PhysicsActor != null)
{ {
m_pos = PhysicsActor.Position; m_pos = PhysicsActor.Position;
@ -455,19 +455,12 @@ namespace OpenSim.Region.Framework.Scenes
// in the sim unless the avatar is on a sit target. While // in the sim unless the avatar is on a sit target. While
// on a sit target, m_pos will contain the desired offset // on a sit target, m_pos will contain the desired offset
// without the parent rotation applied. // without the parent rotation applied.
if (ParentID != 0) SceneObjectPart sitPart = ParentPart;
{
SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); if (sitPart != null)
if (part != null) return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation());
{
return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
}
else
{
return ParentPosition + m_pos;
}
}
} }
return m_pos; return m_pos;
} }
set set
@ -484,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// Don't update while sitting // Don't update while sitting. The PhysicsActor above is null whilst sitting.
if (ParentID == 0) if (ParentID == 0)
{ {
m_pos = value; m_pos = value;
@ -511,6 +504,7 @@ namespace OpenSim.Region.Framework.Scenes
// There is no offset position when not seated // There is no offset position when not seated
if (ParentID == 0) if (ParentID == 0)
return; return;
m_pos = value; m_pos = value;
} }
} }
@ -569,12 +563,18 @@ namespace OpenSim.Region.Framework.Scenes
public bool IsChildAgent { get; set; } public bool IsChildAgent { get; set; }
public uint ParentID /// <summary>
{ /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
get { return m_parentID; } /// </summary>
set { m_parentID = value; } public uint ParentID { get; set; }
}
private uint m_parentID; /// <summary>
/// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
/// </summary>
/// <remarks>
/// If you use this property then you must take a reference since another thread could set it to null.
/// </remarks>
public SceneObjectPart ParentPart { get; set; }
public float Health public float Health
{ {
@ -1751,36 +1751,34 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentID != 0) if (ParentID != 0)
{ {
SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); SceneObjectPart part = ParentPart;
if (part != null) TaskInventoryDictionary taskIDict = part.TaskInventory;
if (taskIDict != null)
{ {
TaskInventoryDictionary taskIDict = part.TaskInventory; lock (taskIDict)
if (taskIDict != null)
{ {
lock (taskIDict) foreach (UUID taskID in taskIDict.Keys)
{ {
foreach (UUID taskID in taskIDict.Keys) UnRegisterControlEventsToScript(LocalId, taskID);
{ taskIDict[taskID].PermsMask &= ~(
UnRegisterControlEventsToScript(LocalId, taskID); 2048 | //PERMISSION_CONTROL_CAMERA
taskIDict[taskID].PermsMask &= ~( 4); // PERMISSION_TAKE_CONTROLS
2048 | //PERMISSION_CONTROL_CAMERA
4); // PERMISSION_TAKE_CONTROLS
}
} }
} }
// Reset sit target.
if (part.SitTargetAvatar == UUID)
part.SitTargetAvatar = UUID.Zero;
ParentPosition = part.GetWorldPosition();
ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
} }
// Reset sit target.
if (part.SitTargetAvatar == UUID)
part.SitTargetAvatar = UUID.Zero;
ParentPosition = part.GetWorldPosition();
ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
ParentPosition = Vector3.Zero; ParentPosition = Vector3.Zero;
ParentID = 0; ParentID = 0;
ParentPart = null;
SendAvatarDataToAllAgents(); SendAvatarDataToAllAgents();
m_requestedSitTargetID = 0; m_requestedSitTargetID = 0;
@ -2206,19 +2204,16 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
} }
ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
ParentID = m_requestedSitTargetID;
Velocity = Vector3.Zero;
RemoveFromPhysicalScene();
Animator.TrySetMovementAnimation(sitAnimation);
SendAvatarDataToAllAgents();
} }
else
{
return;
}
ParentID = m_requestedSitTargetID;
Velocity = Vector3.Zero;
RemoveFromPhysicalScene();
Animator.TrySetMovementAnimation(sitAnimation);
SendAvatarDataToAllAgents();
} }
public void HandleAgentSitOnGround() public void HandleAgentSitOnGround()
@ -2298,7 +2293,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (direc.Z > 2.0f) if (direc.Z > 2.0f)
{ {
direc.Z *= 3.0f; direc.Z *= 2.6f;
// TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
Animator.TrySetMovementAnimation("PREJUMP"); Animator.TrySetMovementAnimation("PREJUMP");
@ -3831,7 +3826,7 @@ namespace OpenSim.Region.Framework.Scenes
ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
if (land != null) if (land != null)
{ {
if (Scene.DEBUG) if (Scene.DebugTeleporting)
TeleportFlagsDebug(); TeleportFlagsDebug();
// If we come in via login, landmark or map, we want to // If we come in via login, landmark or map, we want to

View File

@ -178,13 +178,19 @@ namespace OpenSim.Region.Framework.Scenes
m_objectCapacity = scene.RegionInfo.ObjectCapacity; m_objectCapacity = scene.RegionInfo.ObjectCapacity;
m_report.AutoReset = true; m_report.AutoReset = true;
m_report.Interval = statsUpdatesEveryMS; m_report.Interval = statsUpdatesEveryMS;
m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat); m_report.Elapsed += statsHeartBeat;
m_report.Enabled = true; m_report.Enabled = true;
if (StatsManager.SimExtraStats != null) if (StatsManager.SimExtraStats != null)
OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
} }
public void Close()
{
m_report.Elapsed -= statsHeartBeat;
m_report.Close();
}
public void SetUpdateMS(int ms) public void SetUpdateMS(int ms)
{ {
statsUpdatesEveryMS = ms; statsUpdatesEveryMS = ms;

View File

@ -46,23 +46,20 @@ namespace OpenSim.Region.Framework.Scenes
public TerrainChannel() public TerrainChannel()
{ {
map = new double[Constants.RegionSize, Constants.RegionSize]; map = new double[Constants.RegionSize, Constants.RegionSize];
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
int x; PinHeadIsland();
for (x = 0; x < Constants.RegionSize; x++) }
{
int y; public TerrainChannel(String type)
for (y = 0; y < Constants.RegionSize; y++) {
{ map = new double[Constants.RegionSize, Constants.RegionSize];
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01;
double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; if (type.Equals("flat"))
if (map[x, y] < spherFacA) FlatLand();
map[x, y] = spherFacA; else
if (map[x, y] < spherFacB) PinHeadIsland();
map[x, y] = spherFacB;
}
}
} }
public TerrainChannel(double[,] import) public TerrainChannel(double[,] import)
@ -238,5 +235,36 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
private void PinHeadIsland()
{
int x;
for (x = 0; x < Constants.RegionSize; x++)
{
int y;
for (y = 0; y < Constants.RegionSize; y++)
{
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01;
double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001;
if (map[x, y] < spherFacA)
map[x, y] = spherFacA;
if (map[x, y] < spherFacB)
map[x, y] = spherFacB;
}
}
}
private void FlatLand()
{
int x;
for (x = 0; x < Constants.RegionSize; x++)
{
int y;
for (y = 0; y < Constants.RegionSize; y++)
map[x, y] = 21;
}
}
} }
} }

View File

@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// For now, we'll make the scene presence fly to simplify this test, but this needs to change. // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
sp.Flying = true; sp.Flying = true;
m_scene.Update(); m_scene.Update(1);
Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
Vector3 targetPos = startPos + new Vector3(0, 10, 0); Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That( Assert.That(
sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
m_scene.Update(); m_scene.Update(1);
// We should really check the exact figure. // We should really check the exact figure.
Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
for (int i = 0; i < 10; i++) m_scene.Update(10);
m_scene.Update();
double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That( Assert.That(
sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
m_scene.Update(); m_scene.Update(1);
// We should really check the exact figure. // We should really check the exact figure.
Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
for (int i = 0; i < 10; i++) m_scene.Update(10);
m_scene.Update();
distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");

View File

@ -63,17 +63,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Thread testThread = new Thread(testClass.run); Thread testThread = new Thread(testClass.run);
try // Seems kind of redundant to start a thread and then join it, however.. We need to protect against
{ // A thread abort exception in the simulator code.
// Seems kind of redundant to start a thread and then join it, however.. We need to protect against testThread.Start();
// A thread abort exception in the simulator code. testThread.Join();
testThread.Start();
testThread.Join();
}
catch (ThreadAbortException)
{
}
Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message);
// Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
} }

View File

@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
Scene scene = SceneHelpers.SetupScene(); Scene scene = SceneHelpers.SetupScene();
scene.Update(); scene.Update(1);
Assert.That(scene.Frame, Is.EqualTo(1)); Assert.That(scene.Frame, Is.EqualTo(1));
} }

View File

@ -113,7 +113,7 @@ namespace OpenSim.Region.Framework.Tests
} }
/// <summary> /// <summary>
/// Test MoveTaskInventoryItem where the item has no parent folder assigned. /// Test MoveTaskInventoryItem from a part inventory to a user inventory where the item has no parent folder assigned.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This should place it in the most suitable user folder. /// This should place it in the most suitable user folder.
@ -142,9 +142,11 @@ namespace OpenSim.Region.Framework.Tests
} }
/// <summary> /// <summary>
/// Test MoveTaskInventoryItem where the item has no parent folder assigned. /// Test MoveTaskInventoryItem from a part inventory to a user inventory where the item has no parent folder assigned.
/// </summary> /// </summary>
/// <remarks>
/// This should place it in the most suitable user folder. /// This should place it in the most suitable user folder.
/// </remarks>
[Test] [Test]
public void TestMoveTaskInventoryItemNoParent() public void TestMoveTaskInventoryItemNoParent()
{ {

View File

@ -1203,11 +1203,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
} }
public UUID GetDefaultAnimation(string name)
{
return UUID.Zero;
}
public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, byte[] charterMember, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID) public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, byte[] charterMember, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID)
{ {

View File

@ -92,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Agent.TextureSender
m_scene = scene; m_scene = scene;
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"j2k", "Assets",
false, false,
"j2k decode", "j2k decode",
"j2k decode <ID>", "j2k decode <ID>",

View File

@ -82,19 +82,19 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
scene.AddCommand( scene.AddCommand(
this, "image queues clear", "Comms", this, "image queues clear",
"image queues clear <first-name> <last-name>", "image queues clear <first-name> <last-name>",
"Clear the image queues (textures downloaded via UDP) for a particular client.", "Clear the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd))); (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
scene.AddCommand( scene.AddCommand(
this, "image queues show", "Comms", this, "image queues show",
"image queues show <first-name> <last-name>", "image queues show <first-name> <last-name>",
"Show the image queues (textures downloaded via UDP) for a particular client.", "Show the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
scene.AddCommand( scene.AddCommand(
this, "show pqueues", "Comms", this, "show pqueues",
"show pqueues [full]", "show pqueues [full]",
"Show priority queue data for each client", "Show priority queue data for each client",
"Without the 'full' option, only root agents are shown." "Without the 'full' option, only root agents are shown."
@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
(mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd)));
scene.AddCommand( scene.AddCommand(
this, "show queues", "Comms", this, "show queues",
"show queues [full]", "show queues [full]",
"Show queue data for each client", "Show queue data for each client",
"Without the 'full' option, only root agents are shown." "Without the 'full' option, only root agents are shown."
@ -110,13 +110,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
(mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
scene.AddCommand( scene.AddCommand(
this, "show image queues", "Comms", this, "show image queues",
"show image queues <first-name> <last-name>", "show image queues <first-name> <last-name>",
"Show the image queues (textures downloaded via UDP) for a particular client.", "Show the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
scene.AddCommand( scene.AddCommand(
this, "show throttles", "Comms", this, "show throttles",
"show throttles [full]", "show throttles [full]",
"Show throttle settings for each client and for the server overall", "Show throttle settings for each client and for the server overall",
"Without the 'full' option, only root agents are shown." "Without the 'full' option, only root agents are shown."
@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
(mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd)));
scene.AddCommand( scene.AddCommand(
this, "emergency-monitoring", "Comms", this, "emergency-monitoring",
"emergency-monitoring", "emergency-monitoring",
"Go on/off emergency monitoring mode", "Go on/off emergency monitoring mode",
"Go on/off emergency monitoring mode", "Go on/off emergency monitoring mode",

View File

@ -88,7 +88,7 @@ namespace OpenSim.Region.OptionalModules.Asset
m_scene = scene; m_scene = scene;
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"asset", "Assets",
false, false,
"show asset", "show asset",
"show asset <ID>", "show asset <ID>",
@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.Asset
HandleShowAsset); HandleShowAsset);
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
"asset", false, "dump asset", "Assets", false, "dump asset",
"dump asset <id>", "dump asset <id>",
"Dump an asset", "Dump an asset",
HandleDumpAsset); HandleDumpAsset);

View File

@ -94,13 +94,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
scene.AddCommand( scene.AddCommand(
this, "show appearance", "Users", this, "show appearance",
"show appearance [<first-name> <last-name>]", "show appearance [<first-name> <last-name>]",
"Synonym for 'appearance show'", "Synonym for 'appearance show'",
HandleShowAppearanceCommand); HandleShowAppearanceCommand);
scene.AddCommand( scene.AddCommand(
this, "appearance show", "Users", this, "appearance show",
"appearance show [<first-name> <last-name>]", "appearance show [<first-name> <last-name>]",
"Show appearance information for each avatar in the simulator.", "Show appearance information for each avatar in the simulator.",
"This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. "
@ -110,14 +110,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
HandleShowAppearanceCommand); HandleShowAppearanceCommand);
scene.AddCommand( scene.AddCommand(
this, "appearance send", "Users", this, "appearance send",
"appearance send [<first-name> <last-name>]", "appearance send [<first-name> <last-name>]",
"Send appearance data for each avatar in the simulator to other viewers.", "Send appearance data for each avatar in the simulator to other viewers.",
"Optionally, you can specify that only a particular avatar's appearance data is sent.", "Optionally, you can specify that only a particular avatar's appearance data is sent.",
HandleSendAppearanceCommand); HandleSendAppearanceCommand);
scene.AddCommand( scene.AddCommand(
this, "appearance rebake", "Users", this, "appearance rebake",
"appearance rebake <first-name> <last-name>", "appearance rebake <first-name> <last-name>",
"Send a request to the user's viewer for it to rebake and reupload its appearance textures.", "Send a request to the user's viewer for it to rebake and reupload its appearance textures.",
"This is currently done for all baked texture references previously received, whether the simulator can find the asset or not." "This is currently done for all baked texture references previously received, whether the simulator can find the asset or not."
@ -127,7 +127,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
HandleRebakeAppearanceCommand); HandleRebakeAppearanceCommand);
scene.AddCommand( scene.AddCommand(
this, "appearance find", "Users", this, "appearance find",
"appearance find <uuid-or-start-of-uuid>", "appearance find <uuid-or-start-of-uuid>",
"Find out which avatar uses the given asset as a baked texture, if any.", "Find out which avatar uses the given asset as a baked texture, if any.",
"You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.",

View File

@ -100,22 +100,22 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
{ {
if (!m_commandsLoaded) if (!m_commandsLoaded)
{ {
MainConsole.Instance.Commands.AddCommand("Physics", false, "physics set", MainConsole.Instance.Commands.AddCommand(
"physics set", "Regions", false, "physics set",
"Set physics parameter from currently selected region" + Environment.NewLine setInvocation,
+ "Invocation: " + setInvocation, "Set physics parameter from currently selected region",
ProcessPhysicsSet); ProcessPhysicsSet);
MainConsole.Instance.Commands.AddCommand("Physics", false, "physics get", MainConsole.Instance.Commands.AddCommand(
"physics get", "Regions", false, "physics get",
"Get physics parameter from currently selected region" + Environment.NewLine getInvocation,
+ "Invocation: " + getInvocation, "Get physics parameter from currently selected region",
ProcessPhysicsGet); ProcessPhysicsGet);
MainConsole.Instance.Commands.AddCommand("Physics", false, "physics list", MainConsole.Instance.Commands.AddCommand(
"physics list", "Regions", false, "physics list",
"List settable physics parameters" + Environment.NewLine listInvocation,
+ "Invocation: " + listInvocation, "List settable physics parameters",
ProcessPhysicsList); ProcessPhysicsList);
m_commandsLoaded = true; m_commandsLoaded = true;
@ -264,14 +264,14 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
private void WriteOut(string msg, params object[] args) private void WriteOut(string msg, params object[] args)
{ {
m_log.InfoFormat(msg, args); // m_log.InfoFormat(msg, args);
// MainConsole.Instance.OutputFormat(msg, args); MainConsole.Instance.OutputFormat(msg, args);
} }
private void WriteError(string msg, params object[] args) private void WriteError(string msg, params object[] args)
{ {
m_log.ErrorFormat(msg, args); // m_log.ErrorFormat(msg, args);
// MainConsole.Instance.OutputFormat(msg, args); MainConsole.Instance.OutputFormat(msg, args);
} }
} }
} }

View File

@ -70,8 +70,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
//m_log.Info("[RegionReady] Initialising");
m_config = config.Configs["RegionReady"]; m_config = config.Configs["RegionReady"];
if (m_config != null) if (m_config != null)
{ {
@ -84,9 +82,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
m_uri = m_config.GetString("alert_uri",string.Empty); m_uri = m_config.GetString("alert_uri",string.Empty);
} }
} }
// if (!m_enabled)
// m_log.Info("[RegionReady] disabled.");
} }
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
@ -113,7 +108,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
{ {
scene.LoginLock = true; scene.LoginLock = true;
scene.LoginsDisabled = true; scene.LoginsDisabled = true;
m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName); m_log.InfoFormat("[RegionReady]: Region {0} - logins disabled during initialization.",m_scene.RegionInfo.RegionName);
if(m_uri != string.Empty) if(m_uri != string.Empty)
{ {
@ -167,7 +162,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) void OnEmptyScriptCompileQueue(int numScriptsFailed, string message)
{ {
m_log.InfoFormat("[RegionReady]: Script compile queue empty!"); m_log.DebugFormat("[RegionReady]: Script compile queue empty!");
if (m_firstEmptyCompileQueue || m_oarFileLoading) if (m_firstEmptyCompileQueue || m_oarFileLoading)
{ {
@ -194,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
c.SenderUUID = UUID.Zero; c.SenderUUID = UUID.Zero;
c.Scene = m_scene; c.Scene = m_scene;
m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_log.DebugFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
m_scene.EventManager.TriggerOnChatBroadcast(this, c); m_scene.EventManager.TriggerOnChatBroadcast(this, c);
@ -210,7 +205,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
{ {
m_lastOarLoadedOk = true; m_lastOarLoadedOk = true;
} else { } else {
m_log.InfoFormat("[RegionReady]: Oar file load errors: {0}", message); m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message);
m_lastOarLoadedOk = false; m_lastOarLoadedOk = false;
} }
} }
@ -233,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
// m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
// m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName);
if ( m_uri != string.Empty ) if ( m_uri != string.Empty )
{ {

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Collections.Generic;
using Nini.Config; using Nini.Config;
using log4net; using log4net;
using OpenSim.Framework; using OpenSim.Framework;
@ -34,8 +35,10 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using Mono.Addins; using Mono.Addins;
using OpenMetaverse; using OpenMetaverse;
using System.Linq;
using System.Linq.Expressions;
namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
@ -43,10 +46,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IScriptModule m_scriptModule = null; #region ScriptInvocation
protected class ScriptInvocationData
{
public Delegate ScriptInvocationDelegate { get; private set; }
public string FunctionName { get; private set; }
public Type[] TypeSignature { get; private set; }
public Type ReturnType { get; private set; }
public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
{
FunctionName = fname;
ScriptInvocationDelegate = fn;
TypeSignature = callsig;
ReturnType = returnsig;
}
}
private Dictionary<string,ScriptInvocationData> m_scriptInvocation = new Dictionary<string,ScriptInvocationData>();
#endregion
private IScriptModule m_scriptModule = null;
public event ScriptCommand OnScriptCommand; public event ScriptCommand OnScriptCommand;
#region RegionModuleInterface
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
} }
@ -81,6 +104,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
public void Close() public void Close()
{ {
} }
#endregion
#region ScriptModuleComms
public void RaiseEvent(UUID script, string id, string module, string command, string k) public void RaiseEvent(UUID script, string id, string module, string command, string k)
{ {
@ -101,5 +127,149 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
m_scriptModule.PostScriptEvent(script, "link_message", args); m_scriptModule.PostScriptEvent(script, "link_message", args);
} }
public void RegisterScriptInvocation(object target, string meth)
{
MethodInfo mi = target.GetType().GetMethod(meth,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (mi == null)
{
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
return;
}
RegisterScriptInvocation(target, mi);
}
public void RegisterScriptInvocation(object target, string[] meth)
{
foreach (string m in meth)
RegisterScriptInvocation(target, m);
}
public void RegisterScriptInvocation(object target, MethodInfo mi)
{
m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name);
Type delegateType;
var typeArgs = mi.GetParameters()
.Select(p => p.ParameterType)
.ToList();
if (mi.ReturnType == typeof(void))
{
delegateType = Expression.GetActionType(typeArgs.ToArray());
}
else
{
typeArgs.Add(mi.ReturnType);
delegateType = Expression.GetFuncType(typeArgs.ToArray());
}
Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
lock (m_scriptInvocation)
{
ParameterInfo[] parameters = fcall.Method.GetParameters ();
if (parameters.Length < 2) // Must have two UUID params
return;
// Hide the first two parameters
Type[] parmTypes = new Type[parameters.Length - 2];
for (int i = 2 ; i < parameters.Length ; i++)
parmTypes[i - 2] = parameters[i].ParameterType;
m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
}
}
public Delegate[] GetScriptInvocationList()
{
List<Delegate> ret = new List<Delegate>();
lock (m_scriptInvocation)
{
foreach (ScriptInvocationData d in m_scriptInvocation.Values)
ret.Add(d.ScriptInvocationDelegate);
}
return ret.ToArray();
}
public string LookupModInvocation(string fname)
{
lock (m_scriptInvocation)
{
ScriptInvocationData sid;
if (m_scriptInvocation.TryGetValue(fname,out sid))
{
if (sid.ReturnType == typeof(string))
return "modInvokeS";
else if (sid.ReturnType == typeof(int))
return "modInvokeI";
else if (sid.ReturnType == typeof(float))
return "modInvokeF";
else if (sid.ReturnType == typeof(UUID))
return "modInvokeK";
else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
return "modInvokeV";
else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
return "modInvokeR";
else if (sid.ReturnType == typeof(object[]))
return "modInvokeL";
m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
}
}
return null;
}
public Delegate LookupScriptInvocation(string fname)
{
lock (m_scriptInvocation)
{
ScriptInvocationData sid;
if (m_scriptInvocation.TryGetValue(fname,out sid))
return sid.ScriptInvocationDelegate;
}
return null;
}
public Type[] LookupTypeSignature(string fname)
{
lock (m_scriptInvocation)
{
ScriptInvocationData sid;
if (m_scriptInvocation.TryGetValue(fname,out sid))
return sid.TypeSignature;
}
return null;
}
public Type LookupReturnType(string fname)
{
lock (m_scriptInvocation)
{
ScriptInvocationData sid;
if (m_scriptInvocation.TryGetValue(fname,out sid))
return sid.ReturnType;
}
return null;
}
public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
{
List<object> olist = new List<object>();
olist.Add(hostid);
olist.Add(scriptid);
foreach (object o in parms)
olist.Add(o);
Delegate fn = LookupScriptInvocation(fname);
return fn.DynamicInvoke(olist.ToArray());
}
#endregion
} }
} }

View File

@ -34,6 +34,9 @@ using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.CoreModules.World.Estate; using OpenSim.Region.CoreModules.World.Estate;
using log4net;
using System.Reflection;
using System.Xml;
namespace OpenSim.Region.OptionalModules.World.NPC namespace OpenSim.Region.OptionalModules.World.NPC
{ {
@ -130,11 +133,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
} }
public UUID GetDefaultAnimation(string name)
{
return UUID.Zero;
}
public Vector3 Position public Vector3 Position
{ {
get { return m_scene.Entities[m_uuid].AbsolutePosition; } get { return m_scene.Entities[m_uuid].AbsolutePosition; }

View File

@ -88,22 +88,26 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene) public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene)
{ {
ScenePresence sp = scene.GetScenePresence(agentId); ScenePresence npc = scene.GetScenePresence(agentId);
if (sp == null || sp.IsChildAgent) if (npc == null || npc.IsChildAgent)
return false; return false;
lock (m_avatars) lock (m_avatars)
if (!m_avatars.ContainsKey(agentId)) if (!m_avatars.ContainsKey(agentId))
return false; return false;
// Delete existing sp attachments // Delete existing npc attachments
scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
// Set new sp appearance. Also sends to clients. // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments
scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, new AvatarAppearance(appearance, true)); AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
npc.Appearance = npcAppearance;
// Rez needed sp attachments // Rez needed npc attachments
scene.AttachmentsModule.RezAttachments(sp); scene.AttachmentsModule.RezAttachments(npc);
IAvatarFactoryModule module = scene.RequestModuleInterface<IAvatarFactoryModule>();
module.SendAppearance(npc.UUID);
return true; return true;
} }

Some files were not shown because too many files have changed in this diff Show More