Merge git://opensimulator.org/git/opensim
commit
fffd42f5cb
|
@ -1,34 +1,36 @@
|
||||||
The following people have contributed to OpenSim (Thank you
|
The following people have contributed to OpenSim (Thank you
|
||||||
for your effort!)
|
for your effort!)
|
||||||
|
|
||||||
Add your name in here if you have committed to OpenSim
|
|
||||||
|
|
||||||
= Current OpenSim Developers (in very rough order of appearance) =
|
= Current OpenSim Developers (in very rough order of appearance) =
|
||||||
These folks represent the current core team for OpenSim, and are the
|
These folks represent the current core team for OpenSim, and are the
|
||||||
people that make the day to day of OpenSim happen.
|
people that make the day to day of OpenSim happen.
|
||||||
|
|
||||||
|
* justincc
|
||||||
|
* chi11ken (Genkii)
|
||||||
|
* dahlia
|
||||||
|
* Melanie Thielker
|
||||||
|
* Diva (Crista Lopes, University of California, Irvine)
|
||||||
|
* Dan Lake (Intel)
|
||||||
|
* Marck
|
||||||
|
* Mic Bowman (Intel)
|
||||||
|
* BlueWall (James Hughes)
|
||||||
|
|
||||||
|
= Core Developers Following the White Rabbit =
|
||||||
|
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||||
|
They are in all similar to the active core developers, except that they haven't
|
||||||
|
been that active lately, so their voting rights are awaiting their come back.
|
||||||
|
|
||||||
* MW (Tribal Media AB)
|
* MW (Tribal Media AB)
|
||||||
* Adam Frisby (DeepThink Pty Ltd)
|
* Adam Frisby (DeepThink Pty Ltd)
|
||||||
* MingChen (DeepThink Pty Ltd)
|
|
||||||
* lbsa71 (Tribal Media AB)
|
* lbsa71 (Tribal Media AB)
|
||||||
* Sean Dague / sdague (IBM)
|
|
||||||
* Tedd
|
|
||||||
* justincc
|
|
||||||
* Teravus (w3z)
|
* Teravus (w3z)
|
||||||
* Johan Berntsson (3Di)
|
|
||||||
* Ckrinke (Charles Krinke)
|
* Ckrinke (Charles Krinke)
|
||||||
* chi11ken (Genkii)
|
|
||||||
* adjohn (Genkii)
|
|
||||||
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
|
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
|
||||||
* dahlia
|
|
||||||
* mikem (3Di)
|
* mikem (3Di)
|
||||||
* Melanie Thielker
|
|
||||||
* Homer_Horwitz
|
* Homer_Horwitz
|
||||||
* idb (Ian Brown)
|
|
||||||
* Diva (Crista Lopes, University of California, Irvine)
|
|
||||||
* nlin (3Di)
|
* nlin (3Di)
|
||||||
* Arthur Rodrigo S Valadares (IBM)
|
* Arthur Rodrigo S Valadares (IBM)
|
||||||
* BlueWall (James Hughes)
|
* John Hurliman
|
||||||
|
|
||||||
= Past Open Sim Developers =
|
= Past Open Sim Developers =
|
||||||
These folks are alumns of the OpenSim core group, but are now
|
These folks are alumns of the OpenSim core group, but are now
|
||||||
|
@ -44,6 +46,12 @@ where we are today.
|
||||||
* Dalien
|
* Dalien
|
||||||
* Darok
|
* Darok
|
||||||
* Alondria
|
* Alondria
|
||||||
|
* Sean Dague / sdague (IBM)
|
||||||
|
* Tedd
|
||||||
|
* MingChen (DeepThink Pty Ltd)
|
||||||
|
* adjohn (Genkii)
|
||||||
|
* idb (Ian Brown)
|
||||||
|
* Johan Berntsson (3Di)
|
||||||
|
|
||||||
|
|
||||||
= Additional OpenSim Contributors =
|
= Additional OpenSim Contributors =
|
||||||
|
@ -102,6 +110,7 @@ what it is today.
|
||||||
* Misterblue (Intel)
|
* Misterblue (Intel)
|
||||||
* Mircea Kitsune
|
* Mircea Kitsune
|
||||||
* mpallari
|
* mpallari
|
||||||
|
* MrMonkE
|
||||||
* nornalbion
|
* nornalbion
|
||||||
* Omar Vera Ustariz (IBM)
|
* Omar Vera Ustariz (IBM)
|
||||||
* openlifegrid.com
|
* openlifegrid.com
|
||||||
|
|
|
@ -57,14 +57,14 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
m_Realm = realm;
|
m_Realm = realm;
|
||||||
|
|
||||||
|
m_ConnectionString = connectionString;
|
||||||
|
|
||||||
if (storeName != String.Empty)
|
if (storeName != String.Empty)
|
||||||
{
|
{
|
||||||
Assembly assem = GetType().Assembly;
|
|
||||||
m_ConnectionString = connectionString;
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
Migration m = new Migration(conn, assem, storeName);
|
Migration m = new Migration(conn, GetType().Assembly, storeName);
|
||||||
m.Update();
|
m.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ namespace OpenSim.Data.MSSQL
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// Something went wrong, so we're version 0
|
// Return -1 to indicate table does not exist
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -492,12 +492,11 @@ ELSE
|
||||||
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))
|
||||||
{
|
{
|
||||||
|
conn.Open();
|
||||||
foreach (TaskInventoryItem taskItem in items)
|
foreach (TaskInventoryItem taskItem in items)
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem));
|
cmd.Parameters.AddRange(CreatePrimInventoryParameters(taskItem));
|
||||||
conn.Open();
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1154,9 +1153,9 @@ VALUES
|
||||||
PrimitiveBaseShape baseShape = new PrimitiveBaseShape();
|
PrimitiveBaseShape baseShape = new PrimitiveBaseShape();
|
||||||
|
|
||||||
baseShape.Scale = new Vector3(
|
baseShape.Scale = new Vector3(
|
||||||
Convert.ToSingle(shapeRow["ScaleX"]),
|
(float)Convert.ToDouble(shapeRow["ScaleX"]),
|
||||||
Convert.ToSingle(shapeRow["ScaleY"]),
|
(float)Convert.ToDouble(shapeRow["ScaleY"]),
|
||||||
Convert.ToSingle(shapeRow["ScaleZ"]));
|
(float)Convert.ToDouble(shapeRow["ScaleZ"]));
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
baseShape.PCode = Convert.ToByte(shapeRow["PCode"]);
|
baseShape.PCode = Convert.ToByte(shapeRow["PCode"]);
|
||||||
|
@ -1193,8 +1192,11 @@ VALUES
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(shapeRow["Media"] is System.DBNull))
|
if (!(shapeRow["Media"] is System.DBNull) )
|
||||||
|
{
|
||||||
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return baseShape;
|
return baseShape;
|
||||||
}
|
}
|
||||||
|
@ -1573,7 +1575,16 @@ VALUES
|
||||||
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
|
parameters.Add(_Database.CreateParameter("Texture", s.TextureEntry));
|
||||||
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
||||||
parameters.Add(_Database.CreateParameter("State", s.State));
|
parameters.Add(_Database.CreateParameter("State", s.State));
|
||||||
parameters.Add(_Database.CreateParameter("Media", null == s.Media ? null : s.Media.ToXml()));
|
|
||||||
|
if(null == s.Media )
|
||||||
|
{
|
||||||
|
parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return parameters.ToArray();
|
return parameters.ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,11 @@ COMMIT
|
||||||
|
|
||||||
BEGIN TRANSACTION
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users;
|
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND type in (N'U'))
|
||||||
|
INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users;
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,5 +13,28 @@ PRIMARY KEY CLUSTERED
|
||||||
) ON [PRIMARY]
|
) ON [PRIMARY]
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 2
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
CREATE TABLE dbo.Tmp_Avatars
|
||||||
|
(
|
||||||
|
PrincipalID uniqueidentifier NOT NULL,
|
||||||
|
[Name] varchar(32) NOT NULL,
|
||||||
|
Value text NOT NULL DEFAULT '',
|
||||||
|
) ON [PRIMARY]
|
||||||
|
TEXTIMAGE_ON [PRIMARY]
|
||||||
|
|
||||||
|
IF EXISTS(SELECT * FROM dbo.Avatars)
|
||||||
|
EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
|
||||||
|
SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
|
||||||
|
|
||||||
|
DROP TABLE dbo.Avatars
|
||||||
|
|
||||||
|
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ COMMIT
|
||||||
|
|
||||||
BEGIN TRANSACTION
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
INSERT INTO Friends (PrincipalID, Friend, Flags, Offered) SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
|
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[userfriends]') AND type in (N'U'))
|
||||||
|
INSERT INTO Friends (PrincipalID, Friend, Flags, Offered)
|
||||||
|
SELECT [ownerID], [friendID], [friendPerms], 0 FROM userfriends;
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
|
@ -222,4 +222,17 @@ ALTER TABLE [regions] ADD [Token] varchar(255) NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 8
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
ALTER TABLE regions ALTER COLUMN regionName VarChar(128)
|
||||||
|
|
||||||
|
DROP INDEX IX_regions_name ON dbo.regions
|
||||||
|
ALTER TABLE regions ALTER COLUMN regionName VarChar(128) null
|
||||||
|
|
||||||
|
CREATE NONCLUSTERED INDEX IX_regions_name ON dbo.regions
|
||||||
|
(
|
||||||
|
regionName
|
||||||
|
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||||
|
|
||||||
|
COMMIT
|
|
@ -238,7 +238,10 @@ alter table inventoryitems
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 8
|
||||||
|
|
||||||
|
ALTER TABLE inventoryitems
|
||||||
|
ADD CONSTRAINT DF_inventoryitems_creatorID
|
||||||
|
DEFAULT '00000000-0000-0000-0000-000000000000' FOR creatorID
|
||||||
|
|
||||||
|
:GO
|
||||||
|
|
|
@ -7,14 +7,7 @@ CREATE TABLE [Presence] (
|
||||||
[RegionID] uniqueidentifier NOT NULL,
|
[RegionID] uniqueidentifier NOT NULL,
|
||||||
[SessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
[SessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||||
[SecureSessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
[SecureSessionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||||
[Online] char(5) NOT NULL DEFAULT 'false',
|
|
||||||
[Login] char(16) NOT NULL DEFAULT '0',
|
|
||||||
[Logout] char(16) NOT NULL DEFAULT '0',
|
|
||||||
[Position] char(64) NOT NULL DEFAULT '<0,0,0>',
|
|
||||||
[LookAt] char(64) NOT NULL DEFAULT '<0,0,0>',
|
|
||||||
[HomeRegionID] uniqueidentifier NOT NULL,
|
|
||||||
[HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
|
||||||
[HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
|
||||||
)
|
)
|
||||||
ON [PRIMARY]
|
ON [PRIMARY]
|
||||||
|
|
||||||
|
@ -28,3 +21,11 @@ CREATE UNIQUE INDEX SessionID ON Presence(SessionID);
|
||||||
CREATE INDEX UserID ON Presence(UserID);
|
CREATE INDEX UserID ON Presence(UserID);
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 2
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE Presence ADD LastSeen DateTime
|
||||||
|
|
||||||
|
COMMIT
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
:VERSION 1
|
:VERSION 1
|
||||||
|
|
||||||
CREATE TABLE [dbo].[prims](
|
CREATE TABLE [dbo].[prims](
|
||||||
|
@ -926,11 +925,121 @@ ALTER TABLE regionsettings ADD loaded_creation_datetime int NOT NULL default 0
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
:VERSION 24
|
:VERSION 24
|
||||||
-- Added post 0.7
|
|
||||||
|
|
||||||
BEGIN TRANSACTION
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
ALTER TABLE prims ADD COLUMN MediaURL varchar(255)
|
ALTER TABLE prims ADD MediaURL varchar(255)
|
||||||
ALTER TABLE primshapes ADD COLUMN Media TEXT
|
ALTER TABLE primshapes ADD Media TEXT NULL
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 25
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
CREATE TABLE "regionwindlight" (
|
||||||
|
"region_id" varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
|
||||||
|
"water_color_r" [float] NOT NULL DEFAULT '4.000000',
|
||||||
|
"water_color_g" [float] NOT NULL DEFAULT '38.000000',
|
||||||
|
"water_color_b" [float] NOT NULL DEFAULT '64.000000',
|
||||||
|
"water_fog_density_exponent" [float] NOT NULL DEFAULT '4.0',
|
||||||
|
"underwater_fog_modifier" [float] NOT NULL DEFAULT '0.25',
|
||||||
|
"reflection_wavelet_scale_1" [float] NOT NULL DEFAULT '2.0',
|
||||||
|
"reflection_wavelet_scale_2" [float] NOT NULL DEFAULT '2.0',
|
||||||
|
"reflection_wavelet_scale_3" [float] NOT NULL DEFAULT '2.0',
|
||||||
|
"fresnel_scale" [float] NOT NULL DEFAULT '0.40',
|
||||||
|
"fresnel_offset" [float] NOT NULL DEFAULT '0.50',
|
||||||
|
"refract_scale_above" [float] NOT NULL DEFAULT '0.03',
|
||||||
|
"refract_scale_below" [float] NOT NULL DEFAULT '0.20',
|
||||||
|
"blur_multiplier" [float] NOT NULL DEFAULT '0.040',
|
||||||
|
"big_wave_direction_x" [float] NOT NULL DEFAULT '1.05',
|
||||||
|
"big_wave_direction_y" [float] NOT NULL DEFAULT '-0.42',
|
||||||
|
"little_wave_direction_x" [float] NOT NULL DEFAULT '1.11',
|
||||||
|
"little_wave_direction_y" [float] NOT NULL DEFAULT '-1.16',
|
||||||
|
"normal_map_texture" varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
|
||||||
|
"horizon_r" [float] NOT NULL DEFAULT '0.25',
|
||||||
|
"horizon_g" [float] NOT NULL DEFAULT '0.25',
|
||||||
|
"horizon_b" [float] NOT NULL DEFAULT '0.32',
|
||||||
|
"horizon_i" [float] NOT NULL DEFAULT '0.32',
|
||||||
|
"haze_horizon" [float] NOT NULL DEFAULT '0.19',
|
||||||
|
"blue_density_r" [float] NOT NULL DEFAULT '0.12',
|
||||||
|
"blue_density_g" [float] NOT NULL DEFAULT '0.22',
|
||||||
|
"blue_density_b" [float] NOT NULL DEFAULT '0.38',
|
||||||
|
"blue_density_i" [float] NOT NULL DEFAULT '0.38',
|
||||||
|
"haze_density" [float] NOT NULL DEFAULT '0.70',
|
||||||
|
"density_multiplier" [float] NOT NULL DEFAULT '0.18',
|
||||||
|
"distance_multiplier" [float] NOT NULL DEFAULT '0.8',
|
||||||
|
"max_altitude" int NOT NULL DEFAULT '1605',
|
||||||
|
"sun_moon_color_r" [float] NOT NULL DEFAULT '0.24',
|
||||||
|
"sun_moon_color_g" [float] NOT NULL DEFAULT '0.26',
|
||||||
|
"sun_moon_color_b" [float] NOT NULL DEFAULT '0.30',
|
||||||
|
"sun_moon_color_i" [float] NOT NULL DEFAULT '0.30',
|
||||||
|
"sun_moon_position" [float] NOT NULL DEFAULT '0.317',
|
||||||
|
"ambient_r" [float] NOT NULL DEFAULT '0.35',
|
||||||
|
"ambient_g" [float] NOT NULL DEFAULT '0.35',
|
||||||
|
"ambient_b" [float] NOT NULL DEFAULT '0.35',
|
||||||
|
"ambient_i" [float] NOT NULL DEFAULT '0.35',
|
||||||
|
"east_angle" [float] NOT NULL DEFAULT '0.00',
|
||||||
|
"sun_glow_focus" [float] NOT NULL DEFAULT '0.10',
|
||||||
|
"sun_glow_size" [float] NOT NULL DEFAULT '1.75',
|
||||||
|
"scene_gamma" [float] NOT NULL DEFAULT '1.00',
|
||||||
|
"star_brightness" [float] NOT NULL DEFAULT '0.00',
|
||||||
|
"cloud_color_r" [float] NOT NULL DEFAULT '0.41',
|
||||||
|
"cloud_color_g" [float] NOT NULL DEFAULT '0.41',
|
||||||
|
"cloud_color_b" [float] NOT NULL DEFAULT '0.41',
|
||||||
|
"cloud_color_i" [float] NOT NULL DEFAULT '0.41',
|
||||||
|
"cloud_x" [float] NOT NULL DEFAULT '1.00',
|
||||||
|
"cloud_y" [float] NOT NULL DEFAULT '0.53',
|
||||||
|
"cloud_density" [float] NOT NULL DEFAULT '1.00',
|
||||||
|
"cloud_coverage" [float] NOT NULL DEFAULT '0.27',
|
||||||
|
"cloud_scale" [float] NOT NULL DEFAULT '0.42',
|
||||||
|
"cloud_detail_x" [float] NOT NULL DEFAULT '1.00',
|
||||||
|
"cloud_detail_y" [float] NOT NULL DEFAULT '0.53',
|
||||||
|
"cloud_detail_density" [float] NOT NULL DEFAULT '0.12',
|
||||||
|
"cloud_scroll_x" [float] NOT NULL DEFAULT '0.20',
|
||||||
|
"cloud_scroll_x_lock" tinyint NOT NULL DEFAULT '0',
|
||||||
|
"cloud_scroll_y" [float] NOT NULL DEFAULT '0.01',
|
||||||
|
"cloud_scroll_y_lock" tinyint NOT NULL DEFAULT '0',
|
||||||
|
"draw_classic_clouds" tinyint NOT NULL DEFAULT '1',
|
||||||
|
PRIMARY KEY ("region_id")
|
||||||
|
)
|
||||||
|
|
||||||
|
COMMIT TRANSACTION
|
||||||
|
|
||||||
|
:VERSION 26
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE regionsettings ADD map_tile_ID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 27 #---------------------
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
ALTER TABLE land ADD MediaType VARCHAR(32) NOT NULL DEFAULT 'none/none'
|
||||||
|
ALTER TABLE land ADD MediaDescription VARCHAR(255) NOT NULL DEFAULT ''
|
||||||
|
ALTER TABLE land ADD MediaSize VARCHAR(16) NOT NULL DEFAULT '0,0'
|
||||||
|
ALTER TABLE land ADD MediaLoop bit NOT NULL DEFAULT 0
|
||||||
|
ALTER TABLE land ADD ObscureMusic bit NOT NULL DEFAULT 0
|
||||||
|
ALTER TABLE land ADD ObscureMedia bit NOT NULL DEFAULT 0
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 28 #---------------------
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE prims
|
||||||
|
ADD CONSTRAINT DF_prims_CreatorID
|
||||||
|
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||||
|
FOR CreatorID
|
||||||
|
|
||||||
|
ALTER TABLE prims ALTER COLUMN CreatorID uniqueidentifier NOT NULL
|
||||||
|
|
||||||
|
ALTER TABLE primitems
|
||||||
|
ADD CONSTRAINT DF_primitems_CreatorID
|
||||||
|
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||||
|
FOR CreatorID
|
||||||
|
|
||||||
|
ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
|
@ -19,7 +19,7 @@ CREATE TABLE [UserAccounts] (
|
||||||
:VERSION 2
|
:VERSION 2
|
||||||
|
|
||||||
BEGIN TRANSACTION
|
BEGIN TRANSACTION
|
||||||
|
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND type in (N'U'))
|
||||||
INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT [UUID] AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID,
|
INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT [UUID] AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID,
|
||||||
username AS FirstName,
|
username AS FirstName,
|
||||||
lastname AS LastName,
|
lastname AS LastName,
|
||||||
|
|
|
@ -151,27 +151,6 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create AgentCircuitData from a Serializable AgentCircuitData
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cAgent"></param>
|
|
||||||
public AgentCircuitData(sAgentCircuitData cAgent)
|
|
||||||
{
|
|
||||||
AgentID = new UUID(cAgent.AgentID);
|
|
||||||
SessionID = new UUID(cAgent.SessionID);
|
|
||||||
SecureSessionID = new UUID(cAgent.SecureSessionID);
|
|
||||||
startpos = new Vector3(cAgent.startposx, cAgent.startposy, cAgent.startposz);
|
|
||||||
firstname = cAgent.firstname;
|
|
||||||
lastname = cAgent.lastname;
|
|
||||||
circuitcode = cAgent.circuitcode;
|
|
||||||
child = cAgent.child;
|
|
||||||
InventoryFolder = new UUID(cAgent.InventoryFolder);
|
|
||||||
BaseFolder = new UUID(cAgent.BaseFolder);
|
|
||||||
CapsPath = cAgent.CapsPath;
|
|
||||||
ChildrenCapSeeds = cAgent.ChildrenCapSeeds;
|
|
||||||
Viewer = cAgent.Viewer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json
|
/// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -369,52 +348,4 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Serializable Agent Circuit Data
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
public class sAgentCircuitData
|
|
||||||
{
|
|
||||||
public Guid AgentID;
|
|
||||||
public Guid BaseFolder;
|
|
||||||
public string CapsPath = String.Empty;
|
|
||||||
public Dictionary<ulong, string> ChildrenCapSeeds;
|
|
||||||
public bool child;
|
|
||||||
public uint circuitcode;
|
|
||||||
public string firstname;
|
|
||||||
public Guid InventoryFolder;
|
|
||||||
public string lastname;
|
|
||||||
public Guid SecureSessionID;
|
|
||||||
public Guid SessionID;
|
|
||||||
public float startposx;
|
|
||||||
public float startposy;
|
|
||||||
public float startposz;
|
|
||||||
public string Viewer;
|
|
||||||
public string Channel;
|
|
||||||
public string Mac;
|
|
||||||
public string Id0;
|
|
||||||
|
|
||||||
public sAgentCircuitData()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public sAgentCircuitData(AgentCircuitData cAgent)
|
|
||||||
{
|
|
||||||
AgentID = cAgent.AgentID.Guid;
|
|
||||||
SessionID = cAgent.SessionID.Guid;
|
|
||||||
SecureSessionID = cAgent.SecureSessionID.Guid;
|
|
||||||
startposx = cAgent.startpos.X;
|
|
||||||
startposy = cAgent.startpos.Y;
|
|
||||||
startposz = cAgent.startpos.Z;
|
|
||||||
firstname = cAgent.firstname;
|
|
||||||
lastname = cAgent.lastname;
|
|
||||||
circuitcode = cAgent.circuitcode;
|
|
||||||
child = cAgent.child;
|
|
||||||
InventoryFolder = cAgent.InventoryFolder.Guid;
|
|
||||||
BaseFolder = cAgent.BaseFolder.Guid;
|
|
||||||
CapsPath = cAgent.CapsPath;
|
|
||||||
ChildrenCapSeeds = cAgent.ChildrenCapSeeds;
|
|
||||||
Viewer = cAgent.Viewer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace OpenSim.Framework
|
||||||
UUID AgentID { get; set; }
|
UUID AgentID { get; set; }
|
||||||
|
|
||||||
OSDMap Pack();
|
OSDMap Pack();
|
||||||
void Unpack(OSDMap map);
|
void Unpack(OSDMap map, IScene scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -122,7 +122,7 @@ namespace OpenSim.Framework
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unpack(OSDMap args)
|
public void Unpack(OSDMap args, IScene scene)
|
||||||
{
|
{
|
||||||
if (args.ContainsKey("region_handle"))
|
if (args.ContainsKey("region_handle"))
|
||||||
UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
|
UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
|
||||||
|
@ -329,6 +329,10 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public string CallbackURI;
|
public string CallbackURI;
|
||||||
|
|
||||||
|
// These two must have the same Count
|
||||||
|
public List<ISceneObject> AttachmentObjects;
|
||||||
|
public List<string> AttachmentObjectStates;
|
||||||
|
|
||||||
public virtual OSDMap Pack()
|
public virtual OSDMap Pack()
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||||
|
@ -441,7 +445,30 @@ namespace OpenSim.Framework
|
||||||
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
|
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
|
||||||
args["callback_uri"] = OSD.FromString(CallbackURI);
|
args["callback_uri"] = OSD.FromString(CallbackURI);
|
||||||
|
|
||||||
|
// Attachment objects for fatpack messages
|
||||||
|
if (AttachmentObjects != null)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
OSDArray attObjs = new OSDArray(AttachmentObjects.Count);
|
||||||
|
foreach (ISceneObject so in AttachmentObjects)
|
||||||
|
{
|
||||||
|
OSDMap info = new OSDMap(4);
|
||||||
|
info["sog"] = OSD.FromString(so.ToXml2());
|
||||||
|
info["extra"] = OSD.FromString(so.ExtraToXmlString());
|
||||||
|
info["modified"] = OSD.FromBoolean(so.HasGroupChanged);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
info["state"] = OSD.FromString(AttachmentObjectStates[i++]);
|
||||||
|
}
|
||||||
|
catch (IndexOutOfRangeException e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list.");
|
||||||
|
}
|
||||||
|
|
||||||
|
attObjs.Add(info);
|
||||||
|
}
|
||||||
|
args["attach_objects"] = attObjs;
|
||||||
|
}
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +477,7 @@ namespace OpenSim.Framework
|
||||||
/// Avoiding reflection makes it painful to write, but that's the price!
|
/// Avoiding reflection makes it painful to write, but that's the price!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hash"></param>
|
/// <param name="hash"></param>
|
||||||
public virtual void Unpack(OSDMap args)
|
public virtual void Unpack(OSDMap args, IScene scene)
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data");
|
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data");
|
||||||
|
|
||||||
|
@ -628,6 +655,26 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (args["callback_uri"] != null)
|
if (args["callback_uri"] != null)
|
||||||
CallbackURI = args["callback_uri"].AsString();
|
CallbackURI = args["callback_uri"].AsString();
|
||||||
|
|
||||||
|
// Attachment objects
|
||||||
|
if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array)
|
||||||
|
{
|
||||||
|
OSDArray attObjs = (OSDArray)(args["attach_objects"]);
|
||||||
|
AttachmentObjects = new List<ISceneObject>();
|
||||||
|
AttachmentObjectStates = new List<string>();
|
||||||
|
foreach (OSD o in attObjs)
|
||||||
|
{
|
||||||
|
if (o.Type == OSDType.Map)
|
||||||
|
{
|
||||||
|
OSDMap info = (OSDMap)o;
|
||||||
|
ISceneObject so = scene.DeserializeObject(info["sog"].AsString());
|
||||||
|
so.ExtraFromXmlString(info["extra"].AsString());
|
||||||
|
so.HasGroupChanged = info["modified"].AsBoolean();
|
||||||
|
AttachmentObjects.Add(so);
|
||||||
|
AttachmentObjectStates.Add(info["state"].AsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AgentData()
|
public AgentData()
|
||||||
|
@ -655,9 +702,9 @@ namespace OpenSim.Framework
|
||||||
return base.Pack();
|
return base.Pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unpack(OSDMap map)
|
public override void Unpack(OSDMap map, IScene scene)
|
||||||
{
|
{
|
||||||
base.Unpack(map);
|
base.Unpack(map, scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,9 @@ using System.Net;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
[Serializable]
|
|
||||||
public class ClientInfo
|
public class ClientInfo
|
||||||
{
|
{
|
||||||
public sAgentCircuitData agentcircuit;
|
public AgentCircuitData agentcircuit;
|
||||||
|
|
||||||
public Dictionary<uint, byte[]> needAck;
|
public Dictionary<uint, byte[]> needAck;
|
||||||
|
|
||||||
|
|
|
@ -572,34 +572,69 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public class IEntityUpdate
|
public class IEntityUpdate
|
||||||
{
|
{
|
||||||
public ISceneEntity Entity;
|
private ISceneEntity m_entity;
|
||||||
public uint Flags;
|
private uint m_flags;
|
||||||
|
private int m_updateTime;
|
||||||
|
|
||||||
|
public ISceneEntity Entity
|
||||||
|
{
|
||||||
|
get { return m_entity; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Flags
|
||||||
|
{
|
||||||
|
get { return m_flags; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int UpdateTime
|
||||||
|
{
|
||||||
|
get { return m_updateTime; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Update(IEntityUpdate update)
|
public virtual void Update(IEntityUpdate update)
|
||||||
{
|
{
|
||||||
this.Flags |= update.Flags;
|
m_flags |= update.Flags;
|
||||||
|
|
||||||
|
// Use the older of the updates as the updateTime
|
||||||
|
if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0)
|
||||||
|
m_updateTime = update.UpdateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEntityUpdate(ISceneEntity entity, uint flags)
|
public IEntityUpdate(ISceneEntity entity, uint flags)
|
||||||
{
|
{
|
||||||
Entity = entity;
|
m_entity = entity;
|
||||||
Flags = flags;
|
m_flags = flags;
|
||||||
|
m_updateTime = Util.EnvironmentTickCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime)
|
||||||
|
{
|
||||||
|
m_entity = entity;
|
||||||
|
m_flags = flags;
|
||||||
|
m_updateTime = updateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class EntityUpdate : IEntityUpdate
|
public class EntityUpdate : IEntityUpdate
|
||||||
{
|
{
|
||||||
// public ISceneEntity Entity;
|
private float m_timeDilation;
|
||||||
// public PrimUpdateFlags Flags;
|
|
||||||
public float TimeDilation;
|
public float TimeDilation
|
||||||
|
{
|
||||||
|
get { return m_timeDilation; }
|
||||||
|
}
|
||||||
|
|
||||||
public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation)
|
public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation)
|
||||||
: base(entity,(uint)flags)
|
: base(entity, (uint)flags)
|
||||||
{
|
{
|
||||||
//Entity = entity;
|
|
||||||
// Flags = flags;
|
// Flags = flags;
|
||||||
TimeDilation = timedilation;
|
m_timeDilation = timedilation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation, Int32 updateTime)
|
||||||
|
: base(entity,(uint)flags,updateTime)
|
||||||
|
{
|
||||||
|
m_timeDilation = timedilation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,50 +34,81 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Client;
|
using OpenSim.Framework.Client;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class PriorityQueue
|
public class PriorityQueue
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
internal delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity);
|
public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity);
|
||||||
|
|
||||||
// Heap[0] for self updates
|
/// <summary>
|
||||||
// Heap[1..12] for entity updates
|
/// Total number of queues (priorities) available
|
||||||
|
/// </summary>
|
||||||
|
public const uint NumberOfQueues = 12;
|
||||||
|
|
||||||
internal const uint m_numberOfQueues = 12;
|
/// <summary>
|
||||||
|
/// Number of queuest (priorities) that are processed immediately
|
||||||
|
/// </summary.
|
||||||
|
public const uint NumberOfImmediateQueues = 2;
|
||||||
|
|
||||||
private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[m_numberOfQueues];
|
private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues];
|
||||||
private Dictionary<uint, LookupItem> m_lookupTable;
|
private Dictionary<uint, LookupItem> m_lookupTable;
|
||||||
|
|
||||||
|
// internal state used to ensure the deqeues are spread across the priority
|
||||||
|
// queues "fairly". queuecounts is the amount to pull from each queue in
|
||||||
|
// each pass. weighted towards the higher priority queues
|
||||||
private uint m_nextQueue = 0;
|
private uint m_nextQueue = 0;
|
||||||
|
private uint m_countFromQueue = 0;
|
||||||
|
private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 };
|
||||||
|
|
||||||
|
// next request is a counter of the number of updates queued, it provides
|
||||||
|
// a total ordering on the updates coming through the queue and is more
|
||||||
|
// lightweight (and more discriminating) than tick count
|
||||||
private UInt64 m_nextRequest = 0;
|
private UInt64 m_nextRequest = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lock for enqueue and dequeue operations on the priority queue
|
||||||
|
/// </summary>
|
||||||
private object m_syncRoot = new object();
|
private object m_syncRoot = new object();
|
||||||
public object SyncRoot {
|
public object SyncRoot {
|
||||||
get { return this.m_syncRoot; }
|
get { return this.m_syncRoot; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { }
|
#region constructor
|
||||||
|
public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { }
|
||||||
|
|
||||||
internal PriorityQueue(int capacity)
|
public PriorityQueue(int capacity)
|
||||||
{
|
{
|
||||||
m_lookupTable = new Dictionary<uint, LookupItem>(capacity);
|
m_lookupTable = new Dictionary<uint, LookupItem>(capacity);
|
||||||
|
|
||||||
for (int i = 0; i < m_heaps.Length; ++i)
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
|
m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
|
||||||
}
|
|
||||||
|
|
||||||
internal int Count
|
m_nextQueue = NumberOfImmediateQueues;
|
||||||
|
m_countFromQueue = m_queueCounts[m_nextQueue];
|
||||||
|
}
|
||||||
|
#endregion Constructor
|
||||||
|
|
||||||
|
#region PublicMethods
|
||||||
|
/// <summary>
|
||||||
|
/// Return the number of items in the queues
|
||||||
|
/// </summary>
|
||||||
|
public int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < m_heaps.Length; ++i)
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
count += m_heaps[i].Count;
|
count += m_heaps[i].Count;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enqueue an item into the specified priority queue
|
||||||
|
/// </summary>
|
||||||
public bool Enqueue(uint pqueue, IEntityUpdate value)
|
public bool Enqueue(uint pqueue, IEntityUpdate value)
|
||||||
{
|
{
|
||||||
LookupItem lookup;
|
LookupItem lookup;
|
||||||
|
@ -91,7 +122,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
lookup.Heap.Remove(lookup.Handle);
|
lookup.Heap.Remove(lookup.Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1);
|
pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1);
|
||||||
lookup.Heap = m_heaps[pqueue];
|
lookup.Heap = m_heaps[pqueue];
|
||||||
lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle);
|
lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle);
|
||||||
m_lookupTable[localid] = lookup;
|
m_lookupTable[localid] = lookup;
|
||||||
|
@ -99,20 +130,62 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
|
/// <summary>
|
||||||
|
/// Remove an item from one of the queues. Specifically, it removes the
|
||||||
|
/// oldest item from the next queue in order to provide fair access to
|
||||||
|
/// all of the queues
|
||||||
|
/// </summary>
|
||||||
|
public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_numberOfQueues; ++i)
|
// If there is anything in priority queue 0, return it first no
|
||||||
|
// matter what else. Breaks fairness. But very useful.
|
||||||
|
for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
|
||||||
{
|
{
|
||||||
// To get the fair queing, we cycle through each of the
|
if (m_heaps[iq].Count > 0)
|
||||||
// queues when finding an element to dequeue, this code
|
|
||||||
// assumes that the distribution of updates in the queues
|
|
||||||
// is polynomial, probably quadractic (eg distance of PI * R^2)
|
|
||||||
uint h = (uint)((m_nextQueue + i) % m_numberOfQueues);
|
|
||||||
if (m_heaps[h].Count > 0)
|
|
||||||
{
|
{
|
||||||
m_nextQueue = (uint)((h + 1) % m_numberOfQueues);
|
MinHeapItem item = m_heaps[iq].RemoveMin();
|
||||||
|
m_lookupTable.Remove(item.Value.Entity.LocalId);
|
||||||
|
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
|
||||||
|
value = item.Value;
|
||||||
|
|
||||||
MinHeapItem item = m_heaps[h].RemoveMin();
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To get the fair queing, we cycle through each of the
|
||||||
|
// queues when finding an element to dequeue.
|
||||||
|
// We pull (NumberOfQueues - QueueIndex) items from each queue in order
|
||||||
|
// to give lower numbered queues a higher priority and higher percentage
|
||||||
|
// of the bandwidth.
|
||||||
|
|
||||||
|
// Check for more items to be pulled from the current queue
|
||||||
|
if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0)
|
||||||
|
{
|
||||||
|
m_countFromQueue--;
|
||||||
|
|
||||||
|
MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
|
||||||
|
m_lookupTable.Remove(item.Value.Entity.LocalId);
|
||||||
|
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
|
||||||
|
value = item.Value;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the next non-immediate queue with updates in it
|
||||||
|
for (int i = 0; i < NumberOfQueues; ++i)
|
||||||
|
{
|
||||||
|
m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues);
|
||||||
|
m_countFromQueue = m_queueCounts[m_nextQueue];
|
||||||
|
|
||||||
|
// if this is one of the immediate queues, just skip it
|
||||||
|
if (m_nextQueue < NumberOfImmediateQueues)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_heaps[m_nextQueue].Count > 0)
|
||||||
|
{
|
||||||
|
m_countFromQueue--;
|
||||||
|
|
||||||
|
MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
|
||||||
m_lookupTable.Remove(item.Value.Entity.LocalId);
|
m_lookupTable.Remove(item.Value.Entity.LocalId);
|
||||||
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
|
timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
|
||||||
value = item.Value;
|
value = item.Value;
|
||||||
|
@ -126,7 +199,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Reprioritize(UpdatePriorityHandler handler)
|
/// <summary>
|
||||||
|
/// Reapply the prioritization function to each of the updates currently
|
||||||
|
/// stored in the priority queues.
|
||||||
|
/// </summary
|
||||||
|
public void Reprioritize(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
MinHeapItem item;
|
MinHeapItem item;
|
||||||
foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values))
|
foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values))
|
||||||
|
@ -140,7 +217,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
// unless the priority queue has changed, there is no need to modify
|
// unless the priority queue has changed, there is no need to modify
|
||||||
// the entry
|
// the entry
|
||||||
pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1);
|
pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1);
|
||||||
if (pqueue != item.PriorityQueue)
|
if (pqueue != item.PriorityQueue)
|
||||||
{
|
{
|
||||||
lookup.Heap.Remove(lookup.Handle);
|
lookup.Heap.Remove(lookup.Handle);
|
||||||
|
@ -161,17 +238,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
string s = "";
|
string s = "";
|
||||||
for (int i = 0; i < m_numberOfQueues; i++)
|
for (int i = 0; i < NumberOfQueues; i++)
|
||||||
{
|
s += String.Format("{0,7} ",m_heaps[i].Count);
|
||||||
if (s != "") s += ",";
|
|
||||||
s += m_heaps[i].Count.ToString();
|
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion PublicMethods
|
||||||
|
|
||||||
#region MinHeapItem
|
#region MinHeapItem
|
||||||
private struct MinHeapItem : IComparable<MinHeapItem>
|
private struct MinHeapItem : IComparable<MinHeapItem>
|
||||||
{
|
{
|
|
@ -115,7 +115,7 @@ namespace OpenSim.Framework.Tests
|
||||||
position2 = new AgentPosition();
|
position2 = new AgentPosition();
|
||||||
|
|
||||||
Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition");
|
Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition");
|
||||||
position2.Unpack(position1.Pack());
|
position2.Unpack(position1.Pack(), null);
|
||||||
|
|
||||||
Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed");
|
Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed");
|
||||||
Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed");
|
Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed");
|
||||||
|
|
|
@ -1537,6 +1537,23 @@ namespace OpenSim.Framework
|
||||||
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
|
||||||
|
// Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount().
|
||||||
|
// A positive return value indicates A occured later than B
|
||||||
|
public static Int32 EnvironmentTickCountCompare(Int32 tcA, Int32 tcB)
|
||||||
|
{
|
||||||
|
// A, B and TC are all between 0 and 0x3fffffff
|
||||||
|
int tc = EnvironmentTickCount();
|
||||||
|
|
||||||
|
if (tc - tcA >= 0)
|
||||||
|
tcA += EnvironmentTickCountMask + 1;
|
||||||
|
|
||||||
|
if (tc - tcB >= 0)
|
||||||
|
tcB += EnvironmentTickCountMask + 1;
|
||||||
|
|
||||||
|
return tcA - tcB;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prints the call stack at any given point. Useful for debugging.
|
/// Prints the call stack at any given point. Useful for debugging.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -142,17 +142,17 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static OSDMap PutToService(string url, OSDMap data)
|
public static OSDMap PutToService(string url, OSDMap data)
|
||||||
{
|
{
|
||||||
return ServiceOSDRequest(url,data,"PUT",10000);
|
return ServiceOSDRequest(url,data,"PUT",30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OSDMap PostToService(string url, OSDMap data)
|
public static OSDMap PostToService(string url, OSDMap data)
|
||||||
{
|
{
|
||||||
return ServiceOSDRequest(url,data,"POST",10000);
|
return ServiceOSDRequest(url,data,"POST",30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OSDMap GetFromService(string url)
|
public static OSDMap GetFromService(string url)
|
||||||
{
|
{
|
||||||
return ServiceOSDRequest(url,null,"GET",10000);
|
return ServiceOSDRequest(url,null,"GET",30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout)
|
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout)
|
||||||
|
@ -171,13 +171,13 @@ namespace OpenSim.Framework
|
||||||
request.Timeout = timeout;
|
request.Timeout = timeout;
|
||||||
request.KeepAlive = false;
|
request.KeepAlive = false;
|
||||||
request.MaximumAutomaticRedirections = 10;
|
request.MaximumAutomaticRedirections = 10;
|
||||||
request.ReadWriteTimeout = timeout / 4;
|
request.ReadWriteTimeout = timeout * 8;
|
||||||
request.Headers[OSHeaderRequestID] = reqnum.ToString();
|
request.Headers[OSHeaderRequestID] = reqnum.ToString();
|
||||||
|
|
||||||
// If there is some input, write it into the request
|
// If there is some input, write it into the request
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
string strBuffer = OSDParser.SerializeJsonString(data);
|
string strBuffer = OSDParser.SerializeJsonString(data);
|
||||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
||||||
|
|
||||||
request.ContentType = "application/json";
|
request.ContentType = "application/json";
|
||||||
|
|
|
@ -384,6 +384,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
|
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
|
||||||
public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
|
public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entity update queues
|
||||||
|
/// </summary>
|
||||||
|
public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// First name of the agent/avatar represented by the client
|
/// First name of the agent/avatar represented by the client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3561,6 +3566,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
|
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requeue an EntityUpdate when it was not acknowledged by the client.
|
||||||
|
/// We will update the priority and put it in the correct queue, merging update flags
|
||||||
|
/// with any other updates that may be queued for the same entity.
|
||||||
|
/// The original update time is used for the merged update.
|
||||||
|
/// </summary>
|
||||||
|
private void ResendPrimUpdate(EntityUpdate update)
|
||||||
|
{
|
||||||
|
// If the update exists in priority queue, it will be updated.
|
||||||
|
// If it does not exist then it will be added with the current (rather than its original) priority
|
||||||
|
uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
|
||||||
|
|
||||||
|
lock (m_entityUpdates.SyncRoot)
|
||||||
|
m_entityUpdates.Enqueue(priority, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requeue a list of EntityUpdates when they were not acknowledged by the client.
|
||||||
|
/// We will update the priority and put it in the correct queue, merging update flags
|
||||||
|
/// with any other updates that may be queued for the same entity.
|
||||||
|
/// The original update time is used for the merged update.
|
||||||
|
/// </summary>
|
||||||
|
private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat("[CLIENT] resending prim update {0}",updates[0].UpdateTime);
|
||||||
|
|
||||||
|
// Remove the update packet from the list of packets waiting for acknowledgement
|
||||||
|
// because we are requeuing the list of updates. They will be resent in new packets
|
||||||
|
// with the most recent state and priority.
|
||||||
|
m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
|
||||||
|
|
||||||
|
// Count this as a resent packet since we are going to requeue all of the updates contained in it
|
||||||
|
Interlocked.Increment(ref m_udpClient.PacketsResent);
|
||||||
|
|
||||||
|
foreach (EntityUpdate update in updates)
|
||||||
|
ResendPrimUpdate(update);
|
||||||
|
}
|
||||||
|
|
||||||
private void ProcessEntityUpdates(int maxUpdates)
|
private void ProcessEntityUpdates(int maxUpdates)
|
||||||
{
|
{
|
||||||
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
@ -3568,6 +3611,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
|
||||||
|
OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
|
||||||
// Check to see if this is a flush
|
// Check to see if this is a flush
|
||||||
if (maxUpdates <= 0)
|
if (maxUpdates <= 0)
|
||||||
{
|
{
|
||||||
|
@ -3688,24 +3736,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (update.Entity is ScenePresence)
|
if (update.Entity is ScenePresence)
|
||||||
{
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
||||||
|
objectUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
||||||
|
objectUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!canUseImproved)
|
else if (!canUseImproved)
|
||||||
{
|
{
|
||||||
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
|
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
|
||||||
|
compressedUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
|
if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
|
||||||
|
{
|
||||||
// Self updates go into a special list
|
// Self updates go into a special list
|
||||||
terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
||||||
|
terseAgentUpdates.Value.Add(update);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// Everything else goes here
|
// Everything else goes here
|
||||||
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
||||||
|
terseUpdates.Value.Add(update);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Block Construction
|
#endregion Block Construction
|
||||||
|
@ -3713,10 +3770,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
|
|
||||||
#region Packet Sending
|
#region Packet Sending
|
||||||
|
|
||||||
//const float TIME_DILATION = 1.0f;
|
|
||||||
|
|
||||||
|
|
||||||
ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
|
ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
|
||||||
|
|
||||||
if (terseAgentUpdateBlocks.IsValueCreated)
|
if (terseAgentUpdateBlocks.IsValueCreated)
|
||||||
|
@ -3730,9 +3783,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
packet.ObjectData[i] = blocks[i];
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
// If any of the packets created from this call go unacknowledged, all of the updates will be resent
|
||||||
|
OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
|
||||||
OutPacket(packet, ThrottleOutPacketType.Unknown, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objectUpdateBlocks.IsValueCreated)
|
if (objectUpdateBlocks.IsValueCreated)
|
||||||
|
@ -3746,8 +3798,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
packet.ObjectData[i] = blocks[i];
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
// If any of the packets created from this call go unacknowledged, all of the updates will be resent
|
||||||
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compressedUpdateBlocks.IsValueCreated)
|
if (compressedUpdateBlocks.IsValueCreated)
|
||||||
|
@ -3761,8 +3813,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
packet.ObjectData[i] = blocks[i];
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
// If any of the packets created from this call go unacknowledged, all of the updates will be resent
|
||||||
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (terseUpdateBlocks.IsValueCreated)
|
if (terseUpdateBlocks.IsValueCreated)
|
||||||
|
@ -3776,8 +3828,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
packet.ObjectData[i] = blocks[i];
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
// If any of the packets created from this call go unacknowledged, all of the updates will be resent
|
||||||
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3969,7 +4021,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
|
SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
|
||||||
SendObjectProps = SendObjectProps || update.SendObjectProps;
|
SendObjectProps = SendObjectProps || update.SendObjectProps;
|
||||||
Flags |= update.Flags;
|
// other properties may need to be updated by base class
|
||||||
|
base.Update(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3980,6 +4033,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
|
m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ResendPropertyUpdate(ObjectPropertyUpdate update)
|
||||||
|
{
|
||||||
|
uint priority = 0;
|
||||||
|
lock (m_entityProps.SyncRoot)
|
||||||
|
m_entityProps.Enqueue(priority, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResendPropertyUpdates(List<ObjectPropertyUpdate> updates, OutgoingPacket oPacket)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat("[CLIENT] resending object property {0}",updates[0].UpdateTime);
|
||||||
|
|
||||||
|
// Remove the update packet from the list of packets waiting for acknowledgement
|
||||||
|
// because we are requeuing the list of updates. They will be resent in new packets
|
||||||
|
// with the most recent state.
|
||||||
|
m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
|
||||||
|
|
||||||
|
// Count this as a resent packet since we are going to requeue all of the updates contained in it
|
||||||
|
Interlocked.Increment(ref m_udpClient.PacketsResent);
|
||||||
|
|
||||||
|
foreach (ObjectPropertyUpdate update in updates)
|
||||||
|
ResendPropertyUpdate(update);
|
||||||
|
}
|
||||||
|
|
||||||
public void SendObjectPropertiesReply(ISceneEntity entity)
|
public void SendObjectPropertiesReply(ISceneEntity entity)
|
||||||
{
|
{
|
||||||
uint priority = 0; // time based ordering only
|
uint priority = 0; // time based ordering only
|
||||||
|
@ -3995,6 +4071,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
|
OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
|
||||||
new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
|
new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
|
||||||
|
|
||||||
|
OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
|
||||||
|
new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
|
||||||
|
|
||||||
|
OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
|
||||||
|
new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
|
||||||
|
|
||||||
IEntityUpdate iupdate;
|
IEntityUpdate iupdate;
|
||||||
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
Int32 timeinqueue; // this is just debugging code & can be dropped later
|
||||||
|
|
||||||
|
@ -4013,6 +4095,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
SceneObjectPart sop = (SceneObjectPart)update.Entity;
|
SceneObjectPart sop = (SceneObjectPart)update.Entity;
|
||||||
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
|
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
|
||||||
objectFamilyBlocks.Value.Add(objPropDB);
|
objectFamilyBlocks.Value.Add(objPropDB);
|
||||||
|
familyUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4023,6 +4106,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
SceneObjectPart sop = (SceneObjectPart)update.Entity;
|
SceneObjectPart sop = (SceneObjectPart)update.Entity;
|
||||||
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
|
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
|
||||||
objectPropertiesBlocks.Value.Add(objPropDB);
|
objectPropertiesBlocks.Value.Add(objPropDB);
|
||||||
|
propertyUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4030,12 +4114,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Int32 ppcnt = 0;
|
// Int32 ppcnt = 0;
|
||||||
Int32 pbcnt = 0;
|
// Int32 pbcnt = 0;
|
||||||
|
|
||||||
if (objectPropertiesBlocks.IsValueCreated)
|
if (objectPropertiesBlocks.IsValueCreated)
|
||||||
{
|
{
|
||||||
List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
|
List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
|
||||||
|
List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
|
||||||
|
|
||||||
ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
|
ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
|
||||||
packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
|
packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
|
||||||
|
@ -4043,28 +4128,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
packet.ObjectData[i] = blocks[i];
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
|
||||||
packet.Header.Zerocoded = true;
|
packet.Header.Zerocoded = true;
|
||||||
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
|
||||||
|
|
||||||
pbcnt += blocks.Count;
|
// Pass in the delegate so that if this packet needs to be resent, we send the current properties
|
||||||
ppcnt++;
|
// of the object rather than the properties when the packet was created
|
||||||
|
OutPacket(packet, ThrottleOutPacketType.Task, true,
|
||||||
|
delegate(OutgoingPacket oPacket)
|
||||||
|
{
|
||||||
|
ResendPropertyUpdates(updates, oPacket);
|
||||||
|
});
|
||||||
|
|
||||||
|
// pbcnt += blocks.Count;
|
||||||
|
// ppcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Int32 fpcnt = 0;
|
// Int32 fpcnt = 0;
|
||||||
Int32 fbcnt = 0;
|
// Int32 fbcnt = 0;
|
||||||
|
|
||||||
if (objectFamilyBlocks.IsValueCreated)
|
if (objectFamilyBlocks.IsValueCreated)
|
||||||
{
|
{
|
||||||
List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
|
List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
|
||||||
|
|
||||||
// ObjectPropertiesFamilyPacket objPropFamilyPack =
|
|
||||||
// (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
|
|
||||||
//
|
|
||||||
// objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count];
|
|
||||||
// for (int i = 0; i < blocks.Count; i++)
|
|
||||||
// objPropFamilyPack.ObjectData[i] = blocks[i];
|
|
||||||
//
|
|
||||||
// OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true);
|
|
||||||
|
|
||||||
// one packet per object block... uggh...
|
// one packet per object block... uggh...
|
||||||
for (int i = 0; i < blocks.Count; i++)
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -4073,10 +4156,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
packet.ObjectData = blocks[i];
|
packet.ObjectData = blocks[i];
|
||||||
packet.Header.Zerocoded = true;
|
packet.Header.Zerocoded = true;
|
||||||
OutPacket(packet, ThrottleOutPacketType.Task);
|
|
||||||
|
|
||||||
fpcnt++;
|
// Pass in the delegate so that if this packet needs to be resent, we send the current properties
|
||||||
fbcnt++;
|
// of the object rather than the properties when the packet was created
|
||||||
|
List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
|
||||||
|
updates.Add(familyUpdates.Value[i]);
|
||||||
|
OutPacket(packet, ThrottleOutPacketType.Task, true,
|
||||||
|
delegate(OutgoingPacket oPacket)
|
||||||
|
{
|
||||||
|
ResendPropertyUpdates(updates, oPacket);
|
||||||
|
});
|
||||||
|
|
||||||
|
// fpcnt++;
|
||||||
|
// fbcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11336,7 +11428,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public byte[] GetThrottlesPacked(float multiplier)
|
public byte[] GetThrottlesPacked(float multiplier)
|
||||||
{
|
{
|
||||||
return m_udpClient.GetThrottlesPacked();
|
return m_udpClient.GetThrottlesPacked(multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -11370,6 +11462,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// packets (the default), or false to disable splitting if the calling code
|
/// packets (the default), or false to disable splitting if the calling code
|
||||||
/// handles splitting manually</param>
|
/// handles splitting manually</param>
|
||||||
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
|
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
|
||||||
|
{
|
||||||
|
OutPacket(packet, throttlePacketType, doAutomaticSplitting, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the starting point for sending a simulator packet out to the client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packet">Packet to send</param>
|
||||||
|
/// <param name="throttlePacketType">Throttling category for the packet</param>
|
||||||
|
/// <param name="doAutomaticSplitting">True to automatically split oversized
|
||||||
|
/// packets (the default), or false to disable splitting if the calling code
|
||||||
|
/// handles splitting manually</param>
|
||||||
|
/// <param name="method">The method to be called in the event this packet is reliable
|
||||||
|
/// and unacknowledged. The server will provide normal resend capability if you do not
|
||||||
|
/// provide your own method.</param>
|
||||||
|
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
if (m_debugPacketLevel > 0)
|
if (m_debugPacketLevel > 0)
|
||||||
{
|
{
|
||||||
|
@ -11396,7 +11504,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
|
m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting);
|
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddMoney(int debit)
|
public bool AddMoney(int debit)
|
||||||
|
@ -11527,7 +11635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
info.userEP = m_userEndPoint;
|
info.userEP = m_userEndPoint;
|
||||||
info.proxyEP = null;
|
info.proxyEP = null;
|
||||||
info.agentcircuit = new sAgentCircuitData(RequestClientInfo());
|
info.agentcircuit = RequestClientInfo();
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private int m_nextOnQueueEmpty = 1;
|
private int m_nextOnQueueEmpty = 1;
|
||||||
|
|
||||||
/// <summary>Throttle bucket for this agent's connection</summary>
|
/// <summary>Throttle bucket for this agent's connection</summary>
|
||||||
private readonly TokenBucket m_throttleClient;
|
private readonly AdaptiveTokenBucket m_throttleClient;
|
||||||
|
public AdaptiveTokenBucket FlowThrottle
|
||||||
|
{
|
||||||
|
get { return m_throttleClient; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Throttle bucket for this agent's connection</summary>
|
/// <summary>Throttle bucket for this agent's connection</summary>
|
||||||
private readonly TokenBucket m_throttleCategory;
|
private readonly TokenBucket m_throttleCategory;
|
||||||
/// <summary>Throttle buckets for each packet category</summary>
|
/// <summary>Throttle buckets for each packet category</summary>
|
||||||
|
@ -176,9 +181,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_maxRTO = maxRTO;
|
m_maxRTO = maxRTO;
|
||||||
|
|
||||||
// Create a token bucket throttle for this client that has the scene token bucket as a parent
|
// Create a token bucket throttle for this client that has the scene token bucket as a parent
|
||||||
m_throttleClient = new TokenBucket(parentThrottle, rates.TotalLimit);
|
m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
|
||||||
// Create a token bucket throttle for the total categary with the client bucket as a throttle
|
// Create a token bucket throttle for the total categary with the client bucket as a throttle
|
||||||
m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit);
|
m_throttleCategory = new TokenBucket(m_throttleClient, 0);
|
||||||
// Create an array of token buckets for this clients different throttle categories
|
// Create an array of token buckets for this clients different throttle categories
|
||||||
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
|
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
|
||||||
|
|
||||||
|
@ -189,7 +194,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Initialize the packet outboxes, where packets sit while they are waiting for tokens
|
// Initialize the packet outboxes, where packets sit while they are waiting for tokens
|
||||||
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
|
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
|
||||||
// Initialize the token buckets that control the throttling for each category
|
// Initialize the token buckets that control the throttling for each category
|
||||||
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetLimit(type));
|
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default the retransmission timeout to three seconds
|
// Default the retransmission timeout to three seconds
|
||||||
|
@ -223,26 +228,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <returns>Information about the client connection</returns>
|
/// <returns>Information about the client connection</returns>
|
||||||
public ClientInfo GetClientInfo()
|
public ClientInfo GetClientInfo()
|
||||||
{
|
{
|
||||||
///<mic>
|
|
||||||
TokenBucket tb;
|
|
||||||
|
|
||||||
tb = m_throttleClient.Parent;
|
|
||||||
m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest,"ROOT");
|
|
||||||
|
|
||||||
tb = m_throttleClient;
|
|
||||||
m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CLIENT");
|
|
||||||
|
|
||||||
tb = m_throttleCategory;
|
|
||||||
m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CATEGORY");
|
|
||||||
|
|
||||||
for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
|
|
||||||
{
|
|
||||||
tb = m_throttleCategories[i];
|
|
||||||
m_log.WarnFormat("[TOKENS] {4} <{0}:{1}>: Actual={2},Requested={3}",AgentID,i,tb.DripRate,tb.RequestedDripRate," BUCKET");
|
|
||||||
}
|
|
||||||
|
|
||||||
///</mic>
|
|
||||||
|
|
||||||
// TODO: This data structure is wrong in so many ways. Locking and copying the entire lists
|
// TODO: This data structure is wrong in so many ways. Locking and copying the entire lists
|
||||||
// of pending and needed ACKs for every client every time some method wants information about
|
// of pending and needed ACKs for every client every time some method wants information about
|
||||||
// this connection is a recipe for poor performance
|
// this connection is a recipe for poor performance
|
||||||
|
@ -254,12 +239,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate;
|
info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate;
|
||||||
info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate;
|
info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate;
|
||||||
info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate;
|
info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate;
|
||||||
// info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
|
|
||||||
info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
|
info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
|
||||||
info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
|
info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
|
||||||
info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
|
info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
|
||||||
info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle +
|
info.totalThrottle = (int)m_throttleCategory.DripRate;
|
||||||
info.taskThrottle + info.assetThrottle + info.textureThrottle;
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -346,8 +329,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||||
// State is a subcategory of task that we allocate a percentage to
|
// State is a subcategory of task that we allocate a percentage to
|
||||||
int state = 0;
|
int state = 0;
|
||||||
// int state = (int)((float)task * STATE_TASK_PERCENTAGE);
|
|
||||||
// task -= state;
|
|
||||||
|
|
||||||
// Make sure none of the throttles are set below our packet MTU,
|
// Make sure none of the throttles are set below our packet MTU,
|
||||||
// otherwise a throttle could become permanently clogged
|
// otherwise a throttle could become permanently clogged
|
||||||
|
@ -358,19 +339,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
task = Math.Max(task, LLUDPServer.MTU);
|
task = Math.Max(task, LLUDPServer.MTU);
|
||||||
texture = Math.Max(texture, LLUDPServer.MTU);
|
texture = Math.Max(texture, LLUDPServer.MTU);
|
||||||
asset = Math.Max(asset, LLUDPServer.MTU);
|
asset = Math.Max(asset, LLUDPServer.MTU);
|
||||||
state = Math.Max(state, LLUDPServer.MTU);
|
|
||||||
|
|
||||||
int total = resend + land + wind + cloud + task + texture + asset + state;
|
//int total = resend + land + wind + cloud + task + texture + asset;
|
||||||
|
//m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}",
|
||||||
//m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}",
|
// AgentID, resend, land, wind, cloud, task, texture, asset, total);
|
||||||
// AgentID, resend, land, wind, cloud, task, texture, asset, state, total);
|
|
||||||
|
|
||||||
// Update the token buckets with new throttle values
|
// Update the token buckets with new throttle values
|
||||||
TokenBucket bucket;
|
TokenBucket bucket;
|
||||||
|
|
||||||
bucket = m_throttleCategory;
|
|
||||||
bucket.RequestedDripRate = total;
|
|
||||||
|
|
||||||
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
|
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
|
||||||
bucket.RequestedDripRate = resend;
|
bucket.RequestedDripRate = resend;
|
||||||
|
|
||||||
|
@ -399,22 +375,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_packedThrottles = null;
|
m_packedThrottles = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetThrottlesPacked()
|
public byte[] GetThrottlesPacked(float multiplier)
|
||||||
{
|
{
|
||||||
byte[] data = m_packedThrottles;
|
byte[] data = m_packedThrottles;
|
||||||
|
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
|
float rate;
|
||||||
|
|
||||||
data = new byte[7 * 4];
|
data = new byte[7 * 4];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate), 0, data, i, 4); i += 4;
|
// multiply by 8 to convert bytes back to bits
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate), 0, data, i, 4); i += 4;
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * 8 * multiplier;
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate), 0, data, i, 4); i += 4;
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate), 0, data, i, 4); i += 4;
|
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate), 0, data, i, 4); i += 4;
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * 8 * multiplier;
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate), 0, data, i, 4); i += 4;
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate), 0, data, i, 4); i += 4;
|
|
||||||
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * 8 * multiplier;
|
||||||
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
|
|
||||||
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * 8 * multiplier;
|
||||||
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
|
|
||||||
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * 8 * multiplier;
|
||||||
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
|
|
||||||
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * 8 * multiplier;
|
||||||
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
|
|
||||||
|
rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * 8 * multiplier;
|
||||||
|
Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4;
|
||||||
|
|
||||||
m_packedThrottles = data;
|
m_packedThrottles = data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
delegate(IClientAPI client)
|
delegate(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category);
|
SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category, null);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
delegate(IClientAPI client)
|
delegate(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category);
|
SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category, null);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="packet"></param>
|
/// <param name="packet"></param>
|
||||||
/// <param name="category"></param>
|
/// <param name="category"></param>
|
||||||
/// <param name="allowSplitting"></param>
|
/// <param name="allowSplitting"></param>
|
||||||
public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting)
|
public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
// CoarseLocationUpdate packets cannot be split in an automated way
|
// CoarseLocationUpdate packets cannot be split in an automated way
|
||||||
if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting)
|
if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting)
|
||||||
|
@ -339,13 +339,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
for (int i = 0; i < packetCount; i++)
|
for (int i = 0; i < packetCount; i++)
|
||||||
{
|
{
|
||||||
byte[] data = datas[i];
|
byte[] data = datas[i];
|
||||||
SendPacketData(udpClient, data, packet.Type, category);
|
SendPacketData(udpClient, data, packet.Type, category, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
byte[] data = packet.ToBytes();
|
byte[] data = packet.ToBytes();
|
||||||
SendPacketData(udpClient, data, packet.Type, category);
|
SendPacketData(udpClient, data, packet.Type, category, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="category"></param>
|
/// <param name="category"></param>
|
||||||
public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category)
|
public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
int dataLength = data.Length;
|
int dataLength = data.Length;
|
||||||
bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
|
bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
|
||||||
|
@ -411,7 +411,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
#region Queue or Send
|
#region Queue or Send
|
||||||
|
|
||||||
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
|
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
|
||||||
|
// If we were not provided a method for handling unacked, use the UDPServer default method
|
||||||
|
outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
|
||||||
|
|
||||||
// If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
|
// If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
|
||||||
// continue to display the deleted object until relog. Therefore, we need to always queue a kill object
|
// continue to display the deleted object until relog. Therefore, we need to always queue a kill object
|
||||||
|
@ -445,7 +447,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
packet.Header.Reliable = false;
|
packet.Header.Reliable = false;
|
||||||
packet.Packets = blocks.ToArray();
|
packet.Packets = blocks.ToArray();
|
||||||
|
|
||||||
SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true);
|
SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,17 +460,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
|
// We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
|
||||||
pc.PingID.OldestUnacked = 0;
|
pc.PingID.OldestUnacked = 0;
|
||||||
|
|
||||||
SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false);
|
SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CompletePing(LLUDPClient udpClient, byte pingID)
|
public void CompletePing(LLUDPClient udpClient, byte pingID)
|
||||||
{
|
{
|
||||||
CompletePingCheckPacket completePing = new CompletePingCheckPacket();
|
CompletePingCheckPacket completePing = new CompletePingCheckPacket();
|
||||||
completePing.PingID.PingID = pingID;
|
completePing.PingID.PingID = pingID;
|
||||||
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
|
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResendUnacked(LLUDPClient udpClient)
|
public void HandleUnacked(LLUDPClient udpClient)
|
||||||
{
|
{
|
||||||
if (!udpClient.IsConnected)
|
if (!udpClient.IsConnected)
|
||||||
return;
|
return;
|
||||||
|
@ -488,33 +490,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
if (expiredPackets != null)
|
if (expiredPackets != null)
|
||||||
{
|
{
|
||||||
//m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO);
|
//m_log.Debug("[LLUDPSERVER]: Handling " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO);
|
||||||
|
|
||||||
// Exponential backoff of the retransmission timeout
|
// Exponential backoff of the retransmission timeout
|
||||||
udpClient.BackoffRTO();
|
udpClient.BackoffRTO();
|
||||||
|
for (int i = 0; i < expiredPackets.Count; ++i)
|
||||||
// Resend packets
|
expiredPackets[i].UnackedMethod(expiredPackets[i]);
|
||||||
for (int i = 0; i < expiredPackets.Count; i++)
|
|
||||||
{
|
|
||||||
OutgoingPacket outgoingPacket = expiredPackets[i];
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed",
|
|
||||||
// outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount);
|
|
||||||
|
|
||||||
// Set the resent flag
|
|
||||||
outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT);
|
|
||||||
outgoingPacket.Category = ThrottleOutPacketType.Resend;
|
|
||||||
|
|
||||||
// Bump up the resend count on this packet
|
|
||||||
Interlocked.Increment(ref outgoingPacket.ResendCount);
|
|
||||||
|
|
||||||
// Requeue or resend the packet
|
|
||||||
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
|
|
||||||
SendPacketFinal(outgoingPacket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResendUnacked(OutgoingPacket outgoingPacket)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed",
|
||||||
|
// outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount);
|
||||||
|
|
||||||
|
// Set the resent flag
|
||||||
|
outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT);
|
||||||
|
outgoingPacket.Category = ThrottleOutPacketType.Resend;
|
||||||
|
|
||||||
|
// Bump up the resend count on this packet
|
||||||
|
Interlocked.Increment(ref outgoingPacket.ResendCount);
|
||||||
|
|
||||||
|
// Requeue or resend the packet
|
||||||
|
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
|
||||||
|
SendPacketFinal(outgoingPacket);
|
||||||
|
}
|
||||||
|
|
||||||
public void Flush(LLUDPClient udpClient)
|
public void Flush(LLUDPClient udpClient)
|
||||||
{
|
{
|
||||||
// FIXME: Implement?
|
// FIXME: Implement?
|
||||||
|
@ -672,7 +672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
|
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < packet.Header.AckList.Length; i++)
|
for (int i = 0; i < packet.Header.AckList.Length; i++)
|
||||||
udpClient.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent);
|
udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle PacketAck packets
|
// Handle PacketAck packets
|
||||||
|
@ -681,7 +681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
PacketAckPacket ackPacket = (PacketAckPacket)packet;
|
PacketAckPacket ackPacket = (PacketAckPacket)packet;
|
||||||
|
|
||||||
for (int i = 0; i < ackPacket.Packets.Length; i++)
|
for (int i = 0; i < ackPacket.Packets.Length; i++)
|
||||||
udpClient.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent);
|
udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
|
||||||
|
|
||||||
// We don't need to do anything else with PacketAck packets
|
// We don't need to do anything else with PacketAck packets
|
||||||
return;
|
return;
|
||||||
|
@ -1096,7 +1096,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
if (m_resendUnacked)
|
if (m_resendUnacked)
|
||||||
ResendUnacked(udpClient);
|
HandleUnacked(udpClient);
|
||||||
|
|
||||||
if (m_sendAcks)
|
if (m_sendAcks)
|
||||||
SendAcks(udpClient);
|
SendAcks(udpClient);
|
||||||
|
@ -1152,7 +1152,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
nticksUnack++;
|
nticksUnack++;
|
||||||
watch2.Start();
|
watch2.Start();
|
||||||
|
|
||||||
ResendUnacked(udpClient);
|
HandleUnacked(udpClient);
|
||||||
|
|
||||||
watch2.Stop();
|
watch2.Stop();
|
||||||
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
||||||
|
|
|
@ -31,6 +31,8 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public delegate void UnackedPacketMethod(OutgoingPacket oPacket);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds a reference to the <seealso cref="LLUDPClient"/> this packet is
|
/// Holds a reference to the <seealso cref="LLUDPClient"/> this packet is
|
||||||
/// destined for, along with the serialized packet data, sequence number
|
/// destined for, along with the serialized packet data, sequence number
|
||||||
|
@ -52,6 +54,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public int TickCount;
|
public int TickCount;
|
||||||
/// <summary>Category this packet belongs to</summary>
|
/// <summary>Category this packet belongs to</summary>
|
||||||
public ThrottleOutPacketType Category;
|
public ThrottleOutPacketType Category;
|
||||||
|
/// <summary>The delegate to be called if this packet is determined to be unacknowledged</summary>
|
||||||
|
public UnackedPacketMethod UnackedMethod;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
|
@ -60,11 +64,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="buffer">Serialized packet data. If the flags or sequence number
|
/// <param name="buffer">Serialized packet data. If the flags or sequence number
|
||||||
/// need to be updated, they will be injected directly into this binary buffer</param>
|
/// need to be updated, they will be injected directly into this binary buffer</param>
|
||||||
/// <param name="category">Throttling category for this packet</param>
|
/// <param name="category">Throttling category for this packet</param>
|
||||||
public OutgoingPacket(LLUDPClient client, UDPPacketBuffer buffer, ThrottleOutPacketType category)
|
public OutgoingPacket(LLUDPClient client, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
Client = client;
|
Client = client;
|
||||||
Buffer = buffer;
|
Buffer = buffer;
|
||||||
Category = category;
|
Category = category;
|
||||||
|
UnackedMethod = method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,29 +52,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public int Texture;
|
public int Texture;
|
||||||
/// <summary>Drip rate for asset packets</summary>
|
/// <summary>Drip rate for asset packets</summary>
|
||||||
public int Asset;
|
public int Asset;
|
||||||
/// <summary>Drip rate for state packets</summary>
|
|
||||||
public int State;
|
|
||||||
/// <summary>Drip rate for the parent token bucket</summary>
|
/// <summary>Drip rate for the parent token bucket</summary>
|
||||||
public int Total;
|
public int Total;
|
||||||
|
|
||||||
/// <summary>Maximum burst rate for resent packets</summary>
|
/// <summary>Flag used to enable adaptive throttles</summary>
|
||||||
public int ResendLimit;
|
public bool AdaptiveThrottlesEnabled;
|
||||||
/// <summary>Maximum burst rate for land packets</summary>
|
|
||||||
public int LandLimit;
|
|
||||||
/// <summary>Maximum burst rate for wind packets</summary>
|
|
||||||
public int WindLimit;
|
|
||||||
/// <summary>Maximum burst rate for cloud packets</summary>
|
|
||||||
public int CloudLimit;
|
|
||||||
/// <summary>Maximum burst rate for task (state and transaction) packets</summary>
|
|
||||||
public int TaskLimit;
|
|
||||||
/// <summary>Maximum burst rate for texture packets</summary>
|
|
||||||
public int TextureLimit;
|
|
||||||
/// <summary>Maximum burst rate for asset packets</summary>
|
|
||||||
public int AssetLimit;
|
|
||||||
/// <summary>Maximum burst rate for state packets</summary>
|
|
||||||
public int StateLimit;
|
|
||||||
/// <summary>Burst rate for the parent token bucket</summary>
|
|
||||||
public int TotalLimit;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
|
@ -86,26 +69,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
|
IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
|
||||||
|
|
||||||
Resend = throttleConfig.GetInt("resend_default", 12500);
|
Resend = throttleConfig.GetInt("resend_default", 6625);
|
||||||
Land = throttleConfig.GetInt("land_default", 1000);
|
Land = throttleConfig.GetInt("land_default", 9125);
|
||||||
Wind = throttleConfig.GetInt("wind_default", 1000);
|
Wind = throttleConfig.GetInt("wind_default", 1750);
|
||||||
Cloud = throttleConfig.GetInt("cloud_default", 1000);
|
Cloud = throttleConfig.GetInt("cloud_default", 1750);
|
||||||
Task = throttleConfig.GetInt("task_default", 1000);
|
Task = throttleConfig.GetInt("task_default", 18500);
|
||||||
Texture = throttleConfig.GetInt("texture_default", 1000);
|
Texture = throttleConfig.GetInt("texture_default", 18500);
|
||||||
Asset = throttleConfig.GetInt("asset_default", 1000);
|
Asset = throttleConfig.GetInt("asset_default", 10500);
|
||||||
State = throttleConfig.GetInt("state_default", 1000);
|
|
||||||
|
|
||||||
ResendLimit = throttleConfig.GetInt("resend_limit", 18750);
|
|
||||||
LandLimit = throttleConfig.GetInt("land_limit", 29750);
|
|
||||||
WindLimit = throttleConfig.GetInt("wind_limit", 18750);
|
|
||||||
CloudLimit = throttleConfig.GetInt("cloud_limit", 18750);
|
|
||||||
TaskLimit = throttleConfig.GetInt("task_limit", 18750);
|
|
||||||
TextureLimit = throttleConfig.GetInt("texture_limit", 55750);
|
|
||||||
AssetLimit = throttleConfig.GetInt("asset_limit", 27500);
|
|
||||||
StateLimit = throttleConfig.GetInt("state_limit", 37000);
|
|
||||||
|
|
||||||
Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
|
Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
|
||||||
TotalLimit = Total;
|
|
||||||
|
AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
|
||||||
}
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
|
@ -128,34 +102,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return Texture;
|
return Texture;
|
||||||
case ThrottleOutPacketType.Asset:
|
case ThrottleOutPacketType.Asset:
|
||||||
return Asset;
|
return Asset;
|
||||||
case ThrottleOutPacketType.State:
|
|
||||||
return State;
|
|
||||||
case ThrottleOutPacketType.Unknown:
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetLimit(ThrottleOutPacketType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case ThrottleOutPacketType.Resend:
|
|
||||||
return ResendLimit;
|
|
||||||
case ThrottleOutPacketType.Land:
|
|
||||||
return LandLimit;
|
|
||||||
case ThrottleOutPacketType.Wind:
|
|
||||||
return WindLimit;
|
|
||||||
case ThrottleOutPacketType.Cloud:
|
|
||||||
return CloudLimit;
|
|
||||||
case ThrottleOutPacketType.Task:
|
|
||||||
return TaskLimit;
|
|
||||||
case ThrottleOutPacketType.Texture:
|
|
||||||
return TextureLimit;
|
|
||||||
case ThrottleOutPacketType.Asset:
|
|
||||||
return AssetLimit;
|
|
||||||
case ThrottleOutPacketType.State:
|
|
||||||
return StateLimit;
|
|
||||||
case ThrottleOutPacketType.Unknown:
|
case ThrottleOutPacketType.Unknown:
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -29,6 +29,8 @@ using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
@ -48,31 +50,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Number of ticks (ms) per quantum, drip rate and max burst
|
/// Number of ticks (ms) per quantum, drip rate and max burst
|
||||||
/// are defined over this interval.
|
/// are defined over this interval.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const Int32 m_ticksPerQuantum = 1000;
|
protected const Int32 m_ticksPerQuantum = 1000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the number of quantums worth of packets that can
|
/// This is the number of quantums worth of packets that can
|
||||||
/// be accommodated during a burst
|
/// be accommodated during a burst
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const Double m_quantumsPerBurst = 1.5;
|
protected const Double m_quantumsPerBurst = 1.5;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const Int32 m_minimumDripRate = 1400;
|
protected const Int32 m_minimumDripRate = 1400;
|
||||||
|
|
||||||
/// <summary>Time of the last drip, in system ticks</summary>
|
/// <summary>Time of the last drip, in system ticks</summary>
|
||||||
private Int32 m_lastDrip;
|
protected Int32 m_lastDrip;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of bytes that can be sent at this moment. This is the
|
/// The number of bytes that can be sent at this moment. This is the
|
||||||
/// current number of tokens in the bucket
|
/// current number of tokens in the bucket
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Int64 m_tokenCount;
|
protected Int64 m_tokenCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Map of children buckets and their requested maximum burst rate
|
/// Map of children buckets and their requested maximum burst rate
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>();
|
protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>();
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// parent. The parent bucket will limit the aggregate bandwidth of all
|
/// parent. The parent bucket will limit the aggregate bandwidth of all
|
||||||
/// of its children buckets
|
/// of its children buckets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private TokenBucket m_parent;
|
protected TokenBucket m_parent;
|
||||||
public TokenBucket Parent
|
public TokenBucket Parent
|
||||||
{
|
{
|
||||||
get { return m_parent; }
|
get { return m_parent; }
|
||||||
|
@ -93,7 +95,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// of tokens that can accumulate in the bucket at any one time. This
|
/// of tokens that can accumulate in the bucket at any one time. This
|
||||||
/// also sets the total request for leaf nodes
|
/// also sets the total request for leaf nodes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Int64 m_burstRate;
|
protected Int64 m_burstRate;
|
||||||
public Int64 RequestedBurstRate
|
public Int64 RequestedBurstRate
|
||||||
{
|
{
|
||||||
get { return m_burstRate; }
|
get { return m_burstRate; }
|
||||||
|
@ -118,8 +120,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <remarks>Tokens are added to the bucket any time
|
/// <remarks>Tokens are added to the bucket any time
|
||||||
/// <seealso cref="RemoveTokens"/> is called, at the granularity of
|
/// <seealso cref="RemoveTokens"/> is called, at the granularity of
|
||||||
/// the system tick interval (typically around 15-22ms)</remarks>
|
/// the system tick interval (typically around 15-22ms)</remarks>
|
||||||
private Int64 m_dripRate;
|
protected Int64 m_dripRate;
|
||||||
public Int64 RequestedDripRate
|
public virtual Int64 RequestedDripRate
|
||||||
{
|
{
|
||||||
get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); }
|
get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); }
|
||||||
set {
|
set {
|
||||||
|
@ -131,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int64 DripRate
|
public virtual Int64 DripRate
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
if (m_parent == null)
|
if (m_parent == null)
|
||||||
|
@ -149,7 +151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// The current total of the requested maximum burst rates of
|
/// The current total of the requested maximum burst rates of
|
||||||
/// this bucket's children buckets.
|
/// this bucket's children buckets.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Int64 m_totalDripRequest;
|
protected Int64 m_totalDripRequest;
|
||||||
public Int64 TotalDripRequest
|
public Int64 TotalDripRequest
|
||||||
{
|
{
|
||||||
get { return m_totalDripRequest; }
|
get { return m_totalDripRequest; }
|
||||||
|
@ -177,7 +179,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
RequestedDripRate = dripRate;
|
RequestedDripRate = dripRate;
|
||||||
// TotalDripRequest = dripRate; // this will be overwritten when a child node registers
|
// TotalDripRequest = dripRate; // this will be overwritten when a child node registers
|
||||||
// MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
|
// MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
|
||||||
m_lastDrip = Environment.TickCount & Int32.MaxValue;
|
m_lastDrip = Util.EnvironmentTickCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Constructor
|
#endregion Constructor
|
||||||
|
@ -189,7 +191,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// hierarchy. However, if any of the parents is over-booked, then
|
/// hierarchy. However, if any of the parents is over-booked, then
|
||||||
/// the modifier will be less than 1.
|
/// the modifier will be less than 1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private double DripRateModifier()
|
protected double DripRateModifier()
|
||||||
{
|
{
|
||||||
Int64 driprate = DripRate;
|
Int64 driprate = DripRate;
|
||||||
return driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest;
|
return driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest;
|
||||||
|
@ -197,7 +199,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private double BurstRateModifier()
|
protected double BurstRateModifier()
|
||||||
{
|
{
|
||||||
// for now... burst rate is always m_quantumsPerBurst (constant)
|
// for now... burst rate is always m_quantumsPerBurst (constant)
|
||||||
// larger than drip rate so the ratio of burst requests is the
|
// larger than drip rate so the ratio of burst requests is the
|
||||||
|
@ -211,12 +213,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void RegisterRequest(TokenBucket child, Int64 request)
|
public void RegisterRequest(TokenBucket child, Int64 request)
|
||||||
{
|
{
|
||||||
m_children[child] = request;
|
lock (m_children)
|
||||||
// m_totalDripRequest = m_children.Values.Sum();
|
{
|
||||||
|
m_children[child] = request;
|
||||||
|
// m_totalDripRequest = m_children.Values.Sum();
|
||||||
|
|
||||||
m_totalDripRequest = 0;
|
m_totalDripRequest = 0;
|
||||||
foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
|
foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
|
||||||
m_totalDripRequest += cref.Value;
|
m_totalDripRequest += cref.Value;
|
||||||
|
}
|
||||||
|
|
||||||
// Pass the new values up to the parent
|
// Pass the new values up to the parent
|
||||||
if (m_parent != null)
|
if (m_parent != null)
|
||||||
|
@ -229,12 +234,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UnregisterRequest(TokenBucket child)
|
public void UnregisterRequest(TokenBucket child)
|
||||||
{
|
{
|
||||||
m_children.Remove(child);
|
lock (m_children)
|
||||||
// m_totalDripRequest = m_children.Values.Sum();
|
{
|
||||||
|
m_children.Remove(child);
|
||||||
|
// m_totalDripRequest = m_children.Values.Sum();
|
||||||
|
|
||||||
|
m_totalDripRequest = 0;
|
||||||
|
foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
|
||||||
|
m_totalDripRequest += cref.Value;
|
||||||
|
}
|
||||||
|
|
||||||
m_totalDripRequest = 0;
|
|
||||||
foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
|
|
||||||
m_totalDripRequest += cref.Value;
|
|
||||||
|
|
||||||
// Pass the new values up to the parent
|
// Pass the new values up to the parent
|
||||||
if (m_parent != null)
|
if (m_parent != null)
|
||||||
|
@ -268,7 +277,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Deposit tokens into the bucket from a child bucket that did
|
/// Deposit tokens into the bucket from a child bucket that did
|
||||||
/// not use all of its available tokens
|
/// not use all of its available tokens
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void Deposit(Int64 count)
|
protected void Deposit(Int64 count)
|
||||||
{
|
{
|
||||||
m_tokenCount += count;
|
m_tokenCount += count;
|
||||||
|
|
||||||
|
@ -285,7 +294,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// call to Drip
|
/// call to Drip
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if tokens were added to the bucket, otherwise false</returns>
|
/// <returns>True if tokens were added to the bucket, otherwise false</returns>
|
||||||
private void Drip()
|
protected void Drip()
|
||||||
{
|
{
|
||||||
// This should never happen... means we are a leaf node and were created
|
// This should never happen... means we are a leaf node and were created
|
||||||
// with no drip rate...
|
// with no drip rate...
|
||||||
|
@ -297,10 +306,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// Determine the interval over which we are adding tokens, never add
|
// Determine the interval over which we are adding tokens, never add
|
||||||
// more than a single quantum of tokens
|
// more than a single quantum of tokens
|
||||||
Int32 now = Environment.TickCount & Int32.MaxValue;
|
Int32 deltaMS = Math.Min(Util.EnvironmentTickCountSubtract(m_lastDrip), m_ticksPerQuantum);
|
||||||
Int32 deltaMS = Math.Min(now - m_lastDrip, m_ticksPerQuantum);
|
m_lastDrip = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
m_lastDrip = now;
|
|
||||||
|
|
||||||
// This can be 0 in the very unusual case that the timer wrapped
|
// This can be 0 in the very unusual case that the timer wrapped
|
||||||
// It can be 0 if we try add tokens at a sub-tick rate
|
// It can be 0 if we try add tokens at a sub-tick rate
|
||||||
|
@ -310,4 +317,77 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
Deposit(deltaMS * DripRate / m_ticksPerQuantum);
|
Deposit(deltaMS * DripRate / m_ticksPerQuantum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AdaptiveTokenBucket : TokenBucket
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The minimum rate for flow control. Minimum drip rate is one
|
||||||
|
/// packet per second. Open the throttle to 15 packets per second
|
||||||
|
/// or about 160kbps.
|
||||||
|
/// </summary>
|
||||||
|
protected const Int64 m_minimumFlow = m_minimumDripRate * 15;
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
// The maximum rate for flow control. Drip rate can never be
|
||||||
|
// greater than this.
|
||||||
|
// </summary>
|
||||||
|
protected Int64 m_maxDripRate = 0;
|
||||||
|
protected Int64 MaxDripRate
|
||||||
|
{
|
||||||
|
get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
|
||||||
|
set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool m_enabled = false;
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
//
|
||||||
|
// </summary>
|
||||||
|
public virtual Int64 AdjustedDripRate
|
||||||
|
{
|
||||||
|
get { return m_dripRate; }
|
||||||
|
set {
|
||||||
|
m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value,m_minimumFlow,MaxDripRate);
|
||||||
|
m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst);
|
||||||
|
if (m_parent != null)
|
||||||
|
m_parent.RegisterRequest(this,m_dripRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
//
|
||||||
|
// </summary>
|
||||||
|
public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate)
|
||||||
|
{
|
||||||
|
m_enabled = enabled;
|
||||||
|
|
||||||
|
if (m_enabled)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled");
|
||||||
|
MaxDripRate = maxDripRate;
|
||||||
|
AdjustedDripRate = m_minimumFlow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
//
|
||||||
|
// </summary>
|
||||||
|
public void ExpirePackets(Int32 count)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count);
|
||||||
|
if (m_enabled)
|
||||||
|
AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
|
||||||
|
}
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
//
|
||||||
|
// </summary>
|
||||||
|
public void AcknowledgePackets(Int32 count)
|
||||||
|
{
|
||||||
|
if (m_enabled)
|
||||||
|
AdjustedDripRate = AdjustedDripRate + count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>Holds packets that need to be added to the unacknowledged list</summary>
|
/// <summary>Holds packets that need to be added to the unacknowledged list</summary>
|
||||||
private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>();
|
private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>();
|
||||||
/// <summary>Holds information about pending acknowledgements</summary>
|
/// <summary>Holds information about pending acknowledgements</summary>
|
||||||
private LocklessQueue<PendingAck> m_pendingRemoves = new LocklessQueue<PendingAck>();
|
private LocklessQueue<PendingAck> m_pendingAcknowledgements = new LocklessQueue<PendingAck>();
|
||||||
|
/// <summary>Holds information about pending removals</summary>
|
||||||
|
private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add an unacked packet to the collection
|
/// Add an unacked packet to the collection
|
||||||
|
@ -83,15 +85,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marks a packet as acknowledged
|
/// Marks a packet as acknowledged
|
||||||
|
/// This method is used when an acknowledgement is received from the network for a previously
|
||||||
|
/// sent packet. Effects of removal this way are to update unacked byte count, adjust RTT
|
||||||
|
/// and increase throttle to the coresponding client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sequenceNumber">Sequence number of the packet to
|
/// <param name="sequenceNumber">Sequence number of the packet to
|
||||||
/// acknowledge</param>
|
/// acknowledge</param>
|
||||||
/// <param name="currentTime">Current value of Environment.TickCount</param>
|
/// <param name="currentTime">Current value of Environment.TickCount</param>
|
||||||
/// <remarks>This does not immediately acknowledge the packet, it only
|
/// <remarks>This does not immediately acknowledge the packet, it only
|
||||||
/// queues the ack so it can be handled in a thread-safe way later</remarks>
|
/// queues the ack so it can be handled in a thread-safe way later</remarks>
|
||||||
public void Remove(uint sequenceNumber, int currentTime, bool fromResend)
|
public void Acknowledge(uint sequenceNumber, int currentTime, bool fromResend)
|
||||||
{
|
{
|
||||||
m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
|
m_pendingAcknowledgements.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marks a packet as no longer needing acknowledgement without a received acknowledgement.
|
||||||
|
/// This method is called when a packet expires and we no longer need an acknowledgement.
|
||||||
|
/// When some reliable packet types expire, they are handled in a way other than simply
|
||||||
|
/// resending them. The only effect of removal this way is to update unacked byte count.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sequenceNumber">Sequence number of the packet to
|
||||||
|
/// acknowledge</param>
|
||||||
|
/// <remarks>The does not immediately remove the packet, it only queues the removal
|
||||||
|
/// so it can be handled in a thread safe way later</remarks>
|
||||||
|
public void Remove(uint sequenceNumber)
|
||||||
|
{
|
||||||
|
m_pendingRemoves.Enqueue(sequenceNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -130,6 +150,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// is actually sent out again
|
// is actually sent out again
|
||||||
packet.TickCount = 0;
|
packet.TickCount = 0;
|
||||||
|
|
||||||
|
// As with other network applications, assume that an expired packet is
|
||||||
|
// an indication of some network problem, slow transmission
|
||||||
|
packet.Client.FlowThrottle.ExpirePackets(1);
|
||||||
|
|
||||||
expiredPackets.Add(packet);
|
expiredPackets.Add(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,29 +171,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_packets[pendingAdd.SequenceNumber] = pendingAdd;
|
m_packets[pendingAdd.SequenceNumber] = pendingAdd;
|
||||||
|
|
||||||
// Process all the pending removes, including updating statistics and round-trip times
|
// Process all the pending removes, including updating statistics and round-trip times
|
||||||
PendingAck pendingRemove;
|
PendingAck pendingAcknowledgement;
|
||||||
OutgoingPacket ackedPacket;
|
while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement))
|
||||||
while (m_pendingRemoves.TryDequeue(out pendingRemove))
|
|
||||||
{
|
{
|
||||||
if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket))
|
OutgoingPacket ackedPacket;
|
||||||
|
if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket))
|
||||||
{
|
{
|
||||||
if (ackedPacket != null)
|
if (ackedPacket != null)
|
||||||
{
|
{
|
||||||
m_packets.Remove(pendingRemove.SequenceNumber);
|
m_packets.Remove(pendingAcknowledgement.SequenceNumber);
|
||||||
|
|
||||||
|
// As with other network applications, assume that an acknowledged packet is an
|
||||||
|
// indication that the network can handle a little more load, speed up the transmission
|
||||||
|
ackedPacket.Client.FlowThrottle.AcknowledgePackets(ackedPacket.Buffer.DataLength);
|
||||||
|
|
||||||
// Update stats
|
// Update stats
|
||||||
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
|
Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
|
||||||
|
|
||||||
if (!pendingRemove.FromResend)
|
if (!pendingAcknowledgement.FromResend)
|
||||||
{
|
{
|
||||||
// Calculate the round-trip time for this packet and its ACK
|
// Calculate the round-trip time for this packet and its ACK
|
||||||
int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount;
|
int rtt = pendingAcknowledgement.RemoveTime - ackedPacket.TickCount;
|
||||||
if (rtt > 0)
|
if (rtt > 0)
|
||||||
ackedPacket.Client.UpdateRoundTrip(rtt);
|
ackedPacket.Client.UpdateRoundTrip(rtt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint pendingRemove;
|
||||||
|
while(m_pendingRemoves.TryDequeue(out pendingRemove))
|
||||||
|
{
|
||||||
|
OutgoingPacket removedPacket;
|
||||||
|
if (m_packets.TryGetValue(pendingRemove, out removedPacket))
|
||||||
|
{
|
||||||
|
if (removedPacket != null)
|
||||||
|
{
|
||||||
|
m_packets.Remove(pendingRemove);
|
||||||
|
|
||||||
|
// Update stats
|
||||||
|
Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -41,8 +41,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AgentAssetTransactions
|
public class AgentAssetTransactions
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
private bool m_dumpAssetsToFile;
|
private bool m_dumpAssetsToFile;
|
||||||
|
@ -149,6 +148,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
|
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AGENT ASSETS TRANSACTIONS]: Updating item {0} in {1} for transaction {2}",
|
||||||
|
// item.Name, part.Name, transactionID);
|
||||||
|
|
||||||
asset.FullID = UUID.Random();
|
asset.FullID = UUID.Random();
|
||||||
asset.Name = item.Name;
|
asset.Name = item.Name;
|
||||||
asset.Description = item.Description;
|
asset.Description = item.Description;
|
||||||
|
@ -156,8 +159,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
item.AssetID = asset.FullID;
|
item.AssetID = asset.FullID;
|
||||||
|
|
||||||
m_Scene.AssetService.Store(asset);
|
m_Scene.AssetService.Store(asset);
|
||||||
|
|
||||||
part.Inventory.UpdateInventoryItem(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,14 +562,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
/// <param name="sp"></param>
|
/// <param name="sp"></param>
|
||||||
/// <param name="so"></param>
|
/// <param name="so"></param>
|
||||||
/// <param name="attachmentpoint"></param>
|
/// <param name="attachmentpoint"></param>
|
||||||
/// <param name="AttachOffset"></param>
|
/// <param name="attachOffset"></param>
|
||||||
/// <param name="silent"></param>
|
/// <param name="silent"></param>
|
||||||
protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 AttachOffset, bool silent)
|
protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
|
||||||
{
|
{
|
||||||
// don't attach attachments to child agents
|
|
||||||
if (avatar.IsChildAgent) return;
|
|
||||||
|
|
||||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1}", Name, avatar.Name);
|
m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", Name, avatar.Name,
|
||||||
|
attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
||||||
|
|
||||||
so.DetachFromBackup();
|
so.DetachFromBackup();
|
||||||
|
|
||||||
|
@ -590,8 +589,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
so.RootPart.PhysActor = null;
|
so.RootPart.PhysActor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
so.AbsolutePosition = AttachOffset;
|
so.AbsolutePosition = attachOffset;
|
||||||
so.RootPart.AttachedPos = AttachOffset;
|
so.RootPart.AttachedPos = attachOffset;
|
||||||
so.RootPart.IsAttachment = true;
|
so.RootPart.IsAttachment = true;
|
||||||
|
|
||||||
so.RootPart.SetParentLocalId(avatar.LocalId);
|
so.RootPart.SetParentLocalId(avatar.LocalId);
|
||||||
|
|
|
@ -285,11 +285,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
string reason;
|
string reason;
|
||||||
if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out reason))
|
string version;
|
||||||
|
if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
|
||||||
{
|
{
|
||||||
sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason);
|
sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
|
||||||
|
|
||||||
sp.ControllingClient.SendTeleportStart(teleportFlags);
|
sp.ControllingClient.SendTeleportStart(teleportFlags);
|
||||||
|
|
||||||
|
@ -371,20 +373,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
|
capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect avatar crossing is a heavy-duty function at the destination.
|
|
||||||
// That is where MakeRoot is called, which fetches appearance and inventory.
|
|
||||||
// Plus triggers OnMakeRoot, which spawns a series of asynchronous updates.
|
|
||||||
//m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
|
|
||||||
// position, false);
|
|
||||||
|
|
||||||
//{
|
|
||||||
// avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
|
|
||||||
// // We should close that agent we just created over at destination...
|
|
||||||
// List<ulong> lst = new List<ulong>();
|
|
||||||
// lst.Add(reg.RegionHandle);
|
|
||||||
// SendCloseChildAgentAsync(avatar.UUID, lst);
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
SetInTransit(sp.UUID);
|
SetInTransit(sp.UUID);
|
||||||
|
|
||||||
|
@ -426,7 +414,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
// TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
|
||||||
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
|
// trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
|
||||||
// that the client contacted the destination before we send the attachments and close things here.
|
// that the client contacted the destination before we close things here.
|
||||||
if (!WaitForCallback(sp.UUID))
|
if (!WaitForCallback(sp.UUID))
|
||||||
{
|
{
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
|
@ -437,14 +425,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
|
// For backwards compatibility
|
||||||
CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
|
if (version == "Unknown" || version == string.Empty)
|
||||||
|
{
|
||||||
|
// CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
|
||||||
|
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one...");
|
||||||
|
CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// May need to logout or other cleanup
|
||||||
|
AgentHasMovedAway(sp, logout);
|
||||||
|
|
||||||
// Well, this is it. The agent is over there.
|
// Well, this is it. The agent is over there.
|
||||||
KillEntity(sp.Scene, sp.LocalId);
|
KillEntity(sp.Scene, sp.LocalId);
|
||||||
|
|
||||||
// May need to logout or other cleanup
|
|
||||||
AgentHasMovedAway(sp.ControllingClient.SessionId, logout);
|
|
||||||
|
|
||||||
// Now let's make it officially a child agent
|
// Now let's make it officially a child agent
|
||||||
sp.MakeChildAgent();
|
sp.MakeChildAgent();
|
||||||
|
@ -485,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
// Fail. Reset it back
|
// Fail. Reset it back
|
||||||
sp.IsChildAgent = false;
|
sp.IsChildAgent = false;
|
||||||
|
ReInstantiateScripts(sp);
|
||||||
ResetFromTransit(sp.UUID);
|
ResetFromTransit(sp.UUID);
|
||||||
|
|
||||||
EnableChildAgents(sp);
|
EnableChildAgents(sp);
|
||||||
|
@ -513,8 +507,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AgentHasMovedAway(UUID sessionID, bool logout)
|
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
|
||||||
{
|
{
|
||||||
|
foreach (SceneObjectGroup sop in sp.Attachments)
|
||||||
|
{
|
||||||
|
sop.Scene.DeleteSceneObject(sop, true);
|
||||||
|
}
|
||||||
|
sp.Attachments.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void KillEntity(Scene scene, uint localID)
|
protected void KillEntity(Scene scene, uint localID)
|
||||||
|
@ -784,7 +783,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
||||||
|
|
||||||
string reason;
|
string reason;
|
||||||
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out reason))
|
string version;
|
||||||
|
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
|
||||||
{
|
{
|
||||||
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
|
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
|
||||||
if (r == null)
|
if (r == null)
|
||||||
|
@ -804,7 +804,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
agent.InTransit();
|
agent.InTransit();
|
||||||
|
|
||||||
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
|
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
|
||||||
d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, CrossAgentToNewRegionCompleted, d);
|
d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -861,17 +861,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
icon.EndInvoke(iar);
|
icon.EndInvoke(iar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying);
|
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This Closes child agents on neighbouring regions
|
/// This Closes child agents on neighbouring regions
|
||||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying)
|
protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version)
|
||||||
{
|
{
|
||||||
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
||||||
|
|
||||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury);
|
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
|
||||||
|
|
||||||
Scene m_scene = agent.Scene;
|
Scene m_scene = agent.Scene;
|
||||||
|
|
||||||
|
@ -930,6 +930,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
if (!WaitForCallback(agent.UUID))
|
if (!WaitForCallback(agent.UUID))
|
||||||
{
|
{
|
||||||
m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent");
|
m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent");
|
||||||
|
ReInstantiateScripts(agent);
|
||||||
ResetFromTransit(agent.UUID);
|
ResetFromTransit(agent.UUID);
|
||||||
|
|
||||||
// Yikes! We should just have a ref to scene here.
|
// Yikes! We should just have a ref to scene here.
|
||||||
|
@ -945,7 +946,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
agent.SendOtherAgentsAvatarDataToMe();
|
agent.SendOtherAgentsAvatarDataToMe();
|
||||||
agent.SendOtherAgentsAppearanceToMe();
|
agent.SendOtherAgentsAppearanceToMe();
|
||||||
|
|
||||||
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
|
// Backwards compatibility
|
||||||
|
if (version == "Unknown" || version == string.Empty)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old neighbor, passing attachments one by one...");
|
||||||
|
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
AgentHasMovedAway(agent, false);
|
||||||
|
|
||||||
// the user may change their profile information in other region,
|
// the user may change their profile information in other region,
|
||||||
// so the userinfo in UserProfileCache is not reliable any more, delete it
|
// so the userinfo in UserProfileCache is not reliable any more, delete it
|
||||||
|
@ -1749,7 +1757,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void ReInstantiateScripts(ScenePresence sp)
|
||||||
|
{
|
||||||
|
sp.Attachments.ForEach(delegate(SceneObjectGroup sog)
|
||||||
|
{
|
||||||
|
sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0);
|
||||||
|
sog.ResumeScripts();
|
||||||
|
});
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,11 +142,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AgentHasMovedAway(UUID sessionID, bool logout)
|
protected override void AgentHasMovedAway(ScenePresence sp, bool logout)
|
||||||
{
|
{
|
||||||
|
base.AgentHasMovedAway(sp, logout);
|
||||||
if (logout)
|
if (logout)
|
||||||
// Log them out of this grid
|
// Log them out of this grid
|
||||||
m_aScene.PresenceService.LogoutAgent(sessionID);
|
m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
|
protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
|
||||||
|
|
|
@ -41,6 +41,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService
|
public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
// Version of this service
|
||||||
|
private const string m_Version = "SIMULATION/0.1";
|
||||||
|
|
||||||
private List<Scene> m_sceneList = new List<Scene>();
|
private List<Scene> m_sceneList = new List<Scene>();
|
||||||
|
|
||||||
private IEntityTransferModule m_AgentTransferModule;
|
private IEntityTransferModule m_AgentTransferModule;
|
||||||
|
@ -257,9 +260,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason)
|
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
reason = "Communications failure";
|
reason = "Communications failure";
|
||||||
|
version = m_Version;
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// else do the remote thing
|
// else do the remote thing
|
||||||
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
|
if (!m_localBackend.IsLocalRegion(destination.RegionID))
|
||||||
{
|
{
|
||||||
return m_remoteConnector.CreateAgent(destination, aCircuit, teleportFlags, out reason);
|
return m_remoteConnector.CreateAgent(destination, aCircuit, teleportFlags, out reason);
|
||||||
}
|
}
|
||||||
|
@ -229,19 +229,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason)
|
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
reason = "Communications failure";
|
reason = "Communications failure";
|
||||||
|
version = "Unknown";
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Try local first
|
// Try local first
|
||||||
if (m_localBackend.QueryAccess(destination, id, position, out reason))
|
if (m_localBackend.QueryAccess(destination, id, position, out version, out reason))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// else do the remote thing
|
// else do the remote thing
|
||||||
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
|
if (!m_localBackend.IsLocalRegion(destination.RegionID))
|
||||||
return m_remoteConnector.QueryAccess(destination, id, position, out reason);
|
return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -119,16 +119,40 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity)
|
private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity)
|
||||||
{
|
{
|
||||||
return 1;
|
// And anything attached to this avatar gets top priority as well
|
||||||
|
if (entity is SceneObjectPart)
|
||||||
|
{
|
||||||
|
SceneObjectPart sop = (SceneObjectPart)entity;
|
||||||
|
if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PriorityQueue.NumberOfImmediateQueues; // first queue past the immediate queues
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
|
private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
|
||||||
{
|
{
|
||||||
|
// And anything attached to this avatar gets top priority as well
|
||||||
|
if (entity is SceneObjectPart)
|
||||||
|
{
|
||||||
|
SceneObjectPart sop = (SceneObjectPart)entity;
|
||||||
|
if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return ComputeDistancePriority(client,entity,false);
|
return ComputeDistancePriority(client,entity,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
|
private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
|
||||||
{
|
{
|
||||||
|
// And anything attached to this avatar gets top priority as well
|
||||||
|
if (entity is SceneObjectPart)
|
||||||
|
{
|
||||||
|
SceneObjectPart sop = (SceneObjectPart)entity;
|
||||||
|
if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return ComputeDistancePriority(client,entity,true);
|
return ComputeDistancePriority(client,entity,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,18 +165,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (!presence.IsChildAgent)
|
if (!presence.IsChildAgent)
|
||||||
{
|
{
|
||||||
|
// All avatars other than our own go into pqueue 1
|
||||||
|
if (entity is ScenePresence)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (entity is SceneObjectPart)
|
if (entity is SceneObjectPart)
|
||||||
{
|
{
|
||||||
|
// Attachments are high priority,
|
||||||
|
if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
|
||||||
|
return 1;
|
||||||
|
|
||||||
// Non physical prims are lower priority than physical prims
|
// Non physical prims are lower priority than physical prims
|
||||||
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
|
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
|
||||||
if (physActor == null || !physActor.IsPhysical)
|
if (physActor == null || !physActor.IsPhysical)
|
||||||
pqueue++;
|
pqueue++;
|
||||||
|
|
||||||
// Attachments are high priority,
|
|
||||||
// MIC: shouldn't these already be in the highest priority queue already
|
|
||||||
// since their root position is same as the avatars?
|
|
||||||
if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
|
|
||||||
pqueue = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +198,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// m_log.WarnFormat("[PRIORITIZER] attempt to use agent {0} not in the scene",client.AgentId);
|
// m_log.WarnFormat("[PRIORITIZER] attempt to use agent {0} not in the scene",client.AgentId);
|
||||||
// throw new InvalidOperationException("Prioritization agent not defined");
|
// throw new InvalidOperationException("Prioritization agent not defined");
|
||||||
return Int32.MaxValue;
|
return PriorityQueue.NumberOfQueues - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use group position for child prims, since we are putting child prims in
|
// Use group position for child prims, since we are putting child prims in
|
||||||
|
@ -197,8 +223,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// And convert the distance to a priority queue, this computation gives queues
|
// And convert the distance to a priority queue, this computation gives queues
|
||||||
// at 10, 20, 40, 80, 160, 320, 640, and 1280m
|
// at 10, 20, 40, 80, 160, 320, 640, and 1280m
|
||||||
uint pqueue = 1;
|
uint pqueue = PriorityQueue.NumberOfImmediateQueues;
|
||||||
for (int i = 0; i < 8; i++)
|
uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues;
|
||||||
|
|
||||||
|
for (int i = 0; i < queues - 1; i++)
|
||||||
{
|
{
|
||||||
if (distance < 10 * Math.Pow(2.0,i))
|
if (distance < 10 * Math.Pow(2.0,i))
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1430,6 +1430,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else // Updating existing item with new perms etc
|
else // Updating existing item with new perms etc
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
|
||||||
|
// currentItem.Name, part.Name);
|
||||||
|
|
||||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||||
if (agentTransactions != null)
|
if (agentTransactions != null)
|
||||||
{
|
{
|
||||||
|
@ -2039,6 +2043,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (rot != null)
|
if (rot != null)
|
||||||
group.UpdateGroupRotationR((Quaternion)rot);
|
group.UpdateGroupRotationR((Quaternion)rot);
|
||||||
|
|
||||||
|
// TODO: This needs to be refactored with the similar code in
|
||||||
|
// SceneGraph.AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel)
|
||||||
|
// possibly by allowing this method to take a null rotation.
|
||||||
|
if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
|
||||||
|
group.RootPart.ApplyImpulse((vel * group.GetMass()), false);
|
||||||
|
|
||||||
// We can only call this after adding the scene object, since the scene object references the scene
|
// We can only call this after adding the scene object, since the scene object references the scene
|
||||||
// to find out if scripts should be activated at all.
|
// to find out if scripts should be activated at all.
|
||||||
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
|
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
|
||||||
|
|
|
@ -1229,7 +1229,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Increment the frame counter
|
// Increment the frame counter
|
||||||
++Frame;
|
++Frame;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Check if any objects have reached their targets
|
// Check if any objects have reached their targets
|
||||||
|
@ -2316,7 +2315,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool IncomingCreateObject(ISceneObject sog)
|
public bool IncomingCreateObject(ISceneObject sog)
|
||||||
{
|
{
|
||||||
//m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted);
|
//m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
|
||||||
|
// ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
|
||||||
|
|
||||||
SceneObjectGroup newObject;
|
SceneObjectGroup newObject;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -2334,9 +2335,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
|
// For attachments, we need to wait until the agent is root
|
||||||
|
// before we restart the scripts, or else some functions won't work.
|
||||||
newObject.ResumeScripts();
|
if (!newObject.IsAttachment)
|
||||||
|
{
|
||||||
|
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
|
||||||
|
newObject.ResumeScripts();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScenePresence sp;
|
||||||
|
if (TryGetScenePresence(newObject.OwnerID, out sp))
|
||||||
|
{
|
||||||
|
// If the scene presence is here and already a root
|
||||||
|
// agent, we came from a ;egacy region. Start the scripts
|
||||||
|
// here as they used to start.
|
||||||
|
// TODO: Remove in 0.7.3
|
||||||
|
if (!sp.IsChildAgent)
|
||||||
|
{
|
||||||
|
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
|
||||||
|
newObject.ResumeScripts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Do this as late as possible so that listeners have full access to the incoming object
|
// Do this as late as possible so that listeners have full access to the incoming object
|
||||||
EventManager.TriggerOnIncomingSceneObject(newObject);
|
EventManager.TriggerOnIncomingSceneObject(newObject);
|
||||||
|
@ -2453,17 +2474,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScenePresence sp = GetScenePresence(sog.OwnerID);
|
ScenePresence sp = GetScenePresence(sog.OwnerID);
|
||||||
|
|
||||||
if (sp != null)
|
if (sp != null)
|
||||||
{
|
return sp.GetStateSource();
|
||||||
AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(sp.UUID);
|
|
||||||
|
|
||||||
if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
|
|
||||||
{
|
|
||||||
// This will get your attention
|
|
||||||
//m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
|
|
||||||
|
|
||||||
return 5; // StateSource.Teleporting
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 2; // StateSource.PrimCrossing
|
return 2; // StateSource.PrimCrossing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -693,8 +693,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
TaskInventoryItem it = GetInventoryItem(item.ItemID);
|
TaskInventoryItem it = GetInventoryItem(item.ItemID);
|
||||||
if (it != null)
|
if (it != null)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
|
||||||
|
|
||||||
item.ParentID = m_part.UUID;
|
item.ParentID = m_part.UUID;
|
||||||
item.ParentPartID = m_part.UUID;
|
item.ParentPartID = m_part.UUID;
|
||||||
|
|
||||||
|
@ -714,11 +715,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (fireScriptEvents)
|
if (fireScriptEvents)
|
||||||
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
|
||||||
|
|
||||||
if (considerChanged)
|
if (considerChanged)
|
||||||
{
|
{
|
||||||
HasInventoryChanged = true;
|
HasInventoryChanged = true;
|
||||||
m_part.ParentGroup.HasGroupChanged = true;
|
m_part.ParentGroup.HasGroupChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -840,6 +840,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
//m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
|
//m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
|
||||||
|
|
||||||
|
bool wasChild = m_isChildAgent;
|
||||||
|
m_isChildAgent = false;
|
||||||
|
|
||||||
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
|
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||||
if (gm != null)
|
if (gm != null)
|
||||||
m_grouptitle = gm.GetGroupTitle(m_uuid);
|
m_grouptitle = gm.GetGroupTitle(m_uuid);
|
||||||
|
@ -930,13 +933,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_scene.SwapRootAgentCount(false);
|
m_scene.SwapRootAgentCount(false);
|
||||||
|
|
||||||
//CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid);
|
// The initial login scene presence is already root when it gets here
|
||||||
//if (userInfo != null)
|
// and it has already rezzed the attachments and started their scripts.
|
||||||
// userInfo.FetchInventory();
|
// We do the following only for non-login agents, because their scripts
|
||||||
//else
|
// haven't started yet.
|
||||||
// m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid);
|
if (wasChild && Attachments != null && Attachments.Count > 0)
|
||||||
|
{
|
||||||
m_isChildAgent = false;
|
m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
|
||||||
|
// Resume scripts
|
||||||
|
Attachments.ForEach(delegate(SceneObjectGroup sog)
|
||||||
|
{
|
||||||
|
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
|
||||||
|
sog.ResumeScripts();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// send the animations of the other presences to me
|
// send the animations of the other presences to me
|
||||||
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
|
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
|
||||||
|
@ -948,6 +958,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_scene.EventManager.TriggerOnMakeRootAgent(this);
|
m_scene.EventManager.TriggerOnMakeRootAgent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetStateSource()
|
||||||
|
{
|
||||||
|
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID);
|
||||||
|
|
||||||
|
if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
|
||||||
|
{
|
||||||
|
// This will get your attention
|
||||||
|
//m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
|
||||||
|
|
||||||
|
return 5; // StateSource.Teleporting
|
||||||
|
}
|
||||||
|
return 2; // StateSource.PrimCrossing
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This turns a root agent into a child agent
|
/// This turns a root agent into a child agent
|
||||||
/// when an agent departs this region for a neighbor, this gets called.
|
/// when an agent departs this region for a neighbor, this gets called.
|
||||||
|
@ -1139,7 +1163,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AbsolutePosition = pos;
|
AbsolutePosition = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isChildAgent = false;
|
|
||||||
bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
|
bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
|
||||||
MakeRootAgent(AbsolutePosition, m_flying);
|
MakeRootAgent(AbsolutePosition, m_flying);
|
||||||
|
|
||||||
|
@ -2340,12 +2363,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#region Update Client(s)
|
#region Update Client(s)
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a location update to the client connected to this scenePresence
|
/// Sends a location update to the client connected to this scenePresence
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="remoteClient"></param>
|
/// <param name="remoteClient"></param>
|
||||||
public void SendTerseUpdateToClient(IClientAPI remoteClient)
|
public void SendTerseUpdateToClient(IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
|
|
||||||
// If the client is inactive, it's getting its updates from another
|
// If the client is inactive, it's getting its updates from another
|
||||||
// server.
|
// server.
|
||||||
if (remoteClient.IsActive)
|
if (remoteClient.IsActive)
|
||||||
|
@ -2367,16 +2392,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// vars to support reduced update frequency when velocity is unchanged
|
||||||
|
private Vector3 lastVelocitySentToAllClients = Vector3.Zero;
|
||||||
|
private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send a location/velocity/accelleration update to all agents in scene
|
/// Send a location/velocity/accelleration update to all agents in scene
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendTerseUpdateToAllClients()
|
public void SendTerseUpdateToAllClients()
|
||||||
{
|
{
|
||||||
m_perfMonMS = Util.EnvironmentTickCount();
|
int currentTick = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
m_scene.ForEachClient(SendTerseUpdateToClient);
|
// decrease update frequency when avatar is moving but velocity is not changing
|
||||||
|
if (m_velocity.Length() < 0.01f
|
||||||
|
|| Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f
|
||||||
|
|| currentTick - lastTerseUpdateToAllClientsTick > 1500)
|
||||||
|
{
|
||||||
|
m_perfMonMS = currentTick;
|
||||||
|
lastVelocitySentToAllClients = m_velocity;
|
||||||
|
lastTerseUpdateToAllClientsTick = currentTick;
|
||||||
|
|
||||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
m_scene.ForEachClient(SendTerseUpdateToClient);
|
||||||
|
|
||||||
|
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
|
public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
|
||||||
|
@ -2632,18 +2672,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
cadu.GroupAccess = 0;
|
cadu.GroupAccess = 0;
|
||||||
cadu.Position = AbsolutePosition;
|
cadu.Position = AbsolutePosition;
|
||||||
cadu.regionHandle = m_rootRegionHandle;
|
cadu.regionHandle = m_rootRegionHandle;
|
||||||
float multiplier = 1;
|
|
||||||
int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
|
|
||||||
if (innacurateNeighbors != 0)
|
|
||||||
{
|
|
||||||
multiplier = 1f / (float)innacurateNeighbors;
|
|
||||||
}
|
|
||||||
if (multiplier <= 0f)
|
|
||||||
{
|
|
||||||
multiplier = 0.25f;
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
|
// Throttles
|
||||||
|
float multiplier = 1;
|
||||||
|
int childRegions = m_knownChildRegions.Count;
|
||||||
|
if (childRegions != 0)
|
||||||
|
multiplier = 1f / childRegions;
|
||||||
|
|
||||||
|
// Minimum throttle for a child region is 1/4 of the root region throttle
|
||||||
|
if (multiplier <= 0.25f)
|
||||||
|
multiplier = 0.25f;
|
||||||
|
|
||||||
cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier);
|
cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier);
|
||||||
cadu.Velocity = Velocity;
|
cadu.Velocity = Velocity;
|
||||||
|
|
||||||
|
@ -3039,16 +3078,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Throttles
|
// Throttles
|
||||||
float multiplier = 1;
|
float multiplier = 1;
|
||||||
int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
|
int childRegions = m_knownChildRegions.Count;
|
||||||
if (innacurateNeighbors != 0)
|
if (childRegions != 0)
|
||||||
{
|
multiplier = 1f / childRegions;
|
||||||
multiplier = 1f / innacurateNeighbors;
|
|
||||||
}
|
// Minimum throttle for a child region is 1/4 of the root region throttle
|
||||||
if (multiplier <= 0f)
|
if (multiplier <= 0.25f)
|
||||||
{
|
|
||||||
multiplier = 0.25f;
|
multiplier = 0.25f;
|
||||||
}
|
|
||||||
//m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
|
|
||||||
cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier);
|
cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier);
|
||||||
|
|
||||||
cAgent.HeadRotation = m_headrotation;
|
cAgent.HeadRotation = m_headrotation;
|
||||||
|
@ -3064,54 +3101,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
cAgent.Appearance = new AvatarAppearance(m_appearance);
|
cAgent.Appearance = new AvatarAppearance(m_appearance);
|
||||||
|
|
||||||
/*
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// We might not pass the Wearables in all cases...
|
|
||||||
// They're only needed so that persistent changes to the appearance
|
|
||||||
// are preserved in the new region where the user is moving to.
|
|
||||||
// But in Hypergrid we might not let this happen.
|
|
||||||
int i = 0;
|
|
||||||
UUID[] wears = new UUID[m_appearance.Wearables.Length * 2];
|
|
||||||
foreach (AvatarWearable aw in m_appearance.Wearables)
|
|
||||||
{
|
|
||||||
if (aw != null)
|
|
||||||
{
|
|
||||||
wears[i++] = aw.ItemID;
|
|
||||||
wears[i++] = aw.AssetID;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wears[i++] = UUID.Zero;
|
|
||||||
wears[i++] = UUID.Zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cAgent.Wearables = wears;
|
|
||||||
|
|
||||||
cAgent.VisualParams = m_appearance.VisualParams;
|
|
||||||
|
|
||||||
if (m_appearance.Texture != null)
|
|
||||||
cAgent.AgentTextures = m_appearance.Texture.GetBytes();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Attachments
|
|
||||||
List<int> attPoints = m_appearance.GetAttachedPoints();
|
|
||||||
if (attPoints != null)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
|
|
||||||
int i = 0;
|
|
||||||
AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count];
|
|
||||||
foreach (int point in attPoints)
|
|
||||||
{
|
|
||||||
attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point));
|
|
||||||
}
|
|
||||||
cAgent.Attachments = attachs;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
lock (scriptedcontrols)
|
lock (scriptedcontrols)
|
||||||
{
|
{
|
||||||
ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
|
ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
|
||||||
|
@ -3131,9 +3120,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
// cAgent.GroupID = ??
|
// Attachment objects
|
||||||
// Groups???
|
if (m_attachments != null && m_attachments.Count > 0)
|
||||||
|
{
|
||||||
|
cAgent.AttachmentObjects = new List<ISceneObject>();
|
||||||
|
cAgent.AttachmentObjectStates = new List<string>();
|
||||||
|
IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||||
|
foreach (SceneObjectGroup sog in m_attachments)
|
||||||
|
{
|
||||||
|
// We need to make a copy and pass that copy
|
||||||
|
// because of transfers withn the same sim
|
||||||
|
ISceneObject clone = sog.CloneForNewScene();
|
||||||
|
// Attachment module assumes that GroupPosition holds the offsets...!
|
||||||
|
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
||||||
|
((SceneObjectGroup)clone).RootPart.IsAttachment = false;
|
||||||
|
cAgent.AttachmentObjects.Add(clone);
|
||||||
|
cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot());
|
||||||
|
// Let's remove the scripts of the original object here
|
||||||
|
sog.RemoveScriptInstances(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyFrom(AgentData cAgent)
|
public void CopyFrom(AgentData cAgent)
|
||||||
|
@ -3174,50 +3180,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AddToPhysicalScene(isFlying);
|
AddToPhysicalScene(isFlying);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
uint i = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (cAgent.Wearables == null)
|
|
||||||
cAgent.Wearables = new UUID[0];
|
|
||||||
AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2];
|
|
||||||
for (uint n = 0; n < cAgent.Wearables.Length; n += 2)
|
|
||||||
{
|
|
||||||
UUID itemId = cAgent.Wearables[n];
|
|
||||||
UUID assetId = cAgent.Wearables[n + 1];
|
|
||||||
wears[i++] = new AvatarWearable(itemId, assetId);
|
|
||||||
}
|
|
||||||
// m_appearance.Wearables = wears;
|
|
||||||
Primitive.TextureEntry textures = null;
|
|
||||||
if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
|
|
||||||
textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
|
|
||||||
|
|
||||||
byte[] visuals = null;
|
|
||||||
|
|
||||||
if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
|
|
||||||
visuals = (byte[])cAgent.VisualParams.Clone();
|
|
||||||
|
|
||||||
m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attachments
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (cAgent.Attachments != null)
|
|
||||||
{
|
|
||||||
m_appearance.ClearAttachments();
|
|
||||||
foreach (AvatarAttachment att in cAgent.Attachments)
|
|
||||||
{
|
|
||||||
m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
*/
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (scriptedcontrols)
|
lock (scriptedcontrols)
|
||||||
|
@ -3247,8 +3209,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
//cAgent.GroupID = ??
|
if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0)
|
||||||
//Groups???
|
{
|
||||||
|
m_attachments = new List<SceneObjectGroup>();
|
||||||
|
int i = 0;
|
||||||
|
foreach (ISceneObject so in cAgent.AttachmentObjects)
|
||||||
|
{
|
||||||
|
((SceneObjectGroup)so).LocalId = 0;
|
||||||
|
((SceneObjectGroup)so).RootPart.UpdateFlag = 0;
|
||||||
|
so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
|
||||||
|
m_scene.IncomingCreateObject(so);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CopyAgent(out IAgentData agent)
|
public bool CopyAgent(out IAgentData agent)
|
||||||
|
@ -3271,10 +3243,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_updateflag = true;
|
m_updateflag = true;
|
||||||
|
|
||||||
// The magic constant 0.95f seems to make walking feel less jerky,
|
Velocity = force;
|
||||||
// probably because it hackishly accounts for the overall latency of
|
|
||||||
// these Velocity updates -- Diva
|
|
||||||
Velocity = force * .95F;
|
|
||||||
|
|
||||||
m_forceToApply = null;
|
m_forceToApply = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,14 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
lock (m_scenes)
|
lock (m_scenes)
|
||||||
m_scenes[scene.RegionInfo.RegionID] = scene;
|
m_scenes[scene.RegionInfo.RegionID] = scene;
|
||||||
|
|
||||||
|
scene.AddCommand(
|
||||||
|
this, "show pqueues",
|
||||||
|
"show pqueues [full]",
|
||||||
|
"Show priority queue data for each client",
|
||||||
|
"Without the 'full' option, only root agents are shown."
|
||||||
|
+ " With the 'full' option child agents are also shown.",
|
||||||
|
ShowPQueuesReport);
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
this, "show queues",
|
this, "show queues",
|
||||||
"show queues [full]",
|
"show queues [full]",
|
||||||
|
@ -119,6 +127,11 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void ShowPQueuesReport(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output(GetPQueuesReport(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
protected void ShowQueuesReport(string module, string[] cmd)
|
protected void ShowQueuesReport(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output(GetQueuesReport(cmd));
|
MainConsole.Instance.Output(GetQueuesReport(cmd));
|
||||||
|
@ -155,6 +168,80 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate UDP Queue data report for each client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="showParams"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected string GetPQueuesReport(string[] showParams)
|
||||||
|
{
|
||||||
|
bool showChildren = false;
|
||||||
|
string pname = "";
|
||||||
|
|
||||||
|
if (showParams.Length > 2 && showParams[2] == "full")
|
||||||
|
showChildren = true;
|
||||||
|
else if (showParams.Length > 3)
|
||||||
|
pname = showParams[2] + " " + showParams[3];
|
||||||
|
|
||||||
|
StringBuilder report = new StringBuilder();
|
||||||
|
|
||||||
|
int columnPadding = 2;
|
||||||
|
int maxNameLength = 18;
|
||||||
|
int maxRegionNameLength = 14;
|
||||||
|
int maxTypeLength = 4;
|
||||||
|
int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
|
||||||
|
|
||||||
|
report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
|
||||||
|
report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
|
||||||
|
report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
|
||||||
|
|
||||||
|
report.AppendFormat(
|
||||||
|
"{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7} {10,7} {11,7}\n",
|
||||||
|
"Pri 0",
|
||||||
|
"Pri 1",
|
||||||
|
"Pri 2",
|
||||||
|
"Pri 3",
|
||||||
|
"Pri 4",
|
||||||
|
"Pri 5",
|
||||||
|
"Pri 6",
|
||||||
|
"Pri 7",
|
||||||
|
"Pri 8",
|
||||||
|
"Pri 9",
|
||||||
|
"Pri 10",
|
||||||
|
"Pri 11");
|
||||||
|
|
||||||
|
lock (m_scenes)
|
||||||
|
{
|
||||||
|
foreach (Scene scene in m_scenes.Values)
|
||||||
|
{
|
||||||
|
scene.ForEachClient(
|
||||||
|
delegate(IClientAPI client)
|
||||||
|
{
|
||||||
|
if (client is LLClientView)
|
||||||
|
{
|
||||||
|
bool isChild = scene.PresenceChildStatus(client.AgentId);
|
||||||
|
if (isChild && !showChildren)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string name = client.Name;
|
||||||
|
if (pname != "" && name != pname)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string regionName = scene.RegionInfo.RegionName;
|
||||||
|
|
||||||
|
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
|
||||||
|
report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
|
||||||
|
report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
|
||||||
|
report.AppendLine(((LLClientView)client).EntityUpdateQueue.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return report.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate UDP Queue data report for each client
|
/// Generate UDP Queue data report for each client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -163,9 +250,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
protected string GetQueuesReport(string[] showParams)
|
protected string GetQueuesReport(string[] showParams)
|
||||||
{
|
{
|
||||||
bool showChildren = false;
|
bool showChildren = false;
|
||||||
|
string pname = "";
|
||||||
|
|
||||||
if (showParams.Length > 2 && showParams[2] == "full")
|
if (showParams.Length > 2 && showParams[2] == "full")
|
||||||
showChildren = true;
|
showChildren = true;
|
||||||
|
else if (showParams.Length > 3)
|
||||||
|
pname = showParams[2] + " " + showParams[3];
|
||||||
|
|
||||||
StringBuilder report = new StringBuilder();
|
StringBuilder report = new StringBuilder();
|
||||||
|
|
||||||
|
@ -224,6 +314,9 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string name = client.Name;
|
string name = client.Name;
|
||||||
|
if (pname != "" && name != pname)
|
||||||
|
return;
|
||||||
|
|
||||||
string regionName = scene.RegionInfo.RegionName;
|
string regionName = scene.RegionInfo.RegionName;
|
||||||
|
|
||||||
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
|
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
|
||||||
|
@ -249,9 +342,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
protected string GetThrottlesReport(string[] showParams)
|
protected string GetThrottlesReport(string[] showParams)
|
||||||
{
|
{
|
||||||
bool showChildren = false;
|
bool showChildren = false;
|
||||||
|
string pname = "";
|
||||||
|
|
||||||
if (showParams.Length > 2 && showParams[2] == "full")
|
if (showParams.Length > 2 && showParams[2] == "full")
|
||||||
showChildren = true;
|
showChildren = true;
|
||||||
|
else if (showParams.Length > 3)
|
||||||
|
pname = showParams[2] + " " + showParams[3];
|
||||||
|
|
||||||
StringBuilder report = new StringBuilder();
|
StringBuilder report = new StringBuilder();
|
||||||
|
|
||||||
|
@ -314,6 +410,9 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string name = client.Name;
|
string name = client.Name;
|
||||||
|
if (pname != "" && name != pname)
|
||||||
|
return;
|
||||||
|
|
||||||
string regionName = scene.RegionInfo.RegionName;
|
string regionName = scene.RegionInfo.RegionName;
|
||||||
|
|
||||||
LLUDPClient llUdpClient = llClient.UDPClient;
|
LLUDPClient llUdpClient = llClient.UDPClient;
|
||||||
|
@ -352,7 +451,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
int maxRegionNameLength = 14;
|
int maxRegionNameLength = 14;
|
||||||
int maxTypeLength = 4;
|
int maxTypeLength = 4;
|
||||||
|
|
||||||
string name = "SERVER AGENT LIMITS";
|
string name = "SERVER AGENT RATES";
|
||||||
|
|
||||||
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
|
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
|
||||||
report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding));
|
report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding));
|
||||||
|
@ -362,13 +461,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
|
||||||
report.AppendFormat(
|
report.AppendFormat(
|
||||||
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
|
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
|
||||||
(throttleRates.Total * 8) / 1000,
|
(throttleRates.Total * 8) / 1000,
|
||||||
(throttleRates.ResendLimit * 8) / 1000,
|
(throttleRates.Resend * 8) / 1000,
|
||||||
(throttleRates.LandLimit * 8) / 1000,
|
(throttleRates.Land * 8) / 1000,
|
||||||
(throttleRates.WindLimit * 8) / 1000,
|
(throttleRates.Wind * 8) / 1000,
|
||||||
(throttleRates.CloudLimit * 8) / 1000,
|
(throttleRates.Cloud * 8) / 1000,
|
||||||
(throttleRates.TaskLimit * 8) / 1000,
|
(throttleRates.Task * 8) / 1000,
|
||||||
(throttleRates.TextureLimit * 8) / 1000,
|
(throttleRates.Texture * 8) / 1000,
|
||||||
(throttleRates.AssetLimit * 8) / 1000);
|
(throttleRates.Asset * 8) / 1000);
|
||||||
|
|
||||||
return report.ToString();
|
return report.ToString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
||||||
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
||||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
if(mesh_config != null)
|
||||||
|
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
public class AgentHandler
|
public class AgentHandler
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private ISimulationService m_SimulationService;
|
private ISimulationService m_SimulationService;
|
||||||
|
|
||||||
protected bool m_Proxy = false;
|
protected bool m_Proxy = false;
|
||||||
|
@ -275,7 +276,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
AgentData agent = new AgentData();
|
AgentData agent = new AgentData();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
agent.Unpack(args);
|
agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -295,7 +296,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
AgentPosition agent = new AgentPosition();
|
AgentPosition agent = new AgentPosition();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
agent.Unpack(args);
|
agent.Unpack(args, m_SimulationService.GetScene(destination.RegionHandle));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -342,7 +343,8 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
destination.RegionID = regionID;
|
destination.RegionID = regionID;
|
||||||
|
|
||||||
string reason;
|
string reason;
|
||||||
bool result = m_SimulationService.QueryAccess(destination, id, position, out reason);
|
string version;
|
||||||
|
bool result = m_SimulationService.QueryAccess(destination, id, position, out version, out reason);
|
||||||
|
|
||||||
responsedata["int_response_code"] = HttpStatusCode.OK;
|
responsedata["int_response_code"] = HttpStatusCode.OK;
|
||||||
|
|
||||||
|
@ -350,6 +352,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
|
|
||||||
resp["success"] = OSD.FromBoolean(result);
|
resp["success"] = OSD.FromBoolean(result);
|
||||||
resp["reason"] = OSD.FromString(reason);
|
resp["reason"] = OSD.FromString(reason);
|
||||||
|
resp["version"] = OSD.FromString(version);
|
||||||
|
|
||||||
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
|
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
if (args != null)
|
if (args != null)
|
||||||
{
|
{
|
||||||
agent = new CompleteAgentData();
|
agent = new CompleteAgentData();
|
||||||
agent.Unpack(args);
|
agent.Unpack(args, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,9 +256,10 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason)
|
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
reason = "Failed to contact destination";
|
reason = "Failed to contact destination";
|
||||||
|
version = "Unknown";
|
||||||
|
|
||||||
// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position);
|
// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position);
|
||||||
|
|
||||||
|
@ -275,9 +276,16 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
{
|
{
|
||||||
OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000);
|
OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000);
|
||||||
bool success = result["success"].AsBoolean();
|
bool success = result["success"].AsBoolean();
|
||||||
reason = result["reason"].AsString();
|
if (result.ContainsKey("_Result"))
|
||||||
|
{
|
||||||
|
OSDMap data = (OSDMap)result["_Result"];
|
||||||
|
|
||||||
//m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}", uri, success);
|
reason = data["reason"].AsString();
|
||||||
|
if (data["version"] != null && data["version"].AsString() != string.Empty)
|
||||||
|
version = data["version"].AsString();
|
||||||
|
|
||||||
|
m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString());
|
||||||
|
}
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
|
@ -57,6 +58,9 @@ namespace OpenSim.Services.HypergridService
|
||||||
private static IUserAgentService m_UserAgentService;
|
private static IUserAgentService m_UserAgentService;
|
||||||
private static ISimulationService m_SimulationService;
|
private static ISimulationService m_SimulationService;
|
||||||
|
|
||||||
|
protected string m_AllowedClients = string.Empty;
|
||||||
|
protected string m_DeniedClients = string.Empty;
|
||||||
|
|
||||||
private static UUID m_ScopeID;
|
private static UUID m_ScopeID;
|
||||||
private static bool m_AllowTeleportsToAnyRegion;
|
private static bool m_AllowTeleportsToAnyRegion;
|
||||||
private static string m_ExternalName;
|
private static string m_ExternalName;
|
||||||
|
@ -104,6 +108,9 @@ namespace OpenSim.Services.HypergridService
|
||||||
else if (simulationService != string.Empty)
|
else if (simulationService != string.Empty)
|
||||||
m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
|
m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
|
||||||
|
|
||||||
|
m_AllowedClients = serverConfig.GetString("AllowedClients", string.Empty);
|
||||||
|
m_DeniedClients = serverConfig.GetString("DeniedClients", string.Empty);
|
||||||
|
|
||||||
if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
|
if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
|
||||||
throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
|
throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
|
||||||
|
|
||||||
|
@ -181,8 +188,36 @@ namespace OpenSim.Services.HypergridService
|
||||||
string authURL = string.Empty;
|
string authURL = string.Empty;
|
||||||
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||||
authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
|
authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
|
||||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}",
|
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}",
|
||||||
aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName);
|
aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName,
|
||||||
|
aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check client
|
||||||
|
//
|
||||||
|
if (m_AllowedClients != string.Empty)
|
||||||
|
{
|
||||||
|
Regex arx = new Regex(m_AllowedClients);
|
||||||
|
Match am = arx.Match(aCircuit.Viewer);
|
||||||
|
|
||||||
|
if (!am.Success)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", aCircuit.Viewer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_DeniedClients != string.Empty)
|
||||||
|
{
|
||||||
|
Regex drx = new Regex(m_DeniedClients);
|
||||||
|
Match dm = drx.Match(aCircuit.Viewer);
|
||||||
|
|
||||||
|
if (dm.Success)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", aCircuit.Viewer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Authenticate the user
|
// Authenticate the user
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace OpenSim.Services.Interfaces
|
||||||
|
|
||||||
bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent);
|
bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent);
|
||||||
|
|
||||||
bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string reason);
|
bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Message from receiving region to departing region, telling it got contacted by the client.
|
/// Message from receiving region to departing region, telling it got contacted by the client.
|
||||||
|
|
|
@ -77,7 +77,11 @@ namespace OpenSim.Services.LLLoginService
|
||||||
protected string m_MapTileURL;
|
protected string m_MapTileURL;
|
||||||
protected string m_SearchURL;
|
protected string m_SearchURL;
|
||||||
|
|
||||||
|
protected string m_AllowedClients;
|
||||||
|
protected string m_DeniedClients;
|
||||||
|
|
||||||
IConfig m_LoginServerConfig;
|
IConfig m_LoginServerConfig;
|
||||||
|
IConfig m_ClientsConfig;
|
||||||
|
|
||||||
public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
|
public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
|
||||||
{
|
{
|
||||||
|
@ -106,6 +110,9 @@ namespace OpenSim.Services.LLLoginService
|
||||||
m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty);
|
m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty);
|
||||||
m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty);
|
m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty);
|
||||||
|
|
||||||
|
m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
|
||||||
|
m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty);
|
||||||
|
|
||||||
// These are required; the others aren't
|
// These are required; the others aren't
|
||||||
if (accountService == string.Empty || authService == string.Empty)
|
if (accountService == string.Empty || authService == string.Empty)
|
||||||
throw new Exception("LoginService is missing service specifications");
|
throw new Exception("LoginService is missing service specifications");
|
||||||
|
@ -215,10 +222,37 @@ namespace OpenSim.Services.LLLoginService
|
||||||
bool success = false;
|
bool success = false;
|
||||||
UUID session = UUID.Random();
|
UUID session = UUID.Random();
|
||||||
|
|
||||||
m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} from {2} with user agent {3} starting in {4}",
|
m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}",
|
||||||
firstName, lastName, clientIP.Address.ToString(), clientVersion, startLocation);
|
firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Check client
|
||||||
|
//
|
||||||
|
if (m_AllowedClients != string.Empty)
|
||||||
|
{
|
||||||
|
Regex arx = new Regex(m_AllowedClients);
|
||||||
|
Match am = arx.Match(clientVersion);
|
||||||
|
|
||||||
|
if (!am.Success)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is not allowed", clientVersion);
|
||||||
|
return LLFailedLoginResponse.LoginBlockedProblem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_DeniedClients != string.Empty)
|
||||||
|
{
|
||||||
|
Regex drx = new Regex(m_DeniedClients);
|
||||||
|
Match dm = drx.Match(clientVersion);
|
||||||
|
|
||||||
|
if (dm.Success)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client {0} is denied", clientVersion);
|
||||||
|
return LLFailedLoginResponse.LoginBlockedProblem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the account and check that it exists
|
// Get the account and check that it exists
|
||||||
//
|
//
|
||||||
|
|
|
@ -37,7 +37,7 @@ Now see the "Configuring OpenSim" section
|
||||||
=== Running OpenSim on Linux ===
|
=== Running OpenSim on Linux ===
|
||||||
================================
|
================================
|
||||||
|
|
||||||
You will need Mono >= 2.4.2 to run OpenSim. On some Linux distributions you
|
You will need Mono >= 2.4.3 to run OpenSim. On some Linux distributions you
|
||||||
may need to install additional packages. See http://opensimulator.org/wiki/Dependencies
|
may need to install additional packages. See http://opensimulator.org/wiki/Dependencies
|
||||||
for more information.
|
for more information.
|
||||||
|
|
||||||
|
|
|
@ -626,7 +626,7 @@
|
||||||
; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector
|
; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector
|
||||||
|
|
||||||
;; If using a remote connector, specify the server URL
|
;; If using a remote connector, specify the server URL
|
||||||
; FreeswitchServiceURL = http://my.grid.server:8003/fsapi
|
; FreeswitchServiceURL = http://my.grid.server:8004/fsapi
|
||||||
|
|
||||||
|
|
||||||
[FreeswitchService]
|
[FreeswitchService]
|
||||||
|
|
|
@ -362,30 +362,24 @@
|
||||||
;
|
;
|
||||||
;client_throttle_max_bps = 196608
|
;client_throttle_max_bps = 196608
|
||||||
|
|
||||||
; Per-client bytes per second rates for the various throttle categories.
|
; Adaptive throttling attempts to limit network overload when multiple
|
||||||
; These are default values that will be overriden by clients
|
; clients login by starting each connection more slowly. Disabled by
|
||||||
|
; default
|
||||||
;
|
;
|
||||||
;resend_default = 12500
|
;enable_adaptive_throttles = true
|
||||||
;land_default = 1000
|
|
||||||
;wind_default = 1000
|
|
||||||
;cloud_default = 1000
|
|
||||||
;task_default = 1000
|
|
||||||
;texture_default = 1000
|
|
||||||
;asset_default = 1000
|
|
||||||
;state_default = 1000
|
|
||||||
|
|
||||||
; Per-client maximum burst rates in bytes per second for the various
|
; Per-client bytes per second rates for the various throttle categories.
|
||||||
; throttle categories. These are default values that will be overriden by
|
; These are default values that will be overriden by clients. These
|
||||||
; clients
|
; defaults are approximately equivalent to the throttles set by the Imprudence
|
||||||
;
|
; viewer when maximum bandwidth is set to 350kbps
|
||||||
;resend_limit = 18750
|
|
||||||
;land_limit = 29750
|
;resend_default = 6625
|
||||||
;wind_limit = 18750
|
;land_default = 9125
|
||||||
;cloud_limit = 18750
|
;wind_default = 1750
|
||||||
;task_limit = 18750
|
;cloud_default = 1750
|
||||||
;texture_limit = 55750
|
;task_default = 18500
|
||||||
;asset_limit = 27500
|
;texture_default = 18500
|
||||||
;state_limit = 37000
|
;asset_default = 10500
|
||||||
|
|
||||||
; Configures how ObjectUpdates are aggregated. These numbers
|
; Configures how ObjectUpdates are aggregated. These numbers
|
||||||
; do not literally mean how many updates will be put in each
|
; do not literally mean how many updates will be put in each
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
|
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
|
||||||
; *
|
; *
|
||||||
[Startup]
|
[Startup]
|
||||||
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector"
|
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector"
|
||||||
|
|
||||||
; * This is common for all services, it's the network setup for the entire
|
; * This is common for all services, it's the network setup for the entire
|
||||||
; * server instance, if none is specified above
|
; * server instance, if none is specified above
|
||||||
|
@ -197,6 +197,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
SRV_AssetServerURI = "http://127.0.0.1:8002"
|
SRV_AssetServerURI = "http://127.0.0.1:8002"
|
||||||
SRV_ProfileServerURI = "http://127.0.0.1:8002/user"
|
SRV_ProfileServerURI = "http://127.0.0.1:8002/user"
|
||||||
|
|
||||||
|
;; Regular expressions for controlling which client versions are accepted/denied.
|
||||||
|
;; An empty string means nothing is checked.
|
||||||
|
;;
|
||||||
|
;; Example 1: allow only these 3 types of clients (any version of them)
|
||||||
|
;; AllowedClients = "Imprudence|Hippo|Second Life"
|
||||||
|
;;
|
||||||
|
;; Example 2: allow all clients except these
|
||||||
|
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
|
||||||
|
;;
|
||||||
|
;; Note that these are regular expressions, so every character counts.
|
||||||
|
;; Also note that this is very weak security and should not be trusted as a reliable means
|
||||||
|
;; for keeping bad clients out; modified clients can fake their identifiers.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;AllowedClients = ""
|
||||||
|
;DeniedClients = ""
|
||||||
|
|
||||||
[GridInfoService]
|
[GridInfoService]
|
||||||
; These settings are used to return information on a get_grid_info call.
|
; These settings are used to return information on a get_grid_info call.
|
||||||
; Client launcher scripts and third-party clients make use of this to
|
; Client launcher scripts and third-party clients make use of this to
|
||||||
|
@ -256,6 +273,22 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
; If you run this gatekeeper server behind a proxy, set this to true
|
; If you run this gatekeeper server behind a proxy, set this to true
|
||||||
; HasProxy = false
|
; HasProxy = false
|
||||||
|
|
||||||
|
;; Regular expressions for controlling which client versions are accepted/denied.
|
||||||
|
;; An empty string means nothing is checked.
|
||||||
|
;;
|
||||||
|
;; Example 1: allow only these 3 types of clients (any version of them)
|
||||||
|
;; AllowedClients = "Imprudence|Hippo|Second Life"
|
||||||
|
;;
|
||||||
|
;; Example 2: allow all clients except these
|
||||||
|
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
|
||||||
|
;;
|
||||||
|
;; Note that these are regular expressions, so every character counts.
|
||||||
|
;; Also note that this is very weak security and should not be trusted as a reliable means
|
||||||
|
;; for keeping bad clients out; modified clients can fake their identifiers.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;AllowedClients = ""
|
||||||
|
;DeniedClients = ""
|
||||||
|
|
||||||
[UserAgentService]
|
[UserAgentService]
|
||||||
LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService"
|
LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
|
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
|
||||||
; *
|
; *
|
||||||
[Startup]
|
[Startup]
|
||||||
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
|
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
|
||||||
|
|
||||||
; * This is common for all services, it's the network setup for the entire
|
; * This is common for all services, it's the network setup for the entire
|
||||||
; * server instance, if none is specified above
|
; * server instance, if none is specified above
|
||||||
|
@ -176,6 +176,23 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
|
||||||
; If you run this login server behind a proxy, set this to true
|
; If you run this login server behind a proxy, set this to true
|
||||||
; HasProxy = false
|
; HasProxy = false
|
||||||
|
|
||||||
|
;; Regular expressions for controlling which client versions are accepted/denied.
|
||||||
|
;; An empty string means nothing is checked.
|
||||||
|
;;
|
||||||
|
;; Example 1: allow only these 3 types of clients (any version of them)
|
||||||
|
;; AllowedClients = "Imprudence|Hippo|Second Life"
|
||||||
|
;;
|
||||||
|
;; Example 2: allow all clients except these
|
||||||
|
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
|
||||||
|
;;
|
||||||
|
;; Note that these are regular expressions, so every character counts.
|
||||||
|
;; Also note that this is very weak security and should not be trusted as a reliable means
|
||||||
|
;; for keeping bad clients out; modified clients can fake their identifiers.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;AllowedClients = ""
|
||||||
|
;DeniedClients = ""
|
||||||
|
|
||||||
[GridInfoService]
|
[GridInfoService]
|
||||||
; These settings are used to return information on a get_grid_info call.
|
; These settings are used to return information on a get_grid_info call.
|
||||||
; Client launcher scripts and third-party clients make use of this to
|
; Client launcher scripts and third-party clients make use of this to
|
||||||
|
|
|
@ -83,6 +83,23 @@
|
||||||
SRV_AssetServerURI = "http://127.0.0.1:9000"
|
SRV_AssetServerURI = "http://127.0.0.1:9000"
|
||||||
SRV_ProfileServerURI = "http://127.0.0.1:9000"
|
SRV_ProfileServerURI = "http://127.0.0.1:9000"
|
||||||
|
|
||||||
|
;; Regular expressions for controlling which client versions are accepted/denied.
|
||||||
|
;; An empty string means nothing is checked.
|
||||||
|
;;
|
||||||
|
;; Example 1: allow only these 3 types of clients (any version of them)
|
||||||
|
;; AllowedClients = "Imprudence|Hippo|Second Life"
|
||||||
|
;;
|
||||||
|
;; Example 2: allow all clients except these
|
||||||
|
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
|
||||||
|
;;
|
||||||
|
;; Note that these are regular expressions, so every character counts.
|
||||||
|
;; Also note that this is very weak security and should not be trusted as a reliable means
|
||||||
|
;; for keeping bad clients out; modified clients can fake their identifiers.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;AllowedClients = ""
|
||||||
|
;DeniedClients = ""
|
||||||
|
|
||||||
[GatekeeperService]
|
[GatekeeperService]
|
||||||
ExternalName = "http://127.0.0.1:9000"
|
ExternalName = "http://127.0.0.1:9000"
|
||||||
|
|
||||||
|
@ -90,6 +107,23 @@
|
||||||
; If false, HG TPs happen only to the Default regions specified in [GridService] section
|
; If false, HG TPs happen only to the Default regions specified in [GridService] section
|
||||||
AllowTeleportsToAnyRegion = true
|
AllowTeleportsToAnyRegion = true
|
||||||
|
|
||||||
|
;; Regular expressions for controlling which client versions are accepted/denied.
|
||||||
|
;; An empty string means nothing is checked.
|
||||||
|
;;
|
||||||
|
;; Example 1: allow only these 3 types of clients (any version of them)
|
||||||
|
;; AllowedClients = "Imprudence|Hippo|Second Life"
|
||||||
|
;;
|
||||||
|
;; Example 2: allow all clients except these
|
||||||
|
;; DeniedClients = "Twisted|Crawler|Cryolife|FuckLife|StreetLife|GreenLife|AntiLife|KORE-Phaze|Synlyfe|Purple Second Life|SecondLi |Emerald"
|
||||||
|
;;
|
||||||
|
;; Note that these are regular expressions, so every character counts.
|
||||||
|
;; Also note that this is very weak security and should not be trusted as a reliable means
|
||||||
|
;; for keeping bad clients out; modified clients can fake their identifiers.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;AllowedClients = ""
|
||||||
|
;DeniedClients = ""
|
||||||
|
|
||||||
[GridInfoService]
|
[GridInfoService]
|
||||||
; These settings are used to return information on a get_grid_info call.
|
; These settings are used to return information on a get_grid_info call.
|
||||||
; Client launcher scripts and third-party clients make use of this to
|
; Client launcher scripts and third-party clients make use of this to
|
||||||
|
|
Loading…
Reference in New Issue