aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorSean Dague2008-09-03 18:11:44 +0000
committerSean Dague2008-09-03 18:11:44 +0000
commitaf5c7e52b1163cf65f897e5c7ecf9ef2d9f6e88e (patch)
treefcc52c0f3e20f005873def97e3be5cd9ca16270e /OpenSim/Region
parentwhite space fixes (diff)
downloadopensim-SC_OLD-af5c7e52b1163cf65f897e5c7ecf9ef2d9f6e88e.zip
opensim-SC_OLD-af5c7e52b1163cf65f897e5c7ecf9ef2d9f6e88e.tar.gz
opensim-SC_OLD-af5c7e52b1163cf65f897e5c7ecf9ef2d9f6e88e.tar.bz2
opensim-SC_OLD-af5c7e52b1163cf65f897e5c7ecf9ef2d9f6e88e.tar.xz
narrange to do basic cleanup of the CMS module
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs210
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs172
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs1359
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs277
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs229
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs301
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs650
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs75
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs467
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs228
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs103
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs435
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs100
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs298
14 files changed, 2620 insertions, 2284 deletions
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs
index 2155b4c..3188c6c 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/AuraMetaEntity.cs
@@ -1,114 +1,136 @@
1#region Header
2
1// AuraMetaEntity.cs created with MonoDevelop 3// AuraMetaEntity.cs created with MonoDevelop
2// User: bongiojp at 3:03 PM 8/6/2008 4// User: bongiojp at 3:03 PM 8/6/2008
3// 5//
4// To change standard headers go to Edit->Preferences->Coding->Standard Headers 6// To change standard headers go to Edit->Preferences->Coding->Standard Headers
5// 7//
6 8
9#endregion Header
10
7using System; 11using System;
8using System.Collections.Generic; 12using System.Collections.Generic;
9using System.Drawing; 13using System.Drawing;
14
10using libsecondlife; 15using libsecondlife;
16
11using Nini.Config; 17using Nini.Config;
18
12using OpenSim.Framework; 19using OpenSim.Framework;
13using OpenSim.Region.Environment.Interfaces; 20using OpenSim.Region.Environment.Interfaces;
14using OpenSim.Region.Environment.Scenes; 21using OpenSim.Region.Environment.Scenes;
15using log4net;
16using OpenSim.Region.Physics.Manager; 22using OpenSim.Region.Physics.Manager;
23
24using log4net;
25
17using Axiom.Math; 26using Axiom.Math;
18 27
19namespace OpenSim.Region.Environment.Modules.ContentManagement 28namespace OpenSim.Region.Environment.Modules.ContentManagement
20{ 29{
21 30 public class AuraMetaEntity : PointMetaEntity
22 31 {
23 public class AuraMetaEntity : PointMetaEntity 32 #region Constructors
24 { 33
25 //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency. 34 //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency.
26 public AuraMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale) : base(scene, LocalId, groupPos, transparency) 35 public AuraMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale)
27 { 36 : base(scene, LocalId, groupPos, transparency)
28 SetAura(color, scale); 37 {
29 } 38 SetAura(color, scale);
30 39 }
31 public AuraMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale) : base(scene, uuid, LocalId, groupPos, transparency) 40
32 { 41 public AuraMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, LLVector3 color, LLVector3 scale)
33 SetAura(color, scale); 42 : base(scene, uuid, LocalId, groupPos, transparency)
34 } 43 {
35 44 SetAura(color, scale);
36 private float Average(LLVector3 values) 45 }
37 { 46
38 return (values.X + values.Y + values.Z)/3f; 47 #endregion Constructors
39 } 48
40 49 #region Private Methods
41 public void SetAura(LLVector3 color, LLVector3 scale) 50
42 { 51 private float Average(LLVector3 values)
43 SetAura(color, Average(scale) * 2.0f); 52 {
44 } 53 return (values.X + values.Y + values.Z)/3f;
45 54 }
46 public void SetAura(LLVector3 color, float radius) 55
47 { 56 #endregion Private Methods
48 SceneObjectPart From = m_Entity.RootPart; 57
49 58 #region Public Methods
50 //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius); 59
51 float burstRadius = 0.1f; 60 public void SetAura(LLVector3 color, LLVector3 scale)
52 Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None; 61 {
53 float age = 1.5f; 62 SetAura(color, Average(scale) * 2.0f);
54 float burstRate = 0.4f; 63 }
55 if (radius >= 8.0f) 64
56 { 65 public void SetAura(LLVector3 color, float radius)
57 //float sizeOfObject = radius / 2.0f; 66 {
58 burstRadius = (radius - 8.0f)/3f; 67 SceneObjectPart From = m_Entity.RootPart;
59 burstRate = 1.5f; 68
60 radius = 7.99f; 69 //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius);
61 patternFlags = Primitive.ParticleSystem.SourcePattern.Explode; 70 float burstRadius = 0.1f;
62 age = 4.0f; 71 Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None;
63 } 72 float age = 1.5f;
64 SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags); 73 float burstRate = 0.4f;
65 } 74 if (radius >= 8.0f)
66 public void SetAura(SceneObjectPart From, LLVector3 color, float radius, float burstRadius, float age, float burstRate, libsecondlife.Primitive.ParticleSystem.SourcePattern patternFlags) 75 {
67 { 76 //float sizeOfObject = radius / 2.0f;
68 Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); 77 burstRadius = (radius - 8.0f)/3f;
69 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | 78 burstRate = 1.5f;
70 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS 79 radius = 7.99f;
71 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | 80 patternFlags = Primitive.ParticleSystem.SourcePattern.Explode;
72 // Primitive.ParticleSystem.ParticleDataFlags.TargetPos; 81 age = 4.0f;
73 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR 82 }
74 prules.PartStartColor.G = color.Y; 83 SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags);
75 prules.PartStartColor.B = color.Z; 84 }
76 prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency 85
77 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR 86 public void SetAura(SceneObjectPart From, LLVector3 color, float radius, float burstRadius, float age, float burstRate, libsecondlife.Primitive.ParticleSystem.SourcePattern patternFlags)
78 prules.PartEndColor.G = color.Y; 87 {
79 prules.PartEndColor.B = color.Z; 88 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
80 prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency 89 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
81 /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE 90 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
82 prules.PartStartScaleY = 0.5f; 91 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
83 prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE 92 // Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
84 prules.PartEndScaleY = 0.5f; 93 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
85 */ 94 prules.PartStartColor.G = color.Y;
86 prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE 95 prules.PartStartColor.B = color.Z;
87 prules.PartStartScaleY = radius; 96 prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency
88 prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE 97 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
89 prules.PartEndScaleY = radius; 98 prules.PartEndColor.G = color.Y;
90 prules.PartMaxAge = age; //PSYS_PART_MAX_AGE 99 prules.PartEndColor.B = color.Z;
91 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL 100 prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency
92 prules.PartAcceleration.Y = 0.0f; 101 /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE
93 prules.PartAcceleration.Z = 0.0f; 102 prules.PartStartScaleY = 0.5f;
94 prules.Pattern = patternFlags; //PSYS_SRC_PATTERN 103 prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE
95 //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank 104 prules.PartEndScaleY = 0.5f;
96 prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE 105 */
97 prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT 106 prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE
98 //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS 107 prules.PartStartScaleY = radius;
99 prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS 108 prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE
100 prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN 109 prules.PartEndScaleY = radius;
110 prules.PartMaxAge = age; //PSYS_PART_MAX_AGE
111 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
112 prules.PartAcceleration.Y = 0.0f;
113 prules.PartAcceleration.Z = 0.0f;
114 prules.Pattern = patternFlags; //PSYS_SRC_PATTERN
115 //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank
116 prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE
117 prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT
118 //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS
119 prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS
120 prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN
101 prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX 121 prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX
102 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE 122 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
103 //prules.Target = To; //PSYS_SRC_TARGET_KEY 123 //prules.Target = To; //PSYS_SRC_TARGET_KEY
104 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA 124 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
105 prules.AngularVelocity.Y = 0.0f; 125 prules.AngularVelocity.Y = 0.0f;
106 prules.AngularVelocity.Z = 0.0f; 126 prules.AngularVelocity.Z = 0.0f;
107 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN 127 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
108 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END 128 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
109 129
110 prules.CRC = 1; //activates the particle system?? 130 prules.CRC = 1; //activates the particle system??
111 From.AddNewParticleSystem(prules); 131 From.AddNewParticleSystem(prules);
112 } 132 }
113 } 133
114} 134 #endregion Public Methods
135 }
136} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs
index 499d1bc..cea9550 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/BeamMetaEntity.cs
@@ -1,98 +1,114 @@
1#region Header
2
1// BeamMetaEntity.cs created with MonoDevelop 3// BeamMetaEntity.cs created with MonoDevelop
2// User: bongiojp at 3:03 PM 8/6/2008 4// User: bongiojp at 3:03 PM 8/6/2008
3// 5//
4// To change standard headers go to Edit->Preferences->Coding->Standard Headers 6// To change standard headers go to Edit->Preferences->Coding->Standard Headers
5// 7//
6 8
9#endregion Header
10
7using System; 11using System;
8using System.Collections.Generic; 12using System.Collections.Generic;
9using System.Drawing; 13using System.Drawing;
14
10using libsecondlife; 15using libsecondlife;
16
11using Nini.Config; 17using Nini.Config;
18
12using OpenSim.Framework; 19using OpenSim.Framework;
13using OpenSim.Region.Environment.Interfaces; 20using OpenSim.Region.Environment.Interfaces;
14using OpenSim.Region.Environment.Scenes; 21using OpenSim.Region.Environment.Scenes;
15using log4net;
16using OpenSim.Region.Physics.Manager; 22using OpenSim.Region.Physics.Manager;
23
24using log4net;
25
17using Axiom.Math; 26using Axiom.Math;
18 27
19namespace OpenSim.Region.Environment.Modules.ContentManagement 28namespace OpenSim.Region.Environment.Modules.ContentManagement
20{ 29{
21 30 public class BeamMetaEntity : PointMetaEntity
22 31 {
23 public class BeamMetaEntity : PointMetaEntity 32 #region Constructors
24 { 33
25 34 public BeamMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color)
26 public BeamMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color) : base(scene, LocalId, groupPos, transparency) 35 : base(scene, LocalId, groupPos, transparency)
27 { 36 {
28 SetBeamToUUID(To, color); 37 SetBeamToUUID(To, color);
29 } 38 }
30 39
31 public BeamMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color) : base(scene, uuid, LocalId, groupPos, transparency) 40 public BeamMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency, SceneObjectPart To, LLVector3 color)
32 { 41 : base(scene, uuid, LocalId, groupPos, transparency)
33 SetBeamToUUID(To, color); 42 {
34 } 43 SetBeamToUUID(To, color);
35 44 }
36 public void SetBeamToUUID(SceneObjectPart To, LLVector3 color) 45
37 { 46 #endregion Constructors
38 SceneObjectPart From = m_Entity.RootPart; 47
39 //Scale size of particles to distance objects are apart (for better visibility) 48 #region Public Methods
40 LLVector3 FromPos = From.GetWorldPosition(); 49
41 LLVector3 ToPos = From.GetWorldPosition(); 50 public void SetBeamToUUID(SceneObjectPart To, LLVector3 color)
42 LLUUID toUUID = To.UUID; 51 {
43 float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) + 52 SceneObjectPart From = m_Entity.RootPart;
44 Math.Pow(FromPos.X-ToPos.Y, 2) + 53 //Scale size of particles to distance objects are apart (for better visibility)
45 Math.Pow(FromPos.X-ToPos.Z, 2) 54 LLVector3 FromPos = From.GetWorldPosition();
46 ) 55 LLVector3 ToPos = From.GetWorldPosition();
47 ); 56 LLUUID toUUID = To.UUID;
48 //float rate = (float) (distance/4f); 57 float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) +
49 float rate = 0.5f; 58 Math.Pow(FromPos.X-ToPos.Y, 2) +
50 float scale = (float) (distance/128f); 59 Math.Pow(FromPos.X-ToPos.Z, 2)
51 float speed = (float) (2.0f - distance/128f); 60 )
52 61 );
53 SetBeamToUUID(From, To, color, rate, scale, speed); 62 //float rate = (float) (distance/4f);
54 } 63 float rate = 0.5f;
55 64 float scale = (float) (distance/128f);
56 public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, LLVector3 color, float rate, float scale, float speed) 65 float speed = (float) (2.0f - distance/128f);
57 { 66
58 Primitive.ParticleSystem prules = new Primitive.ParticleSystem(); 67 SetBeamToUUID(From, To, color, rate, scale, speed);
59 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive | 68 }
60 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS 69
61 prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam | 70 public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, LLVector3 color, float rate, float scale, float speed)
62 Primitive.ParticleSystem.ParticleDataFlags.TargetPos; 71 {
63 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR 72 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
64 prules.PartStartColor.G = color.Y; 73 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
65 prules.PartStartColor.B = color.Z; 74 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
66 prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency 75 prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
67 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR 76 Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
68 prules.PartEndColor.G = color.Y; 77 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
69 prules.PartEndColor.B = color.Z; 78 prules.PartStartColor.G = color.Y;
70 prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency 79 prules.PartStartColor.B = color.Z;
71 prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE 80 prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency
72 prules.PartStartScaleY = scale; 81 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
73 prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE 82 prules.PartEndColor.G = color.Y;
74 prules.PartEndScaleY = scale; 83 prules.PartEndColor.B = color.Z;
75 prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE 84 prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency
76 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL 85 prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE
77 prules.PartAcceleration.Y = 0.0f; 86 prules.PartStartScaleY = scale;
78 prules.PartAcceleration.Z = 0.0f; 87 prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE
79 //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN 88 prules.PartEndScaleY = scale;
80 //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank 89 prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE
81 prules.BurstRate = rate; //PSYS_SRC_BURST_RATE 90 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
82 prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT 91 prules.PartAcceleration.Y = 0.0f;
83 prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS 92 prules.PartAcceleration.Z = 0.0f;
84 prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN 93 //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN
94 //prules.Texture = LLUUID.Zero;//= LLUUID //PSYS_SRC_TEXTURE, default used if blank
95 prules.BurstRate = rate; //PSYS_SRC_BURST_RATE
96 prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT
97 prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS
98 prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN
85 prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX 99 prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX
86 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE 100 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
87 prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY 101 prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY
88 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA 102 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
89 prules.AngularVelocity.Y = 0.0f; 103 prules.AngularVelocity.Y = 0.0f;
90 prules.AngularVelocity.Z = 0.0f; 104 prules.AngularVelocity.Z = 0.0f;
91 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN 105 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
92 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END 106 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
93 107
94 prules.CRC = 1; //activates the particle system?? 108 prules.CRC = 1; //activates the particle system??
95 From.AddNewParticleSystem(prules); 109 From.AddNewParticleSystem(prules);
96 } 110 }
97 } 111
98} 112 #endregion Public Methods
113 }
114} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs
index d3ca3cf..a179fb1 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMController.cs
@@ -1,684 +1,721 @@
1#region Header
2
1// CMController.cs 3// CMController.cs
2// User: bongiojp 4// User: bongiojp
3// 5//
4 6
7#endregion Header
8
5using System; 9using System;
6using System.Collections.Generic;
7using System.Collections; 10using System.Collections;
11using System.Collections.Generic;
12using System.Diagnostics;
13using System.Threading;
14
8using libsecondlife; 15using libsecondlife;
16
9using OpenSim; 17using OpenSim;
10using OpenSim.Framework; 18using OpenSim.Framework;
11using OpenSim.Region.Environment.Interfaces; 19using OpenSim.Region.Environment.Interfaces;
12using OpenSim.Region.Environment.Scenes; 20using OpenSim.Region.Environment.Scenes;
13using log4net;
14using OpenSim.Region.Physics.Manager; 21using OpenSim.Region.Physics.Manager;
22
23using log4net;
24
15using Axiom.Math; 25using Axiom.Math;
16using System.Threading;
17using System.Diagnostics;
18 26
19namespace OpenSim.Region.Environment.Modules.ContentManagement 27namespace OpenSim.Region.Environment.Modules.ContentManagement
20{ 28{
21 29 /// <summary>
22 /// <summary> 30 /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread,
23 /// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread, 31 /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system.
24 /// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system. 32 /// </summary>
25 /// </summary> 33 public class CMController
26 public class CMController 34 {
27 { 35 #region Static Fields
28 36
29 /// <value> 37 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
30 /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem. 38
31 /// </value> 39 /// <value>
32 private struct Work 40 /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
33 { 41 /// </value>
34 public WorkType Type; 42 private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
35 public Object Data1; //Just space for holding data. 43
36 public Object Data2; //Just more space for holding data. 44 #endregion Static Fields
37 public uint LocalId; //Convenient 45
38 public LLUUID UUID; //Convenient 46 #region Fields
39 } 47
40 48 bool init = false;
41 /// <value> 49 int m_channel = -1;
42 /// Identifies what the data in struct Work should be used for. 50
43 /// </value> 51 /// <value>
44 private enum WorkType 52 /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
45 { 53 /// </value>
46 NONE, 54 IEstateModule m_estateModule = null;
47 OBJECTATTRIBUTECHANGE, 55
48 PRIMITIVEADDED, 56 //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
49 OBJECTDUPLICATED, 57 CMModel m_model = null;
50 OBJECTKILLED, 58
51 UNDODID, 59 /// <value>
52 NEWCLIENT, 60 /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
53 SIMCHAT 61 /// </value>
54 } 62 Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
55 63 State m_state = State.NONE;
56 /// <value> 64 Thread m_thread = null;
57 /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk. 65 CMView m_view = null;
58 /// </value> 66
59 [Flags] 67 #endregion Fields
60 private enum State 68
61 { 69 #region Constructors
62 NONE = 0, 70
63 DIRTY = 1, // The meta entities may not correctly represent the last revision. 71 /// <summary>
64 SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user. 72 /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
65 } 73 /// </summary>
66 74 /// <param name="model">
67 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 75 /// <see cref="CMModel"/>
68 76 /// </param>
69 /// <value> 77 /// <param name="view">
70 /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue. 78 /// <see cref="CMView"/>
71 /// </value> 79 /// </param>
72 private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>(); 80 /// <param name="scene">
73 81 /// The first scene to keep track of. <see cref="Scene"/>
74 /// <value> 82 /// </param>
75 /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region. 83 /// <param name="channel">
76 /// </value> 84 /// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
77 Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable()); 85 /// </param>
78 86 public CMController(CMModel model, CMView view, Scene scene, int channel)
79 /// <value> 87 {
80 /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers. 88 m_model = model; m_view = view; m_channel = channel;
81 /// </value> 89 RegisterNewRegion(scene);
82 IEstateModule m_estateModule = null; 90 Initialize(model, view, scene, channel);
83 91 }
84 Thread m_thread = null; 92
85 State m_state = State.NONE; 93 #endregion Constructors
86 bool init = false; 94
87 95 #region Private Methods
88 //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop) 96
89 CMModel m_model = null; 97 //------------------------------------------------ EVENTS ----------------------------------------------------//
90 CMView m_view = null; 98 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
91 int m_channel = -1; 99 {
92 100 }
93 /// <summary> 101
94 /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method. 102 /// <summary>
95 /// </summary> 103 /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
96 /// <param name="model"> 104 /// </summary>
97 /// <see cref="CMModel"/> 105 private SceneObjectGroup GetGroupByPrim(uint localID)
98 /// </param> 106 {
99 /// <param name="view"> 107 foreach(Object currScene in m_sceneList.Values)
100 /// <see cref="CMView"/> 108 {
101 /// </param> 109 foreach (EntityBase ent in ((Scene)currScene).GetEntities())
102 /// <param name="scene"> 110 {
103 /// The first scene to keep track of. <see cref="Scene"/> 111 if (ent is SceneObjectGroup)
104 /// </param> 112 {
105 /// <param name="channel"> 113 if (((SceneObjectGroup)ent).HasChildPrim(localID))
106 /// The simchat channel number to listen to for instructions <see cref="System.Int32"/> 114 return (SceneObjectGroup)ent;
107 /// </param> 115 }
108 public CMController(CMModel model, CMView view, Scene scene, int channel) 116 }
109 { 117 }
110 m_model = model; m_view = view; m_channel = channel;
111 RegisterNewRegion(scene);
112 Initialize(model, view, scene, channel);
113 }
114
115 private void Initialize(CMModel model, CMView view, Scene scene, int channel)
116 {
117 lock(this)
118 {
119 m_estateModule = scene.RequestModuleInterface<IEstateModule>();
120 m_thread = new Thread( MainLoop );
121 m_thread.Name = "Content Management";
122 m_thread.IsBackground = true;
123 m_thread.Start();
124 ThreadTracker.Add(m_thread);
125 m_state = State.NONE;
126 }
127 }
128
129 /// <summary>
130 /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
131 /// </summary>
132 /// <param name="scene">
133 /// A <see cref="Scene"/>
134 /// </param>
135 public void RegisterNewRegion(Scene scene)
136 {
137 m_sceneList.Add(scene.RegionInfo.RegionID, scene);
138
139 m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
140 m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
141
142 scene.EventManager.OnNewClient += StartManaging;
143 scene.EventManager.OnRemovePresence += StopManaging;
144 // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
145 scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
146 }
147
148 /// <summary>
149 /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
150 /// </summary>
151 private void MainLoop()
152 {
153 CMModel model = m_model; CMView view = m_view; int channel = m_channel;
154 Work currentJob = new Work();
155 while(true)
156 {
157 currentJob = m_WorkQueue.Dequeue();
158 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
159 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
160 switch(currentJob.Type)
161 {
162 case WorkType.NONE:
163 break;
164 case WorkType.OBJECTATTRIBUTECHANGE:
165 ObjectAttributeChanged(model, view, currentJob.LocalId);
166 break;
167 case WorkType.PRIMITIVEADDED:
168 PrimitiveAdded(model, view, currentJob);
169 break;
170 case WorkType.OBJECTDUPLICATED:
171 ObjectDuplicated(model, view, currentJob.LocalId);
172 break;
173 case WorkType.OBJECTKILLED:
174 ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
175 break;
176 case WorkType.UNDODID:
177 UndoDid(model, view, currentJob.UUID);
178 break;
179 case WorkType.NEWCLIENT:
180 NewClient(view, (IClientAPI) currentJob.Data1);
181 break;
182 case WorkType.SIMCHAT:
183 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
184 SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
185 break;
186 default:
187 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
188 break;
189 }
190 }
191 }
192
193 /// <summary>
194 /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
195 /// </summary>
196 private void NewClient(CMView view, IClientAPI client)
197 {
198 if ((m_state & State.SHOWING_CHANGES) > 0)
199 view.SendMetaEntitiesToNewClient(client);
200 }
201
202 /// <summary>
203 /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
204 /// </summary>
205 private void ObjectDuplicated(CMModel model, CMView view, uint localId)
206 {
207 if ((m_state & State.SHOWING_CHANGES) > 0)
208 view.DisplayAuras(model.CheckForNewEntitiesMissingAuras( GetGroupByPrim(localId).Scene ));
209 }
210
211 /// <summary>
212 /// Only called by the MainLoop.
213 /// </summary>
214 private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
215 {
216 if ((m_state & State.SHOWING_CHANGES) > 0)
217 {
218 view.RemoveOrUpdateDeletedEntity(group);
219 model.RemoveOrUpdateDeletedEntity(group);
220 }
221 }
222
223 /// <summary>
224 /// Only called by the MainLoop.
225 /// </summary>
226 private void UndoDid(CMModel model, CMView view, LLUUID uuid)
227 {
228 if ((m_state & State.SHOWING_CHANGES) > 0)
229 {
230 ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
231 if (ent != null)
232 view.DisplayEntity(ent);
233 }
234 }
235
236 /// <summary>
237 /// Only called by the MainLoop.
238 /// </summary>
239 private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
240 {
241 SceneObjectGroup group = null;
242 if ((m_state & State.SHOWING_CHANGES) > 0)
243 {
244 group = GetGroupByPrim(LocalId);
245 if (group != null)
246 {
247 view.DisplayAuras( model.UpdateNormalEntityEffects(group) ); //Might be a normal entity (green aura)
248 m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
249 }
250 }
251 }
252
253 /// <summary>
254 /// Only called by the MainLoop.
255 /// </summary>
256 private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
257 {
258 if ((m_state & State.SHOWING_CHANGES) > 0)
259 {
260 foreach(Object scene in m_sceneList.Values)
261 m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
262 }
263 }
264
265 /// <summary>
266 /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
267 /// </summary>
268 public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
269 {
270 if (e.Channel != channel)
271 return;
272 if (e.Sender == null)
273 return;
274
275 m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
276
277 IClientAPI client = e.Sender;
278 Scene scene = (Scene) e.Scene;
279 string message = e.Message;
280 string[] args = e.Message.Split(new char[] {' '});
281
282 ScenePresence avatar = scene.GetScenePresence(client.AgentId);
283
284 if (!(m_estateModule.IsManager(avatar.UUID)))
285 {
286 m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
287 view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
288 return;
289 }
290
291 switch(args[0])
292 {
293 case "ci":
294 case "commit":
295 commit(message, scene, model, view);
296 break;
297 case "dm":
298 case "diff-mode":
299 diffmode(scene, model, view);
300 break;
301 case "rb":
302 case "rollback":
303 rollback(scene, model, view);
304 break;
305 case "help":
306 m_view.DisplayHelpMenu(scene);
307 break;
308 default:
309 view.SendSimChatMessage(scene, "Command not found: " + args[0]);
310 break;
311 }
312 }
313
314 /// <summary>
315 /// Only called from within the SimChat method. Hides all auras and meta entities,
316 /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
317 /// then lets the view update the clients of the new objects.
318 /// </summary>
319 protected void rollback(Scene scene, CMModel model, CMView view)
320 {
321 if ((m_state & State.SHOWING_CHANGES) > 0)
322 {
323 view.HideAllAuras();
324 view.HideAllMetaEntities();
325 }
326
327 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
328 foreach(Scene currScene in proximitySceneList)
329 model.RollbackRegion(currScene);
330
331 if ((m_state & State.DIRTY) != 0 )
332 {
333 model.DeleteAllMetaObjects();
334 foreach(Scene currScene in proximitySceneList)
335 model.UpdateCMEntities(currScene);
336 }
337
338 if ((m_state & State.SHOWING_CHANGES) > 0)
339 view.DisplayRecentChanges();
340
341 }
342
343 /// <summary>
344 /// Only called from within the SimChat method.
345 /// </summary>
346 protected void diffmode(Scene scene, CMModel model, CMView view)
347 {
348 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
349
350 if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
351 {
352 view.SendSimChatMessage(scene, "Hiding all meta objects.");
353 view.HideAllMetaEntities();
354 view.HideAllAuras();
355 view.SendSimChatMessage(scene, "Diff-mode = OFF");
356
357 m_state &= ~State.SHOWING_CHANGES;
358 return;
359 }
360 else // TURN ON
361 {
362 if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
363 {
364 view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
365 //Hide objects from users and Forget about them
366 view.HideAllMetaEntities();
367 view.HideAllAuras();
368 model.DeleteAllMetaObjects();
369 //Recreate them from backend files
370 foreach(Object currScene in m_sceneList.Values)
371 model.UpdateCMEntities((Scene) currScene);
372 }
373 else if ((m_state & State.DIRTY) != 0) {
374 view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
375 foreach(Scene currScene in proximitySceneList)
376 model.UpdateCMEntities(currScene);
377 }
378
379 view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
380 foreach(Scene currScene in proximitySceneList)
381 model.CheckForNewEntitiesMissingAuras(currScene);
382 view.DisplayRecentChanges();
383
384 view.SendSimChatMessage(scene, "Diff-mode = ON");
385 m_state |= State.SHOWING_CHANGES;
386 m_state &= ~State.DIRTY;
387 }
388 }
389
390 /// <summary>
391 /// Only called from within the SimChat method.
392 /// </summary>
393 protected void commit(string message, Scene scene, CMModel model, CMView view)
394 {
395 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
396
397 string[] args = message.Split(new char[] {' '});
398
399 char[] logMessage = {' '};
400 if (args.Length > 1)
401 {
402 logMessage = new char[message.Length - (args[0].Length)];
403 message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
404 }
405
406 m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
407 foreach(Scene currScene in proximitySceneList)
408 {
409 model.CommitRegion(currScene, new String(logMessage));
410 view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
411 }
412
413 view.SendSimChatMessage(scene, "Successfully saved all regions.");
414 m_state |= State.DIRTY;
415
416 if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
417 {
418 view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
419 //Hide objects from users and Forget about them
420 view.HideAllMetaEntities();
421 view.HideAllAuras();
422 model.DeleteAllMetaObjects();
423
424 //Recreate them from backend files
425 foreach(Scene currScene in proximitySceneList)
426 {
427 model.UpdateCMEntities(currScene);
428 view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
429 }
430
431 //Display new objects to users1
432 view.DisplayRecentChanges();
433 view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
434 m_state &= ~(State.DIRTY);
435 m_state |= State.SHOWING_CHANGES;
436 }
437 }
438
439 /// <summary>
440 /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
441 /// </summary>
442 protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity( Hashtable sceneList, Scene scene)
443 {
444 int somethingAddedToList = 1;
445 System.Collections.Generic.List<Scene> newList = new List<Scene>();
446 newList.Add(scene);
447
448 if (! sceneList.ContainsValue(scene))
449 {
450 foreach(Object sceneObj in sceneList)
451 newList.Add((Scene) sceneObj);
452 return newList;
453 }
454
455 while(somethingAddedToList > 0)
456 {
457 somethingAddedToList = 0;
458 for(int i = 0; i < newList.Count; i++)
459 {
460 foreach(Object sceneObj in sceneList.Values)
461 {
462 if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (! newList.Contains((Scene)sceneObj)) )
463 {
464 newList.Add((Scene)sceneObj);
465 somethingAddedToList++;
466 }
467 }
468 }
469 }
470
471 foreach(Object sceneObj in sceneList.Values)
472 if (! newList.Contains((Scene)sceneObj))
473 newList.Add((Scene)sceneObj);
474
475 return newList;
476 }
477
478 /// <summary>
479 /// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
480 /// </summary>
481 private SceneObjectGroup GetGroupByPrim(uint localID)
482 {
483 foreach(Object currScene in m_sceneList.Values)
484 {
485 foreach (EntityBase ent in ((Scene)currScene).GetEntities())
486 {
487 if (ent is SceneObjectGroup)
488 {
489 if (((SceneObjectGroup)ent).HasChildPrim(localID))
490 return (SceneObjectGroup)ent;
491 }
492 }
493 }
494 return null; 118 return null;
495 } 119 }
496 //------------------------------------------------ EVENTS ----------------------------------------------------// 120
497 121 private void Initialize(CMModel model, CMView view, Scene scene, int channel)
498 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) 122 {
499 { 123 lock(this)
500 } 124 {
501 125 m_estateModule = scene.RequestModuleInterface<IEstateModule>();
502 /// <summary> 126 m_thread = new Thread( MainLoop );
503 /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions. 127 m_thread.Name = "Content Management";
504 /// </summary> 128 m_thread.IsBackground = true;
505 protected void StartManaging(IClientAPI client) 129 m_thread.Start();
506 { 130 ThreadTracker.Add(m_thread);
507 m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services."); 131 m_state = State.NONE;
508 client.OnChatFromViewer += SimChatSent; 132 }
509 init = true; 133 }
510 134
511 OnNewClient(client); 135 /// <summary>
512 136 /// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
513 m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client."); 137 /// </summary>
514 client.OnUpdatePrimScale += UpdateSingleScale; 138 private void MainLoop()
139 {
140 CMModel model = m_model; CMView view = m_view; int channel = m_channel;
141 Work currentJob = new Work();
142 while(true)
143 {
144 currentJob = m_WorkQueue.Dequeue();
145 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
146 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
147 switch(currentJob.Type)
148 {
149 case WorkType.NONE:
150 break;
151 case WorkType.OBJECTATTRIBUTECHANGE:
152 ObjectAttributeChanged(model, view, currentJob.LocalId);
153 break;
154 case WorkType.PRIMITIVEADDED:
155 PrimitiveAdded(model, view, currentJob);
156 break;
157 case WorkType.OBJECTDUPLICATED:
158 ObjectDuplicated(model, view, currentJob.LocalId);
159 break;
160 case WorkType.OBJECTKILLED:
161 ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
162 break;
163 case WorkType.UNDODID:
164 UndoDid(model, view, currentJob.UUID);
165 break;
166 case WorkType.NEWCLIENT:
167 NewClient(view, (IClientAPI) currentJob.Data1);
168 break;
169 case WorkType.SIMCHAT:
170 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
171 SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
172 break;
173 default:
174 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
175 break;
176 }
177 }
178 }
179
180 /// <summary>
181 /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
182 /// </summary>
183 private void NewClient(CMView view, IClientAPI client)
184 {
185 if ((m_state & State.SHOWING_CHANGES) > 0)
186 view.SendMetaEntitiesToNewClient(client);
187 }
188
189 /// <summary>
190 /// Only called by the MainLoop.
191 /// </summary>
192 private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
193 {
194 SceneObjectGroup group = null;
195 if ((m_state & State.SHOWING_CHANGES) > 0)
196 {
197 group = GetGroupByPrim(LocalId);
198 if (group != null)
199 {
200 view.DisplayAuras( model.UpdateNormalEntityEffects(group) ); //Might be a normal entity (green aura)
201 m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
202 }
203 }
204 }
205
206 /// <summary>
207 /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
208 /// </summary>
209 private void ObjectDuplicated(CMModel model, CMView view, uint localId)
210 {
211 if ((m_state & State.SHOWING_CHANGES) > 0)
212 view.DisplayAuras(model.CheckForNewEntitiesMissingAuras( GetGroupByPrim(localId).Scene ));
213 }
214
215 /// <summary>
216 /// Only called by the MainLoop.
217 /// </summary>
218 private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
219 {
220 if ((m_state & State.SHOWING_CHANGES) > 0)
221 {
222 view.RemoveOrUpdateDeletedEntity(group);
223 model.RemoveOrUpdateDeletedEntity(group);
224 }
225 }
226
227 /// <summary>
228 /// Only called by the MainLoop.
229 /// </summary>
230 private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
231 {
232 if ((m_state & State.SHOWING_CHANGES) > 0)
233 {
234 foreach(Object scene in m_sceneList.Values)
235 m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
236 }
237 }
238
239 /// <summary>
240 /// Only called by the MainLoop.
241 /// </summary>
242 private void UndoDid(CMModel model, CMView view, LLUUID uuid)
243 {
244 if ((m_state & State.SHOWING_CHANGES) > 0)
245 {
246 ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
247 if (ent != null)
248 view.DisplayEntity(ent);
249 }
250 }
251
252 #endregion Private Methods
253
254 #region Protected Methods
255
256 protected void GroupBeingDeleted(SceneObjectGroup group)
257 {
258 m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
259 Work moreWork = new Work();
260 moreWork.Type = WorkType.OBJECTKILLED;
261 moreWork.Data1 = group.Copy();
262 m_WorkQueue.Enqueue(moreWork);
263 }
264
265 protected void ObjectDuplicated(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID)
266 {
267 Work moreWork = new Work();
268 moreWork.Type = WorkType.OBJECTDUPLICATED;
269 moreWork.LocalId = localID;
270 m_WorkQueue.Enqueue(moreWork);
271 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
272 }
273
274 protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID,
275 LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart,
276 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
277 {
278 Work moreWork = new Work();
279 moreWork.Type = WorkType.OBJECTDUPLICATED;
280 moreWork.LocalId = localID;
281 m_WorkQueue.Enqueue(moreWork);
282 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
283 }
284
285 protected void OnNewClient(IClientAPI client)
286 {
287 Work moreWork = new Work();
288 moreWork.Type = WorkType.NEWCLIENT;
289 moreWork.Data1 = client;
290 m_WorkQueue.Enqueue(moreWork);
291 m_log.Debug("[CONTENT MANAGEMENT] new client");
292 }
293
294 protected void OnUnDid(IClientAPI remoteClient, LLUUID primId)
295 {
296 Work moreWork = new Work();
297 moreWork.Type = WorkType.UNDODID;
298 moreWork.UUID = primId;
299 m_WorkQueue.Enqueue(moreWork);
300 m_log.Debug("[CONTENT MANAGEMENT] undid");
301 }
302
303 /// <summary>
304 /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
305 /// </summary>
306 protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity( Hashtable sceneList, Scene scene)
307 {
308 int somethingAddedToList = 1;
309 System.Collections.Generic.List<Scene> newList = new List<Scene>();
310 newList.Add(scene);
311
312 if (! sceneList.ContainsValue(scene))
313 {
314 foreach(Object sceneObj in sceneList)
315 newList.Add((Scene) sceneObj);
316 return newList;
317 }
318
319 while(somethingAddedToList > 0)
320 {
321 somethingAddedToList = 0;
322 for(int i = 0; i < newList.Count; i++)
323 {
324 foreach(Object sceneObj in sceneList.Values)
325 {
326 if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (! newList.Contains((Scene)sceneObj)) )
327 {
328 newList.Add((Scene)sceneObj);
329 somethingAddedToList++;
330 }
331 }
332 }
333 }
334
335 foreach(Object sceneObj in sceneList.Values)
336 if (! newList.Contains((Scene)sceneObj))
337 newList.Add((Scene)sceneObj);
338
339 return newList;
340 }
341
342 //This is stupid, the same information is contained in the first and second argument
343 protected void SimChatSent(Object x, OSChatMessage e)
344 {
345 m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
346 m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
347 Work moreWork = new Work();
348 moreWork.Type = WorkType.SIMCHAT;
349 moreWork.Data1 = e;
350 m_WorkQueue.Enqueue(moreWork);
351 }
352
353 /// <summary>
354 /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
355 /// </summary>
356 protected void StartManaging(IClientAPI client)
357 {
358 m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
359 client.OnChatFromViewer += SimChatSent;
360 init = true;
361
362 OnNewClient(client);
363
364 m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
365 client.OnUpdatePrimScale += UpdateSingleScale;
515 client.OnUpdatePrimGroupScale += UpdateMultipleScale; 366 client.OnUpdatePrimGroupScale += UpdateMultipleScale;
516 client.OnUpdatePrimGroupPosition += UpdateMultiplePosition; 367 client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
517 client.OnUpdatePrimSinglePosition += UpdateSinglePosition; 368 client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
518 client.OnUpdatePrimGroupRotation += UpdateMultipleRotation; 369 client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
519 client.OnUpdatePrimSingleRotation += UpdateSingleRotation; 370 client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
520 client.OnAddPrim += UpdateNewParts; 371 client.OnAddPrim += UpdateNewParts;
521 client.OnObjectDuplicate += ObjectDuplicated; 372 client.OnObjectDuplicate += ObjectDuplicated;
522 client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay; 373 client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
523 client.OnUndo += OnUnDid; 374 client.OnUndo += OnUnDid;
524 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; 375 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
525 } 376 }
526 377
527 /// <summary> 378 /// <summary>
528 /// 379 ///
529 /// </summary> 380 /// </summary>
530 protected void StopManaging(LLUUID clientUUID) 381 protected void StopManaging(LLUUID clientUUID)
531 { 382 {
532 foreach(Object sceneobj in m_sceneList.Values) 383 foreach(Object sceneobj in m_sceneList.Values)
533 { 384 {
534 ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID); 385 ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
535 if (presence != null) 386 if (presence != null)
536 { 387 {
537 IClientAPI client = presence.ControllingClient; 388 IClientAPI client = presence.ControllingClient;
538 m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services."); 389 m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
539 client.OnChatFromViewer -= SimChatSent; 390 client.OnChatFromViewer -= SimChatSent;
540 391
541 m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client"); 392 m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
542 client.OnUpdatePrimScale -= UpdateSingleScale; 393 client.OnUpdatePrimScale -= UpdateSingleScale;
543 client.OnUpdatePrimGroupScale -= UpdateMultipleScale; 394 client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
544 client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition; 395 client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
545 client.OnUpdatePrimSinglePosition -= UpdateSinglePosition; 396 client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
546 client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation; 397 client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
547 client.OnUpdatePrimSingleRotation -= UpdateSingleRotation; 398 client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
548 client.OnAddPrim -= UpdateNewParts; 399 client.OnAddPrim -= UpdateNewParts;
549 client.OnObjectDuplicate -= ObjectDuplicated; 400 client.OnObjectDuplicate -= ObjectDuplicated;
550 client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay; 401 client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
551 client.OnUndo -= OnUnDid; 402 client.OnUndo -= OnUnDid;
552 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; 403 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
553 return; 404 return;
554 } 405 }
555 } 406 }
556 } 407 }
557 408
558 protected void GroupBeingDeleted(SceneObjectGroup group) 409 protected void UpdateMultiplePosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
559 { 410 {
560 m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!"); 411 Work moreWork = new Work();
561 Work moreWork = new Work(); 412 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
562 moreWork.Type = WorkType.OBJECTKILLED; 413 moreWork.LocalId = localID;
563 moreWork.Data1 = group.Copy(); 414 m_WorkQueue.Enqueue(moreWork);
564 m_WorkQueue.Enqueue(moreWork); 415 m_log.Debug("[CONTENT MANAGEMENT] pos");
565 } 416 }
566 417
567 //This is stupid, the same information is contained in the first and second argument 418 protected void UpdateMultipleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
568 protected void SimChatSent(Object x, OSChatMessage e) 419 {
569 { 420 Work moreWork = new Work();
570 m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!"); 421 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
571 m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message); 422 moreWork.LocalId = localID;
572 Work moreWork = new Work(); 423 m_WorkQueue.Enqueue(moreWork);
573 moreWork.Type = WorkType.SIMCHAT; 424 m_log.Debug("[CONTENT MANAGEMENT] rot");
574 moreWork.Data1 = e; 425 }
575 m_WorkQueue.Enqueue(moreWork); 426
576 } 427 protected void UpdateMultipleScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
577 428 {
578 protected void ObjectDuplicated(uint localID, LLVector3 offset, uint dupeFlags, LLUUID AgentID, LLUUID GroupID) 429 Work moreWork = new Work();
579 { 430 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
580 Work moreWork = new Work(); 431 moreWork.LocalId = localID;
581 moreWork.Type = WorkType.OBJECTDUPLICATED; 432 m_WorkQueue.Enqueue(moreWork);
582 moreWork.LocalId = localID; 433 m_log.Debug("[CONTENT MANAGEMENT]scale");
583 m_WorkQueue.Enqueue(moreWork); 434 }
584 m_log.Debug("[CONTENT MANAGEMENT] dup queue"); 435
585 } 436 protected void UpdateNewParts(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape,
586 437 byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID,
587 protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID, 438 byte RayEndIsIntersection)
588 LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart, 439 {
589 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) 440 Work moreWork = new Work();
590 { 441 moreWork.Type = WorkType.PRIMITIVEADDED;
591 Work moreWork = new Work(); 442 moreWork.UUID = ownerID;
592 moreWork.Type = WorkType.OBJECTDUPLICATED; 443 m_WorkQueue.Enqueue(moreWork);
593 moreWork.LocalId = localID; 444 m_log.Debug("[CONTENT MANAGEMENT] new parts");
594 m_WorkQueue.Enqueue(moreWork); 445 }
595 m_log.Debug("[CONTENT MANAGEMENT] dup queue"); 446
596 } 447 protected void UpdateSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient)
597 448 {
598 protected void OnNewClient(IClientAPI client) 449 Work moreWork = new Work();
599 { 450 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
600 Work moreWork = new Work(); 451 moreWork.LocalId = localID;
601 moreWork.Type = WorkType.NEWCLIENT; 452 m_WorkQueue.Enqueue(moreWork);
602 moreWork.Data1 = client; 453 m_log.Debug("[CONTENT MANAGEMENT] move");
603 m_WorkQueue.Enqueue(moreWork); 454 }
604 m_log.Debug("[CONTENT MANAGEMENT] new client"); 455
605 } 456 /// <summary>
606 457 ///
607 protected void OnUnDid(IClientAPI remoteClient, LLUUID primId) 458 /// </summary>
608 { 459 protected void UpdateSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient)
609 Work moreWork = new Work(); 460 {
610 moreWork.Type = WorkType.UNDODID; 461 Work moreWork = new Work();
611 moreWork.UUID = primId; 462 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
612 m_WorkQueue.Enqueue(moreWork); 463 moreWork.LocalId = localID;
613 m_log.Debug("[CONTENT MANAGEMENT] undid"); 464 m_WorkQueue.Enqueue(moreWork);
614 } 465 m_log.Debug("[CONTENT MANAGEMENT] rot");
615 466 }
616 protected void UpdateSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) 467
617 { 468 protected void UpdateSingleScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
618 Work moreWork = new Work(); 469 {
619 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; 470 Work moreWork = new Work();
620 moreWork.LocalId = localID; 471 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
621 m_WorkQueue.Enqueue(moreWork); 472 moreWork.LocalId = localID;
622 m_log.Debug("[CONTENT MANAGEMENT] move"); 473 m_WorkQueue.Enqueue(moreWork);
623 } 474 m_log.Debug("[CONTENT MANAGEMENT] scale");
624 475 }
625 /// <summary> 476
626 /// 477 /// <summary>
627 /// </summary> 478 /// Only called from within the SimChat method.
628 protected void UpdateSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) 479 /// </summary>
629 { 480 protected void commit(string message, Scene scene, CMModel model, CMView view)
630 Work moreWork = new Work(); 481 {
631 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; 482 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
632 moreWork.LocalId = localID; 483
633 m_WorkQueue.Enqueue(moreWork); 484 string[] args = message.Split(new char[] {' '});
634 m_log.Debug("[CONTENT MANAGEMENT] rot"); 485
635 } 486 char[] logMessage = {' '};
636 487 if (args.Length > 1)
637 protected void UpdateSingleScale(uint localID, LLVector3 scale, IClientAPI remoteClient) 488 {
638 { 489 logMessage = new char[message.Length - (args[0].Length)];
639 Work moreWork = new Work(); 490 message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
640 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; 491 }
641 moreWork.LocalId = localID; 492
642 m_WorkQueue.Enqueue(moreWork); 493 m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
643 m_log.Debug("[CONTENT MANAGEMENT] scale"); 494 foreach(Scene currScene in proximitySceneList)
644 } 495 {
645 496 model.CommitRegion(currScene, new String(logMessage));
646 protected void UpdateMultiplePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) 497 view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
647 { 498 }
648 Work moreWork = new Work(); 499
649 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; 500 view.SendSimChatMessage(scene, "Successfully saved all regions.");
650 moreWork.LocalId = localID; 501 m_state |= State.DIRTY;
651 m_WorkQueue.Enqueue(moreWork); 502
652 m_log.Debug("[CONTENT MANAGEMENT] pos"); 503 if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
653 } 504 {
654 505 view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
655 protected void UpdateMultipleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) 506 //Hide objects from users and Forget about them
656 { 507 view.HideAllMetaEntities();
657 Work moreWork = new Work(); 508 view.HideAllAuras();
658 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; 509 model.DeleteAllMetaObjects();
659 moreWork.LocalId = localID; 510
660 m_WorkQueue.Enqueue(moreWork); 511 //Recreate them from backend files
661 m_log.Debug("[CONTENT MANAGEMENT] rot"); 512 foreach(Scene currScene in proximitySceneList)
662 } 513 {
663 514 model.UpdateCMEntities(currScene);
664 protected void UpdateMultipleScale(uint localID, LLVector3 scale, IClientAPI remoteClient) 515 view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
665 { 516 }
666 Work moreWork = new Work(); 517
667 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE; 518 //Display new objects to users1
668 moreWork.LocalId = localID; 519 view.DisplayRecentChanges();
669 m_WorkQueue.Enqueue(moreWork); 520 view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
670 m_log.Debug("[CONTENT MANAGEMENT]scale"); 521 m_state &= ~(State.DIRTY);
671 } 522 m_state |= State.SHOWING_CHANGES;
672 523 }
673 protected void UpdateNewParts(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape, 524 }
674 byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID, 525
675 byte RayEndIsIntersection) 526 /// <summary>
676 { 527 /// Only called from within the SimChat method.
677 Work moreWork = new Work(); 528 /// </summary>
678 moreWork.Type = WorkType.PRIMITIVEADDED; 529 protected void diffmode(Scene scene, CMModel model, CMView view)
679 moreWork.UUID = ownerID; 530 {
680 m_WorkQueue.Enqueue(moreWork); 531 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
681 m_log.Debug("[CONTENT MANAGEMENT] new parts"); 532
682 } 533 if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
683 } 534 {
684} 535 view.SendSimChatMessage(scene, "Hiding all meta objects.");
536 view.HideAllMetaEntities();
537 view.HideAllAuras();
538 view.SendSimChatMessage(scene, "Diff-mode = OFF");
539
540 m_state &= ~State.SHOWING_CHANGES;
541 return;
542 }
543 else // TURN ON
544 {
545 if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
546 {
547 view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
548 //Hide objects from users and Forget about them
549 view.HideAllMetaEntities();
550 view.HideAllAuras();
551 model.DeleteAllMetaObjects();
552 //Recreate them from backend files
553 foreach(Object currScene in m_sceneList.Values)
554 model.UpdateCMEntities((Scene) currScene);
555 }
556 else if ((m_state & State.DIRTY) != 0) {
557 view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
558 foreach(Scene currScene in proximitySceneList)
559 model.UpdateCMEntities(currScene);
560 }
561
562 view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
563 foreach(Scene currScene in proximitySceneList)
564 model.CheckForNewEntitiesMissingAuras(currScene);
565 view.DisplayRecentChanges();
566
567 view.SendSimChatMessage(scene, "Diff-mode = ON");
568 m_state |= State.SHOWING_CHANGES;
569 m_state &= ~State.DIRTY;
570 }
571 }
572
573 /// <summary>
574 /// Only called from within the SimChat method. Hides all auras and meta entities,
575 /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
576 /// then lets the view update the clients of the new objects.
577 /// </summary>
578 protected void rollback(Scene scene, CMModel model, CMView view)
579 {
580 if ((m_state & State.SHOWING_CHANGES) > 0)
581 {
582 view.HideAllAuras();
583 view.HideAllMetaEntities();
584 }
585
586 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity( m_sceneList, scene);
587 foreach(Scene currScene in proximitySceneList)
588 model.RollbackRegion(currScene);
589
590 if ((m_state & State.DIRTY) != 0 )
591 {
592 model.DeleteAllMetaObjects();
593 foreach(Scene currScene in proximitySceneList)
594 model.UpdateCMEntities(currScene);
595 }
596
597 if ((m_state & State.SHOWING_CHANGES) > 0)
598 view.DisplayRecentChanges();
599 }
600
601 #endregion Protected Methods
602
603 #region Public Methods
604
605 /// <summary>
606 /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
607 /// </summary>
608 /// <param name="scene">
609 /// A <see cref="Scene"/>
610 /// </param>
611 public void RegisterNewRegion(Scene scene)
612 {
613 m_sceneList.Add(scene.RegionInfo.RegionID, scene);
614
615 m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
616 m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
617
618 scene.EventManager.OnNewClient += StartManaging;
619 scene.EventManager.OnRemovePresence += StopManaging;
620 // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
621 scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
622 }
623
624 /// <summary>
625 /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
626 /// </summary>
627 public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
628 {
629 if (e.Channel != channel)
630 return;
631 if (e.Sender == null)
632 return;
633
634 m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
635
636 IClientAPI client = e.Sender;
637 Scene scene = (Scene) e.Scene;
638 string message = e.Message;
639 string[] args = e.Message.Split(new char[] {' '});
640
641 ScenePresence avatar = scene.GetScenePresence(client.AgentId);
642
643 if (!(m_estateModule.IsManager(avatar.UUID)))
644 {
645 m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
646 view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
647 return;
648 }
649
650 switch(args[0])
651 {
652 case "ci":
653 case "commit":
654 commit(message, scene, model, view);
655 break;
656 case "dm":
657 case "diff-mode":
658 diffmode(scene, model, view);
659 break;
660 case "rb":
661 case "rollback":
662 rollback(scene, model, view);
663 break;
664 case "help":
665 m_view.DisplayHelpMenu(scene);
666 break;
667 default:
668 view.SendSimChatMessage(scene, "Command not found: " + args[0]);
669 break;
670 }
671 }
672
673 #endregion Public Methods
674
675 #region Other
676
677 /// <value>
678 /// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk.
679 /// </value>
680 [Flags]
681 private enum State
682 {
683 NONE = 0,
684 DIRTY = 1, // The meta entities may not correctly represent the last revision.
685 SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
686 }
687
688 /// <value>
689 /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
690 /// </value>
691 private struct Work
692 {
693 #region Fields
694
695 public Object Data1; //Just space for holding data.
696 public Object Data2; //Just more space for holding data.
697 public uint LocalId; //Convenient
698 public WorkType Type;
699 public LLUUID UUID; //Convenient
700
701 #endregion Fields
702 }
703
704 /// <value>
705 /// Identifies what the data in struct Work should be used for.
706 /// </value>
707 private enum WorkType
708 {
709 NONE,
710 OBJECTATTRIBUTECHANGE,
711 PRIMITIVEADDED,
712 OBJECTDUPLICATED,
713 OBJECTKILLED,
714 UNDODID,
715 NEWCLIENT,
716 SIMCHAT
717 }
718
719 #endregion Other
720 }
721} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs
index 9f50e23..2383a6d 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMEntityCollection.cs
@@ -1,148 +1,169 @@
1#region Header
2
1// CMEntityCollection.cs created with MonoDevelop 3// CMEntityCollection.cs created with MonoDevelop
2// User: bongiojp at 10:09 AM 7/7/2008 4// User: bongiojp at 10:09 AM 7/7/2008
3// 5//
4// Creates, Deletes, Stores ContentManagementEntities 6// Creates, Deletes, Stores ContentManagementEntities
5// 7//
6 8
9#endregion Header
7 10
8using System; 11using System;
9using System.Collections.Generic;
10using System.Collections; 12using System.Collections;
13using System.Collections.Generic;
14using System.Threading;
15
11using libsecondlife; 16using libsecondlife;
17
12using Nini.Config; 18using Nini.Config;
19
13using OpenSim; 20using OpenSim;
14using OpenSim.Framework; 21using OpenSim.Framework;
15using OpenSim.Region.Environment.Interfaces; 22using OpenSim.Region.Environment.Interfaces;
16using OpenSim.Region.Environment.Scenes; 23using OpenSim.Region.Environment.Scenes;
17using log4net;
18using OpenSim.Region.Physics.Manager; 24using OpenSim.Region.Physics.Manager;
25
26using log4net;
27
19using Axiom.Math; 28using Axiom.Math;
20using System.Threading;
21 29
22namespace OpenSim.Region.Environment.Modules.ContentManagement 30namespace OpenSim.Region.Environment.Modules.ContentManagement
23{ 31{
24 32 public class CMEntityCollection
25 public class CMEntityCollection 33 {
26 { 34 #region Fields
27 // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 35
28 36 // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
29 // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or 37 // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or
30 // old versions of deleted SceneObjectGroups will be stored in this hash table. 38 // old versions of deleted SceneObjectGroups will be stored in this hash table.
31 // The LLUUID keys are from the SceneObjectGroup RootPart UUIDs 39 // The LLUUID keys are from the SceneObjectGroup RootPart UUIDs
32 protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //LLUUID to ContentManagementEntity 40 protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //LLUUID to ContentManagementEntity
33 41
34 // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable 42 // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable
35 // The LLUUID keys are from the SceneObjectPart that they are supposed to be on. 43 // The LLUUID keys are from the SceneObjectPart that they are supposed to be on.
36 protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //LLUUID to AuraMetaEntity 44 protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //LLUUID to AuraMetaEntity
37 45
38 public Hashtable Entities 46 #endregion Fields
39 { 47
40 get { return m_CMEntityHash; } 48 #region Constructors
41 } 49
42 50 public CMEntityCollection()
43 public Hashtable Auras 51 {
44 { 52 }
45 get {return m_NewlyCreatedEntityAura; } 53
46 } 54 #endregion Constructors
47 55
48 public CMEntityCollection() 56 #region Public Properties
49 {} 57
50 58 public Hashtable Auras
51 public bool AddAura(ContentManagementEntity aura) 59 {
52 { 60 get {return m_NewlyCreatedEntityAura; }
53 if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID)) 61 }
54 return false; 62
55 m_NewlyCreatedEntityAura.Add(aura.UUID, aura); 63 public Hashtable Entities
56 return true; 64 {
57 } 65 get { return m_CMEntityHash; }
58 66 }
59 public bool AddEntity(ContentManagementEntity ent) 67
60 { 68 #endregion Public Properties
61 if (m_CMEntityHash.ContainsKey(ent.UUID)) 69
62 return false; 70 #region Public Methods
63 m_CMEntityHash.Add(ent.UUID, ent); 71
64 return true; 72 public bool AddAura(ContentManagementEntity aura)
65 } 73 {
66 74 if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID))
67 public bool RemoveNewlyCreatedEntityAura(LLUUID uuid) 75 return false;
68 { 76 m_NewlyCreatedEntityAura.Add(aura.UUID, aura);
69 if (!m_NewlyCreatedEntityAura.ContainsKey(uuid)) 77 return true;
70 return false; 78 }
71 m_NewlyCreatedEntityAura.Remove(uuid); 79
72 return true; 80 public bool AddEntity(ContentManagementEntity ent)
73 } 81 {
74 82 if (m_CMEntityHash.ContainsKey(ent.UUID))
75 public bool RemoveEntity(LLUUID uuid) 83 return false;
76 { 84 m_CMEntityHash.Add(ent.UUID, ent);
77 if (!m_CMEntityHash.ContainsKey(uuid)) 85 return true;
78 return false; 86 }
79 m_CMEntityHash.Remove(uuid); 87
80 return true; 88 // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
81 } 89 public System.Collections.ArrayList CheckForMissingEntities(System.Collections.Generic.List<EntityBase> currList)
82 90 {
83 public void ClearAll() 91 System.Collections.ArrayList missingList = new System.Collections.ArrayList();
84 { 92 SceneObjectGroup temp = null;
85 m_CMEntityHash.Clear(); 93 foreach( EntityBase currObj in currList )
86 m_NewlyCreatedEntityAura.Clear(); 94 {
87 } 95 if (! (currObj is SceneObjectGroup))
88 96 continue;
89 97 temp = (SceneObjectGroup) currObj;
90 98
91 // Old uuid and new sceneobjectgroup 99 if (m_CMEntityHash.ContainsKey(temp.UUID))
92 public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part) 100 {
93 { 101 foreach(SceneObjectPart part in temp.Children.Values)
94 AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene, 102 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
95 part.ParentGroup.Scene.PrimIDAllocate(), 103 missingList.Add(part);
96 part.GetWorldPosition(), 104 }
97 MetaEntity.TRANSLUCENT, 105 else //Entire group is missing from revision. (and is a new part in region)
98 new LLVector3(0,254,0), 106 {
99 part.Scale 107 foreach(SceneObjectPart part in temp.Children.Values)
100 ); 108 missingList.Add(part);
101 m_NewlyCreatedEntityAura.Add(part.UUID, ent); 109 }
102 return ent; 110 }
103 } 111 return missingList;
104 112 }
105 // Old uuid and new sceneobjectgroup 113
106 public ContentManagementEntity CreateNewEntity(SceneObjectGroup group) 114 public void ClearAll()
107 { 115 {
108 ContentManagementEntity ent = new ContentManagementEntity(group, false); 116 m_CMEntityHash.Clear();
109 m_CMEntityHash.Add(group.UUID, ent); 117 m_NewlyCreatedEntityAura.Clear();
110 return ent; 118 }
111 } 119
112 120 // Old uuid and new sceneobjectgroup
113 public ContentManagementEntity CreateNewEntity(String xml, Scene scene) 121 public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
114 { 122 {
115 ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false); 123 AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
116 if (ent == null) 124 part.ParentGroup.Scene.PrimIDAllocate(),
117 return null; 125 part.GetWorldPosition(),
118 m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent); 126 MetaEntity.TRANSLUCENT,
119 return ent; 127 new LLVector3(0,254,0),
120 } 128 part.Scale
121 129 );
122 // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash 130 m_NewlyCreatedEntityAura.Add(part.UUID, ent);
123 public System.Collections.ArrayList CheckForMissingEntities(System.Collections.Generic.List<EntityBase> currList) 131 return ent;
124 { 132 }
125 System.Collections.ArrayList missingList = new System.Collections.ArrayList(); 133
126 SceneObjectGroup temp = null; 134 // Old uuid and new sceneobjectgroup
127 foreach( EntityBase currObj in currList ) 135 public ContentManagementEntity CreateNewEntity(SceneObjectGroup group)
128 { 136 {
129 if (! (currObj is SceneObjectGroup)) 137 ContentManagementEntity ent = new ContentManagementEntity(group, false);
130 continue; 138 m_CMEntityHash.Add(group.UUID, ent);
131 temp = (SceneObjectGroup) currObj; 139 return ent;
132 140 }
133 if (m_CMEntityHash.ContainsKey(temp.UUID)) 141
134 { 142 public ContentManagementEntity CreateNewEntity(String xml, Scene scene)
135 foreach(SceneObjectPart part in temp.Children.Values) 143 {
136 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) 144 ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false);
137 missingList.Add(part); 145 if (ent == null)
138 } 146 return null;
139 else //Entire group is missing from revision. (and is a new part in region) 147 m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent);
140 { 148 return ent;
141 foreach(SceneObjectPart part in temp.Children.Values) 149 }
142 missingList.Add(part); 150
143 } 151 public bool RemoveEntity(LLUUID uuid)
144 } 152 {
145 return missingList; 153 if (!m_CMEntityHash.ContainsKey(uuid))
146 } 154 return false;
147 } 155 m_CMEntityHash.Remove(uuid);
148} 156 return true;
157 }
158
159 public bool RemoveNewlyCreatedEntityAura(LLUUID uuid)
160 {
161 if (!m_NewlyCreatedEntityAura.ContainsKey(uuid))
162 return false;
163 m_NewlyCreatedEntityAura.Remove(uuid);
164 return true;
165 }
166
167 #endregion Public Methods
168 }
169} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs
index a47f83a..3355fa3 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs
@@ -1,47 +1,128 @@
1#region Header
2
1// CMModel.cs 3// CMModel.cs
2// User: bongiojp 4// User: bongiojp
3// 5//
4// 6//
5 7
8#endregion Header
9
6using System; 10using System;
7using System.Collections.Generic;
8using System.Collections; 11using System.Collections;
12using System.Collections.Generic;
13using System.Diagnostics;
14
9using libsecondlife; 15using libsecondlife;
16
10using OpenSim; 17using OpenSim;
11using OpenSim.Framework; 18using OpenSim.Framework;
12using OpenSim.Region.Environment.Interfaces; 19using OpenSim.Region.Environment.Interfaces;
13using OpenSim.Region.Environment.Scenes; 20using OpenSim.Region.Environment.Scenes;
14using log4net;
15using OpenSim.Region.Physics.Manager; 21using OpenSim.Region.Physics.Manager;
22
23using log4net;
24
16using Axiom.Math; 25using Axiom.Math;
17using System.Diagnostics;
18 26
19namespace OpenSim.Region.Environment.Modules.ContentManagement 27namespace OpenSim.Region.Environment.Modules.ContentManagement
20{ 28{
21
22 public class CMModel 29 public class CMModel
23 { 30 {
31 #region Static Fields
32
24 static float TimeToUpdate = 0; 33 static float TimeToUpdate = 0;
25 static float TimeToConvertXml = 0; 34 static float TimeToConvertXml = 0;
26
27 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 35 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
28 36
29 IContentDatabase m_database = null; 37 #endregion Static Fields
30 38
39 #region Fields
40
31 /// <value> 41 /// <value>
32 /// The class that contains all auras and metaentities used in the CMS. 42 /// The class that contains all auras and metaentities used in the CMS.
33 /// </value> 43 /// </value>
34 CMEntityCollection m_MetaEntityCollection = new CMEntityCollection(); 44 CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
35 45 IContentDatabase m_database = null;
46
47 #endregion Fields
48
49 #region Constructors
50
51 public CMModel()
52 {
53 }
54
55 #endregion Constructors
56
57 #region Public Properties
58
36 public CMEntityCollection MetaEntityCollection 59 public CMEntityCollection MetaEntityCollection
37 { 60 {
38 get { return m_MetaEntityCollection; } 61 get { return m_MetaEntityCollection; }
39 } 62 }
40 63
41 public CMModel() 64 #endregion Public Properties
65
66 #region Public Methods
67
68 /// <summary>
69 /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity
70 /// it is a new part that must have a green aura (for diff mode).
71 /// Returns list of ContentManagementEntities
72 /// </summary>
73 public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
74 {
75 ArrayList missingList = null;
76 ArrayList newList = new ArrayList();
77
78 m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
79
80 //Check if the current scene has groups not included in the current list of MetaEntities
81 //If so, then the current scene's parts that are new should be marked green.
82 missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
83
84 foreach(Object missingPart in missingList)
85 {
86 if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
87 continue;
88 newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
89 }
90 m_log.Info("Number of missing objects found: " + newList.Count);
91 return newList;
92 }
93
94 /// <summary>
95 /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
96 /// </summary>
97 public void CommitRegion(Scene scene, String logMessage)
42 { 98 {
99 m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
100 m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
101 m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName );
43 } 102 }
44 103
104 public void DeleteAllMetaObjects()
105 {
106 m_MetaEntityCollection.ClearAll();
107 }
108
109 public ContentManagementEntity FindMetaEntityAffectedByUndo(LLUUID uuid)
110 {
111 ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
112 return ent;
113 }
114
115 //-------------------------------- HELPERS --------------------------------------------------------------------//
116 public ContentManagementEntity GetMetaGroupByPrim(LLUUID uuid)
117 {
118 foreach (Object ent in m_MetaEntityCollection.Entities.Values)
119 {
120 if (((ContentManagementEntity)ent).HasChildPrim(uuid))
121 return (ContentManagementEntity)ent;
122 }
123 return null;
124 }
125
45 public void Initialise(string database) 126 public void Initialise(string database)
46 { 127 {
47 if (database == "FileSystemDatabase") 128 if (database == "FileSystemDatabase")
@@ -49,12 +130,12 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
49 else if (database == "GitDatabase") 130 else if (database == "GitDatabase")
50 m_database = new GitDatabase(); 131 m_database = new GitDatabase();
51 } 132 }
52 133
53 public void InitialiseDatabase(Scene scene, string dir) 134 public void InitialiseDatabase(Scene scene, string dir)
54 { 135 {
55 m_database.Initialise(scene, dir); 136 m_database.Initialise(scene, dir);
56 } 137 }
57 138
58 /// <summary> 139 /// <summary>
59 /// Should be called just once to finish initializing the database. 140 /// Should be called just once to finish initializing the database.
60 /// </summary> 141 /// </summary>
@@ -62,13 +143,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
62 { 143 {
63 m_database.PostInitialise(); 144 m_database.PostInitialise();
64 } 145 }
65 146
66 public ContentManagementEntity FindMetaEntityAffectedByUndo(LLUUID uuid)
67 {
68 ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
69 return ent;
70 }
71
72 /// <summary> 147 /// <summary>
73 /// Removes the green aura when an a new scene object group is deleted. 148 /// Removes the green aura when an a new scene object group is deleted.
74 /// </summary> 149 /// </summary>
@@ -79,17 +154,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
79 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) 154 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
80 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); 155 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
81 } 156 }
82 157
83 /// <summary>
84 /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
85 /// </summary>
86 public void CommitRegion(Scene scene, String logMessage)
87 {
88 m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
89 m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
90 m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName );
91 }
92
93 /// <summary> 158 /// <summary>
94 /// Retrieves the latest revision of a region in xml form, 159 /// Retrieves the latest revision of a region in xml form,
95 /// converts it to scene object groups and scene presences, 160 /// converts it to scene object groups and scene presences,
@@ -105,20 +170,20 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
105 Dictionary<LLUUID, EntityBase> ReplacementList = new Dictionary<LLUUID,EntityBase>(); 170 Dictionary<LLUUID, EntityBase> ReplacementList = new Dictionary<LLUUID,EntityBase>();
106 int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID); 171 int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
107 EntityBase[] searchArray; 172 EntityBase[] searchArray;
108 173
109 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision); 174 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
110 if (xmllist == null) 175 if (xmllist == null)
111 { 176 {
112 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ")."); 177 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
113 return; 178 return;
114 } 179 }
115 180
116 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ")."); 181 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
117 m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count); 182 m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
118 m_log.Info("[CMMODEL]: Converting scene entities list to specified revision."); 183 m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
119 184
120 m_log.ErrorFormat("[CMMODEL]: 1"); 185 m_log.ErrorFormat("[CMMODEL]: 1");
121 186
122 foreach (string xml in xmllist) 187 foreach (string xml in xmllist)
123 { 188 {
124 try{ 189 try{
@@ -143,7 +208,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
143 { 208 {
144 if (entity == null) 209 if (entity == null)
145 continue; 210 continue;
146 211
147 if (entity is ScenePresence) 212 if (entity is ScenePresence)
148 { 213 {
149 ReplacementList.Add(entity.UUID, entity); 214 ReplacementList.Add(entity.UUID, entity);
@@ -162,7 +227,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
162 } 227 }
163 break; 228 break;
164 } 229 }
165 230
166 foreach(LLUUID uuid in deleteListUUIDs.Keys) 231 foreach(LLUUID uuid in deleteListUUIDs.Keys)
167 { 232 {
168 try 233 try
@@ -179,7 +244,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
179 m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e); 244 m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
180 } 245 }
181 } 246 }
182 247
183 lock (scene) 248 lock (scene)
184 { 249 {
185 scene.Entities = ReplacementList; 250 scene.Entities = ReplacementList;
@@ -191,7 +256,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
191 { 256 {
192 if (!(ent is SceneObjectGroup)) 257 if (!(ent is SceneObjectGroup))
193 continue; 258 continue;
194 259
195 if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) LLObject.ObjectFlags.Phantom) == 0) 260 if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) LLObject.ObjectFlags.Phantom) == 0)
196 ((SceneObjectGroup)ent).ApplyPhysics(true); 261 ((SceneObjectGroup)ent).ApplyPhysics(true);
197 ((SceneObjectGroup)ent).AttachToBackup(); 262 ((SceneObjectGroup)ent).AttachToBackup();
@@ -206,32 +271,6 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
206 m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup."); 271 m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
207 scene.Backup(); 272 scene.Backup();
208 } 273 }
209
210 /// <summary>
211 /// Detects if a scene object group from the scene list has moved or changed scale. The green aura
212 /// that surrounds the object is then moved or scaled with the group.
213 /// </summary>
214 public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
215 {
216 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
217 if (group == null)
218 return null;
219 foreach(SceneObjectPart part in group.Children.Values)
220 {
221 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
222 {
223 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new LLVector3(0,254,0), part.Scale);
224 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
225 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
226 }
227 }
228 return auraList;
229 }
230
231 public void DeleteAllMetaObjects()
232 {
233 m_MetaEntityCollection.ClearAll();
234 }
235 274
236 /// <summary> 275 /// <summary>
237 /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences 276 /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
@@ -257,53 +296,37 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
257 TimeToConvertXml += y.ElapsedMilliseconds; 296 TimeToConvertXml += y.ElapsedMilliseconds;
258 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds); 297 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
259 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml); 298 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
260 299
261 m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras"); 300 m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
262 CheckForNewEntitiesMissingAuras(scene); 301 CheckForNewEntitiesMissingAuras(scene);
263 302
264 x.Stop(); 303 x.Stop();
265 TimeToUpdate += x.ElapsedMilliseconds; 304 TimeToUpdate += x.ElapsedMilliseconds;
266 m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds); 305 m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
267 m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate); 306 m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
268
269 } 307 }
270 308
271 /// <summary> 309 /// <summary>
272 /// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity 310 /// Detects if a scene object group from the scene list has moved or changed scale. The green aura
273 /// it is a new part that must have a green aura (for diff mode). 311 /// that surrounds the object is then moved or scaled with the group.
274 /// Returns list of ContentManagementEntities
275 /// </summary> 312 /// </summary>
276 public ArrayList CheckForNewEntitiesMissingAuras(Scene scene) 313 public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
277 {
278 ArrayList missingList = null;
279 ArrayList newList = new ArrayList();
280
281 m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
282
283 //Check if the current scene has groups not included in the current list of MetaEntities
284 //If so, then the current scene's parts that are new should be marked green.
285 missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
286
287 foreach(Object missingPart in missingList)
288 {
289 if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
290 continue;
291 newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
292 }
293 m_log.Info("Number of missing objects found: " + newList.Count);
294 return newList;
295 }
296
297 //-------------------------------- HELPERS --------------------------------------------------------------------//
298
299 public ContentManagementEntity GetMetaGroupByPrim(LLUUID uuid)
300 { 314 {
301 foreach (Object ent in m_MetaEntityCollection.Entities.Values) 315 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
316 if (group == null)
317 return null;
318 foreach(SceneObjectPart part in group.Children.Values)
302 { 319 {
303 if (((ContentManagementEntity)ent).HasChildPrim(uuid)) 320 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
304 return (ContentManagementEntity)ent; 321 {
322 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new LLVector3(0,254,0), part.Scale);
323 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
324 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
325 }
305 } 326 }
306 return null; 327 return auraList;
307 } 328 }
308 } 329
330 #endregion Public Methods
331 }
309} \ No newline at end of file 332} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs
index f8b0ec9..f801f67 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMView.cs
@@ -1,156 +1,181 @@
1#region Header
2
1// CMView.cs created with MonoDevelop 3// CMView.cs created with MonoDevelop
2// User: bongiojp at 11:57 AM 7/3/2008 4// User: bongiojp at 11:57 AM 7/3/2008
3// 5//
4// To change standard headers go to Edit->Preferences->Coding->Standard Headers 6// To change standard headers go to Edit->Preferences->Coding->Standard Headers
5// 7//
6 8
9#endregion Header
10
7using System; 11using System;
8using System.Collections.Generic;
9using System.Collections; 12using System.Collections;
13using System.Collections.Generic;
14
10using libsecondlife; 15using libsecondlife;
16
11using OpenSim; 17using OpenSim;
12using OpenSim.Framework; 18using OpenSim.Framework;
13using OpenSim.Region.Environment.Interfaces; 19using OpenSim.Region.Environment.Interfaces;
14using OpenSim.Region.Environment.Scenes; 20using OpenSim.Region.Environment.Scenes;
15using log4net;
16using OpenSim.Region.Physics.Manager; 21using OpenSim.Region.Physics.Manager;
22
23using log4net;
24
17using Axiom.Math; 25using Axiom.Math;
18 26
19namespace OpenSim.Region.Environment.Modules.ContentManagement 27namespace OpenSim.Region.Environment.Modules.ContentManagement
20{ 28{
21 29 public class CMView
22 public class CMView 30 {
23 { 31 #region Static Fields
24 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 32
25 CMModel m_model = null; 33 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
26 34
27 public CMView() 35 #endregion Static Fields
28 {} 36
29 37 #region Fields
30 public void Initialise(CMModel model) 38
31 { 39 CMModel m_model = null;
32 m_model = model; 40
33 } 41 #endregion Fields
34 42
35 public void SendMetaEntitiesToNewClient(IClientAPI client) 43 #region Constructors
36 { 44
37 } 45 public CMView()
38 46 {
39 /// <summary> 47 }
40 /// update all clients of red/green/blue auras and meta entities that the model knows about. 48
41 /// </summary> 49 #endregion Constructors
42 public void DisplayRecentChanges() 50
43 { 51 #region Public Methods
44 m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects."); 52
45 DisplayEntities(m_model.MetaEntityCollection); 53 // Auras To
46 DisplayAuras(m_model.MetaEntityCollection); 54 public void DisplayAuras(CMEntityCollection auraCollection)
47 } 55 {
48 56 foreach( Object ent in auraCollection.Auras.Values)
49 /// <summary> 57 ((AuraMetaEntity)ent).SendFullUpdateToAll();
50 /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted. 58 }
51 /// If it's a new scene object, any green aura attached to it is deleted. 59
52 /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will 60 // Auras To Client
53 /// figure out that there should be a red aura and not a blue aura/beam. 61 public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client)
54 /// </summary> 62 {
55 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) 63 foreach( Object ent in auraCollection.Auras.Values)
56 { 64 ((AuraMetaEntity)ent).SendFullUpdate(client);
57 // Deal with revisioned parts that have been deleted. 65 }
58 if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID)) 66
59 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); 67 // Auras from List To ALL
60 68 public void DisplayAuras(ArrayList list)
61 // Deal with new parts not revisioned that have been deleted. 69 {
62 foreach(SceneObjectPart part in group.Children.Values) 70 foreach( Object ent in list)
63 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) 71 {
64 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); 72 m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW");
65 } 73 ((AuraMetaEntity)ent).SendFullUpdateToAll();
66 74 }
67 // Auras To 75 }
68 public void DisplayAuras(CMEntityCollection auraCollection) 76
69 { 77 // Entities to ALL
70 foreach( Object ent in auraCollection.Auras.Values) 78 public void DisplayEntities(CMEntityCollection entityCollection)
71 ((AuraMetaEntity)ent).SendFullUpdateToAll(); 79 {
72 } 80 foreach( Object ent in entityCollection.Entities.Values)
73 81 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
74 // Entities to ALL 82 }
75 public void DisplayEntities(CMEntityCollection entityCollection) 83
76 { 84 // Entities to Client
77 foreach( Object ent in entityCollection.Entities.Values) 85 public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client)
78 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); 86 {
79 } 87 foreach( Object ent in entityCollection.Entities.Values)
80 88 ((ContentManagementEntity)ent).SendFullDiffUpdate(client);
81 // Auras To Client 89 }
82 public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client) 90
83 { 91 // Entities from List to ALL
84 foreach( Object ent in auraCollection.Auras.Values) 92 public void DisplayEntities(ArrayList list)
85 ((AuraMetaEntity)ent).SendFullUpdate(client); 93 {
86 } 94 foreach( Object ent in list)
87 95 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
88 // Entities to Client 96 }
89 public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client) 97
90 { 98 // Entity to ALL
91 foreach( Object ent in entityCollection.Entities.Values) 99 public void DisplayEntity(ContentManagementEntity ent)
92 ((ContentManagementEntity)ent).SendFullDiffUpdate(client); 100 {
93 } 101 ent.SendFullDiffUpdateToAll();
94 102 }
95 // Entity to ALL 103
96 public void DisplayEntity(ContentManagementEntity ent) 104 public void DisplayHelpMenu(Scene scene)
97 { 105 {
98 ent.SendFullDiffUpdateToAll(); 106 string menu = "Menu:\n";
99 } 107 menu += "commit (ci) - saves current state of the region to a database on the server\n";
100 108 menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n";
101 public void DisplayMetaEntity(LLUUID uuid) 109 SendSimChatMessage(scene, menu);
102 { 110 }
103 ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid); 111
104 if (group != null) 112 public void DisplayMetaEntity(LLUUID uuid)
105 group.SendFullDiffUpdateToAll(); 113 {
106 } 114 ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid);
107 115 if (group != null)
108 // Auras from List To ALL 116 group.SendFullDiffUpdateToAll();
109 public void DisplayAuras(ArrayList list) 117 }
110 { 118
111 foreach( Object ent in list) 119 /// <summary>
112 { 120 /// update all clients of red/green/blue auras and meta entities that the model knows about.
113 m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW"); 121 /// </summary>
114 ((AuraMetaEntity)ent).SendFullUpdateToAll(); 122 public void DisplayRecentChanges()
115 } 123 {
116 } 124 m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects.");
117 125 DisplayEntities(m_model.MetaEntityCollection);
118 // Entities from List to ALL 126 DisplayAuras(m_model.MetaEntityCollection);
119 public void DisplayEntities(ArrayList list) 127 }
120 { 128
121 foreach( Object ent in list) 129 public void Hide(ContentManagementEntity ent)
122 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll(); 130 {
123 } 131 ent.HideFromAll();
124 132 }
125 public void DisplayHelpMenu(Scene scene) 133
126 { 134 public void HideAllAuras()
127 string menu = "Menu:\n"; 135 {
128 menu += "commit (ci) - saves current state of the region to a database on the server\n"; 136 foreach(Object obj in m_model.MetaEntityCollection.Auras.Values)
129 menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n"; 137 ((MetaEntity)obj).HideFromAll();
130 SendSimChatMessage(scene, menu); 138 }
131 } 139
132 140 public void HideAllMetaEntities()
133 public void SendSimChatMessage(Scene scene, string message) 141 {
134 { 142 foreach(Object obj in m_model.MetaEntityCollection.Entities.Values)
135 scene.SimChat(Helpers.StringToField(message), 143 ((ContentManagementEntity)obj).HideFromAll();
136 ChatTypeEnum.Broadcast, 0, new LLVector3(0,0,0), "Content Manager", LLUUID.Zero, false); 144 }
137 } 145
138 146 public void Initialise(CMModel model)
139 public void Hide(ContentManagementEntity ent) 147 {
140 { 148 m_model = model;
141 ent.HideFromAll(); 149 }
142 } 150
143 151 /// <summary>
144 public void HideAllMetaEntities() 152 /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted.
145 { 153 /// If it's a new scene object, any green aura attached to it is deleted.
146 foreach(Object obj in m_model.MetaEntityCollection.Entities.Values) 154 /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will
147 ((ContentManagementEntity)obj).HideFromAll(); 155 /// figure out that there should be a red aura and not a blue aura/beam.
148 } 156 /// </summary>
149 157 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
150 public void HideAllAuras() 158 {
151 { 159 // Deal with revisioned parts that have been deleted.
152 foreach(Object obj in m_model.MetaEntityCollection.Auras.Values) 160 if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID))
153 ((MetaEntity)obj).HideFromAll(); 161 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
154 } 162
155 } 163 // Deal with new parts not revisioned that have been deleted.
156} 164 foreach(SceneObjectPart part in group.Children.Values)
165 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
166 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
167 }
168
169 public void SendMetaEntitiesToNewClient(IClientAPI client)
170 {
171 }
172
173 public void SendSimChatMessage(Scene scene, string message)
174 {
175 scene.SimChat(Helpers.StringToField(message),
176 ChatTypeEnum.Broadcast, 0, new LLVector3(0,0,0), "Content Manager", LLUUID.Zero, false);
177 }
178
179 #endregion Public Methods
180 }
181} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs
index fb9df8f..bdf8560 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs
@@ -1,326 +1,362 @@
1#region Header
2
1// ContentManagementEntity.cs 3// ContentManagementEntity.cs
2// User: bongiojp 4// User: bongiojp
3// 5//
4// 6//
5 7
8#endregion Header
9
6using System; 10using System;
7using System.Collections.Generic; 11using System.Collections.Generic;
8using System.Drawing; 12using System.Drawing;
13
9using libsecondlife; 14using libsecondlife;
15
10using Nini.Config; 16using Nini.Config;
17
11using OpenSim.Framework; 18using OpenSim.Framework;
12using OpenSim.Region.Environment.Interfaces; 19using OpenSim.Region.Environment.Interfaces;
13using OpenSim.Region.Environment.Scenes; 20using OpenSim.Region.Environment.Scenes;
14using log4net;
15using OpenSim.Region.Physics.Manager; 21using OpenSim.Region.Physics.Manager;
22
23using log4net;
24
16using Axiom.Math; 25using Axiom.Math;
17 26
18namespace OpenSim.Region.Environment.Modules.ContentManagement 27namespace OpenSim.Region.Environment.Modules.ContentManagement
19{ 28{
20 public class ContentManagementEntity : MetaEntity 29 public class ContentManagementEntity : MetaEntity
21 { 30 {
22 static float TimeToDiff = 0; 31 #region Static Fields
23 static float TimeToCreateEntities = 0; 32
24 33 static float TimeToDiff = 0;
25 // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different. 34 static float TimeToCreateEntities = 0;
26 // This can come in handy. 35
27 protected SceneObjectGroup m_UnchangedEntity = null; 36 #endregion Static Fields
28 protected Dictionary<LLUUID, BeamMetaEntity> m_BeamEntities = new Dictionary<LLUUID, BeamMetaEntity>(); 37
29 protected Dictionary<LLUUID, AuraMetaEntity> m_AuraEntities = new Dictionary<LLUUID, AuraMetaEntity>(); 38 #region Fields
30 39
31 /// <value> 40 protected Dictionary<LLUUID, AuraMetaEntity> m_AuraEntities = new Dictionary<LLUUID, AuraMetaEntity>();
32 /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list. 41 protected Dictionary<LLUUID, BeamMetaEntity> m_BeamEntities = new Dictionary<LLUUID, BeamMetaEntity>();
33 /// </value> 42
34 bool DiffersFromSceneGroup = false; 43 // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
35 44 // This can come in handy.
36 public SceneObjectGroup UnchangedEntity 45 protected SceneObjectGroup m_UnchangedEntity = null;
37 { 46
38 get { return m_UnchangedEntity; } 47 /// <value>
39 } 48 /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
40 49 /// </value>
41 public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics) : base(Unchanged, false) 50 bool DiffersFromSceneGroup = false;
42 { 51
43 m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false); 52 #endregion Fields
44 } 53
45 54 #region Constructors
46 public ContentManagementEntity(string objectXML, Scene scene, bool physics) : base(objectXML, scene, false) 55
47 { 56 public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
48 m_UnchangedEntity = new SceneObjectGroup(objectXML); 57 : base(Unchanged, false)
49 } 58 {
50 59 m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false);
51 public override void Hide(IClientAPI client) 60 }
52 { 61
53 base.Hide(client); 62 public ContentManagementEntity(string objectXML, Scene scene, bool physics)
54 foreach(MetaEntity group in m_AuraEntities.Values) 63 : base(objectXML, scene, false)
55 group.Hide(client); 64 {
56 foreach(MetaEntity group in m_BeamEntities.Values) 65 m_UnchangedEntity = new SceneObjectGroup(objectXML);
57 group.Hide(client); 66 }
58 } 67
59 68 #endregion Constructors
60 public override void HideFromAll() 69
61 { 70 #region Public Properties
62 base.HideFromAll(); 71
63 foreach(MetaEntity group in m_AuraEntities.Values) 72 public SceneObjectGroup UnchangedEntity
64 group.HideFromAll(); 73 {
65 foreach(MetaEntity group in m_BeamEntities.Values) 74 get { return m_UnchangedEntity; }
66 group.HideFromAll(); 75 }
67 } 76
68 77 #endregion Public Properties
69 public void SendFullDiffUpdateToAll() 78
70 { 79 #region Private Methods
71 FindDifferences(); 80
72 if (DiffersFromSceneGroup) 81 /// <summary>
73 { 82 /// Check if an entitybase list (like that returned by scene.GetEntities() ) contains a group with the rootpart uuid that matches the current uuid.
74 SendFullUpdateToAll(); 83 /// </summary>
75 SendFullAuraUpdateToAll(); 84 private bool ContainsKey(List<EntityBase> list, LLUUID uuid)
76 SendFullBeamUpdateToAll(); 85 {
77 } 86 foreach( EntityBase part in list)
78 } 87 if (part.UUID == uuid)
79 88 return true;
80 public void SendFullDiffUpdate(IClientAPI client) 89 return false;
81 { 90 }
82 FindDifferences(); 91
83 if (DiffersFromSceneGroup) 92 private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, LLUUID uuid)
84 { 93 {
85 SendFullUpdate(client); 94 foreach (EntityBase ent in list)
86 SendFullAuraUpdate(client); 95 {
87 SendFullBeamUpdate(client); 96 if (ent is SceneObjectGroup)
88 } 97 if (ent.UUID == uuid)
89 } 98 return (SceneObjectGroup)ent;
90 99 }
91 public void SendFullBeamUpdate(IClientAPI client) 100 return null;
92 { 101 }
93 if (DiffersFromSceneGroup) 102
94 { 103 #endregion Private Methods
95 foreach(BeamMetaEntity group in m_BeamEntities.Values) 104
96 group.SendFullUpdate(client); 105 #region Public Methods
97 } 106
98 } 107 /// <summary>
99 108 /// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
100 public void SendFullAuraUpdate(IClientAPI client) 109 /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
101 { 110 /// </summary>
102 if (DiffersFromSceneGroup) 111 public void FindDifferences()
103 { 112 {
104 foreach(AuraMetaEntity group in m_AuraEntities.Values) 113 System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities();
105 group.SendFullUpdate(client); 114 DiffersFromSceneGroup = false;
106 } 115 // if group is not contained in scene's list
107 } 116 if(!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
108 117 {
109 public void SendFullBeamUpdateToAll() 118 foreach(SceneObjectPart part in m_UnchangedEntity.Children.Values)
110 { 119 {
111 if (DiffersFromSceneGroup) 120 // if scene list no longer contains this part, display translucent part and mark with red aura
112 { 121 if(! ContainsKey(sceneEntityList, part.UUID))
113 foreach(BeamMetaEntity group in m_BeamEntities.Values) 122 {
114 group.SendFullUpdateToAll(); 123 // if already displaying a red aura over part, make sure its red
115 } 124 if (m_AuraEntities.ContainsKey(part.UUID))
116 } 125 {
117 126 m_AuraEntities[part.UUID].SetAura(new LLVector3(254,0,0), part.Scale);
118 public void SendFullAuraUpdateToAll() 127 }
119 { 128 else
120 if (DiffersFromSceneGroup) 129 {
121 { 130 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
122 foreach(AuraMetaEntity group in m_AuraEntities.Values) 131 m_Entity.Scene.PrimIDAllocate(),
123 group.SendFullUpdateToAll(); 132 part.GetWorldPosition(),
124 } 133 MetaEntity.TRANSLUCENT,
125 } 134 new LLVector3(254,0,0),
126 135 part.Scale
127 /// <summary> 136 );
128 /// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately. 137 m_AuraEntities.Add(part.UUID, auraGroup);
129 /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately. 138 }
130 /// </summary> 139 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
131 public void FindDifferences() 140 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
132 { 141 }
133 System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities(); 142 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
134 DiffersFromSceneGroup = false; 143 }
135 // if group is not contained in scene's list 144
136 if(!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) 145 // a deleted part has no where to point a beam particle system,
137 { 146 // if a metapart had a particle system (maybe it represented a moved part) remove it
138 foreach(SceneObjectPart part in m_UnchangedEntity.Children.Values) 147 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
139 { 148 {
140 // if scene list no longer contains this part, display translucent part and mark with red aura 149 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
141 if(! ContainsKey(sceneEntityList, part.UUID)) 150 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
142 { 151 }
143 // if already displaying a red aura over part, make sure its red 152
144 if (m_AuraEntities.ContainsKey(part.UUID)) 153 DiffersFromSceneGroup = true;
145 { 154 }
146 m_AuraEntities[part.UUID].SetAura(new LLVector3(254,0,0), part.Scale); 155 // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
147 } 156 else
148 else 157 {
149 { 158 MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
150 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, 159 }
151 m_Entity.Scene.PrimIDAllocate(), 160 }
152 part.GetWorldPosition(), 161
153 MetaEntity.TRANSLUCENT, 162 /// <summary>
154 new LLVector3(254,0,0), 163 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
155 part.Scale 164 /// </summary>
156 ); 165 public bool HasChildPrim(LLUUID uuid)
157 m_AuraEntities.Add(part.UUID, auraGroup); 166 {
158 } 167 if (m_UnchangedEntity.Children.ContainsKey(uuid))
159 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); 168 return true;
160 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); 169 return false;
161 } 170 }
162 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id 171
163 } 172 /// <summary>
164 173 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
165 // a deleted part has no where to point a beam particle system, 174 /// </summary>
166 // if a metapart had a particle system (maybe it represented a moved part) remove it 175 public bool HasChildPrim(uint localID)
167 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) 176 {
168 { 177 foreach( SceneObjectPart part in m_UnchangedEntity.Children.Values)
169 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); 178 if ( part.LocalId == localID )
170 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); 179 return true;
171 } 180 return false;
172 181 }
173 DiffersFromSceneGroup = true; 182
174 } 183 public override void Hide(IClientAPI client)
175 // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately 184 {
176 else 185 base.Hide(client);
177 { 186 foreach(MetaEntity group in m_AuraEntities.Values)
178 MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID)); 187 group.Hide(client);
179 } 188 foreach(MetaEntity group in m_BeamEntities.Values)
180 } 189 group.Hide(client);
181 190 }
182 /// <summary> 191
183 /// Returns true if there was a change between meta entity and the entity group, false otherwise. 192 public override void HideFromAll()
184 /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated). 193 {
185 /// </summary> 194 base.HideFromAll();
186 public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup) 195 foreach(MetaEntity group in m_AuraEntities.Values)
187 { 196 group.HideFromAll();
188 SceneObjectPart sceneEntityPart; 197 foreach(MetaEntity group in m_BeamEntities.Values)
189 SceneObjectPart metaEntityPart; 198 group.HideFromAll();
190 Diff differences; 199 }
191 bool changed = false; 200
192 201 /// <summary>
193 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user 202 /// Returns true if there was a change between meta entity and the entity group, false otherwise.
194 // had originally saved. 203 /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
195 // m_Entity will NOT necessarily be the same entity as the user had saved. 204 /// </summary>
196 foreach(SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) 205 public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
197 {
198 //This is the part that we use to show changes.
199 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
200 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
201 {
202 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
203 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
204 if (differences != Diff.NONE)
205 metaEntityPart.Text = "CHANGE: " + differences.ToString();
206 if (differences != 0)
207 {
208 // Root Part that has been modified
209 if ((differences&Diff.POSITION) > 0)
210 {
211 // If the position of any part has changed, make sure the RootPart of the
212 // meta entity is pointing with a beam particle system
213 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
214 {
215 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
216 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
217 }
218 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
219 m_Entity.Scene.PrimIDAllocate(),
220 m_UnchangedEntity.RootPart.GetWorldPosition(),
221 MetaEntity.TRANSLUCENT,
222 sceneEntityPart,
223 new LLVector3(0,0,254)
224 );
225 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
226 }
227
228 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
229 {
230 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
231 m_AuraEntities.Remove(UnchangedPart.UUID);
232 }
233 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
234 m_Entity.Scene.PrimIDAllocate(),
235 UnchangedPart.GetWorldPosition(),
236 MetaEntity.TRANSLUCENT,
237 new LLVector3(0,0,254),
238 UnchangedPart.Scale
239 );
240 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
241 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
242
243 DiffersFromSceneGroup = true;
244 }
245 else // no differences between scene part and meta part
246 {
247 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
248 {
249 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
250 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
251 }
252 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
253 {
254 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
255 m_AuraEntities.Remove(UnchangedPart.UUID);
256 }
257 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
258 }
259 }
260 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
261 {
262 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
263 {
264 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
265 m_AuraEntities.Remove(UnchangedPart.UUID);
266 }
267 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
268 m_Entity.Scene.PrimIDAllocate(),
269 UnchangedPart.GetWorldPosition(),
270 MetaEntity.TRANSLUCENT,
271 new LLVector3(254,0,0),
272 UnchangedPart.Scale
273 );
274 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
275 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
276
277 DiffersFromSceneGroup = true;
278 }
279 }
280 return changed;
281 }
282
283 private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, LLUUID uuid)
284 { 206 {
285 foreach (EntityBase ent in list) 207 SceneObjectPart sceneEntityPart;
286 { 208 SceneObjectPart metaEntityPart;
287 if (ent is SceneObjectGroup) 209 Diff differences;
288 if (ent.UUID == uuid) 210 bool changed = false;
289 return (SceneObjectGroup)ent; 211
290 } 212 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
291 return null; 213 // had originally saved.
292 } 214 // m_Entity will NOT necessarily be the same entity as the user had saved.
293 215 foreach(SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
294 /// <summary> 216 {
295 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID. 217 //This is the part that we use to show changes.
296 /// </summary> 218 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
297 public bool HasChildPrim(LLUUID uuid) 219 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
298 { 220 {
299 if (m_UnchangedEntity.Children.ContainsKey(uuid)) 221 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
300 return true; 222 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
301 return false; 223 if (differences != Diff.NONE)
302 } 224 metaEntityPart.Text = "CHANGE: " + differences.ToString();
303 225 if (differences != 0)
304 /// <summary> 226 {
305 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId. 227 // Root Part that has been modified
306 /// </summary> 228 if ((differences&Diff.POSITION) > 0)
307 public bool HasChildPrim(uint localID) 229 {
308 { 230 // If the position of any part has changed, make sure the RootPart of the
309 foreach( SceneObjectPart part in m_UnchangedEntity.Children.Values) 231 // meta entity is pointing with a beam particle system
310 if ( part.LocalId == localID ) 232 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
311 return true; 233 {
312 return false; 234 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
313 } 235 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
314 236 }
315 /// <summary> 237 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
316 /// Check if an entitybase list (like that returned by scene.GetEntities() ) contains a group with the rootpart uuid that matches the current uuid. 238 m_Entity.Scene.PrimIDAllocate(),
317 /// </summary> 239 m_UnchangedEntity.RootPart.GetWorldPosition(),
318 private bool ContainsKey(List<EntityBase> list, LLUUID uuid) 240 MetaEntity.TRANSLUCENT,
319 { 241 sceneEntityPart,
320 foreach( EntityBase part in list) 242 new LLVector3(0,0,254)
321 if (part.UUID == uuid) 243 );
322 return true; 244 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
323 return false; 245 }
324 } 246
325 } 247 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
326} 248 {
249 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
250 m_AuraEntities.Remove(UnchangedPart.UUID);
251 }
252 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
253 m_Entity.Scene.PrimIDAllocate(),
254 UnchangedPart.GetWorldPosition(),
255 MetaEntity.TRANSLUCENT,
256 new LLVector3(0,0,254),
257 UnchangedPart.Scale
258 );
259 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
260 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
261
262 DiffersFromSceneGroup = true;
263 }
264 else // no differences between scene part and meta part
265 {
266 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
267 {
268 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
269 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
270 }
271 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
272 {
273 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
274 m_AuraEntities.Remove(UnchangedPart.UUID);
275 }
276 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
277 }
278 }
279 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
280 {
281 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
282 {
283 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
284 m_AuraEntities.Remove(UnchangedPart.UUID);
285 }
286 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
287 m_Entity.Scene.PrimIDAllocate(),
288 UnchangedPart.GetWorldPosition(),
289 MetaEntity.TRANSLUCENT,
290 new LLVector3(254,0,0),
291 UnchangedPart.Scale
292 );
293 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
294 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
295
296 DiffersFromSceneGroup = true;
297 }
298 }
299 return changed;
300 }
301
302 public void SendFullAuraUpdate(IClientAPI client)
303 {
304 if (DiffersFromSceneGroup)
305 {
306 foreach(AuraMetaEntity group in m_AuraEntities.Values)
307 group.SendFullUpdate(client);
308 }
309 }
310
311 public void SendFullAuraUpdateToAll()
312 {
313 if (DiffersFromSceneGroup)
314 {
315 foreach(AuraMetaEntity group in m_AuraEntities.Values)
316 group.SendFullUpdateToAll();
317 }
318 }
319
320 public void SendFullBeamUpdate(IClientAPI client)
321 {
322 if (DiffersFromSceneGroup)
323 {
324 foreach(BeamMetaEntity group in m_BeamEntities.Values)
325 group.SendFullUpdate(client);
326 }
327 }
328
329 public void SendFullBeamUpdateToAll()
330 {
331 if (DiffersFromSceneGroup)
332 {
333 foreach(BeamMetaEntity group in m_BeamEntities.Values)
334 group.SendFullUpdateToAll();
335 }
336 }
337
338 public void SendFullDiffUpdate(IClientAPI client)
339 {
340 FindDifferences();
341 if (DiffersFromSceneGroup)
342 {
343 SendFullUpdate(client);
344 SendFullAuraUpdate(client);
345 SendFullBeamUpdate(client);
346 }
347 }
348
349 public void SendFullDiffUpdateToAll()
350 {
351 FindDifferences();
352 if (DiffersFromSceneGroup)
353 {
354 SendFullUpdateToAll();
355 SendFullAuraUpdateToAll();
356 SendFullBeamUpdateToAll();
357 }
358 }
359
360 #endregion Public Methods
361 }
362} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs
index 413d00d..ef27f46 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementModule.cs
@@ -1,31 +1,69 @@
1#region Header
2
1// ContentManagementModule.cs 3// ContentManagementModule.cs
2// User: bongiojp 4// User: bongiojp
3 5
6#endregion Header
7
4using System; 8using System;
5using System.Collections.Generic; 9using System.Collections.Generic;
10using System.Threading;
11
6using libsecondlife; 12using libsecondlife;
13
7using Nini.Config; 14using Nini.Config;
15
8using OpenSim; 16using OpenSim;
9using OpenSim.Framework; 17using OpenSim.Framework;
10using OpenSim.Region.Environment.Interfaces; 18using OpenSim.Region.Environment.Interfaces;
11using OpenSim.Region.Environment.Scenes; 19using OpenSim.Region.Environment.Scenes;
12using log4net;
13using OpenSim.Region.Physics.Manager; 20using OpenSim.Region.Physics.Manager;
21
22using log4net;
23
14using Axiom.Math; 24using Axiom.Math;
15using System.Threading; 25
16
17namespace OpenSim.Region.Environment.Modules.ContentManagement 26namespace OpenSim.Region.Environment.Modules.ContentManagement
18{ 27{
19 public class ContentManagementModule : IRegionModule 28 public class ContentManagementModule : IRegionModule
20 { 29 {
30 #region Static Fields
31
21 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 32 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
33
34 #endregion Static Fields
35
36 #region Fields
37
38 bool initialised = false;
22 CMController m_control = null; 39 CMController m_control = null;
40 bool m_enabled = false;
23 CMModel m_model = null; 41 CMModel m_model = null;
24 CMView m_view = null;
25 bool initialised = false;
26 bool m_posted = false; 42 bool m_posted = false;
27 bool m_enabled = false; 43 CMView m_view = null;
28 44
45 #endregion Fields
46
47 #region Public Properties
48
49 public bool IsSharedModule
50 {
51 get { return true; }
52 }
53
54 public string Name
55 {
56 get { return "ContentManagementModule"; }
57 }
58
59 #endregion Public Properties
60
61 #region Public Methods
62
63 public void Close()
64 {
65 }
66
29 public void Initialise(Scene scene, IConfigSource source) 67 public void Initialise(Scene scene, IConfigSource source)
30 { 68 {
31 string databaseDir = "./"; 69 string databaseDir = "./";
@@ -52,13 +90,13 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
52 m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e); 90 m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e);
53 m_enabled = false; 91 m_enabled = false;
54 } 92 }
55 93
56 if (!m_enabled) 94 if (!m_enabled)
57 { 95 {
58 m_log.Info("[Content Management]: Content Management System is not Enabled."); 96 m_log.Info("[Content Management]: Content Management System is not Enabled.");
59 return; 97 return;
60 } 98 }
61 99
62 lock(this) 100 lock(this)
63 { 101 {
64 if (!initialised) //only init once 102 if (!initialised) //only init once
@@ -79,12 +117,12 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
79 } 117 }
80 } 118 }
81 } 119 }
82 120
83 public void PostInitialise() 121 public void PostInitialise()
84 { 122 {
85 if (! m_enabled) 123 if (! m_enabled)
86 return; 124 return;
87 125
88 lock(this) 126 lock(this)
89 { 127 {
90 if (!m_posted) //only post once 128 if (!m_posted) //only post once
@@ -94,18 +132,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
94 } 132 }
95 } 133 }
96 } 134 }
97
98 public void Close()
99 {}
100
101 public string Name
102 {
103 get { return "ContentManagementModule"; }
104 }
105 135
106 public bool IsSharedModule 136 #endregion Public Methods
107 {
108 get { return true; }
109 }
110 } 137 }
111} 138} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs
index e1f519b..680cefbd 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/FileSystemDatabase.cs
@@ -1,159 +1,132 @@
1#region Header
2
1// FileSystemDatabase.cs 3// FileSystemDatabase.cs
2// User: bongiojp 4// User: bongiojp
3 5
6#endregion Header
7
4using System; 8using System;
5using System.Collections.Generic; 9using System.Collections.Generic;
10using System.Diagnostics;
6using System.IO; 11using System.IO;
12using Slash = System.IO.Path;
7using System.Reflection; 13using System.Reflection;
8using System.Xml; 14using System.Xml;
15
9using libsecondlife; 16using libsecondlife;
17
10using Nini.Config; 18using Nini.Config;
19
11using OpenSim.Framework; 20using OpenSim.Framework;
12using OpenSim.Region.Environment.Interfaces; 21using OpenSim.Region.Environment.Interfaces;
13using OpenSim.Region.Environment.Modules.World.Serialiser; 22using OpenSim.Region.Environment.Modules.World.Serialiser;
14using OpenSim.Region.Environment.Modules.World.Terrain; 23using OpenSim.Region.Environment.Modules.World.Terrain;
15using OpenSim.Region.Environment.Scenes; 24using OpenSim.Region.Environment.Scenes;
16using log4net;
17using OpenSim.Region.Physics.Manager; 25using OpenSim.Region.Physics.Manager;
26
27using log4net;
28
18using Axiom.Math; 29using Axiom.Math;
19using Slash=System.IO.Path;
20using System.Diagnostics;
21 30
22namespace OpenSim.Region.Environment.Modules.ContentManagement 31namespace OpenSim.Region.Environment.Modules.ContentManagement
23{ 32{
24 public class FileSystemDatabase : IContentDatabase 33 public class FileSystemDatabase : IContentDatabase
25 { 34 {
26 public static float TimeToDownload = 0; 35 #region Static Fields
27 public static float TimeToSave = 0; 36
28 37 public static float TimeToDownload = 0;
29 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 38 public static float TimeToSave = 0;
30 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
31 private string m_repodir = null; 40
32 private Dictionary<LLUUID, IRegionSerialiser> m_serialiser = new Dictionary<LLUUID, IRegionSerialiser>(); 41 #endregion Static Fields
33 private Dictionary<LLUUID, Scene> m_scenes = new Dictionary<LLUUID, Scene>(); 42
34 43 #region Fields
35 public FileSystemDatabase() 44
36 { 45 private string m_repodir = null;
37 } 46 private Dictionary<LLUUID, Scene> m_scenes = new Dictionary<LLUUID, Scene>();
38 47 private Dictionary<LLUUID, IRegionSerialiser> m_serialiser = new Dictionary<LLUUID, IRegionSerialiser>();
39 public void Initialise(Scene scene, string dir) 48
40 { 49 #endregion Fields
41 lock(this) 50
42 { 51 #region Constructors
43 if (m_repodir == null) 52
44 m_repodir = dir; 53 public FileSystemDatabase()
45 } 54 {
46 lock(m_scenes) 55 }
47 m_scenes.Add(scene.RegionInfo.RegionID, scene); 56
48 } 57 #endregion Constructors
49 58
50 59 #region Private Methods
51 // Run once and only once. 60
52 public void PostInitialise() 61 // called by postinitialise
53 { 62 private void CreateDirectory()
54 SetupSerialiser(); 63 {
55 64 string scenedir;
56 m_log.Info("[FSDB]: Creating repository in " + m_repodir + "."); 65 if (!Directory.Exists(m_repodir))
57 CreateDirectory(); 66 Directory.CreateDirectory(m_repodir);
58 } 67
59 68 foreach (LLUUID region in m_scenes.Keys)
60 // called by postinitialise 69 {
61 private void SetupSerialiser() 70 scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
71 if (!Directory.Exists(scenedir))
72 Directory.CreateDirectory(scenedir);
73 }
74 }
75
76 // called by postinitialise
77 private void SetupSerialiser()
62 { 78 {
63 if (m_serialiser.Count == 0) 79 if (m_serialiser.Count == 0)
64 foreach(LLUUID region in m_scenes.Keys) 80 foreach(LLUUID region in m_scenes.Keys)
65 m_serialiser.Add(region, 81 m_serialiser.Add(region,
66 m_scenes[region].RequestModuleInterface<IRegionSerialiser>() 82 m_scenes[region].RequestModuleInterface<IRegionSerialiser>()
67 ); 83 );
84 }
85
86 #endregion Private Methods
87
88 #region Public Methods
89
90 public int GetMostRecentRevision(LLUUID regionid)
91 {
92 return NumOfRegionRev(regionid);
93 }
94
95 public string GetRegionObjectHeightMap(LLUUID regionid)
96 {
97 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
98 Slash.DirectorySeparatorChar + "heightmap.r32";
99 FileStream fs = new FileStream( filename, FileMode.Open);
100 StreamReader sr = new StreamReader(fs);
101 String result = sr.ReadToEnd();
102 sr.Close();
103 fs.Close();
104 return result;
105 }
106
107 public string GetRegionObjectHeightMap(LLUUID regionid, int revision)
108 {
109 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
110 Slash.DirectorySeparatorChar + "heightmap.r32";
111 FileStream fs = new FileStream( filename, FileMode.Open);
112 StreamReader sr = new StreamReader(fs);
113 String result = sr.ReadToEnd();
114 sr.Close();
115 fs.Close();
116 return result;
68 } 117 }
69 118
70 // called by postinitialise 119 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision)
71 private void CreateDirectory() 120 {
72 { 121 System.Collections.ArrayList objectList = new System.Collections.ArrayList();
73 string scenedir; 122 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
74 if (!Directory.Exists(m_repodir)) 123 + revision + Slash.DirectorySeparatorChar + "objects.xml";
75 Directory.CreateDirectory(m_repodir); 124 XmlDocument doc = new XmlDocument();
76
77 foreach (LLUUID region in m_scenes.Keys)
78 {
79 scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
80 if (!Directory.Exists(scenedir))
81 Directory.CreateDirectory(scenedir);
82 }
83 }
84
85 public int NumOfRegionRev(LLUUID regionid)
86 {
87 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
88 m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
89 string[] directories = Directory.GetDirectories(scenedir);
90 return directories.Length;
91 }
92
93 public int GetMostRecentRevision(LLUUID regionid)
94 {
95 return NumOfRegionRev(regionid);
96 }
97
98 public void SaveRegion(LLUUID regionid, string regionName, string logMessage)
99 {
100 m_log.Info("[FSDB]: ...............................");
101 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
102
103 m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
104 if (!Directory.Exists(scenedir))
105 Directory.CreateDirectory(scenedir);
106
107 int newRevisionNum = GetMostRecentRevision(regionid)+1;
108 string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
109
110 m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
111 if (!Directory.Exists(revisiondir))
112 Directory.CreateDirectory(revisiondir);
113
114 try {
115 Stopwatch x = new Stopwatch();
116 x.Start();
117 if (m_scenes.ContainsKey(regionid))
118 {
119 m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
120 }
121 x.Stop();
122 TimeToSave += x.ElapsedMilliseconds;
123 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
124 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
125 }
126 catch (Exception e)
127 {
128 m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
129 return;
130 }
131
132 try {
133 // Finish by writing log message.
134 FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
135 StreamWriter sw = new StreamWriter(file);
136 sw.Write(logMessage);
137 sw.Close();
138 }
139 catch (Exception e)
140 {
141 m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
142 return;
143 }
144 }
145
146 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision)
147 {
148 System.Collections.ArrayList objectList = new System.Collections.ArrayList();
149 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
150 + revision + Slash.DirectorySeparatorChar + "objects.xml";
151 XmlDocument doc = new XmlDocument();
152 XmlNode rootNode; 125 XmlNode rootNode;
153 //int primCount = 0; 126 //int primCount = 0;
154 //SceneObjectGroup obj = null; 127 //SceneObjectGroup obj = null;
155 128
156 if(File.Exists(filename)) 129 if(File.Exists(filename))
157 { 130 {
158 XmlTextReader reader = new XmlTextReader(filename); 131 XmlTextReader reader = new XmlTextReader(filename);
159 reader.WhitespaceHandling = WhitespaceHandling.None; 132 reader.WhitespaceHandling = WhitespaceHandling.None;
@@ -162,99 +135,153 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
162 rootNode = doc.FirstChild; 135 rootNode = doc.FirstChild;
163 foreach (XmlNode aPrimNode in rootNode.ChildNodes) 136 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
164 { 137 {
165 objectList.Add(aPrimNode.OuterXml); 138 objectList.Add(aPrimNode.OuterXml);
166 } 139 }
167 return objectList; 140 return objectList;
168 } 141 }
169 return null; 142 return null;
170 } 143 }
171 144
172 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid) 145 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid)
173 { 146 {
174 int revision = NumOfRegionRev(regionid); 147 int revision = NumOfRegionRev(regionid);
175 m_log.Info("[FSDB]: found revisions:" + revision); 148 m_log.Info("[FSDB]: found revisions:" + revision);
176 System.Collections.ArrayList xmlList = new System.Collections.ArrayList(); 149 System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
177 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar + 150 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
178 + revision + Slash.DirectorySeparatorChar + "objects.xml"; 151 + revision + Slash.DirectorySeparatorChar + "objects.xml";
179 XmlDocument doc = new XmlDocument(); 152 XmlDocument doc = new XmlDocument();
180 XmlNode rootNode; 153 XmlNode rootNode;
181 154
182 155
183 m_log.Info("[FSDB]: Checking if " + filename + " exists."); 156 m_log.Info("[FSDB]: Checking if " + filename + " exists.");
184 if(File.Exists(filename)) 157 if(File.Exists(filename))
185 { 158 {
186 Stopwatch x = new Stopwatch(); 159 Stopwatch x = new Stopwatch();
187 x.Start(); 160 x.Start();
188 161
189 XmlTextReader reader = new XmlTextReader(filename); 162 XmlTextReader reader = new XmlTextReader(filename);
190 reader.WhitespaceHandling = WhitespaceHandling.None; 163 reader.WhitespaceHandling = WhitespaceHandling.None;
191 doc.Load(reader); 164 doc.Load(reader);
192 reader.Close(); 165 reader.Close();
193 rootNode = doc.FirstChild; 166 rootNode = doc.FirstChild;
194 167
195 foreach (XmlNode aPrimNode in rootNode.ChildNodes) 168 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
196 xmlList.Add(aPrimNode.OuterXml); 169 xmlList.Add(aPrimNode.OuterXml);
197 170
198 x.Stop(); 171 x.Stop();
199 TimeToDownload += x.ElapsedMilliseconds; 172 TimeToDownload += x.ElapsedMilliseconds;
200 m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload); 173 m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
201 174
202 return xmlList; 175 return xmlList;
203 } 176 }
204 return null; 177 return null;
205 } 178 }
206 179
207 public string GetRegionObjectHeightMap(LLUUID regionid) 180 public void Initialise(Scene scene, string dir)
208 { 181 {
209 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + 182 lock(this)
210 Slash.DirectorySeparatorChar + "heightmap.r32"; 183 {
211 FileStream fs = new FileStream( filename, FileMode.Open); 184 if (m_repodir == null)
212 StreamReader sr = new StreamReader(fs); 185 m_repodir = dir;
213 String result = sr.ReadToEnd(); 186 }
214 sr.Close(); 187 lock(m_scenes)
215 fs.Close(); 188 m_scenes.Add(scene.RegionInfo.RegionID, scene);
216 return result; 189 }
217 } 190
218 191 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID regionid)
219 public string GetRegionObjectHeightMap(LLUUID regionid, int revision) 192 {
220 { 193 SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
221 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid + 194
222 Slash.DirectorySeparatorChar + "heightmap.r32"; 195 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
223 FileStream fs = new FileStream( filename, FileMode.Open); 196 string[] directories = Directory.GetDirectories(scenedir);
224 StreamReader sr = new StreamReader(fs); 197
225 String result = sr.ReadToEnd(); 198 FileStream fs = null;
226 sr.Close(); 199 StreamReader sr = null;
227 fs.Close(); 200 String logMessage = "";
228 return result; 201 String logLocation = "";
229 } 202 foreach(string revisionDir in directories)
230 203 {
231 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID regionid) 204 try {
232 { 205 logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
233 SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>(); 206 fs = new FileStream( logLocation, FileMode.Open);
234 207 sr = new StreamReader(fs);
235 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar; 208 logMessage = sr.ReadToEnd();
236 string[] directories = Directory.GetDirectories(scenedir); 209 sr.Close();
237 210 fs.Close();
238 FileStream fs = null; 211 revisionDict.Add(revisionDir, logMessage);
239 StreamReader sr = null; 212 }
240 String logMessage = ""; 213 catch (Exception)
241 String logLocation = ""; 214 {}
242 foreach(string revisionDir in directories) 215 }
243 { 216
244 try { 217 return revisionDict;
245 logLocation = revisionDir + Slash.DirectorySeparatorChar + "log"; 218 }
246 fs = new FileStream( logLocation, FileMode.Open); 219
247 sr = new StreamReader(fs); 220 public int NumOfRegionRev(LLUUID regionid)
248 logMessage = sr.ReadToEnd(); 221 {
249 sr.Close(); 222 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
250 fs.Close(); 223 m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
251 revisionDict.Add(revisionDir, logMessage); 224 string[] directories = Directory.GetDirectories(scenedir);
252 } 225 return directories.Length;
253 catch (Exception) 226 }
254 {} 227
255 } 228 // Run once and only once.
256 229 public void PostInitialise()
257 return revisionDict; 230 {
258 } 231 SetupSerialiser();
259 } 232
260} 233 m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
234 CreateDirectory();
235 }
236
237 public void SaveRegion(LLUUID regionid, string regionName, string logMessage)
238 {
239 m_log.Info("[FSDB]: ...............................");
240 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
241
242 m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
243 if (!Directory.Exists(scenedir))
244 Directory.CreateDirectory(scenedir);
245
246 int newRevisionNum = GetMostRecentRevision(regionid)+1;
247 string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
248
249 m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
250 if (!Directory.Exists(revisiondir))
251 Directory.CreateDirectory(revisiondir);
252
253 try {
254 Stopwatch x = new Stopwatch();
255 x.Start();
256 if (m_scenes.ContainsKey(regionid))
257 {
258 m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
259 }
260 x.Stop();
261 TimeToSave += x.ElapsedMilliseconds;
262 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
263 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
264 }
265 catch (Exception e)
266 {
267 m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
268 return;
269 }
270
271 try {
272 // Finish by writing log message.
273 FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
274 StreamWriter sw = new StreamWriter(file);
275 sw.Write(logMessage);
276 sw.Close();
277 }
278 catch (Exception e)
279 {
280 m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
281 return;
282 }
283 }
284
285 #endregion Public Methods
286 }
287} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs
index e337482..5e85b2e 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/GitDatabase.cs
@@ -1,130 +1,142 @@
1#region Header
2
1// GitDatabase.cs 3// GitDatabase.cs
2// 4//
3// 5//
4// 6//
5 7
8#endregion Header
9
6using System; 10using System;
7using System.Collections.Generic; 11using System.Collections.Generic;
8using System.IO; 12using System.IO;
13using Slash = System.IO.Path;
9using System.Reflection; 14using System.Reflection;
10using System.Xml; 15using System.Xml;
16
11using libsecondlife; 17using libsecondlife;
18
12using Nini.Config; 19using Nini.Config;
20
13using OpenSim.Framework; 21using OpenSim.Framework;
14using OpenSim.Region.Environment.Interfaces; 22using OpenSim.Region.Environment.Interfaces;
15using OpenSim.Region.Environment.Modules.World.Serialiser; 23using OpenSim.Region.Environment.Modules.World.Serialiser;
16using OpenSim.Region.Environment.Modules.World.Terrain; 24using OpenSim.Region.Environment.Modules.World.Terrain;
17using OpenSim.Region.Environment.Scenes; 25using OpenSim.Region.Environment.Scenes;
18using log4net;
19using OpenSim.Region.Physics.Manager; 26using OpenSim.Region.Physics.Manager;
27
28using log4net;
29
20using Axiom.Math; 30using Axiom.Math;
21using Slash=System.IO.Path;
22 31
23namespace OpenSim.Region.Environment.Modules.ContentManagement 32namespace OpenSim.Region.Environment.Modules.ContentManagement
24{ 33{
25 34 /// <summary>
26 /// <summary> 35 /// Just a stub :-(
27 /// Just a stub :-( 36 /// </summary>
28 /// </summary> 37 public class GitDatabase : IContentDatabase
29 public class GitDatabase : IContentDatabase 38 {
30 { 39 #region Constructors
31 40
32 public GitDatabase() 41 public GitDatabase()
33 { 42 {
34 } 43 }
35 44
36 public void Initialise(Scene scene, String dir) 45 #endregion Constructors
37 { 46
38 47 #region Public Methods
39 } 48
40 49 public SceneObjectGroup GetMostRecentObjectRevision(LLUUID id)
41 public void PostInitialise() 50 {
42 { 51 return null;
43 52 }
44 } 53
45 54 public int GetMostRecentRevision(LLUUID regionid)
46 public int NumOfObjectRev(LLUUID id) 55 {
47 { 56 return 0;
48 return 0; 57 }
49 } 58
50 59 public SceneObjectGroup GetObjectRevision(LLUUID id, int revision)
51 public int NumOfRegionRev(LLUUID regionid) 60 {
52 { 61 return null;
53 return 0; 62 }
54 } 63
55 64 public System.Collections.ArrayList GetObjectsFromRegion(LLUUID regionid, int revision)
56 public bool InRepository(LLUUID id) 65 {
57 { 66 return null;
58 return false; 67 }
59 } 68
60 69 public string GetRegionObjectHeightMap(LLUUID regionid)
61 public void SaveRegion(LLUUID regionid, string regionName, string logMessage) 70 {
62 { 71 return null;
63 72 }
64 } 73
65 74 public string GetRegionObjectHeightMap(LLUUID regionid, int revision)
66 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid) 75 {
67 { 76 return null;
68 return null; 77 }
69 } 78
70 79 public string GetRegionObjectXML(LLUUID regionid)
71 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision) 80 {
72 { 81 return null;
73 return null; 82 }
74 } 83
75 84 public string GetRegionObjectXML(LLUUID regionid, int revision)
76 public string GetRegionObjectXML(LLUUID regionid) 85 {
77 { 86 return null;
78 return null; 87 }
79 } 88
80 89 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid)
81 public string GetRegionObjectXML(LLUUID regionid, int revision) 90 {
82 { 91 return null;
83 return null; 92 }
84 } 93
85 94 public System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision)
86 public string GetRegionObjectHeightMap(LLUUID regionid) 95 {
87 { 96 return null;
88 return null; 97 }
89 } 98
90 99 public bool InRepository(LLUUID id)
91 public string GetRegionObjectHeightMap(LLUUID regionid, int revision) 100 {
92 { 101 return false;
93 return null; 102 }
94 } 103
95 104 public void Initialise(Scene scene, String dir)
96 public System.Collections.ArrayList GetObjectsFromRegion(LLUUID regionid, int revision) 105 {
97 { 106 }
98 return null; 107
99 } 108 public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(LLUUID id)
100 109 {
101 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id) 110 return null;
102 { 111 }
103 return null; 112
104 } 113 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id)
105 114 {
106 public void SaveObject(SceneObjectGroup entity) 115 return null;
107 { 116 }
108 } 117
109 118 public int NumOfObjectRev(LLUUID id)
110 public SceneObjectGroup GetMostRecentObjectRevision(LLUUID id) 119 {
111 { 120 return 0;
112 return null; 121 }
113 } 122
114 123 public int NumOfRegionRev(LLUUID regionid)
115 public SceneObjectGroup GetObjectRevision(LLUUID id, int revision) 124 {
116 { 125 return 0;
117 return null; 126 }
118 } 127
119 128 public void PostInitialise()
120 public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(LLUUID id) 129 {
121 { 130 }
122 return null; 131
123 } 132 public void SaveObject(SceneObjectGroup entity)
124 133 {
125 public int GetMostRecentRevision(LLUUID regionid) 134 }
126 { 135
127 return 0; 136 public void SaveRegion(LLUUID regionid, string regionName, string logMessage)
128 } 137 {
129 } 138 }
130} 139
140 #endregion Public Methods
141 }
142} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs
index f37f95d..1d81978 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/IContentDatabase.cs
@@ -1,57 +1,70 @@
1#region Header
2
1// IContentDatabase.cs 3// IContentDatabase.cs
2// User: bongiojp 4// User: bongiojp
3// 5//
4// 6//
5// 7//
6 8
9#endregion Header
10
7using System; 11using System;
12
8using libsecondlife; 13using libsecondlife;
14
9using OpenSim.Region.Environment.Scenes; 15using OpenSim.Region.Environment.Scenes;
16
10using Nini.Config; 17using Nini.Config;
11 18
12namespace OpenSim.Region.Environment.Modules.ContentManagement 19namespace OpenSim.Region.Environment.Modules.ContentManagement
13{ 20{
14 public interface IContentDatabase 21 public interface IContentDatabase
15 { 22 {
16 /// <summary> 23 #region Methods
17 /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database. 24
18 /// Initialise should be called one for each region to be contained in the database. The directory should be the full path 25 /// <summary>
19 /// to the repository and will only be defined once, regardless of how many times the method is called. 26 /// Returns the most recent revision number of a region.
20 /// </summary> 27 /// </summary>
21 void Initialise(Scene scene, String dir); 28 int GetMostRecentRevision(LLUUID regionid);
22 29
23 /// <summary> 30 string GetRegionObjectHeightMap(LLUUID regionid);
24 /// Should be called once after Initialise has been called. 31
25 /// </summary> 32 string GetRegionObjectHeightMap(LLUUID regionid, int revision);
26 void PostInitialise(); 33
27 34 /// <summary>
28 /// <summary> 35 /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region.
29 /// Returns the total number of revisions saved for a specific region. 36 /// </summary>
30 /// </summary> 37 System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid);
31 int NumOfRegionRev(LLUUID regionid); 38
32 39 System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision);
33 /// <summary> 40
34 /// Saves the Region terrain map and objects within the region as xml to the database. 41 /// <summary>
35 /// </summary> 42 /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database.
36 void SaveRegion(LLUUID regionid, string regionName, string logMessage); 43 /// Initialise should be called one for each region to be contained in the database. The directory should be the full path
37 44 /// to the repository and will only be defined once, regardless of how many times the method is called.
38 /// <summary> 45 /// </summary>
39 /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region. 46 void Initialise(Scene scene, String dir);
40 /// </summary> 47
41 System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid); 48 /// <summary>
42 System.Collections.ArrayList GetRegionObjectXMLList(LLUUID regionid, int revision); 49 /// Returns a list of the revision numbers and corresponding log messages for a given region.
43 50 /// </summary>
44 string GetRegionObjectHeightMap(LLUUID regionid); 51 System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id);
45 string GetRegionObjectHeightMap(LLUUID regionid, int revision); 52
46 53 /// <summary>
47 /// <summary> 54 /// Returns the total number of revisions saved for a specific region.
48 /// Returns a list of the revision numbers and corresponding log messages for a given region. 55 /// </summary>
49 /// </summary> 56 int NumOfRegionRev(LLUUID regionid);
50 System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(LLUUID id); 57
51 58 /// <summary>
52 /// <summary> 59 /// Should be called once after Initialise has been called.
53 /// Returns the most recent revision number of a region. 60 /// </summary>
54 /// </summary> 61 void PostInitialise();
55 int GetMostRecentRevision(LLUUID regionid); 62
56 } 63 /// <summary>
57} 64 /// Saves the Region terrain map and objects within the region as xml to the database.
65 /// </summary>
66 void SaveRegion(LLUUID regionid, string regionName, string logMessage);
67
68 #endregion Methods
69 }
70} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs
index f0763d3..c203054 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs
@@ -1,219 +1,256 @@
1#region Header
2
1// MetaEntity.cs 3// MetaEntity.cs
2// User: bongiojp 4// User: bongiojp
3// 5//
4// TODO: 6// TODO:
5// Create a physics manager to the meta object if there isn't one or the object knows of no scene but the user wants physics enabled. 7// Create a physics manager to the meta object if there isn't one or the object knows of no scene but the user wants physics enabled.
6 8
9#endregion Header
7 10
8using System; 11using System;
9using System.Collections.Generic; 12using System.Collections.Generic;
10using System.Drawing; 13using System.Drawing;
14
11using libsecondlife; 15using libsecondlife;
16
12using Nini.Config; 17using Nini.Config;
18
13using OpenSim.Framework; 19using OpenSim.Framework;
14using OpenSim.Region.Environment.Interfaces; 20using OpenSim.Region.Environment.Interfaces;
15using OpenSim.Region.Environment.Scenes; 21using OpenSim.Region.Environment.Scenes;
16using log4net;
17using OpenSim.Region.Physics.Manager; 22using OpenSim.Region.Physics.Manager;
23
24using log4net;
25
18using Axiom.Math; 26using Axiom.Math;
19 27
20namespace OpenSim.Region.Environment.Modules.ContentManagement 28namespace OpenSim.Region.Environment.Modules.ContentManagement
21{ 29{
22 public class MetaEntity 30 public class MetaEntity
23 { 31 {
24 protected static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 32 #region Constants
25 33
26 protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity. 34 public const float INVISIBLE = .95f;
27 protected uint m_metaLocalid; 35
28 36 // Settings for transparency of metaentity
29 // Settings for transparency of metaentity 37 public const float NONE = 0f;
30 public const float NONE = 0f; 38 public const float TRANSLUCENT = .5f;
31 public const float TRANSLUCENT = .5f; 39
32 public const float INVISIBLE = .95f; 40 #endregion Constants
33 41
34 public Scene Scene 42 #region Static Fields
35 { 43
36 get { return m_Entity.Scene; } 44 protected static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
37 } 45
38 46 #endregion Static Fields
39 public SceneObjectPart RootPart 47
40 { 48 #region Fields
41 get { return m_Entity.RootPart; } 49
42 set { m_Entity.RootPart = value; } 50 protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity.
43 } 51 protected uint m_metaLocalid;
44 52
45 public LLUUID UUID 53 #endregion Fields
46 { 54
47 get { return m_Entity.UUID; } 55 #region Constructors
48 set { m_Entity.UUID = value; } 56
49 } 57 public MetaEntity()
50 58 {
51 public uint LocalId 59 }
52 { 60
53 get { return m_Entity.LocalId; } 61 /// <summary>
54 set { m_Entity.LocalId = value; } 62 /// Makes a new meta entity by copying the given scene object group.
55 } 63 /// The physics boolean is just a stub right now.
56 64 /// </summary>
57 public SceneObjectGroup ObjectGroup 65 public MetaEntity(SceneObjectGroup orig, bool physics)
58 { 66 {
59 get { return m_Entity; } 67 m_Entity = orig.Copy(orig.RootPart.OwnerID, orig.RootPart.GroupID, false);
60 } 68 Initialize(physics);
61 69 }
62 public Dictionary<LLUUID, SceneObjectPart> Children 70
63 { 71 /// <summary>
64 get { return m_Entity.Children; } 72 /// Takes an XML description of a scene object group and converts it to a meta entity.
65 set { m_Entity.Children = value; } 73 /// </summary>
66 } 74 public MetaEntity(string objectXML, Scene scene, bool physics)
67 75 {
68 public int PrimCount 76 m_Entity = new SceneObjectGroup(objectXML);
69 { 77 m_Entity.SetScene(scene);
70 get { return m_Entity.PrimCount; } 78 Initialize(physics);
71 } 79 }
72 80
73 public MetaEntity() 81 #endregion Constructors
74 { 82
75 } 83 #region Public Properties
76 84
77 /// <summary> 85 public Dictionary<LLUUID, SceneObjectPart> Children
78 /// Makes a new meta entity by copying the given scene object group. 86 {
79 /// The physics boolean is just a stub right now. 87 get { return m_Entity.Children; }
80 /// </summary> 88 set { m_Entity.Children = value; }
81 public MetaEntity(SceneObjectGroup orig, bool physics) 89 }
82 { 90
83 m_Entity = orig.Copy(orig.RootPart.OwnerID, orig.RootPart.GroupID, false); 91 public uint LocalId
84 Initialize(physics); 92 {
85 } 93 get { return m_Entity.LocalId; }
86 94 set { m_Entity.LocalId = value; }
87 /// <summary> 95 }
88 /// Takes an XML description of a scene object group and converts it to a meta entity. 96
89 /// </summary> 97 public SceneObjectGroup ObjectGroup
90 public MetaEntity(string objectXML, Scene scene, bool physics) 98 {
91 { 99 get { return m_Entity; }
92 m_Entity = new SceneObjectGroup(objectXML); 100 }
93 m_Entity.SetScene(scene); 101
94 Initialize(physics); 102 public int PrimCount
95 } 103 {
96 104 get { return m_Entity.PrimCount; }
97 // The metaentity objectgroup must have unique localids as well as unique uuids. 105 }
98 // localids are used by the client to refer to parts. 106
99 // uuids are sent to the client and back to the server to identify parts on the server side. 107 public SceneObjectPart RootPart
100 /// <summary> 108 {
101 /// Changes localids and uuids of m_Entity. 109 get { return m_Entity.RootPart; }
102 /// </summary> 110 set { m_Entity.RootPart = value; }
103 protected void Initialize(bool physics) 111 }
104 { 112
105 //make new uuids 113 public Scene Scene
106 Dictionary<LLUUID, SceneObjectPart> parts = new Dictionary<LLUUID, SceneObjectPart>(); 114 {
107 foreach(SceneObjectPart part in m_Entity.Children.Values) 115 get { return m_Entity.Scene; }
108 { 116 }
109 part.ResetIDs(part.LinkNum); 117
110 parts.Add(part.UUID, part); 118 public LLUUID UUID
111 } 119 {
112 120 get { return m_Entity.UUID; }
113 // make new localids 121 set { m_Entity.UUID = value; }
114 foreach (SceneObjectPart part in m_Entity.Children.Values) 122 }
115 part.LocalId = m_Entity.Scene.PrimIDAllocate(); 123
116 124 #endregion Public Properties
117 //finalize 125
118 m_Entity.UpdateParentIDs(); 126 #region Protected Methods
119 m_Entity.RootPart.PhysActor = null; 127
120 m_Entity.Children = parts; 128 // The metaentity objectgroup must have unique localids as well as unique uuids.
121 129 // localids are used by the client to refer to parts.
122 } 130 // uuids are sent to the client and back to the server to identify parts on the server side.
123 131 /// <summary>
124 public void SendFullUpdate(IClientAPI client) 132 /// Changes localids and uuids of m_Entity.
125 { 133 /// </summary>
126 // Not sure what clientFlags should be but 0 seems to work 134 protected void Initialize(bool physics)
127 SendFullUpdate(client, 0); 135 {
128 } 136 //make new uuids
129 public void SendFullUpdateToAll() 137 Dictionary<LLUUID, SceneObjectPart> parts = new Dictionary<LLUUID, SceneObjectPart>();
130 { 138 foreach(SceneObjectPart part in m_Entity.Children.Values)
131 uint clientFlags = 0; 139 {
132 m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) 140 part.ResetIDs(part.LinkNum);
133 { m_Entity.SendFullUpdateToClient(controller, clientFlags); } 141 parts.Add(part.UUID, part);
134 ); 142 }
135 } 143
136 144 // make new localids
137 public void SendFullUpdate(IClientAPI client, uint clientFlags) 145 foreach (SceneObjectPart part in m_Entity.Children.Values)
138 { 146 part.LocalId = m_Entity.Scene.PrimIDAllocate();
139 m_Entity.SendFullUpdateToClient(client, clientFlags); 147
140 } 148 //finalize
141 149 m_Entity.UpdateParentIDs();
142 /// <summary> 150 m_Entity.RootPart.PhysActor = null;
143 /// Hides the metaentity from a single client. 151 m_Entity.Children = parts;
144 /// </summary> 152 }
145 public virtual void Hide(IClientAPI client) 153
146 { 154 #endregion Protected Methods
147 //This deletes the group without removing from any databases. 155
148 //This is important because we are not IN any database. 156 #region Public Methods
149 //m_Entity.FakeDeleteGroup(); 157
150 foreach( SceneObjectPart part in m_Entity.Children.Values) 158 /// <summary>
151 client.SendKillObject(m_Entity.RegionHandle, part.LocalId); 159 /// Hides the metaentity from a single client.
152 } 160 /// </summary>
153 161 public virtual void Hide(IClientAPI client)
154 /// <summary> 162 {
155 /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server. 163 //This deletes the group without removing from any databases.
156 /// </summary> 164 //This is important because we are not IN any database.
157 public virtual void HideFromAll() 165 //m_Entity.FakeDeleteGroup();
158 { 166 foreach( SceneObjectPart part in m_Entity.Children.Values)
159 foreach( SceneObjectPart part in m_Entity.Children.Values) 167 client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
160 m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) 168 }
161 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } 169
162 ); 170 /// <summary>
163 } 171 /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
164 172 /// </summary>
165 /// <summary> 173 public virtual void HideFromAll()
166 /// Makes a single SceneObjectPart see through. 174 {
167 /// </summary> 175 foreach( SceneObjectPart part in m_Entity.Children.Values)
168 /// <param name="part"> 176 m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller)
169 /// A <see cref="SceneObjectPart"/> 177 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
170 /// The part to make see through 178 );
171 /// </param> 179 }
172 /// <param name="transparencyAmount"> 180
173 /// A <see cref="System.Single"/> 181 public void SendFullUpdate(IClientAPI client)
174 /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible. 182 {
175 /// </param> 183 // Not sure what clientFlags should be but 0 seems to work
176 public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount) 184 SendFullUpdate(client, 0);
177 { 185 }
178 LLObject.TextureEntry tex = null; 186
179 LLColor texcolor; 187 public void SendFullUpdate(IClientAPI client, uint clientFlags)
180 try 188 {
181 { 189 m_Entity.SendFullUpdateToClient(client, clientFlags);
182 tex = part.Shape.Textures; 190 }
183 texcolor = new LLColor(); 191
184 } 192 public void SendFullUpdateToAll()
185 catch(Exception) 193 {
186 { 194 uint clientFlags = 0;
187 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e); 195 m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller)
188 return; 196 { m_Entity.SendFullUpdateToClient(controller, clientFlags); }
189 } 197 );
190 198 }
191 for (uint i = 0; i < tex.FaceTextures.Length; i++) 199
192 { 200 /// <summary>
193 try { 201 /// Makes a single SceneObjectPart see through.
194 if (tex.FaceTextures[i] != null) 202 /// </summary>
195 { 203 /// <param name="part">
196 texcolor = tex.FaceTextures[i].RGBA; 204 /// A <see cref="SceneObjectPart"/>
197 texcolor.A = transparencyAmount; 205 /// The part to make see through
198 tex.FaceTextures[i].RGBA = texcolor; 206 /// </param>
199 } 207 /// <param name="transparencyAmount">
200 } 208 /// A <see cref="System.Single"/>
201 catch (Exception) 209 /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible.
202 { 210 /// </param>
203 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e); 211 public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount)
204 continue; 212 {
205 } 213 LLObject.TextureEntry tex = null;
206 } 214 LLColor texcolor;
207 try { 215 try
208 texcolor = tex.DefaultTexture.RGBA; 216 {
209 texcolor.A = transparencyAmount; 217 tex = part.Shape.Textures;
210 tex.DefaultTexture.RGBA = texcolor; 218 texcolor = new LLColor();
211 part.Shape.TextureEntry = tex.ToBytes(); 219 }
212 } 220 catch(Exception)
213 catch (Exception) 221 {
214 { 222 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e);
215 //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e); 223 return;
216 } 224 }
217 } 225
218 } 226 for (uint i = 0; i < tex.FaceTextures.Length; i++)
227 {
228 try {
229 if (tex.FaceTextures[i] != null)
230 {
231 texcolor = tex.FaceTextures[i].RGBA;
232 texcolor.A = transparencyAmount;
233 tex.FaceTextures[i].RGBA = texcolor;
234 }
235 }
236 catch (Exception)
237 {
238 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e);
239 continue;
240 }
241 }
242 try {
243 texcolor = tex.DefaultTexture.RGBA;
244 texcolor.A = transparencyAmount;
245 tex.DefaultTexture.RGBA = texcolor;
246 part.Shape.TextureEntry = tex.ToBytes();
247 }
248 catch (Exception)
249 {
250 //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e);
251 }
252 }
253
254 #endregion Public Methods
255 }
219} \ No newline at end of file 256} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs
index 55365ac..bfa7e5d 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/PointMetaEntity.cs
@@ -1,81 +1,97 @@
1#region Header
2
1// PointMetaEntity.cs created with MonoDevelop 3// PointMetaEntity.cs created with MonoDevelop
2// User: bongiojp at 3:03 PM 8/6/2008 4// User: bongiojp at 3:03 PM 8/6/2008
3// 5//
4// To change standard headers go to Edit->Preferences->Coding->Standard Headers 6// To change standard headers go to Edit->Preferences->Coding->Standard Headers
5// 7//
6 8
9#endregion Header
10
7using System; 11using System;
8using System.Collections.Generic; 12using System.Collections.Generic;
9using System.Drawing; 13using System.Drawing;
14
10using libsecondlife; 15using libsecondlife;
16
11using Nini.Config; 17using Nini.Config;
18
12using OpenSim.Framework; 19using OpenSim.Framework;
13using OpenSim.Region.Environment.Interfaces; 20using OpenSim.Region.Environment.Interfaces;
14using OpenSim.Region.Environment.Scenes; 21using OpenSim.Region.Environment.Scenes;
15using log4net;
16using OpenSim.Region.Physics.Manager; 22using OpenSim.Region.Physics.Manager;
23
24using log4net;
25
17using Axiom.Math; 26using Axiom.Math;
18 27
19namespace OpenSim.Region.Environment.Modules.ContentManagement 28namespace OpenSim.Region.Environment.Modules.ContentManagement
20{ 29{
21 30 public class PointMetaEntity : MetaEntity
22 31 {
23 public class PointMetaEntity : MetaEntity 32 #region Constructors
24 { 33
25 34 public PointMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency)
26 public PointMetaEntity(Scene scene, uint LocalId, LLVector3 groupPos, float transparency) : base() 35 : base()
27 { 36 {
28 CreatePointEntity(scene, LLUUID.Random(), LocalId, groupPos); 37 CreatePointEntity(scene, LLUUID.Random(), LocalId, groupPos);
29 SetPartTransparency(m_Entity.RootPart, transparency); 38 SetPartTransparency(m_Entity.RootPart, transparency);
30 } 39 }
31 40
32 public PointMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency) : base() 41 public PointMetaEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos, float transparency)
33 { 42 : base()
34 CreatePointEntity(scene, uuid, LocalId, groupPos); 43 {
35 SetPartTransparency(m_Entity.RootPart, transparency); 44 CreatePointEntity(scene, uuid, LocalId, groupPos);
36 } 45 SetPartTransparency(m_Entity.RootPart, transparency);
37 46 }
38 private void CreatePointEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos) 47
39 { 48 #endregion Constructors
40 SceneObjectGroup x = new SceneObjectGroup(); 49
41 SceneObjectPart y = new SceneObjectPart(); 50 #region Private Methods
42 51
43 //Initialize part 52 private void CreatePointEntity(Scene scene, LLUUID uuid, uint LocalId, LLVector3 groupPos)
44 y.Name = "Very Small Point"; 53 {
54 SceneObjectGroup x = new SceneObjectGroup();
55 SceneObjectPart y = new SceneObjectPart();
56
57 //Initialize part
58 y.Name = "Very Small Point";
45 y.RegionHandle = scene.RegionInfo.RegionHandle; 59 y.RegionHandle = scene.RegionInfo.RegionHandle;
46 y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; 60 y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
47 y.OwnerID = LLUUID.Zero; 61 y.OwnerID = LLUUID.Zero;
48 y.CreatorID = LLUUID.Zero; 62 y.CreatorID = LLUUID.Zero;
49 y.LastOwnerID = LLUUID.Zero; 63 y.LastOwnerID = LLUUID.Zero;
50 y.UUID = uuid; 64 y.UUID = uuid;
51 65
52 y.LocalId = LocalId; 66 y.LocalId = LocalId;
53 67
54 y.Shape = PrimitiveBaseShape.CreateBox(); 68 y.Shape = PrimitiveBaseShape.CreateBox();
55 y.Scale = new LLVector3(0.01f,0.01f,0.01f); 69 y.Scale = new LLVector3(0.01f,0.01f,0.01f);
56 y.LastOwnerID = LLUUID.Zero; 70 y.LastOwnerID = LLUUID.Zero;
57 y.GroupPosition = groupPos; 71 y.GroupPosition = groupPos;
58 y.OffsetPosition = new LLVector3(0, 0, 0); 72 y.OffsetPosition = new LLVector3(0, 0, 0);
59 y.RotationOffset = new LLQuaternion(0,0,0,0); 73 y.RotationOffset = new LLQuaternion(0,0,0,0);
60 y.Velocity = new LLVector3(0, 0, 0); 74 y.Velocity = new LLVector3(0, 0, 0);
61 y.RotationalVelocity = new LLVector3(0, 0, 0); 75 y.RotationalVelocity = new LLVector3(0, 0, 0);
62 y.AngularVelocity = new LLVector3(0, 0, 0); 76 y.AngularVelocity = new LLVector3(0, 0, 0);
63 y.Acceleration = new LLVector3(0, 0, 0); 77 y.Acceleration = new LLVector3(0, 0, 0);
64 78
65 y.Flags = 0; 79 y.Flags = 0;
66 y.TrimPermissions(); 80 y.TrimPermissions();
67 81
68 //Initialize group and add part as root part 82 //Initialize group and add part as root part
69 x.SetScene(scene); 83 x.SetScene(scene);
70 y.SetParent(x); 84 y.SetParent(x);
71 y.ParentID = 0; 85 y.ParentID = 0;
72 y.LinkNum = 0; 86 y.LinkNum = 0;
73 x.Children.Add(y.UUID, y); 87 x.Children.Add(y.UUID, y);
74 x.RootPart = y; 88 x.RootPart = y;
75 x.RegionHandle = scene.RegionInfo.RegionHandle; 89 x.RegionHandle = scene.RegionInfo.RegionHandle;
76 x.SetScene(scene); 90 x.SetScene(scene);
77 91
78 m_Entity = x; 92 m_Entity = x;
79 } 93 }
80 } 94
81} 95 #endregion Private Methods
96 }
97} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs
index c3817ef..6f34d3b 100644
--- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/SceneObjectGroupDiff.cs
@@ -1,87 +1,113 @@
1#region Header
2
1// SceneObjectGroupDiff.cs 3// SceneObjectGroupDiff.cs
2// User: bongiojp 4// User: bongiojp
3 5
6#endregion Header
7
4using System; 8using System;
5using System.Collections.Generic; 9using System.Collections.Generic;
10using System.Diagnostics;
6using System.Drawing; 11using System.Drawing;
12
7using libsecondlife; 13using libsecondlife;
14
8using Nini.Config; 15using Nini.Config;
16
9using OpenSim.Framework; 17using OpenSim.Framework;
10using OpenSim.Region.Environment.Interfaces; 18using OpenSim.Region.Environment.Interfaces;
11using OpenSim.Region.Environment.Scenes; 19using OpenSim.Region.Environment.Scenes;
12using log4net;
13using OpenSim.Region.Physics.Manager; 20using OpenSim.Region.Physics.Manager;
21
22using log4net;
23
14using Axiom.Math; 24using Axiom.Math;
15using System.Diagnostics;
16 25
17namespace OpenSim.Region.Environment.Modules.ContentManagement 26namespace OpenSim.Region.Environment.Modules.ContentManagement
18{ 27{
19 [Flags] 28 #region Enumerations
20 public enum Diff 29
21 { 30 [Flags]
22 NONE = 0, 31 public enum Diff
23 FACECOLOR = 1, 32 {
24 SHAPE = 1<<1, 33 NONE = 0,
25 MATERIAL = 1<<2, 34 FACECOLOR = 1,
26 TEXTURE = 1<<3, 35 SHAPE = 1<<1,
27 SCALE = 1<<4, 36 MATERIAL = 1<<2,
28 POSITION = 1<<5, 37 TEXTURE = 1<<3,
29 OFFSETPOSITION = 1<<6, 38 SCALE = 1<<4,
30 ROTATIONOFFSET = 1<<7, 39 POSITION = 1<<5,
31 ROTATIONALVELOCITY = 1<<8, 40 OFFSETPOSITION = 1<<6,
32 ACCELERATION = 1<<9, 41 ROTATIONOFFSET = 1<<7,
33 ANGULARVELOCITY = 1<<10, 42 ROTATIONALVELOCITY = 1<<8,
34 VELOCITY = 1<<11, 43 ACCELERATION = 1<<9,
35 OBJECTOWNER = 1<<12, 44 ANGULARVELOCITY = 1<<10,
36 PERMISSIONS = 1<<13, 45 VELOCITY = 1<<11,
37 DESCRIPTION = 1<<14, 46 OBJECTOWNER = 1<<12,
38 NAME = 1<<15, 47 PERMISSIONS = 1<<13,
39 SCRIPT = 1<<16, 48 DESCRIPTION = 1<<14,
40 CLICKACTION = 1<<17, 49 NAME = 1<<15,
41 PARTICLESYSTEM = 1<<18, 50 SCRIPT = 1<<16,
42 GLOW = 1<<19, 51 CLICKACTION = 1<<17,
43 SALEPRICE = 1<<20, 52 PARTICLESYSTEM = 1<<18,
44 SITNAME = 1<<21, 53 GLOW = 1<<19,
45 SITTARGETORIENTATION = 1<<22, 54 SALEPRICE = 1<<20,
46 SITTARGETPOSITION = 1<<23, 55 SITNAME = 1<<21,
47 TEXT = 1<<24, 56 SITTARGETORIENTATION = 1<<22,
48 TOUCHNAME = 1<<25 57 SITTARGETPOSITION = 1<<23,
49 }; 58 TEXT = 1<<24,
50 59 TOUCHNAME = 1<<25
51 public static class Difference 60 }
52 { 61
53 static float TimeToDiff = 0; 62 #endregion Enumerations
54 63
55 private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 64 public static class Difference
56 65 {
57 private static int TruncateSignificant(float num, int digits) 66 #region Static Fields
58 { 67
59 return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits)); 68 static float TimeToDiff = 0;
60 // return (int) ((num * (10*digits))/10*digits); 69 private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
61 } 70
62 71 #endregion Static Fields
63 private static bool AreVectorsEquivalent(LLVector3 first, LLVector3 second) 72
64 { 73 #region Private Methods
65 if(TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2) 74
66 && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2) 75 private static bool AreQuaternionsEquivalent(LLQuaternion first, LLQuaternion second)
67 && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2) 76 {
68 ) 77 LLVector3 firstVector = llRot2Euler(first);
69 return true; 78 LLVector3 secondVector = llRot2Euler(second);
70 else 79 return AreVectorsEquivalent(firstVector, secondVector);
71 return false; 80 }
72 } 81
73 82 private static bool AreVectorsEquivalent(LLVector3 first, LLVector3 second)
74 private static bool AreQuaternionsEquivalent(LLQuaternion first, LLQuaternion second) 83 {
75 { 84 if(TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2)
76 LLVector3 firstVector = llRot2Euler(first); 85 && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2)
77 LLVector3 secondVector = llRot2Euler(second); 86 && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2)
78 return AreVectorsEquivalent(firstVector, secondVector); 87 )
79 } 88 return true;
80 89 else
81 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs 90 return false;
82 // Also changed the original function from LSL_Types to LL types 91 }
92
93 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
94 private static double NormalizeAngle(double angle)
95 {
96 angle = angle % (Math.PI * 2);
97 if (angle < 0) angle = angle + Math.PI * 2;
98 return angle;
99 }
100
101 private static int TruncateSignificant(float num, int digits)
102 {
103 return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits));
104 // return (int) ((num * (10*digits))/10*digits);
105 }
106
107 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
108 // Also changed the original function from LSL_Types to LL types
83 private static LLVector3 llRot2Euler(LLQuaternion r) 109 private static LLVector3 llRot2Euler(LLQuaternion r)
84 { 110 {
85 LLQuaternion t = new LLQuaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W); 111 LLQuaternion t = new LLQuaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W);
86 double m = (t.X + t.Y + t.Z + t.W); 112 double m = (t.X + t.Y + t.Z + t.W);
87 if (m == 0) return new LLVector3(); 113 if (m == 0) return new LLVector3();
@@ -96,74 +122,72 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement
96 else 122 else
97 return new LLVector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z))); 123 return new LLVector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
98 } 124 }
99 125
100 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs 126 #endregion Private Methods
101 private static double NormalizeAngle(double angle) 127
102 { 128 #region Public Methods
103 angle = angle % (Math.PI * 2); 129
104 if (angle < 0) angle = angle + Math.PI * 2; 130 /// <summary>
105 return angle; 131 /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts
132 /// and returns a Diff bitmask which details what the differences are.
133 /// </summary>
134 public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
135 {
136 Stopwatch x = new Stopwatch();
137 x.Start();
138
139 Diff result = 0;
140
141 // VECTOR COMPARISONS
142 if(! AreVectorsEquivalent(first.Acceleration, second.Acceleration))
143 result |= Diff.ACCELERATION;
144 if(! AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
145 result |= Diff.POSITION;
146 if(! AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
147 result |= Diff.ANGULARVELOCITY;
148 if(! AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
149 result |= Diff.OFFSETPOSITION;
150 if(! AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity))
151 result |= Diff.ROTATIONALVELOCITY;
152 if(! AreVectorsEquivalent(first.Scale, second.Scale))
153 result |= Diff.SCALE;
154 if(! AreVectorsEquivalent(first.Velocity, second.Velocity))
155 result |= Diff.VELOCITY;
156
157
158 // QUATERNION COMPARISONS
159 if(! AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
160 result |= Diff.ROTATIONOFFSET;
161
162
163 // MISC COMPARISONS (LLUUID, Byte)
164 if(first.ClickAction != second.ClickAction)
165 result |= Diff.CLICKACTION;
166 if(first.ObjectOwner != second.ObjectOwner)
167 result |= Diff.OBJECTOWNER;
168
169
170 // STRING COMPARISONS
171 if(first.Description != second.Description)
172 result |= Diff.DESCRIPTION;
173 if(first.Material != second.Material)
174 result |= Diff.MATERIAL;
175 if(first.Name != second.Name)
176 result |= Diff.NAME;
177 if(first.SitName != second.SitName)
178 result |= Diff.SITNAME;
179 if(first.Text != second.Text)
180 result |= Diff.TEXT;
181 if(first.TouchName != second.TouchName)
182 result |= Diff.TOUCHNAME;
183
184 x.Stop();
185 TimeToDiff += x.ElapsedMilliseconds;
186 //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
187
188 return result;
106 } 189 }
107 190
108 /// <summary> 191 #endregion Public Methods
109 /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts 192 }
110 /// and returns a Diff bitmask which details what the differences are. 193} \ No newline at end of file
111 /// </summary>
112 public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
113 {
114 Stopwatch x = new Stopwatch();
115 x.Start();
116
117 Diff result = 0;
118
119 // VECTOR COMPARISONS
120 if(! AreVectorsEquivalent(first.Acceleration, second.Acceleration))
121 result |= Diff.ACCELERATION;
122 if(! AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
123 result |= Diff.POSITION;
124 if(! AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
125 result |= Diff.ANGULARVELOCITY;
126 if(! AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
127 result |= Diff.OFFSETPOSITION;
128 if(! AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity))
129 result |= Diff.ROTATIONALVELOCITY;
130 if(! AreVectorsEquivalent(first.Scale, second.Scale))
131 result |= Diff.SCALE;
132 if(! AreVectorsEquivalent(first.Velocity, second.Velocity))
133 result |= Diff.VELOCITY;
134
135
136 // QUATERNION COMPARISONS
137 if(! AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
138 result |= Diff.ROTATIONOFFSET;
139
140
141 // MISC COMPARISONS (LLUUID, Byte)
142 if(first.ClickAction != second.ClickAction)
143 result |= Diff.CLICKACTION;
144 if(first.ObjectOwner != second.ObjectOwner)
145 result |= Diff.OBJECTOWNER;
146
147
148 // STRING COMPARISONS
149 if(first.Description != second.Description)
150 result |= Diff.DESCRIPTION;
151 if(first.Material != second.Material)
152 result |= Diff.MATERIAL;
153 if(first.Name != second.Name)
154 result |= Diff.NAME;
155 if(first.SitName != second.SitName)
156 result |= Diff.SITNAME;
157 if(first.Text != second.Text)
158 result |= Diff.TEXT;
159 if(first.TouchName != second.TouchName)
160 result |= Diff.TOUCHNAME;
161
162 x.Stop();
163 TimeToDiff += x.ElapsedMilliseconds;
164 //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
165
166 return result;
167 }
168 }
169}